public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] linux-patches r2149 - genpatches-2.6/trunk/3.3
@ 2012-06-06  0:39 Mike Pagano (mpagano)
  0 siblings, 0 replies; only message in thread
From: Mike Pagano (mpagano) @ 2012-06-06  0:39 UTC (permalink / raw
  To: gentoo-commits

Author: mpagano
Date: 2012-06-06 00:39:15 +0000 (Wed, 06 Jun 2012)
New Revision: 2149

Added:
   genpatches-2.6/trunk/3.3/1007_linux-3.3.8.patch
Modified:
   genpatches-2.6/trunk/3.3/0000_README
Log:
Linux patch 3.3.8

Modified: genpatches-2.6/trunk/3.3/0000_README
===================================================================
--- genpatches-2.6/trunk/3.3/0000_README	2012-06-04 22:58:55 UTC (rev 2148)
+++ genpatches-2.6/trunk/3.3/0000_README	2012-06-06 00:39:15 UTC (rev 2149)
@@ -68,6 +68,10 @@
 From:   http://www.kernel.org
 Desc:   Linux 3.3.7
 
+Patch:  1007_linux-3.3.8.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.3.8
+
 Patch: 	1700_tsunami-modpost-include-fix.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=415033
 Desc:   Patch to include module.h to fix modpost on Tsunami

Added: genpatches-2.6/trunk/3.3/1007_linux-3.3.8.patch
===================================================================
--- genpatches-2.6/trunk/3.3/1007_linux-3.3.8.patch	                        (rev 0)
+++ genpatches-2.6/trunk/3.3/1007_linux-3.3.8.patch	2012-06-06 00:39:15 UTC (rev 2149)
@@ -0,0 +1,4573 @@
+diff --git a/Documentation/HOWTO b/Documentation/HOWTO
+index f7ade3b..59c080f 100644
+--- a/Documentation/HOWTO
++++ b/Documentation/HOWTO
+@@ -218,16 +218,16 @@ The development process
+ Linux kernel development process currently consists of a few different
+ main kernel "branches" and lots of different subsystem-specific kernel
+ branches.  These different branches are:
+-  - main 2.6.x kernel tree
+-  - 2.6.x.y -stable kernel tree
+-  - 2.6.x -git kernel patches
++  - main 3.x kernel tree
++  - 3.x.y -stable kernel tree
++  - 3.x -git kernel patches
+   - subsystem specific kernel trees and patches
+-  - the 2.6.x -next kernel tree for integration tests
++  - the 3.x -next kernel tree for integration tests
+ 
+-2.6.x kernel tree
++3.x kernel tree
+ -----------------
+-2.6.x kernels are maintained by Linus Torvalds, and can be found on
+-kernel.org in the pub/linux/kernel/v2.6/ directory.  Its development
++3.x kernels are maintained by Linus Torvalds, and can be found on
++kernel.org in the pub/linux/kernel/v3.x/ directory.  Its development
+ process is as follows:
+   - As soon as a new kernel is released a two weeks window is open,
+     during this period of time maintainers can submit big diffs to
+@@ -262,20 +262,20 @@ mailing list about kernel releases:
+ 	released according to perceived bug status, not according to a
+ 	preconceived timeline."
+ 
+-2.6.x.y -stable kernel tree
++3.x.y -stable kernel tree
+ ---------------------------
+-Kernels with 4-part versions are -stable kernels. They contain
++Kernels with 3-part versions are -stable kernels. They contain
+ relatively small and critical fixes for security problems or significant
+-regressions discovered in a given 2.6.x kernel.
++regressions discovered in a given 3.x kernel.
+ 
+ This is the recommended branch for users who want the most recent stable
+ kernel and are not interested in helping test development/experimental
+ versions.
+ 
+-If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
++If no 3.x.y kernel is available, then the highest numbered 3.x
+ kernel is the current stable kernel.
+ 
+-2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
++3.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
+ are released as needs dictate.  The normal release period is approximately
+ two weeks, but it can be longer if there are no pressing problems.  A
+ security-related problem, instead, can cause a release to happen almost
+@@ -285,7 +285,7 @@ The file Documentation/stable_kernel_rules.txt in the kernel tree
+ documents what kinds of changes are acceptable for the -stable tree, and
+ how the release process works.
+ 
+-2.6.x -git patches
++3.x -git patches
+ ------------------
+ These are daily snapshots of Linus' kernel tree which are managed in a
+ git repository (hence the name.) These patches are usually released
+@@ -317,13 +317,13 @@ revisions to it, and maintainers can mark patches as under review,
+ accepted, or rejected.  Most of these patchwork sites are listed at
+ http://patchwork.kernel.org/.
+ 
+-2.6.x -next kernel tree for integration tests
++3.x -next kernel tree for integration tests
+ ---------------------------------------------
+-Before updates from subsystem trees are merged into the mainline 2.6.x
++Before updates from subsystem trees are merged into the mainline 3.x
+ tree, they need to be integration-tested.  For this purpose, a special
+ testing repository exists into which virtually all subsystem trees are
+ pulled on an almost daily basis:
+-	http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
++	http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
+ 	http://linux.f-seidel.de/linux-next/pmwiki/
+ 
+ This way, the -next kernel gives a summary outlook onto what will be
+diff --git a/Makefile b/Makefile
+index 073f74f..db96149 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 3
+-SUBLEVEL = 7
++SUBLEVEL = 8
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+ 
+@@ -442,7 +442,7 @@ asm-generic:
+ 
+ no-dot-config-targets := clean mrproper distclean \
+ 			 cscope gtags TAGS tags help %docs check% coccicheck \
+-			 include/linux/version.h headers_% archheaders \
++			 include/linux/version.h headers_% archheaders archscripts \
+ 			 kernelversion %src-pkg
+ 
+ config-targets := 0
+@@ -979,7 +979,7 @@ prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \
+                    include/config/auto.conf
+ 	$(cmd_crmodverdir)
+ 
+-archprepare: archheaders prepare1 scripts_basic
++archprepare: archheaders archscripts prepare1 scripts_basic
+ 
+ prepare0: archprepare FORCE
+ 	$(Q)$(MAKE) $(build)=.
+@@ -1049,8 +1049,11 @@ hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm)
+ PHONY += archheaders
+ archheaders:
+ 
++PHONY += archscripts
++archscripts:
++
+ PHONY += __headers
+-__headers: include/linux/version.h scripts_basic asm-generic archheaders FORCE
++__headers: include/linux/version.h scripts_basic asm-generic archheaders archscripts FORCE
+ 	$(Q)$(MAKE) $(build)=scripts build_unifdef
+ 
+ PHONY += headers_install_all
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index d5d8d5c..1252a26 100644
+--- a/arch/arm/include/asm/cacheflush.h
++++ b/arch/arm/include/asm/cacheflush.h
+@@ -249,7 +249,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr
+  * Harvard caches are synchronised for the user space address range.
+  * This is used for the ARM private sys_cacheflush system call.
+  */
+-#define flush_cache_user_range(vma,start,end) \
++#define flush_cache_user_range(start,end) \
+ 	__cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
+ 
+ /*
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index f84dfe6..504b28a 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -491,7 +491,9 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
+ 		if (end > vma->vm_end)
+ 			end = vma->vm_end;
+ 
+-		flush_cache_user_range(vma, start, end);
++		up_read(&mm->mmap_sem);
++		flush_cache_user_range(start, end);
++		return;
+ 	}
+ 	up_read(&mm->mmap_sem);
+ }
+diff --git a/arch/parisc/include/asm/prefetch.h b/arch/parisc/include/asm/prefetch.h
+index c5edc60..1ee7c82 100644
+--- a/arch/parisc/include/asm/prefetch.h
++++ b/arch/parisc/include/asm/prefetch.h
+@@ -21,7 +21,12 @@
+ #define ARCH_HAS_PREFETCH
+ static inline void prefetch(const void *addr)
+ {
+-	__asm__("ldw 0(%0), %%r0" : : "r" (addr));
++	__asm__(
++#ifndef CONFIG_PA20
++		/* Need to avoid prefetch of NULL on PA7300LC */
++		"	extrw,u,= %0,31,32,%%r0\n"
++#endif
++		"	ldw 0(%0), %%r0" : : "r" (addr));
+ }
+ 
+ /* LDD is a PA2.0 addition. */
+diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
+index 6f05944..5350342 100644
+--- a/arch/parisc/kernel/entry.S
++++ b/arch/parisc/kernel/entry.S
+@@ -581,7 +581,11 @@
+ 	 */
+ 	cmpiclr,=	0x01,\tmp,%r0
+ 	ldi		(_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
++#ifdef CONFIG_64BIT
+ 	depd,z		\prot,8,7,\prot
++#else
++	depw,z		\prot,8,7,\prot
++#endif
+ 	/*
+ 	 * OK, it is in the temp alias region, check whether "from" or "to".
+ 	 * Check "subtle" note in pacache.S re: r23/r26.
+diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
+index 93ff3d9..5d7218a 100644
+--- a/arch/parisc/kernel/pacache.S
++++ b/arch/parisc/kernel/pacache.S
+@@ -692,7 +692,7 @@ ENTRY(flush_icache_page_asm)
+ 
+ 	/* Purge any old translation */
+ 
+-	pitlb		(%sr0,%r28)
++	pitlb		(%sr4,%r28)
+ 
+ 	ldil		L%icache_stride, %r1
+ 	ldw		R%icache_stride(%r1), %r1
+@@ -706,27 +706,29 @@ ENTRY(flush_icache_page_asm)
+ 	sub		%r25, %r1, %r25
+ 
+ 
+-1:      fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
+-	fic,m		%r1(%r28)
++	/* fic only has the type 26 form on PA1.1, requiring an
++	 * explicit space specification, so use %sr4 */
++1:      fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
++	fic,m		%r1(%sr4,%r28)
+ 	cmpb,COND(<<)		%r28, %r25,1b
+-	fic,m		%r1(%r28)
++	fic,m		%r1(%sr4,%r28)
+ 
+ 	sync
+ 	bv		%r0(%r2)
+-	pitlb		(%sr0,%r25)
++	pitlb		(%sr4,%r25)
+ 	.exit
+ 
+ 	.procend
+diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
+index 0a48bf5..b556964 100644
+--- a/arch/powerpc/kernel/idle.c
++++ b/arch/powerpc/kernel/idle.c
+@@ -109,6 +109,9 @@ void cpu_idle(void)
+ 	}
+ }
+ 
++static void do_nothing(void *unused)
++{
++}
+ 
+ /*
+  * cpu_idle_wait - Used to ensure that all the CPUs come out of the old
+@@ -119,16 +122,9 @@ void cpu_idle(void)
+  */
+ void cpu_idle_wait(void)
+ {
+-	int cpu;
+ 	smp_mb();
+-
+-	/* kick all the CPUs so that they exit out of old idle routine */
+-	get_online_cpus();
+-	for_each_online_cpu(cpu) {
+-		if (cpu != smp_processor_id())
+-			smp_send_reschedule(cpu);
+-	}
+-	put_online_cpus();
++	/* kick all the CPUs so that they exit out of pm_idle */
++	smp_call_function(do_nothing, NULL, 1);
+ }
+ EXPORT_SYMBOL_GPL(cpu_idle_wait);
+ 
+diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
+index e8fcd92..c6057f2 100644
+--- a/arch/s390/mm/fault.c
++++ b/arch/s390/mm/fault.c
+@@ -574,6 +574,7 @@ static void pfault_interrupt(unsigned int ext_int_code,
+ 			tsk->thread.pfault_wait = 0;
+ 			list_del(&tsk->thread.list);
+ 			wake_up_process(tsk);
++			put_task_struct(tsk);
+ 		} else {
+ 			/* Completion interrupt was faster than initial
+ 			 * interrupt. Set pfault_wait to -1 so the initial
+@@ -588,14 +589,22 @@ static void pfault_interrupt(unsigned int ext_int_code,
+ 		put_task_struct(tsk);
+ 	} else {
+ 		/* signal bit not set -> a real page is missing. */
+-		if (tsk->thread.pfault_wait == -1) {
++		if (tsk->thread.pfault_wait == 1) {
++			/* Already on the list with a reference: put to sleep */
++			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
++			set_tsk_need_resched(tsk);
++		} else if (tsk->thread.pfault_wait == -1) {
+ 			/* Completion interrupt was faster than the initial
+ 			 * interrupt (pfault_wait == -1). Set pfault_wait
+ 			 * back to zero and exit. */
+ 			tsk->thread.pfault_wait = 0;
+ 		} else {
+ 			/* Initial interrupt arrived before completion
+-			 * interrupt. Let the task sleep. */
++			 * interrupt. Let the task sleep.
++			 * An extra task reference is needed since a different
++			 * cpu may set the task state to TASK_RUNNING again
++			 * before the scheduler is reached. */
++			get_task_struct(tsk);
+ 			tsk->thread.pfault_wait = 1;
+ 			list_add(&tsk->thread.list, &pfault_list);
+ 			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+@@ -620,6 +629,7 @@ static int __cpuinit pfault_cpu_notify(struct notifier_block *self,
+ 			list_del(&thread->list);
+ 			tsk = container_of(thread, struct task_struct, thread);
+ 			wake_up_process(tsk);
++			put_task_struct(tsk);
+ 		}
+ 		spin_unlock_irq(&pfault_lock);
+ 		break;
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index ca5580e..312fd5f 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -582,6 +582,9 @@ config SYSVIPC_COMPAT
+ 	depends on COMPAT && SYSVIPC
+ 	default y
+ 
++config KEYS_COMPAT
++	def_bool y if COMPAT && KEYS
++
+ endmenu
+ 
+ source "net/Kconfig"
+diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
+index db86b1a..3a58e0d 100644
+--- a/arch/sparc/kernel/systbls_64.S
++++ b/arch/sparc/kernel/systbls_64.S
+@@ -74,7 +74,7 @@ sys_call_table32:
+ 	.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
+ /*270*/	.word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
+ 	.word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
+-/*280*/	.word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
++/*280*/	.word sys32_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
+ 	.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
+ /*290*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
+ 	.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
+diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
+index 11270ca..60e5be83 100644
+--- a/arch/tile/Kconfig
++++ b/arch/tile/Kconfig
+@@ -11,6 +11,7 @@ config TILE
+ 	select GENERIC_IRQ_PROBE
+ 	select GENERIC_PENDING_IRQ if SMP
+ 	select GENERIC_IRQ_SHOW
++	select HAVE_SYSCALL_WRAPPERS if TILEGX
+ 	select SYS_HYPERVISOR
+ 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386
+ 
+diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
+index 16f1fa5..bd186c4 100644
+--- a/arch/tile/include/asm/bitops.h
++++ b/arch/tile/include/asm/bitops.h
+@@ -77,6 +77,11 @@ static inline int ffs(int x)
+ 	return __builtin_ffs(x);
+ }
+ 
++static inline int fls64(__u64 w)
++{
++	return (sizeof(__u64) * 8) - __builtin_clzll(w);
++}
++
+ /**
+  * fls - find last set bit in word
+  * @x: the word to search
+@@ -90,12 +95,7 @@ static inline int ffs(int x)
+  */
+ static inline int fls(int x)
+ {
+-	return (sizeof(int) * 8) - __builtin_clz(x);
+-}
+-
+-static inline int fls64(__u64 w)
+-{
+-	return (sizeof(__u64) * 8) - __builtin_clzll(w);
++	return fls64((unsigned int) x);
+ }
+ 
+ static inline unsigned int __arch_hweight32(unsigned int w)
+diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
+index 41474fb..aa365c5 100644
+--- a/arch/um/include/asm/pgtable.h
++++ b/arch/um/include/asm/pgtable.h
+@@ -271,6 +271,12 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
+ }
+ #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+ 
++#define __HAVE_ARCH_PTE_SAME
++static inline int pte_same(pte_t pte_a, pte_t pte_b)
++{
++	return !((pte_val(pte_a) ^ pte_val(pte_b)) & ~_PAGE_NEWPAGE);
++}
++
+ /*
+  * Conversion functions: convert a page and protection to a page entry,
+  * and a page entry and page directory to the page they refer to.
+@@ -346,11 +352,11 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
+ #define update_mmu_cache(vma,address,ptep) do ; while (0)
+ 
+ /* Encode and de-code a swap entry */
+-#define __swp_type(x)			(((x).val >> 4) & 0x3f)
++#define __swp_type(x)			(((x).val >> 5) & 0x1f)
+ #define __swp_offset(x)			((x).val >> 11)
+ 
+ #define __swp_entry(type, offset) \
+-	((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
++	((swp_entry_t) { ((type) << 5) | ((offset) << 11) })
+ #define __pte_to_swp_entry(pte) \
+ 	((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
+ #define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 209ba12..015f0c5 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -117,6 +117,9 @@ KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
+ KBUILD_CFLAGS += $(mflags-y)
+ KBUILD_AFLAGS += $(mflags-y)
+ 
++archscripts:
++	$(Q)$(MAKE) $(build)=arch/x86/tools relocs
++
+ ###
+ # Syscall table generation
+ 
+@@ -186,6 +189,7 @@ archclean:
+ 	$(Q)rm -rf $(objtree)/arch/i386
+ 	$(Q)rm -rf $(objtree)/arch/x86_64
+ 	$(Q)$(MAKE) $(clean)=$(boot)
++	$(Q)$(MAKE) $(clean)=arch/x86/tools
+ 
+ define archhelp
+   echo  '* bzImage      - Compressed kernel image (arch/x86/boot/bzImage)'
+diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
+index fd55a2f..e398bb5 100644
+--- a/arch/x86/boot/compressed/Makefile
++++ b/arch/x86/boot/compressed/Makefile
+@@ -40,13 +40,12 @@ OBJCOPYFLAGS_vmlinux.bin :=  -R .comment -S
+ $(obj)/vmlinux.bin: vmlinux FORCE
+ 	$(call if_changed,objcopy)
+ 
++targets += vmlinux.bin.all vmlinux.relocs
+ 
+-targets += vmlinux.bin.all vmlinux.relocs relocs
+-hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs
+-
++CMD_RELOCS = arch/x86/tools/relocs
+ quiet_cmd_relocs = RELOCS  $@
+-      cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
+-$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
++      cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $<
++$(obj)/vmlinux.relocs: vmlinux FORCE
+ 	$(call if_changed,relocs)
+ 
+ vmlinux.bin.all-y := $(obj)/vmlinux.bin
+diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
+deleted file mode 100644
+index e77f4e4..0000000
+--- a/arch/x86/boot/compressed/relocs.c
++++ /dev/null
+@@ -1,680 +0,0 @@
+-#include <stdio.h>
+-#include <stdarg.h>
+-#include <stdlib.h>
+-#include <stdint.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <unistd.h>
+-#include <elf.h>
+-#include <byteswap.h>
+-#define USE_BSD
+-#include <endian.h>
+-#include <regex.h>
+-
+-static void die(char *fmt, ...);
+-
+-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+-static Elf32_Ehdr ehdr;
+-static unsigned long reloc_count, reloc_idx;
+-static unsigned long *relocs;
+-
+-struct section {
+-	Elf32_Shdr     shdr;
+-	struct section *link;
+-	Elf32_Sym      *symtab;
+-	Elf32_Rel      *reltab;
+-	char           *strtab;
+-};
+-static struct section *secs;
+-
+-/*
+- * Following symbols have been audited. There values are constant and do
+- * not change if bzImage is loaded at a different physical address than
+- * the address for which it has been compiled. Don't warn user about
+- * absolute relocations present w.r.t these symbols.
+- */
+-static const char abs_sym_regex[] =
+-	"^(xen_irq_disable_direct_reloc$|"
+-	"xen_save_fl_direct_reloc$|"
+-	"VDSO|"
+-	"__crc_)";
+-static regex_t abs_sym_regex_c;
+-static int is_abs_reloc(const char *sym_name)
+-{
+-	return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0);
+-}
+-
+-/*
+- * These symbols are known to be relative, even if the linker marks them
+- * as absolute (typically defined outside any section in the linker script.)
+- */
+-static const char rel_sym_regex[] =
+-	"^_end$";
+-static regex_t rel_sym_regex_c;
+-static int is_rel_reloc(const char *sym_name)
+-{
+-	return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0);
+-}
+-
+-static void regex_init(void)
+-{
+-        char errbuf[128];
+-        int err;
+-	
+-        err = regcomp(&abs_sym_regex_c, abs_sym_regex,
+-                      REG_EXTENDED|REG_NOSUB);
+-        if (err) {
+-                regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf);
+-                die("%s", errbuf);
+-        }
+-
+-        err = regcomp(&rel_sym_regex_c, rel_sym_regex,
+-                      REG_EXTENDED|REG_NOSUB);
+-        if (err) {
+-                regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf);
+-                die("%s", errbuf);
+-        }
+-}
+-
+-static void die(char *fmt, ...)
+-{
+-	va_list ap;
+-	va_start(ap, fmt);
+-	vfprintf(stderr, fmt, ap);
+-	va_end(ap);
+-	exit(1);
+-}
+-
+-static const char *sym_type(unsigned type)
+-{
+-	static const char *type_name[] = {
+-#define SYM_TYPE(X) [X] = #X
+-		SYM_TYPE(STT_NOTYPE),
+-		SYM_TYPE(STT_OBJECT),
+-		SYM_TYPE(STT_FUNC),
+-		SYM_TYPE(STT_SECTION),
+-		SYM_TYPE(STT_FILE),
+-		SYM_TYPE(STT_COMMON),
+-		SYM_TYPE(STT_TLS),
+-#undef SYM_TYPE
+-	};
+-	const char *name = "unknown sym type name";
+-	if (type < ARRAY_SIZE(type_name)) {
+-		name = type_name[type];
+-	}
+-	return name;
+-}
+-
+-static const char *sym_bind(unsigned bind)
+-{
+-	static const char *bind_name[] = {
+-#define SYM_BIND(X) [X] = #X
+-		SYM_BIND(STB_LOCAL),
+-		SYM_BIND(STB_GLOBAL),
+-		SYM_BIND(STB_WEAK),
+-#undef SYM_BIND
+-	};
+-	const char *name = "unknown sym bind name";
+-	if (bind < ARRAY_SIZE(bind_name)) {
+-		name = bind_name[bind];
+-	}
+-	return name;
+-}
+-
+-static const char *sym_visibility(unsigned visibility)
+-{
+-	static const char *visibility_name[] = {
+-#define SYM_VISIBILITY(X) [X] = #X
+-		SYM_VISIBILITY(STV_DEFAULT),
+-		SYM_VISIBILITY(STV_INTERNAL),
+-		SYM_VISIBILITY(STV_HIDDEN),
+-		SYM_VISIBILITY(STV_PROTECTED),
+-#undef SYM_VISIBILITY
+-	};
+-	const char *name = "unknown sym visibility name";
+-	if (visibility < ARRAY_SIZE(visibility_name)) {
+-		name = visibility_name[visibility];
+-	}
+-	return name;
+-}
+-
+-static const char *rel_type(unsigned type)
+-{
+-	static const char *type_name[] = {
+-#define REL_TYPE(X) [X] = #X
+-		REL_TYPE(R_386_NONE),
+-		REL_TYPE(R_386_32),
+-		REL_TYPE(R_386_PC32),
+-		REL_TYPE(R_386_GOT32),
+-		REL_TYPE(R_386_PLT32),
+-		REL_TYPE(R_386_COPY),
+-		REL_TYPE(R_386_GLOB_DAT),
+-		REL_TYPE(R_386_JMP_SLOT),
+-		REL_TYPE(R_386_RELATIVE),
+-		REL_TYPE(R_386_GOTOFF),
+-		REL_TYPE(R_386_GOTPC),
+-#undef REL_TYPE
+-	};
+-	const char *name = "unknown type rel type name";
+-	if (type < ARRAY_SIZE(type_name) && type_name[type]) {
+-		name = type_name[type];
+-	}
+-	return name;
+-}
+-
+-static const char *sec_name(unsigned shndx)
+-{
+-	const char *sec_strtab;
+-	const char *name;
+-	sec_strtab = secs[ehdr.e_shstrndx].strtab;
+-	name = "<noname>";
+-	if (shndx < ehdr.e_shnum) {
+-		name = sec_strtab + secs[shndx].shdr.sh_name;
+-	}
+-	else if (shndx == SHN_ABS) {
+-		name = "ABSOLUTE";
+-	}
+-	else if (shndx == SHN_COMMON) {
+-		name = "COMMON";
+-	}
+-	return name;
+-}
+-
+-static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym)
+-{
+-	const char *name;
+-	name = "<noname>";
+-	if (sym->st_name) {
+-		name = sym_strtab + sym->st_name;
+-	}
+-	else {
+-		name = sec_name(secs[sym->st_shndx].shdr.sh_name);
+-	}
+-	return name;
+-}
+-
+-
+-
+-#if BYTE_ORDER == LITTLE_ENDIAN
+-#define le16_to_cpu(val) (val)
+-#define le32_to_cpu(val) (val)
+-#endif
+-#if BYTE_ORDER == BIG_ENDIAN
+-#define le16_to_cpu(val) bswap_16(val)
+-#define le32_to_cpu(val) bswap_32(val)
+-#endif
+-
+-static uint16_t elf16_to_cpu(uint16_t val)
+-{
+-	return le16_to_cpu(val);
+-}
+-
+-static uint32_t elf32_to_cpu(uint32_t val)
+-{
+-	return le32_to_cpu(val);
+-}
+-
+-static void read_ehdr(FILE *fp)
+-{
+-	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
+-		die("Cannot read ELF header: %s\n",
+-			strerror(errno));
+-	}
+-	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
+-		die("No ELF magic\n");
+-	}
+-	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) {
+-		die("Not a 32 bit executable\n");
+-	}
+-	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
+-		die("Not a LSB ELF executable\n");
+-	}
+-	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
+-		die("Unknown ELF version\n");
+-	}
+-	/* Convert the fields to native endian */
+-	ehdr.e_type      = elf16_to_cpu(ehdr.e_type);
+-	ehdr.e_machine   = elf16_to_cpu(ehdr.e_machine);
+-	ehdr.e_version   = elf32_to_cpu(ehdr.e_version);
+-	ehdr.e_entry     = elf32_to_cpu(ehdr.e_entry);
+-	ehdr.e_phoff     = elf32_to_cpu(ehdr.e_phoff);
+-	ehdr.e_shoff     = elf32_to_cpu(ehdr.e_shoff);
+-	ehdr.e_flags     = elf32_to_cpu(ehdr.e_flags);
+-	ehdr.e_ehsize    = elf16_to_cpu(ehdr.e_ehsize);
+-	ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize);
+-	ehdr.e_phnum     = elf16_to_cpu(ehdr.e_phnum);
+-	ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize);
+-	ehdr.e_shnum     = elf16_to_cpu(ehdr.e_shnum);
+-	ehdr.e_shstrndx  = elf16_to_cpu(ehdr.e_shstrndx);
+-
+-	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
+-		die("Unsupported ELF header type\n");
+-	}
+-	if (ehdr.e_machine != EM_386) {
+-		die("Not for x86\n");
+-	}
+-	if (ehdr.e_version != EV_CURRENT) {
+-		die("Unknown ELF version\n");
+-	}
+-	if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) {
+-		die("Bad Elf header size\n");
+-	}
+-	if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) {
+-		die("Bad program header entry\n");
+-	}
+-	if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) {
+-		die("Bad section header entry\n");
+-	}
+-	if (ehdr.e_shstrndx >= ehdr.e_shnum) {
+-		die("String table index out of bounds\n");
+-	}
+-}
+-
+-static void read_shdrs(FILE *fp)
+-{
+-	int i;
+-	Elf32_Shdr shdr;
+-
+-	secs = calloc(ehdr.e_shnum, sizeof(struct section));
+-	if (!secs) {
+-		die("Unable to allocate %d section headers\n",
+-		    ehdr.e_shnum);
+-	}
+-	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
+-		die("Seek to %d failed: %s\n",
+-			ehdr.e_shoff, strerror(errno));
+-	}
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		struct section *sec = &secs[i];
+-		if (fread(&shdr, sizeof shdr, 1, fp) != 1)
+-			die("Cannot read ELF section headers %d/%d: %s\n",
+-			    i, ehdr.e_shnum, strerror(errno));
+-		sec->shdr.sh_name      = elf32_to_cpu(shdr.sh_name);
+-		sec->shdr.sh_type      = elf32_to_cpu(shdr.sh_type);
+-		sec->shdr.sh_flags     = elf32_to_cpu(shdr.sh_flags);
+-		sec->shdr.sh_addr      = elf32_to_cpu(shdr.sh_addr);
+-		sec->shdr.sh_offset    = elf32_to_cpu(shdr.sh_offset);
+-		sec->shdr.sh_size      = elf32_to_cpu(shdr.sh_size);
+-		sec->shdr.sh_link      = elf32_to_cpu(shdr.sh_link);
+-		sec->shdr.sh_info      = elf32_to_cpu(shdr.sh_info);
+-		sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign);
+-		sec->shdr.sh_entsize   = elf32_to_cpu(shdr.sh_entsize);
+-		if (sec->shdr.sh_link < ehdr.e_shnum)
+-			sec->link = &secs[sec->shdr.sh_link];
+-	}
+-
+-}
+-
+-static void read_strtabs(FILE *fp)
+-{
+-	int i;
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		struct section *sec = &secs[i];
+-		if (sec->shdr.sh_type != SHT_STRTAB) {
+-			continue;
+-		}
+-		sec->strtab = malloc(sec->shdr.sh_size);
+-		if (!sec->strtab) {
+-			die("malloc of %d bytes for strtab failed\n",
+-				sec->shdr.sh_size);
+-		}
+-		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
+-			die("Seek to %d failed: %s\n",
+-				sec->shdr.sh_offset, strerror(errno));
+-		}
+-		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
+-		    != sec->shdr.sh_size) {
+-			die("Cannot read symbol table: %s\n",
+-				strerror(errno));
+-		}
+-	}
+-}
+-
+-static void read_symtabs(FILE *fp)
+-{
+-	int i,j;
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		struct section *sec = &secs[i];
+-		if (sec->shdr.sh_type != SHT_SYMTAB) {
+-			continue;
+-		}
+-		sec->symtab = malloc(sec->shdr.sh_size);
+-		if (!sec->symtab) {
+-			die("malloc of %d bytes for symtab failed\n",
+-				sec->shdr.sh_size);
+-		}
+-		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
+-			die("Seek to %d failed: %s\n",
+-				sec->shdr.sh_offset, strerror(errno));
+-		}
+-		if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
+-		    != sec->shdr.sh_size) {
+-			die("Cannot read symbol table: %s\n",
+-				strerror(errno));
+-		}
+-		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
+-			Elf32_Sym *sym = &sec->symtab[j];
+-			sym->st_name  = elf32_to_cpu(sym->st_name);
+-			sym->st_value = elf32_to_cpu(sym->st_value);
+-			sym->st_size  = elf32_to_cpu(sym->st_size);
+-			sym->st_shndx = elf16_to_cpu(sym->st_shndx);
+-		}
+-	}
+-}
+-
+-
+-static void read_relocs(FILE *fp)
+-{
+-	int i,j;
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		struct section *sec = &secs[i];
+-		if (sec->shdr.sh_type != SHT_REL) {
+-			continue;
+-		}
+-		sec->reltab = malloc(sec->shdr.sh_size);
+-		if (!sec->reltab) {
+-			die("malloc of %d bytes for relocs failed\n",
+-				sec->shdr.sh_size);
+-		}
+-		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
+-			die("Seek to %d failed: %s\n",
+-				sec->shdr.sh_offset, strerror(errno));
+-		}
+-		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
+-		    != sec->shdr.sh_size) {
+-			die("Cannot read symbol table: %s\n",
+-				strerror(errno));
+-		}
+-		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
+-			Elf32_Rel *rel = &sec->reltab[j];
+-			rel->r_offset = elf32_to_cpu(rel->r_offset);
+-			rel->r_info   = elf32_to_cpu(rel->r_info);
+-		}
+-	}
+-}
+-
+-
+-static void print_absolute_symbols(void)
+-{
+-	int i;
+-	printf("Absolute symbols\n");
+-	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		struct section *sec = &secs[i];
+-		char *sym_strtab;
+-		int j;
+-
+-		if (sec->shdr.sh_type != SHT_SYMTAB) {
+-			continue;
+-		}
+-		sym_strtab = sec->link->strtab;
+-		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
+-			Elf32_Sym *sym;
+-			const char *name;
+-			sym = &sec->symtab[j];
+-			name = sym_name(sym_strtab, sym);
+-			if (sym->st_shndx != SHN_ABS) {
+-				continue;
+-			}
+-			printf("%5d %08x %5d %10s %10s %12s %s\n",
+-				j, sym->st_value, sym->st_size,
+-				sym_type(ELF32_ST_TYPE(sym->st_info)),
+-				sym_bind(ELF32_ST_BIND(sym->st_info)),
+-				sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)),
+-				name);
+-		}
+-	}
+-	printf("\n");
+-}
+-
+-static void print_absolute_relocs(void)
+-{
+-	int i, printed = 0;
+-
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		struct section *sec = &secs[i];
+-		struct section *sec_applies, *sec_symtab;
+-		char *sym_strtab;
+-		Elf32_Sym *sh_symtab;
+-		int j;
+-		if (sec->shdr.sh_type != SHT_REL) {
+-			continue;
+-		}
+-		sec_symtab  = sec->link;
+-		sec_applies = &secs[sec->shdr.sh_info];
+-		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+-			continue;
+-		}
+-		sh_symtab  = sec_symtab->symtab;
+-		sym_strtab = sec_symtab->link->strtab;
+-		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
+-			Elf32_Rel *rel;
+-			Elf32_Sym *sym;
+-			const char *name;
+-			rel = &sec->reltab[j];
+-			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
+-			name = sym_name(sym_strtab, sym);
+-			if (sym->st_shndx != SHN_ABS) {
+-				continue;
+-			}
+-
+-			/* Absolute symbols are not relocated if bzImage is
+-			 * loaded at a non-compiled address. Display a warning
+-			 * to user at compile time about the absolute
+-			 * relocations present.
+-			 *
+-			 * User need to audit the code to make sure
+-			 * some symbols which should have been section
+-			 * relative have not become absolute because of some
+-			 * linker optimization or wrong programming usage.
+-			 *
+-			 * Before warning check if this absolute symbol
+-			 * relocation is harmless.
+-			 */
+-			if (is_abs_reloc(name) || is_rel_reloc(name))
+-				continue;
+-
+-			if (!printed) {
+-				printf("WARNING: Absolute relocations"
+-					" present\n");
+-				printf("Offset     Info     Type     Sym.Value "
+-					"Sym.Name\n");
+-				printed = 1;
+-			}
+-
+-			printf("%08x %08x %10s %08x  %s\n",
+-				rel->r_offset,
+-				rel->r_info,
+-				rel_type(ELF32_R_TYPE(rel->r_info)),
+-				sym->st_value,
+-				name);
+-		}
+-	}
+-
+-	if (printed)
+-		printf("\n");
+-}
+-
+-static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
+-{
+-	int i;
+-	/* Walk through the relocations */
+-	for (i = 0; i < ehdr.e_shnum; i++) {
+-		char *sym_strtab;
+-		Elf32_Sym *sh_symtab;
+-		struct section *sec_applies, *sec_symtab;
+-		int j;
+-		struct section *sec = &secs[i];
+-
+-		if (sec->shdr.sh_type != SHT_REL) {
+-			continue;
+-		}
+-		sec_symtab  = sec->link;
+-		sec_applies = &secs[sec->shdr.sh_info];
+-		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+-			continue;
+-		}
+-		sh_symtab = sec_symtab->symtab;
+-		sym_strtab = sec_symtab->link->strtab;
+-		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
+-			Elf32_Rel *rel;
+-			Elf32_Sym *sym;
+-			unsigned r_type;
+-			rel = &sec->reltab[j];
+-			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
+-			r_type = ELF32_R_TYPE(rel->r_info);
+-			/* Don't visit relocations to absolute symbols */
+-			if (sym->st_shndx == SHN_ABS &&
+-			    !is_rel_reloc(sym_name(sym_strtab, sym))) {
+-				continue;
+-			}
+-			switch (r_type) {
+-			case R_386_NONE:
+-			case R_386_PC32:
+-				/*
+-				 * NONE can be ignored and and PC relative
+-				 * relocations don't need to be adjusted.
+-				 */
+-				break;
+-			case R_386_32:
+-				/* Visit relocations that need to be adjusted */
+-				visit(rel, sym);
+-				break;
+-			default:
+-				die("Unsupported relocation type: %s (%d)\n",
+-				    rel_type(r_type), r_type);
+-				break;
+-			}
+-		}
+-	}
+-}
+-
+-static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
+-{
+-	reloc_count += 1;
+-}
+-
+-static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
+-{
+-	/* Remember the address that needs to be adjusted. */
+-	relocs[reloc_idx++] = rel->r_offset;
+-}
+-
+-static int cmp_relocs(const void *va, const void *vb)
+-{
+-	const unsigned long *a, *b;
+-	a = va; b = vb;
+-	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
+-}
+-
+-static void emit_relocs(int as_text)
+-{
+-	int i;
+-	/* Count how many relocations I have and allocate space for them. */
+-	reloc_count = 0;
+-	walk_relocs(count_reloc);
+-	relocs = malloc(reloc_count * sizeof(relocs[0]));
+-	if (!relocs) {
+-		die("malloc of %d entries for relocs failed\n",
+-			reloc_count);
+-	}
+-	/* Collect up the relocations */
+-	reloc_idx = 0;
+-	walk_relocs(collect_reloc);
+-
+-	/* Order the relocations for more efficient processing */
+-	qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs);
+-
+-	/* Print the relocations */
+-	if (as_text) {
+-		/* Print the relocations in a form suitable that
+-		 * gas will like.
+-		 */
+-		printf(".section \".data.reloc\",\"a\"\n");
+-		printf(".balign 4\n");
+-		for (i = 0; i < reloc_count; i++) {
+-			printf("\t .long 0x%08lx\n", relocs[i]);
+-		}
+-		printf("\n");
+-	}
+-	else {
+-		unsigned char buf[4];
+-		/* Print a stop */
+-		fwrite("\0\0\0\0", 4, 1, stdout);
+-		/* Now print each relocation */
+-		for (i = 0; i < reloc_count; i++) {
+-			buf[0] = (relocs[i] >>  0) & 0xff;
+-			buf[1] = (relocs[i] >>  8) & 0xff;
+-			buf[2] = (relocs[i] >> 16) & 0xff;
+-			buf[3] = (relocs[i] >> 24) & 0xff;
+-			fwrite(buf, 4, 1, stdout);
+-		}
+-	}
+-}
+-
+-static void usage(void)
+-{
+-	die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n");
+-}
+-
+-int main(int argc, char **argv)
+-{
+-	int show_absolute_syms, show_absolute_relocs;
+-	int as_text;
+-	const char *fname;
+-	FILE *fp;
+-	int i;
+-
+-	regex_init();
+-
+-	show_absolute_syms = 0;
+-	show_absolute_relocs = 0;
+-	as_text = 0;
+-	fname = NULL;
+-	for (i = 1; i < argc; i++) {
+-		char *arg = argv[i];
+-		if (*arg == '-') {
+-			if (strcmp(argv[1], "--abs-syms") == 0) {
+-				show_absolute_syms = 1;
+-				continue;
+-			}
+-
+-			if (strcmp(argv[1], "--abs-relocs") == 0) {
+-				show_absolute_relocs = 1;
+-				continue;
+-			}
+-			else if (strcmp(argv[1], "--text") == 0) {
+-				as_text = 1;
+-				continue;
+-			}
+-		}
+-		else if (!fname) {
+-			fname = arg;
+-			continue;
+-		}
+-		usage();
+-	}
+-	if (!fname) {
+-		usage();
+-	}
+-	fp = fopen(fname, "r");
+-	if (!fp) {
+-		die("Cannot open %s: %s\n",
+-			fname, strerror(errno));
+-	}
+-	read_ehdr(fp);
+-	read_shdrs(fp);
+-	read_strtabs(fp);
+-	read_symtabs(fp);
+-	read_relocs(fp);
+-	if (show_absolute_syms) {
+-		print_absolute_symbols();
+-		return 0;
+-	}
+-	if (show_absolute_relocs) {
+-		print_absolute_relocs();
+-		return 0;
+-	}
+-	emit_relocs(as_text);
+-	return 0;
+-}
+diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
+index 7395d5f..c9c9cfe 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
++++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
+@@ -145,15 +145,19 @@ static struct severity {
+ };
+ 
+ /*
+- * If the EIPV bit is set, it means the saved IP is the
+- * instruction which caused the MCE.
++ * If mcgstatus indicated that ip/cs on the stack were
++ * no good, then "m->cs" will be zero and we will have
++ * to assume the worst case (IN_KERNEL) as we actually
++ * have no idea what we were executing when the machine
++ * check hit.
++ * If we do have a good "m->cs" (or a faked one in the
++ * case we were executing in VM86 mode) we can use it to
++ * distinguish an exception taken in user from from one
++ * taken in the kernel.
+  */
+ static int error_context(struct mce *m)
+ {
+-	if (m->mcgstatus & MCG_STATUS_EIPV)
+-		return (m->ip && (m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
+-	/* Unknown, assume kernel */
+-	return IN_KERNEL;
++	return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
+ }
+ 
+ int mce_severity(struct mce *m, int tolerant, char **msg)
+diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
+index 5a11ae2..dee004f 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -437,6 +437,14 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs)
+ 		if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) {
+ 			m->ip = regs->ip;
+ 			m->cs = regs->cs;
++
++			/*
++			 * When in VM86 mode make the cs look like ring 3
++			 * always. This is a lie, but it's better than passing
++			 * the additional vm86 bit around everywhere.
++			 */
++			if (v8086_mode(regs))
++				m->cs |= 3;
+ 		}
+ 		/* Use accurate RIP reporting if available. */
+ 		if (rip_msr)
+diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
+index 67250a5..cdd5755 100644
+--- a/arch/x86/kernel/cpu/perf_event_amd.c
++++ b/arch/x86/kernel/cpu/perf_event_amd.c
+@@ -473,6 +473,7 @@ static __initconst const struct x86_pmu amd_pmu = {
+  * 0x023	DE	PERF_CTL[2:0]
+  * 0x02D	LS	PERF_CTL[3]
+  * 0x02E	LS	PERF_CTL[3,0]
++ * 0x031	LS	PERF_CTL[2:0] (**)
+  * 0x043	CU	PERF_CTL[2:0]
+  * 0x045	CU	PERF_CTL[2:0]
+  * 0x046	CU	PERF_CTL[2:0]
+@@ -486,10 +487,12 @@ static __initconst const struct x86_pmu amd_pmu = {
+  * 0x0DD	LS	PERF_CTL[5:0]
+  * 0x0DE	LS	PERF_CTL[5:0]
+  * 0x0DF	LS	PERF_CTL[5:0]
++ * 0x1C0	EX	PERF_CTL[5:3]
+  * 0x1D6	EX	PERF_CTL[5:0]
+  * 0x1D8	EX	PERF_CTL[5:0]
+  *
+- * (*) depending on the umask all FPU counters may be used
++ * (*)  depending on the umask all FPU counters may be used
++ * (**) only one unitmask enabled at a time
+  */
+ 
+ static struct event_constraint amd_f15_PMC0  = EVENT_CONSTRAINT(0, 0x01, 0);
+@@ -539,6 +542,12 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev
+ 			return &amd_f15_PMC3;
+ 		case 0x02E:
+ 			return &amd_f15_PMC30;
++		case 0x031:
++			if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
++				return &amd_f15_PMC20;
++			return &emptyconstraint;
++		case 0x1C0:
++			return &amd_f15_PMC53;
+ 		default:
+ 			return &amd_f15_PMC50;
+ 		}
+diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
+index d99346e..4c262f6 100644
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -64,6 +64,10 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering,
+ 	int shareable = 0;
+ 	char *name;
+ 
++	irq = xen_irq_from_gsi(gsi);
++	if (irq > 0)
++		return irq;
++
+ 	if (set_pirq)
+ 		pirq = gsi;
+ 
+diff --git a/arch/x86/tools/.gitignore b/arch/x86/tools/.gitignore
+new file mode 100644
+index 0000000..be0ed06
+--- /dev/null
++++ b/arch/x86/tools/.gitignore
+@@ -0,0 +1 @@
++relocs
+diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
+index d511aa9..733057b 100644
+--- a/arch/x86/tools/Makefile
++++ b/arch/x86/tools/Makefile
+@@ -36,3 +36,7 @@ HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x
+ $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
+ 
+ $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
++
++HOST_EXTRACFLAGS += -I$(srctree)/tools/include
++hostprogs-y	+= relocs
++relocs: $(obj)/relocs
+diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
+new file mode 100644
+index 0000000..b685296
+--- /dev/null
++++ b/arch/x86/tools/relocs.c
+@@ -0,0 +1,818 @@
++#include <stdio.h>
++#include <stdarg.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <elf.h>
++#include <byteswap.h>
++#define USE_BSD
++#include <endian.h>
++#include <regex.h>
++#include <tools/le_byteshift.h>
++
++static void die(char *fmt, ...);
++
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++static Elf32_Ehdr ehdr;
++static unsigned long reloc_count, reloc_idx;
++static unsigned long *relocs;
++static unsigned long reloc16_count, reloc16_idx;
++static unsigned long *relocs16;
++
++struct section {
++	Elf32_Shdr     shdr;
++	struct section *link;
++	Elf32_Sym      *symtab;
++	Elf32_Rel      *reltab;
++	char           *strtab;
++};
++static struct section *secs;
++
++enum symtype {
++	S_ABS,
++	S_REL,
++	S_SEG,
++	S_LIN,
++	S_NSYMTYPES
++};
++
++static const char * const sym_regex_kernel[S_NSYMTYPES] = {
++/*
++ * Following symbols have been audited. There values are constant and do
++ * not change if bzImage is loaded at a different physical address than
++ * the address for which it has been compiled. Don't warn user about
++ * absolute relocations present w.r.t these symbols.
++ */
++	[S_ABS] =
++	"^(xen_irq_disable_direct_reloc$|"
++	"xen_save_fl_direct_reloc$|"
++	"VDSO|"
++	"__crc_)",
++
++/*
++ * These symbols are known to be relative, even if the linker marks them
++ * as absolute (typically defined outside any section in the linker script.)
++ */
++	[S_REL] =
++	"^(__init_(begin|end)|"
++	"__x86_cpu_dev_(start|end)|"
++	"(__parainstructions|__alt_instructions)(|_end)|"
++	"(__iommu_table|__apicdrivers|__smp_locks)(|_end)|"
++	"__(start|end)_pci_.*|"
++	"__(start|end)_builtin_fw|"
++	"__(start|stop)___ksymtab(|_gpl|_unused|_unused_gpl|_gpl_future)|"
++	"__(start|stop)___kcrctab(|_gpl|_unused|_unused_gpl|_gpl_future)|"
++	"__(start|stop)___param|"
++	"__(start|stop)___modver|"
++	"__(start|stop)___bug_table|"
++	"__tracedata_(start|end)|"
++	"__(start|stop)_notes|"
++	"__end_rodata|"
++	"__initramfs_start|"
++	"(jiffies|jiffies_64)|"
++	"_end)$"
++};
++
++
++static const char * const sym_regex_realmode[S_NSYMTYPES] = {
++/*
++ * These are 16-bit segment symbols when compiling 16-bit code.
++ */
++	[S_SEG] =
++	"^real_mode_seg$",
++
++/*
++ * These are offsets belonging to segments, as opposed to linear addresses,
++ * when compiling 16-bit code.
++ */
++	[S_LIN] =
++	"^pa_",
++};
++
++static const char * const *sym_regex;
++
++static regex_t sym_regex_c[S_NSYMTYPES];
++static int is_reloc(enum symtype type, const char *sym_name)
++{
++	return sym_regex[type] &&
++		!regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
++}
++
++static void regex_init(int use_real_mode)
++{
++        char errbuf[128];
++        int err;
++	int i;
++
++	if (use_real_mode)
++		sym_regex = sym_regex_realmode;
++	else
++		sym_regex = sym_regex_kernel;
++
++	for (i = 0; i < S_NSYMTYPES; i++) {
++		if (!sym_regex[i])
++			continue;
++
++		err = regcomp(&sym_regex_c[i], sym_regex[i],
++			      REG_EXTENDED|REG_NOSUB);
++
++		if (err) {
++			regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf);
++			die("%s", errbuf);
++		}
++        }
++}
++
++static void die(char *fmt, ...)
++{
++	va_list ap;
++	va_start(ap, fmt);
++	vfprintf(stderr, fmt, ap);
++	va_end(ap);
++	exit(1);
++}
++
++static const char *sym_type(unsigned type)
++{
++	static const char *type_name[] = {
++#define SYM_TYPE(X) [X] = #X
++		SYM_TYPE(STT_NOTYPE),
++		SYM_TYPE(STT_OBJECT),
++		SYM_TYPE(STT_FUNC),
++		SYM_TYPE(STT_SECTION),
++		SYM_TYPE(STT_FILE),
++		SYM_TYPE(STT_COMMON),
++		SYM_TYPE(STT_TLS),
++#undef SYM_TYPE
++	};
++	const char *name = "unknown sym type name";
++	if (type < ARRAY_SIZE(type_name)) {
++		name = type_name[type];
++	}
++	return name;
++}
++
++static const char *sym_bind(unsigned bind)
++{
++	static const char *bind_name[] = {
++#define SYM_BIND(X) [X] = #X
++		SYM_BIND(STB_LOCAL),
++		SYM_BIND(STB_GLOBAL),
++		SYM_BIND(STB_WEAK),
++#undef SYM_BIND
++	};
++	const char *name = "unknown sym bind name";
++	if (bind < ARRAY_SIZE(bind_name)) {
++		name = bind_name[bind];
++	}
++	return name;
++}
++
++static const char *sym_visibility(unsigned visibility)
++{
++	static const char *visibility_name[] = {
++#define SYM_VISIBILITY(X) [X] = #X
++		SYM_VISIBILITY(STV_DEFAULT),
++		SYM_VISIBILITY(STV_INTERNAL),
++		SYM_VISIBILITY(STV_HIDDEN),
++		SYM_VISIBILITY(STV_PROTECTED),
++#undef SYM_VISIBILITY
++	};
++	const char *name = "unknown sym visibility name";
++	if (visibility < ARRAY_SIZE(visibility_name)) {
++		name = visibility_name[visibility];
++	}
++	return name;
++}
++
++static const char *rel_type(unsigned type)
++{
++	static const char *type_name[] = {
++#define REL_TYPE(X) [X] = #X
++		REL_TYPE(R_386_NONE),
++		REL_TYPE(R_386_32),
++		REL_TYPE(R_386_PC32),
++		REL_TYPE(R_386_GOT32),
++		REL_TYPE(R_386_PLT32),
++		REL_TYPE(R_386_COPY),
++		REL_TYPE(R_386_GLOB_DAT),
++		REL_TYPE(R_386_JMP_SLOT),
++		REL_TYPE(R_386_RELATIVE),
++		REL_TYPE(R_386_GOTOFF),
++		REL_TYPE(R_386_GOTPC),
++		REL_TYPE(R_386_8),
++		REL_TYPE(R_386_PC8),
++		REL_TYPE(R_386_16),
++		REL_TYPE(R_386_PC16),
++#undef REL_TYPE
++	};
++	const char *name = "unknown type rel type name";
++	if (type < ARRAY_SIZE(type_name) && type_name[type]) {
++		name = type_name[type];
++	}
++	return name;
++}
++
++static const char *sec_name(unsigned shndx)
++{
++	const char *sec_strtab;
++	const char *name;
++	sec_strtab = secs[ehdr.e_shstrndx].strtab;
++	name = "<noname>";
++	if (shndx < ehdr.e_shnum) {
++		name = sec_strtab + secs[shndx].shdr.sh_name;
++	}
++	else if (shndx == SHN_ABS) {
++		name = "ABSOLUTE";
++	}
++	else if (shndx == SHN_COMMON) {
++		name = "COMMON";
++	}
++	return name;
++}
++
++static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym)
++{
++	const char *name;
++	name = "<noname>";
++	if (sym->st_name) {
++		name = sym_strtab + sym->st_name;
++	}
++	else {
++		name = sec_name(sym->st_shndx);
++	}
++	return name;
++}
++
++
++
++#if BYTE_ORDER == LITTLE_ENDIAN
++#define le16_to_cpu(val) (val)
++#define le32_to_cpu(val) (val)
++#endif
++#if BYTE_ORDER == BIG_ENDIAN
++#define le16_to_cpu(val) bswap_16(val)
++#define le32_to_cpu(val) bswap_32(val)
++#endif
++
++static uint16_t elf16_to_cpu(uint16_t val)
++{
++	return le16_to_cpu(val);
++}
++
++static uint32_t elf32_to_cpu(uint32_t val)
++{
++	return le32_to_cpu(val);
++}
++
++static void read_ehdr(FILE *fp)
++{
++	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
++		die("Cannot read ELF header: %s\n",
++			strerror(errno));
++	}
++	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
++		die("No ELF magic\n");
++	}
++	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) {
++		die("Not a 32 bit executable\n");
++	}
++	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
++		die("Not a LSB ELF executable\n");
++	}
++	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
++		die("Unknown ELF version\n");
++	}
++	/* Convert the fields to native endian */
++	ehdr.e_type      = elf16_to_cpu(ehdr.e_type);
++	ehdr.e_machine   = elf16_to_cpu(ehdr.e_machine);
++	ehdr.e_version   = elf32_to_cpu(ehdr.e_version);
++	ehdr.e_entry     = elf32_to_cpu(ehdr.e_entry);
++	ehdr.e_phoff     = elf32_to_cpu(ehdr.e_phoff);
++	ehdr.e_shoff     = elf32_to_cpu(ehdr.e_shoff);
++	ehdr.e_flags     = elf32_to_cpu(ehdr.e_flags);
++	ehdr.e_ehsize    = elf16_to_cpu(ehdr.e_ehsize);
++	ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize);
++	ehdr.e_phnum     = elf16_to_cpu(ehdr.e_phnum);
++	ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize);
++	ehdr.e_shnum     = elf16_to_cpu(ehdr.e_shnum);
++	ehdr.e_shstrndx  = elf16_to_cpu(ehdr.e_shstrndx);
++
++	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
++		die("Unsupported ELF header type\n");
++	}
++	if (ehdr.e_machine != EM_386) {
++		die("Not for x86\n");
++	}
++	if (ehdr.e_version != EV_CURRENT) {
++		die("Unknown ELF version\n");
++	}
++	if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) {
++		die("Bad Elf header size\n");
++	}
++	if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) {
++		die("Bad program header entry\n");
++	}
++	if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) {
++		die("Bad section header entry\n");
++	}
++	if (ehdr.e_shstrndx >= ehdr.e_shnum) {
++		die("String table index out of bounds\n");
++	}
++}
++
++static void read_shdrs(FILE *fp)
++{
++	int i;
++	Elf32_Shdr shdr;
++
++	secs = calloc(ehdr.e_shnum, sizeof(struct section));
++	if (!secs) {
++		die("Unable to allocate %d section headers\n",
++		    ehdr.e_shnum);
++	}
++	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
++		die("Seek to %d failed: %s\n",
++			ehdr.e_shoff, strerror(errno));
++	}
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		struct section *sec = &secs[i];
++		if (fread(&shdr, sizeof shdr, 1, fp) != 1)
++			die("Cannot read ELF section headers %d/%d: %s\n",
++			    i, ehdr.e_shnum, strerror(errno));
++		sec->shdr.sh_name      = elf32_to_cpu(shdr.sh_name);
++		sec->shdr.sh_type      = elf32_to_cpu(shdr.sh_type);
++		sec->shdr.sh_flags     = elf32_to_cpu(shdr.sh_flags);
++		sec->shdr.sh_addr      = elf32_to_cpu(shdr.sh_addr);
++		sec->shdr.sh_offset    = elf32_to_cpu(shdr.sh_offset);
++		sec->shdr.sh_size      = elf32_to_cpu(shdr.sh_size);
++		sec->shdr.sh_link      = elf32_to_cpu(shdr.sh_link);
++		sec->shdr.sh_info      = elf32_to_cpu(shdr.sh_info);
++		sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign);
++		sec->shdr.sh_entsize   = elf32_to_cpu(shdr.sh_entsize);
++		if (sec->shdr.sh_link < ehdr.e_shnum)
++			sec->link = &secs[sec->shdr.sh_link];
++	}
++
++}
++
++static void read_strtabs(FILE *fp)
++{
++	int i;
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		struct section *sec = &secs[i];
++		if (sec->shdr.sh_type != SHT_STRTAB) {
++			continue;
++		}
++		sec->strtab = malloc(sec->shdr.sh_size);
++		if (!sec->strtab) {
++			die("malloc of %d bytes for strtab failed\n",
++				sec->shdr.sh_size);
++		}
++		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
++			die("Seek to %d failed: %s\n",
++				sec->shdr.sh_offset, strerror(errno));
++		}
++		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
++		    != sec->shdr.sh_size) {
++			die("Cannot read symbol table: %s\n",
++				strerror(errno));
++		}
++	}
++}
++
++static void read_symtabs(FILE *fp)
++{
++	int i,j;
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		struct section *sec = &secs[i];
++		if (sec->shdr.sh_type != SHT_SYMTAB) {
++			continue;
++		}
++		sec->symtab = malloc(sec->shdr.sh_size);
++		if (!sec->symtab) {
++			die("malloc of %d bytes for symtab failed\n",
++				sec->shdr.sh_size);
++		}
++		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
++			die("Seek to %d failed: %s\n",
++				sec->shdr.sh_offset, strerror(errno));
++		}
++		if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
++		    != sec->shdr.sh_size) {
++			die("Cannot read symbol table: %s\n",
++				strerror(errno));
++		}
++		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
++			Elf32_Sym *sym = &sec->symtab[j];
++			sym->st_name  = elf32_to_cpu(sym->st_name);
++			sym->st_value = elf32_to_cpu(sym->st_value);
++			sym->st_size  = elf32_to_cpu(sym->st_size);
++			sym->st_shndx = elf16_to_cpu(sym->st_shndx);
++		}
++	}
++}
++
++
++static void read_relocs(FILE *fp)
++{
++	int i,j;
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		struct section *sec = &secs[i];
++		if (sec->shdr.sh_type != SHT_REL) {
++			continue;
++		}
++		sec->reltab = malloc(sec->shdr.sh_size);
++		if (!sec->reltab) {
++			die("malloc of %d bytes for relocs failed\n",
++				sec->shdr.sh_size);
++		}
++		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
++			die("Seek to %d failed: %s\n",
++				sec->shdr.sh_offset, strerror(errno));
++		}
++		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
++		    != sec->shdr.sh_size) {
++			die("Cannot read symbol table: %s\n",
++				strerror(errno));
++		}
++		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
++			Elf32_Rel *rel = &sec->reltab[j];
++			rel->r_offset = elf32_to_cpu(rel->r_offset);
++			rel->r_info   = elf32_to_cpu(rel->r_info);
++		}
++	}
++}
++
++
++static void print_absolute_symbols(void)
++{
++	int i;
++	printf("Absolute symbols\n");
++	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		struct section *sec = &secs[i];
++		char *sym_strtab;
++		int j;
++
++		if (sec->shdr.sh_type != SHT_SYMTAB) {
++			continue;
++		}
++		sym_strtab = sec->link->strtab;
++		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
++			Elf32_Sym *sym;
++			const char *name;
++			sym = &sec->symtab[j];
++			name = sym_name(sym_strtab, sym);
++			if (sym->st_shndx != SHN_ABS) {
++				continue;
++			}
++			printf("%5d %08x %5d %10s %10s %12s %s\n",
++				j, sym->st_value, sym->st_size,
++				sym_type(ELF32_ST_TYPE(sym->st_info)),
++				sym_bind(ELF32_ST_BIND(sym->st_info)),
++				sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)),
++				name);
++		}
++	}
++	printf("\n");
++}
++
++static void print_absolute_relocs(void)
++{
++	int i, printed = 0;
++
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		struct section *sec = &secs[i];
++		struct section *sec_applies, *sec_symtab;
++		char *sym_strtab;
++		Elf32_Sym *sh_symtab;
++		int j;
++		if (sec->shdr.sh_type != SHT_REL) {
++			continue;
++		}
++		sec_symtab  = sec->link;
++		sec_applies = &secs[sec->shdr.sh_info];
++		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
++			continue;
++		}
++		sh_symtab  = sec_symtab->symtab;
++		sym_strtab = sec_symtab->link->strtab;
++		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
++			Elf32_Rel *rel;
++			Elf32_Sym *sym;
++			const char *name;
++			rel = &sec->reltab[j];
++			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
++			name = sym_name(sym_strtab, sym);
++			if (sym->st_shndx != SHN_ABS) {
++				continue;
++			}
++
++			/* Absolute symbols are not relocated if bzImage is
++			 * loaded at a non-compiled address. Display a warning
++			 * to user at compile time about the absolute
++			 * relocations present.
++			 *
++			 * User need to audit the code to make sure
++			 * some symbols which should have been section
++			 * relative have not become absolute because of some
++			 * linker optimization or wrong programming usage.
++			 *
++			 * Before warning check if this absolute symbol
++			 * relocation is harmless.
++			 */
++			if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
++				continue;
++
++			if (!printed) {
++				printf("WARNING: Absolute relocations"
++					" present\n");
++				printf("Offset     Info     Type     Sym.Value "
++					"Sym.Name\n");
++				printed = 1;
++			}
++
++			printf("%08x %08x %10s %08x  %s\n",
++				rel->r_offset,
++				rel->r_info,
++				rel_type(ELF32_R_TYPE(rel->r_info)),
++				sym->st_value,
++				name);
++		}
++	}
++
++	if (printed)
++		printf("\n");
++}
++
++static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym),
++			int use_real_mode)
++{
++	int i;
++	/* Walk through the relocations */
++	for (i = 0; i < ehdr.e_shnum; i++) {
++		char *sym_strtab;
++		Elf32_Sym *sh_symtab;
++		struct section *sec_applies, *sec_symtab;
++		int j;
++		struct section *sec = &secs[i];
++
++		if (sec->shdr.sh_type != SHT_REL) {
++			continue;
++		}
++		sec_symtab  = sec->link;
++		sec_applies = &secs[sec->shdr.sh_info];
++		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
++			continue;
++		}
++		sh_symtab = sec_symtab->symtab;
++		sym_strtab = sec_symtab->link->strtab;
++		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
++			Elf32_Rel *rel;
++			Elf32_Sym *sym;
++			unsigned r_type;
++			const char *symname;
++			int shn_abs;
++
++			rel = &sec->reltab[j];
++			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
++			r_type = ELF32_R_TYPE(rel->r_info);
++
++			shn_abs = sym->st_shndx == SHN_ABS;
++
++			switch (r_type) {
++			case R_386_NONE:
++			case R_386_PC32:
++			case R_386_PC16:
++			case R_386_PC8:
++				/*
++				 * NONE can be ignored and and PC relative
++				 * relocations don't need to be adjusted.
++				 */
++				break;
++
++			case R_386_16:
++				symname = sym_name(sym_strtab, sym);
++				if (!use_real_mode)
++					goto bad;
++				if (shn_abs) {
++					if (is_reloc(S_ABS, symname))
++						break;
++					else if (!is_reloc(S_SEG, symname))
++						goto bad;
++				} else {
++					if (is_reloc(S_LIN, symname))
++						goto bad;
++					else
++						break;
++				}
++				visit(rel, sym);
++				break;
++
++			case R_386_32:
++				symname = sym_name(sym_strtab, sym);
++				if (shn_abs) {
++					if (is_reloc(S_ABS, symname))
++						break;
++					else if (!is_reloc(S_REL, symname))
++						goto bad;
++				} else {
++					if (use_real_mode &&
++					    !is_reloc(S_LIN, symname))
++						break;
++				}
++				visit(rel, sym);
++				break;
++			default:
++				die("Unsupported relocation type: %s (%d)\n",
++				    rel_type(r_type), r_type);
++				break;
++			bad:
++				symname = sym_name(sym_strtab, sym);
++				die("Invalid %s %s relocation: %s\n",
++				    shn_abs ? "absolute" : "relative",
++				    rel_type(r_type), symname);
++			}
++		}
++	}
++}
++
++static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
++{
++	if (ELF32_R_TYPE(rel->r_info) == R_386_16)
++		reloc16_count++;
++	else
++		reloc_count++;
++}
++
++static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
++{
++	/* Remember the address that needs to be adjusted. */
++	if (ELF32_R_TYPE(rel->r_info) == R_386_16)
++		relocs16[reloc16_idx++] = rel->r_offset;
++	else
++		relocs[reloc_idx++] = rel->r_offset;
++}
++
++static int cmp_relocs(const void *va, const void *vb)
++{
++	const unsigned long *a, *b;
++	a = va; b = vb;
++	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
++}
++
++static int write32(unsigned int v, FILE *f)
++{
++	unsigned char buf[4];
++
++	put_unaligned_le32(v, buf);
++	return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
++}
++
++static void emit_relocs(int as_text, int use_real_mode)
++{
++	int i;
++	/* Count how many relocations I have and allocate space for them. */
++	reloc_count = 0;
++	walk_relocs(count_reloc, use_real_mode);
++	relocs = malloc(reloc_count * sizeof(relocs[0]));
++	if (!relocs) {
++		die("malloc of %d entries for relocs failed\n",
++			reloc_count);
++	}
++
++	relocs16 = malloc(reloc16_count * sizeof(relocs[0]));
++	if (!relocs16) {
++		die("malloc of %d entries for relocs16 failed\n",
++			reloc16_count);
++	}
++	/* Collect up the relocations */
++	reloc_idx = 0;
++	walk_relocs(collect_reloc, use_real_mode);
++
++	if (reloc16_count && !use_real_mode)
++		die("Segment relocations found but --realmode not specified\n");
++
++	/* Order the relocations for more efficient processing */
++	qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs);
++	qsort(relocs16, reloc16_count, sizeof(relocs16[0]), cmp_relocs);
++
++	/* Print the relocations */
++	if (as_text) {
++		/* Print the relocations in a form suitable that
++		 * gas will like.
++		 */
++		printf(".section \".data.reloc\",\"a\"\n");
++		printf(".balign 4\n");
++		if (use_real_mode) {
++			printf("\t.long %lu\n", reloc16_count);
++			for (i = 0; i < reloc16_count; i++)
++				printf("\t.long 0x%08lx\n", relocs16[i]);
++			printf("\t.long %lu\n", reloc_count);
++			for (i = 0; i < reloc_count; i++) {
++				printf("\t.long 0x%08lx\n", relocs[i]);
++			}
++		} else {
++			/* Print a stop */
++			printf("\t.long 0x%08lx\n", (unsigned long)0);
++			for (i = 0; i < reloc_count; i++) {
++				printf("\t.long 0x%08lx\n", relocs[i]);
++			}
++		}
++
++		printf("\n");
++	}
++	else {
++		if (use_real_mode) {
++			write32(reloc16_count, stdout);
++			for (i = 0; i < reloc16_count; i++)
++				write32(relocs16[i], stdout);
++			write32(reloc_count, stdout);
++
++			/* Now print each relocation */
++			for (i = 0; i < reloc_count; i++)
++				write32(relocs[i], stdout);
++		} else {
++			/* Print a stop */
++			write32(0, stdout);
++
++			/* Now print each relocation */
++			for (i = 0; i < reloc_count; i++) {
++				write32(relocs[i], stdout);
++			}
++		}
++	}
++}
++
++static void usage(void)
++{
++	die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
++}
++
++int main(int argc, char **argv)
++{
++	int show_absolute_syms, show_absolute_relocs;
++	int as_text, use_real_mode;
++	const char *fname;
++	FILE *fp;
++	int i;
++
++	show_absolute_syms = 0;
++	show_absolute_relocs = 0;
++	as_text = 0;
++	use_real_mode = 0;
++	fname = NULL;
++	for (i = 1; i < argc; i++) {
++		char *arg = argv[i];
++		if (*arg == '-') {
++			if (strcmp(arg, "--abs-syms") == 0) {
++				show_absolute_syms = 1;
++				continue;
++			}
++			if (strcmp(arg, "--abs-relocs") == 0) {
++				show_absolute_relocs = 1;
++				continue;
++			}
++			if (strcmp(arg, "--text") == 0) {
++				as_text = 1;
++				continue;
++			}
++			if (strcmp(arg, "--realmode") == 0) {
++				use_real_mode = 1;
++				continue;
++			}
++		}
++		else if (!fname) {
++			fname = arg;
++			continue;
++		}
++		usage();
++	}
++	if (!fname) {
++		usage();
++	}
++	regex_init(use_real_mode);
++	fp = fopen(fname, "r");
++	if (!fp) {
++		die("Cannot open %s: %s\n",
++			fname, strerror(errno));
++	}
++	read_ehdr(fp);
++	read_shdrs(fp);
++	read_strtabs(fp);
++	read_symtabs(fp);
++	read_relocs(fp);
++	if (show_absolute_syms) {
++		print_absolute_symbols();
++		return 0;
++	}
++	if (show_absolute_relocs) {
++		print_absolute_relocs();
++		return 0;
++	}
++	emit_relocs(as_text, use_real_mode);
++	return 0;
++}
+diff --git a/block/genhd.c b/block/genhd.c
+index df9816e..9cf5583 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -743,7 +743,7 @@ void __init printk_all_partitions(void)
+ 		struct hd_struct *part;
+ 		char name_buf[BDEVNAME_SIZE];
+ 		char devt_buf[BDEVT_SIZE];
+-		u8 uuid[PARTITION_META_INFO_UUIDLTH * 2 + 1];
++		char uuid_buf[PARTITION_META_INFO_UUIDLTH * 2 + 5];
+ 
+ 		/*
+ 		 * Don't show empty devices or things that have been
+@@ -762,14 +762,16 @@ void __init printk_all_partitions(void)
+ 		while ((part = disk_part_iter_next(&piter))) {
+ 			bool is_part0 = part == &disk->part0;
+ 
+-			uuid[0] = 0;
++			uuid_buf[0] = '\0';
+ 			if (part->info)
+-				part_unpack_uuid(part->info->uuid, uuid);
++				snprintf(uuid_buf, sizeof(uuid_buf), "%pU",
++					 part->info->uuid);
+ 
+ 			printk("%s%s %10llu %s %s", is_part0 ? "" : "  ",
+ 			       bdevt_str(part_devt(part), devt_buf),
+ 			       (unsigned long long)part->nr_sects >> 1,
+-			       disk_name(disk, part->partno, name_buf), uuid);
++			       disk_name(disk, part->partno, name_buf),
++			       uuid_buf);
+ 			if (is_part0) {
+ 				if (disk->driverfs_dev != NULL &&
+ 				    disk->driverfs_dev->driver != NULL)
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index ddeb845..ea7ef70 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -386,6 +386,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	  .driver_data = board_ahci_yes_fbs },			/* 88se9128 */
+ 	{ PCI_DEVICE(0x1b4b, 0x9125),
+ 	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */
++	{ PCI_DEVICE(0x1b4b, 0x917a),
++	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */
+ 	{ PCI_DEVICE(0x1b4b, 0x91a3),
+ 	  .driver_data = board_ahci_yes_fbs },
+ 
+diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
+index 74aaee3..c341904 100644
+--- a/drivers/ata/libata-transport.c
++++ b/drivers/ata/libata-transport.c
+@@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,
+ 	device_enable_async_suspend(dev);
+ 	pm_runtime_set_active(dev);
+ 	pm_runtime_enable(dev);
++	pm_runtime_forbid(dev);
+ 
+ 	transport_add_device(dev);
+ 	transport_configure_device(dev);
+diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
+index 5cd04b6..edcffd6 100644
+--- a/drivers/gpio/gpio-mpc8xxx.c
++++ b/drivers/gpio/gpio-mpc8xxx.c
+@@ -163,7 +163,8 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
+ 	if (mask)
+ 		generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
+ 						     32 - ffs(mask)));
+-	chip->irq_eoi(&desc->irq_data);
++	if (chip->irq_eoi)
++		chip->irq_eoi(&desc->irq_data);
+ }
+ 
+ static void mpc8xxx_irq_unmask(struct irq_data *d)
+diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
+index e5f5906..9bbb733 100644
+--- a/drivers/gpu/drm/gma500/psb_device.c
++++ b/drivers/gpu/drm/gma500/psb_device.c
+@@ -196,7 +196,8 @@ static int psb_save_display_registers(struct drm_device *dev)
+ 	}
+ 
+ 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+-		connector->funcs->save(connector);
++		if (connector->funcs->save)
++			connector->funcs->save(connector);
+ 
+ 	mutex_unlock(&dev->mode_config.mutex);
+ 	return 0;
+@@ -233,7 +234,8 @@ static int psb_restore_display_registers(struct drm_device *dev)
+ 			crtc->funcs->restore(crtc);
+ 
+ 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+-		connector->funcs->restore(connector);
++		if (connector->funcs->restore)
++			connector->funcs->restore(connector);
+ 
+ 	mutex_unlock(&dev->mode_config.mutex);
+ 	return 0;
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index 5bd4361..307c5e6 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -424,14 +424,11 @@ static void gen6_pm_rps_work(struct work_struct *work)
+ 	mutex_unlock(&dev_priv->dev->struct_mutex);
+ }
+ 
+-static void pch_irq_handler(struct drm_device *dev)
++static void pch_irq_handler(struct drm_device *dev, u32 pch_iir)
+ {
+ 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+-	u32 pch_iir;
+ 	int pipe;
+ 
+-	pch_iir = I915_READ(SDEIIR);
+-
+ 	if (pch_iir & SDE_AUDIO_POWER_MASK)
+ 		DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
+ 				 (pch_iir & SDE_AUDIO_POWER_MASK) >>
+@@ -529,7 +526,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
+ 	if (de_iir & DE_PCH_EVENT_IVB) {
+ 		if (pch_iir & SDE_HOTPLUG_MASK_CPT)
+ 			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+-		pch_irq_handler(dev);
++		pch_irq_handler(dev, pch_iir);
+ 	}
+ 
+ 	if (pm_iir & GEN6_PM_DEFERRED_EVENTS) {
+@@ -629,7 +626,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
+ 	if (de_iir & DE_PCH_EVENT) {
+ 		if (pch_iir & hotplug_mask)
+ 			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+-		pch_irq_handler(dev);
++		pch_irq_handler(dev, pch_iir);
+ 	}
+ 
+ 	if (de_iir & DE_PCU_EVENT) {
+diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
+index ac38d21..c0fdc31 100644
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -570,6 +570,21 @@
+ 
+ #define GEN6_BSD_RNCID			0x12198
+ 
++#define GEN7_FF_THREAD_MODE		0x20a0
++#define   GEN7_FF_SCHED_MASK		0x0077070
++#define   GEN7_FF_TS_SCHED_HS1		(0x5<<16)
++#define   GEN7_FF_TS_SCHED_HS0		(0x3<<16)
++#define   GEN7_FF_TS_SCHED_LOAD_BALANCE	(0x1<<16)
++#define   GEN7_FF_TS_SCHED_HW		(0x0<<16) /* Default */
++#define   GEN7_FF_VS_SCHED_HS1		(0x5<<12)
++#define   GEN7_FF_VS_SCHED_HS0		(0x3<<12)
++#define   GEN7_FF_VS_SCHED_LOAD_BALANCE	(0x1<<12) /* Default */
++#define   GEN7_FF_VS_SCHED_HW		(0x0<<12)
++#define   GEN7_FF_DS_SCHED_HS1		(0x5<<4)
++#define   GEN7_FF_DS_SCHED_HS0		(0x3<<4)
++#define   GEN7_FF_DS_SCHED_LOAD_BALANCE	(0x1<<4)  /* Default */
++#define   GEN7_FF_DS_SCHED_HW		(0x0<<4)
++
+ /*
+  * Framebuffer compression (915+ only)
+  */
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 2163818..9ab9b16 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -7496,10 +7496,11 @@ static void intel_sanitize_modesetting(struct drm_device *dev,
+ {
+ 	struct drm_i915_private *dev_priv = dev->dev_private;
+ 	u32 reg, val;
++	int i;
+ 
+ 	/* Clear any frame start delays used for debugging left by the BIOS */
+-	for_each_pipe(pipe) {
+-		reg = PIPECONF(pipe);
++	for_each_pipe(i) {
++		reg = PIPECONF(i);
+ 		I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+ 	}
+ 
+@@ -8467,6 +8468,18 @@ static void gen6_init_clock_gating(struct drm_device *dev)
+ 	}
+ }
+ 
++static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
++{
++	uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE);
++
++	reg &= ~GEN7_FF_SCHED_MASK;
++	reg |= GEN7_FF_TS_SCHED_HW;
++	reg |= GEN7_FF_VS_SCHED_HW;
++	reg |= GEN7_FF_DS_SCHED_HW;
++
++	I915_WRITE(GEN7_FF_THREAD_MODE, reg);
++}
++
+ static void ivybridge_init_clock_gating(struct drm_device *dev)
+ {
+ 	struct drm_i915_private *dev_priv = dev->dev_private;
+@@ -8511,6 +8524,8 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
+ 			   DISPPLANE_TRICKLE_FEED_DISABLE);
+ 		intel_flush_display_plane(dev_priv, pipe);
+ 	}
++
++	gen7_setup_fixed_func_scheduler(dev_priv);
+ }
+ 
+ static void g4x_init_clock_gating(struct drm_device *dev)
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
+index ec54364..b1d919f 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
+@@ -1035,7 +1035,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
+ 
+ 	nvbo->placement.fpfn = 0;
+ 	nvbo->placement.lpfn = dev_priv->fb_mappable_pages;
+-	nouveau_bo_placement_set(nvbo, TTM_PL_VRAM, 0);
++	nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_VRAM, 0);
+ 	return nouveau_bo_validate(nvbo, false, true, false);
+ }
+ 
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 38b12e4..2eac8c5 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -26,6 +26,7 @@
+ #include <linux/hid.h>
+ #include <linux/module.h>
+ #include <linux/usb.h>
++#include <asm/unaligned.h>
+ #include "usbhid/usbhid.h"
+ #include "hid-ids.h"
+ #include "hid-logitech-dj.h"
+@@ -265,8 +266,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
+ 		goto dj_device_allocate_fail;
+ 	}
+ 
+-	dj_dev->reports_supported = le32_to_cpu(
+-		dj_report->report_params[DEVICE_PAIRED_RF_REPORT_TYPE]);
++	dj_dev->reports_supported = get_unaligned_le32(
++		dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE);
+ 	dj_dev->hdev = dj_hiddev;
+ 	dj_dev->dj_receiver_dev = djrcv_dev;
+ 	dj_dev->device_index = dj_report->device_index;
+diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
+index cac3589..84e2fbe 100644
+--- a/drivers/hid/hid-wiimote-core.c
++++ b/drivers/hid/hid-wiimote-core.c
+@@ -769,7 +769,7 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir,
+ 
+ 	/*
+ 	 * Basic IR data is encoded into 3 bytes. The first two bytes are the
+-	 * upper 8 bit of the X/Y data, the 3rd byte contains the lower 2 bits
++	 * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits
+ 	 * of both.
+ 	 * If data is packed, then the 3rd byte is put first and slightly
+ 	 * reordered. This allows to interleave packed and non-packed data to
+@@ -778,17 +778,11 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir,
+ 	 */
+ 
+ 	if (packed) {
+-		x = ir[1] << 2;
+-		y = ir[2] << 2;
+-
+-		x |= ir[0] & 0x3;
+-		y |= (ir[0] >> 2) & 0x3;
++		x = ir[1] | ((ir[0] & 0x03) << 8);
++		y = ir[2] | ((ir[0] & 0x0c) << 6);
+ 	} else {
+-		x = ir[0] << 2;
+-		y = ir[1] << 2;
+-
+-		x |= (ir[2] >> 4) & 0x3;
+-		y |= (ir[2] >> 6) & 0x3;
++		x = ir[0] | ((ir[2] & 0x30) << 4);
++		y = ir[1] | ((ir[2] & 0xc0) << 2);
+ 	}
+ 
+ 	input_report_abs(wdata->ir, xid, x);
+diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
+index 5bf91db..4bbb883 100644
+--- a/drivers/hid/usbhid/hid-core.c
++++ b/drivers/hid/usbhid/hid-core.c
+@@ -399,6 +399,16 @@ static int hid_submit_ctrl(struct hid_device *hid)
+  * Output interrupt completion handler.
+  */
+ 
++static int irq_out_pump_restart(struct hid_device *hid)
++{
++	struct usbhid_device *usbhid = hid->driver_data;
++
++	if (usbhid->outhead != usbhid->outtail)
++		return hid_submit_out(hid);
++	else
++		return -1;
++}
++
+ static void hid_irq_out(struct urb *urb)
+ {
+ 	struct hid_device *hid = urb->context;
+@@ -428,7 +438,7 @@ static void hid_irq_out(struct urb *urb)
+ 	else
+ 		usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
+ 
+-	if (usbhid->outhead != usbhid->outtail && !hid_submit_out(hid)) {
++	if (!irq_out_pump_restart(hid)) {
+ 		/* Successfully submitted next urb in queue */
+ 		spin_unlock_irqrestore(&usbhid->lock, flags);
+ 		return;
+@@ -443,6 +453,15 @@ static void hid_irq_out(struct urb *urb)
+ /*
+  * Control pipe completion handler.
+  */
++static int ctrl_pump_restart(struct hid_device *hid)
++{
++	struct usbhid_device *usbhid = hid->driver_data;
++
++	if (usbhid->ctrlhead != usbhid->ctrltail)
++		return hid_submit_ctrl(hid);
++	else
++		return -1;
++}
+ 
+ static void hid_ctrl(struct urb *urb)
+ {
+@@ -476,7 +495,7 @@ static void hid_ctrl(struct urb *urb)
+ 	else
+ 		usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
+ 
+-	if (usbhid->ctrlhead != usbhid->ctrltail && !hid_submit_ctrl(hid)) {
++	if (!ctrl_pump_restart(hid)) {
+ 		/* Successfully submitted next urb in queue */
+ 		spin_unlock(&usbhid->lock);
+ 		return;
+@@ -535,11 +554,27 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
+ 			 * the queue is known to run
+ 			 * but an earlier request may be stuck
+ 			 * we may need to time out
+-			 * no race because this is called under
++			 * no race because the URB is blocked under
+ 			 * spinlock
+ 			 */
+-			if (time_after(jiffies, usbhid->last_out + HZ * 5))
++			if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
++				usb_block_urb(usbhid->urbout);
++				/* drop lock to not deadlock if the callback is called */
++				spin_unlock(&usbhid->lock);
+ 				usb_unlink_urb(usbhid->urbout);
++				spin_lock(&usbhid->lock);
++				usb_unblock_urb(usbhid->urbout);
++				/*
++				 * if the unlinking has already completed
++				 * the pump will have been stopped
++				 * it must be restarted now
++				 */
++				if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
++					if (!irq_out_pump_restart(hid))
++						set_bit(HID_OUT_RUNNING, &usbhid->iofl);
++
++
++			}
+ 		}
+ 		return;
+ 	}
+@@ -583,11 +618,25 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
+ 		 * the queue is known to run
+ 		 * but an earlier request may be stuck
+ 		 * we may need to time out
+-		 * no race because this is called under
++		 * no race because the URB is blocked under
+ 		 * spinlock
+ 		 */
+-		if (time_after(jiffies, usbhid->last_ctrl + HZ * 5))
++		if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
++			usb_block_urb(usbhid->urbctrl);
++			/* drop lock to not deadlock if the callback is called */
++			spin_unlock(&usbhid->lock);
+ 			usb_unlink_urb(usbhid->urbctrl);
++			spin_lock(&usbhid->lock);
++			usb_unblock_urb(usbhid->urbctrl);
++			/*
++			 * if the unlinking has already completed
++			 * the pump will have been stopped
++			 * it must be restarted now
++			 */
++			if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
++				if (!ctrl_pump_restart(hid))
++					set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
++		}
+ 	}
+ }
+ 
+diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
+index a76d85f..79b4bcb 100644
+--- a/drivers/i2c/busses/i2c-davinci.c
++++ b/drivers/i2c/busses/i2c-davinci.c
+@@ -755,7 +755,7 @@ static int davinci_i2c_remove(struct platform_device *pdev)
+ 	dev->clk = NULL;
+ 
+ 	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
+-	free_irq(IRQ_I2C, dev);
++	free_irq(dev->irq, dev);
+ 	iounmap(dev->base);
+ 	kfree(dev);
+ 
+diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
+index 0ab4a95..a54a9c2 100644
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -401,8 +401,6 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
+ 			disable_irq_nosync(i2c_dev->irq);
+ 			i2c_dev->irq_disabled = 1;
+ 		}
+-
+-		complete(&i2c_dev->msg_complete);
+ 		goto err;
+ 	}
+ 
+@@ -411,7 +409,6 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
+ 			i2c_dev->msg_err |= I2C_ERR_NO_ACK;
+ 		if (status & I2C_INT_ARBITRATION_LOST)
+ 			i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST;
+-		complete(&i2c_dev->msg_complete);
+ 		goto err;
+ 	}
+ 
+@@ -429,14 +426,14 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
+ 			tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);
+ 	}
+ 
++	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
++	if (i2c_dev->is_dvc)
++		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
++
+ 	if (status & I2C_INT_PACKET_XFER_COMPLETE) {
+ 		BUG_ON(i2c_dev->msg_buf_remaining);
+ 		complete(&i2c_dev->msg_complete);
+ 	}
+-
+-	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+-	if (i2c_dev->is_dvc)
+-		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
+ 	return IRQ_HANDLED;
+ err:
+ 	/* An error occurred, mask all interrupts */
+@@ -446,6 +443,8 @@ err:
+ 	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+ 	if (i2c_dev->is_dvc)
+ 		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
++
++	complete(&i2c_dev->msg_complete);
+ 	return IRQ_HANDLED;
+ }
+ 
+diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
+index 71f0c0f..a841123 100644
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -269,7 +269,7 @@ void ib_umem_release(struct ib_umem *umem)
+ 	} else
+ 		down_write(&mm->mmap_sem);
+ 
+-	current->mm->locked_vm -= diff;
++	current->mm->pinned_vm -= diff;
+ 	up_write(&mm->mmap_sem);
+ 	mmput(mm);
+ 	kfree(umem);
+diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
+index 0668bb3..d48d173 100644
+--- a/drivers/infiniband/hw/cxgb4/cm.c
++++ b/drivers/infiniband/hw/cxgb4/cm.c
+@@ -1593,7 +1593,7 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst,
+ 					n, n->dev, 0);
+ 		if (!ep->l2t)
+ 			goto out;
+-		ep->mtu = dst_mtu(ep->dst);
++		ep->mtu = dst_mtu(dst);
+ 		ep->tx_chan = cxgb4_port_chan(n->dev);
+ 		ep->smac_idx = (cxgb4_port_viid(n->dev) & 0x7F) << 1;
+ 		step = cdev->rdev.lldi.ntxq /
+@@ -2654,6 +2654,12 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
+ 	unsigned int tid = GET_TID(req);
+ 
+ 	ep = lookup_tid(t, tid);
++	if (!ep) {
++		printk(KERN_WARNING MOD
++		       "Abort on non-existent endpoint, tid %d\n", tid);
++		kfree_skb(skb);
++		return 0;
++	}
+ 	if (is_neg_adv_abort(req->status)) {
+ 		PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
+ 		     ep->hwtid);
+@@ -2665,11 +2671,8 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
+ 
+ 	/*
+ 	 * Wake up any threads in rdma_init() or rdma_fini().
+-	 * However, this is not needed if com state is just
+-	 * MPA_REQ_SENT
+ 	 */
+-	if (ep->com.state != MPA_REQ_SENT)
+-		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
++	c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
+ 	sched(dev, skb);
+ 	return 0;
+ }
+diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
+index 35c1e17..97b2e21 100644
+--- a/drivers/iommu/dmar.c
++++ b/drivers/iommu/dmar.c
+@@ -1056,8 +1056,8 @@ static const char *intr_remap_fault_reasons[] =
+ 
+ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
+ {
+-	if (fault_reason >= 0x20 && (fault_reason <= 0x20 +
+-				     ARRAY_SIZE(intr_remap_fault_reasons))) {
++	if (fault_reason >= 0x20 && (fault_reason - 0x20 <
++					ARRAY_SIZE(intr_remap_fault_reasons))) {
+ 		*fault_type = INTR_REMAP;
+ 		return intr_remap_fault_reasons[fault_reason - 0x20];
+ 	} else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index c9c6053..da50c7e 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -2280,12 +2280,6 @@ static int domain_add_dev_info(struct dmar_domain *domain,
+ 	if (!info)
+ 		return -ENOMEM;
+ 
+-	ret = domain_context_mapping(domain, pdev, translation);
+-	if (ret) {
+-		free_devinfo_mem(info);
+-		return ret;
+-	}
+-
+ 	info->segment = pci_domain_nr(pdev->bus);
+ 	info->bus = pdev->bus->number;
+ 	info->devfn = pdev->devfn;
+@@ -2298,6 +2292,17 @@ static int domain_add_dev_info(struct dmar_domain *domain,
+ 	pdev->dev.archdata.iommu = info;
+ 	spin_unlock_irqrestore(&device_domain_lock, flags);
+ 
++	ret = domain_context_mapping(domain, pdev, translation);
++	if (ret) {
++		spin_lock_irqsave(&device_domain_lock, flags);
++		list_del(&info->link);
++		list_del(&info->global);
++		pdev->dev.archdata.iommu = NULL;
++		spin_unlock_irqrestore(&device_domain_lock, flags);
++		free_devinfo_mem(info);
++		return ret;
++	}
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
+index 6d5ceee..5b80ef7 100644
+--- a/drivers/isdn/gigaset/capi.c
++++ b/drivers/isdn/gigaset/capi.c
+@@ -14,6 +14,7 @@
+ #include "gigaset.h"
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
++#include <linux/ratelimit.h>
+ #include <linux/isdn/capilli.h>
+ #include <linux/isdn/capicmd.h>
+ #include <linux/isdn/capiutil.h>
+@@ -223,10 +224,14 @@ get_appl(struct gigaset_capi_ctr *iif, u16 appl)
+ static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
+ {
+ #ifdef CONFIG_GIGASET_DEBUG
++	/* dump at most 20 messages in 20 secs */
++	static DEFINE_RATELIMIT_STATE(msg_dump_ratelimit, 20 * HZ, 20);
+ 	_cdebbuf *cdb;
+ 
+ 	if (!(gigaset_debuglevel & level))
+ 		return;
++	if (!___ratelimit(&msg_dump_ratelimit, tag))
++		return;
+ 
+ 	cdb = capi_cmsg2str(p);
+ 	if (cdb) {
+@@ -2059,12 +2064,6 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
+ }
+ 
+ /*
+- * dump unsupported/ignored messages at most twice per minute,
+- * some apps send those very frequently
+- */
+-static unsigned long ignored_msg_dump_time;
+-
+-/*
+  * unsupported CAPI message handler
+  */
+ static void do_unsupported(struct gigaset_capi_ctr *iif,
+@@ -2073,8 +2072,7 @@ static void do_unsupported(struct gigaset_capi_ctr *iif,
+ {
+ 	/* decode message */
+ 	capi_message2cmsg(&iif->acmsg, skb->data);
+-	if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000))
+-		dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
++	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+ 	send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
+ }
+ 
+@@ -2085,11 +2083,9 @@ static void do_nothing(struct gigaset_capi_ctr *iif,
+ 		       struct gigaset_capi_appl *ap,
+ 		       struct sk_buff *skb)
+ {
+-	if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) {
+-		/* decode message */
+-		capi_message2cmsg(&iif->acmsg, skb->data);
+-		dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+-	}
++	/* decode message */
++	capi_message2cmsg(&iif->acmsg, skb->data);
++	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+ 	dev_kfree_skb_any(skb);
+ }
+ 
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 363aaf4..1ae4327 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -452,7 +452,7 @@ static void submit_flushes(struct work_struct *ws)
+ 			atomic_inc(&rdev->nr_pending);
+ 			atomic_inc(&rdev->nr_pending);
+ 			rcu_read_unlock();
+-			bi = bio_alloc_mddev(GFP_KERNEL, 0, mddev);
++			bi = bio_alloc_mddev(GFP_NOIO, 0, mddev);
+ 			bi->bi_end_io = md_end_flush;
+ 			bi->bi_private = rdev;
+ 			bi->bi_bdev = rdev->bdev;
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 7294bd1..ce454f0 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -609,6 +609,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev)
+ static void *raid0_takeover_raid1(struct mddev *mddev)
+ {
+ 	struct r0conf *priv_conf;
++	int chunksect;
+ 
+ 	/* Check layout:
+ 	 *  - (N - 1) mirror drives must be already faulty
+@@ -619,10 +620,25 @@ static void *raid0_takeover_raid1(struct mddev *mddev)
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
++	/*
++	 * a raid1 doesn't have the notion of chunk size, so
++	 * figure out the largest suitable size we can use.
++	 */
++	chunksect = 64 * 2; /* 64K by default */
++
++	/* The array must be an exact multiple of chunksize */
++	while (chunksect && (mddev->array_sectors & (chunksect - 1)))
++		chunksect >>= 1;
++
++	if ((chunksect << 9) < PAGE_SIZE)
++		/* array size does not allow a suitable chunk size */
++		return ERR_PTR(-EINVAL);
++
+ 	/* Set new parameters */
+ 	mddev->new_level = 0;
+ 	mddev->new_layout = 0;
+-	mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */
++	mddev->new_chunk_sectors = chunksect;
++	mddev->chunk_sectors = chunksect;
+ 	mddev->delta_disks = 1 - mddev->raid_disks;
+ 	mddev->raid_disks = 1;
+ 	/* make sure it will be not marked as dirty */
+diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
+index b1fe513..63c004a 100644
+--- a/drivers/media/dvb/siano/smsusb.c
++++ b/drivers/media/dvb/siano/smsusb.c
+@@ -542,6 +542,8 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = {
+ 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ 	{ USB_DEVICE(0x2040, 0xc090),
+ 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
++	{ USB_DEVICE(0x2040, 0xc0a0),
++		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ 	{ } /* Terminating entry */
+ 	};
+ 
+diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
+index 2ae4f88..dca9f9b 100644
+--- a/drivers/media/video/uvc/uvc_v4l2.c
++++ b/drivers/media/video/uvc/uvc_v4l2.c
+@@ -686,7 +686,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+ 					break;
+ 			}
+ 			pin = iterm->id;
+-		} else if (pin < selector->bNrInPins) {
++		} else if (index < selector->bNrInPins) {
+ 			pin = selector->baSourceID[index];
+ 			list_for_each_entry(iterm, &chain->entities, chain) {
+ 				if (!UVC_ENTITY_IS_ITERM(iterm))
+diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
+index 082202a..8c3e6f0 100644
+--- a/drivers/mmc/core/cd-gpio.c
++++ b/drivers/mmc/core/cd-gpio.c
+@@ -67,6 +67,9 @@ void mmc_cd_gpio_free(struct mmc_host *host)
+ {
+ 	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+ 
++	if (!cd)
++		return;
++
+ 	free_irq(host->hotplug.irq, host);
+ 	gpio_free(cd->gpio);
+ 	kfree(cd);
+diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
+index 2c7c83f..13d0e95 100644
+--- a/drivers/mmc/core/sdio.c
++++ b/drivers/mmc/core/sdio.c
+@@ -947,7 +947,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
+ 	}
+ 
+ 	if (!err && host->sdio_irqs)
+-		mmc_signal_sdio_irq(host);
++		wake_up_process(host->sdio_irq_thread);
+ 	mmc_release_host(host);
+ 
+ 	/*
+diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
+index f573e7f..3d8ceb4 100644
+--- a/drivers/mmc/core/sdio_irq.c
++++ b/drivers/mmc/core/sdio_irq.c
+@@ -28,18 +28,20 @@
+ 
+ #include "sdio_ops.h"
+ 
+-static int process_sdio_pending_irqs(struct mmc_card *card)
++static int process_sdio_pending_irqs(struct mmc_host *host)
+ {
++	struct mmc_card *card = host->card;
+ 	int i, ret, count;
+ 	unsigned char pending;
+ 	struct sdio_func *func;
+ 
+ 	/*
+ 	 * Optimization, if there is only 1 function interrupt registered
+-	 * call irq handler directly
++	 * and we know an IRQ was signaled then call irq handler directly.
++	 * Otherwise do the full probe.
+ 	 */
+ 	func = card->sdio_single_irq;
+-	if (func) {
++	if (func && host->sdio_irq_pending) {
+ 		func->irq_handler(func);
+ 		return 1;
+ 	}
+@@ -116,7 +118,8 @@ static int sdio_irq_thread(void *_host)
+ 		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
+ 		if (ret)
+ 			break;
+-		ret = process_sdio_pending_irqs(host->card);
++		ret = process_sdio_pending_irqs(host);
++		host->sdio_irq_pending = false;
+ 		mmc_release_host(host);
+ 
+ 		/*
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index fd0c661..56bbfdd 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -2034,7 +2034,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
+ 		ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
+ 					   NULL,
+ 					   omap_hsmmc_detect,
+-					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ 					   mmc_hostname(mmc), host);
+ 		if (ret) {
+ 			dev_dbg(mmc_dev(host->mmc),
+diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
+index 072ed59..9e2dfd5 100644
+--- a/drivers/mtd/sm_ftl.c
++++ b/drivers/mtd/sm_ftl.c
+@@ -1256,7 +1256,7 @@ static void sm_remove_dev(struct mtd_blktrans_dev *dev)
+ 
+ static struct mtd_blktrans_ops sm_ftl_ops = {
+ 	.name		= "smblk",
+-	.major		= -1,
++	.major		= 0,
+ 	.part_bits	= SM_FTL_PARTN_BITS,
+ 	.blksize	= SM_SECTOR_SIZE,
+ 	.getgeo		= sm_getgeo,
+diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
+index 75e70bc..2609cbe 100644
+--- a/drivers/net/wireless/b43legacy/main.c
++++ b/drivers/net/wireless/b43legacy/main.c
+@@ -1564,8 +1564,6 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
+ 	const char *filename;
+ 	int err;
+ 
+-	/* do dummy read */
+-	ssb_read32(dev->dev, SSB_TMSHIGH);
+ 	if (!fw->ucode) {
+ 		if (rev == 2)
+ 			filename = "ucode2";
+diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
+index b588ca8..3c5e890 100644
+--- a/drivers/net/wireless/rtlwifi/pci.c
++++ b/drivers/net/wireless/rtlwifi/pci.c
+@@ -1865,14 +1865,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
+ 	/*like read eeprom and so on */
+ 	rtlpriv->cfg->ops->read_eeprom_info(hw);
+ 
+-	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+-			 ("Can't init_sw_vars.\n"));
+-		goto fail3;
+-	}
+-
+-	rtlpriv->cfg->ops->init_sw_leds(hw);
+-
+ 	/*aspm */
+ 	rtl_pci_init_aspm(hw);
+ 
+@@ -1892,6 +1884,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
+ 		goto fail3;
+ 	}
+ 
++	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
++		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
++			 ("Can't init_sw_vars.\n"));
++		err = -ENODEV;
++		goto fail3;
++	}
++
++	rtlpriv->cfg->ops->init_sw_leds(hw);
++
+ 	err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
+ 	if (err) {
+ 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+index 2afcfe3..2a69e10 100644
+--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+@@ -94,7 +94,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
+ 	u8 tid;
+ 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+ 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+-	static int header_print;
+ 
+ 	rtlpriv->dm.dm_initialgain_enable = true;
+ 	rtlpriv->dm.dm_flag = 0;
+@@ -174,10 +173,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
+ 	for (tid = 0; tid < 8; tid++)
+ 		skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
+ 
+-	/* Only load firmware for first MAC */
+-	if (header_print)
+-		return 0;
+-
+ 	/* for firmware buf */
+ 	rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
+ 	if (!rtlpriv->rtlhal.pfirmware) {
+@@ -189,7 +184,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
+ 	rtlpriv->max_fw_size = 0x8000;
+ 	pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
+ 	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+-	header_print++;
+ 
+ 	/* request fw */
+ 	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
+index 049e207..20b53ae 100644
+--- a/drivers/net/wireless/rtlwifi/usb.c
++++ b/drivers/net/wireless/rtlwifi/usb.c
+@@ -970,12 +970,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
+ 	rtlpriv->cfg->ops->read_chip_version(hw);
+ 	/*like read eeprom and so on */
+ 	rtlpriv->cfg->ops->read_eeprom_info(hw);
+-	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+-			 ("Can't init_sw_vars.\n"));
+-		goto error_out;
+-	}
+-	rtlpriv->cfg->ops->init_sw_leds(hw);
+ 	err = _rtl_usb_init(hw);
+ 	err = _rtl_usb_init_sw(hw);
+ 	/* Init mac80211 sw */
+@@ -985,6 +979,12 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
+ 			 ("Can't allocate sw for mac80211.\n"));
+ 		goto error_out;
+ 	}
++	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
++		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
++			 ("Can't init_sw_vars.\n"));
++		goto error_out;
++	}
++	rtlpriv->cfg->ops->init_sw_leds(hw);
+ 
+ 	return 0;
+ error_out:
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index e9a83f8..9d4b03b 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -2877,6 +2877,8 @@ unset_supplies:
+ 	unset_regulator_supplies(rdev);
+ 
+ scrub:
++	if (rdev->supply)
++		regulator_put(rdev->supply);
+ 	kfree(rdev->constraints);
+ 	device_unregister(&rdev->dev);
+ 	/* device core frees rdev */
+diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
+index ee5a561..0b4f87e 100644
+--- a/drivers/rtc/rtc-pl031.c
++++ b/drivers/rtc/rtc-pl031.c
+@@ -312,6 +312,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
+ 	int ret;
+ 	struct pl031_local *ldata;
+ 	struct rtc_class_ops *ops = id->data;
++	unsigned long time;
+ 
+ 	ret = amba_request_regions(adev, NULL);
+ 	if (ret)
+@@ -343,6 +344,23 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
+ 		writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
+ 		       ldata->base + RTC_CR);
+ 
++	/*
++	 * On ST PL031 variants, the RTC reset value does not provide correct
++	 * weekday for 2000-01-01. Correct the erroneous sunday to saturday.
++	 */
++	if (ldata->hw_designer == AMBA_VENDOR_ST) {
++		if (readl(ldata->base + RTC_YDR) == 0x2000) {
++			time = readl(ldata->base + RTC_DR);
++			if ((time &
++			     (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK))
++			    == 0x02120000) {
++				time = time | (0x7 << RTC_WDAY_SHIFT);
++				writel(0x2000, ldata->base + RTC_YLR);
++				writel(time, ldata->base + RTC_LR);
++			}
++		}
++	}
++
+ 	ldata->rtc = rtc_device_register("pl031", &adev->dev, ops,
+ 					THIS_MODULE);
+ 	if (IS_ERR(ldata->rtc)) {
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index b96962c..e640b73 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1676,30 +1676,26 @@ static void figure_bus_target_lun(struct ctlr_info *h,
+ 
+ 	if (is_logical_dev_addr_mode(lunaddrbytes)) {
+ 		/* logical device */
+-		if (unlikely(is_scsi_rev_5(h))) {
+-			/* p1210m, logical drives lun assignments
+-			 * match SCSI REPORT LUNS data.
++		lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
++		if (is_msa2xxx(h, device)) {
++			/* msa2xxx way, put logicals on bus 1
++			 * and match target/lun numbers box
++			 * reports.
+ 			 */
+-			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+-			*bus = 0;
+-			*target = 0;
+-			*lun = (lunid & 0x3fff) + 1;
++			*bus = 1;
++			*target = (lunid >> 16) & 0x3fff;
++			*lun = lunid & 0x00ff;
+ 		} else {
+-			/* not p1210m... */
+-			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+-			if (is_msa2xxx(h, device)) {
+-				/* msa2xxx way, put logicals on bus 1
+-				 * and match target/lun numbers box
+-				 * reports.
+-				 */
+-				*bus = 1;
+-				*target = (lunid >> 16) & 0x3fff;
+-				*lun = lunid & 0x00ff;
++			if (likely(is_scsi_rev_5(h))) {
++				/* All current smart arrays (circa 2011) */
++				*bus = 0;
++				*target = 0;
++				*lun = (lunid & 0x3fff) + 1;
+ 			} else {
+-				/* Traditional smart array way. */
++				/* Traditional old smart array way. */
+ 				*bus = 0;
+-				*lun = 0;
+ 				*target = lunid & 0x3fff;
++				*lun = 0;
+ 			}
+ 		}
+ 	} else {
+diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
+index 17c4c2c..ff12aef 100644
+--- a/drivers/scsi/isci/init.c
++++ b/drivers/scsi/isci/init.c
+@@ -481,7 +481,7 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
+ 	if (!orom)
+ 		orom = isci_request_oprom(pdev);
+ 
+-	for (i = 0; orom && i < ARRAY_SIZE(orom->ctrl); i++) {
++	for (i = 0; orom && i < num_controllers(pdev); i++) {
+ 		if (sci_oem_parameters_validate(&orom->ctrl[i],
+ 						orom->hdr.version)) {
+ 			dev_warn(&pdev->dev,
+diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
+index a78036f..37fd933 100644
+--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
++++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
+@@ -3340,7 +3340,7 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag)
+ 	}
+ 
+ 	pfacts = &ioc->pfacts[port];
+-	memset(pfacts, 0, sizeof(Mpi2PortFactsReply_t));
++	memset(pfacts, 0, sizeof(struct mpt2sas_port_facts));
+ 	pfacts->PortNumber = mpi_reply.PortNumber;
+ 	pfacts->VP_ID = mpi_reply.VP_ID;
+ 	pfacts->VF_ID = mpi_reply.VF_ID;
+@@ -3382,7 +3382,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
+ 	}
+ 
+ 	facts = &ioc->facts;
+-	memset(facts, 0, sizeof(Mpi2IOCFactsReply_t));
++	memset(facts, 0, sizeof(struct mpt2sas_facts));
+ 	facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion);
+ 	facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion);
+ 	facts->VP_ID = mpi_reply.VP_ID;
+@@ -4259,7 +4259,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
+ 		goto out_free_resources;
+ 
+ 	ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
+-	    sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
++	    sizeof(struct mpt2sas_port_facts), GFP_KERNEL);
+ 	if (!ioc->pfacts) {
+ 		r = -ENOMEM;
+ 		goto out_free_resources;
+diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
+index 24cacff..6a62934 100644
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -139,10 +139,12 @@ static void fsl_spi_change_mode(struct spi_device *spi)
+ static void fsl_spi_chipselect(struct spi_device *spi, int value)
+ {
+ 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
+-	struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
++	struct fsl_spi_platform_data *pdata;
+ 	bool pol = spi->mode & SPI_CS_HIGH;
+ 	struct spi_mpc8xxx_cs	*cs = spi->controller_state;
+ 
++	pdata = spi->dev.parent->parent->platform_data;
++
+ 	if (value == BITBANG_CS_INACTIVE) {
+ 		if (pdata->cs_control)
+ 			pdata->cs_control(spi, !pol);
+@@ -931,7 +933,7 @@ err:
+ 
+ static void fsl_spi_cs_control(struct spi_device *spi, bool on)
+ {
+-	struct device *dev = spi->dev.parent;
++	struct device *dev = spi->dev.parent->parent;
+ 	struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
+ 	u16 cs = spi->chip_select;
+ 	int gpio = pinfo->gpios[cs];
+diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
+index 9bcf87a..a796964 100644
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -280,7 +280,7 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
+ 	if (ret == 0) {
+ 		if (!try_module_get(dev->driver->module)) {
+ 			comedi_device_detach(dev);
+-			return -ENOSYS;
++			ret = -ENOSYS;
+ 		}
+ 	}
+ 
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 858dca8..3614973 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1609,54 +1609,72 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
+ 	{
+ 		.vendor         = PCI_VENDOR_ID_INTEL,
+ 		.device         = 0x8811,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = PCI_VENDOR_ID_INTEL,
+ 		.device         = 0x8812,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = PCI_VENDOR_ID_INTEL,
+ 		.device         = 0x8813,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = PCI_VENDOR_ID_INTEL,
+ 		.device         = 0x8814,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = 0x10DB,
+ 		.device         = 0x8027,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = 0x10DB,
+ 		.device         = 0x8028,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = 0x10DB,
+ 		.device         = 0x8029,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = 0x10DB,
+ 		.device         = 0x800C,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+ 	{
+ 		.vendor         = 0x10DB,
+ 		.device         = 0x800D,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
+ 		.init		= pci_eg20t_init,
+ 		.setup		= pci_default_setup,
+ 	},
+diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
+index 55fd362..039c054 100644
+--- a/drivers/tty/serial/mxs-auart.c
++++ b/drivers/tty/serial/mxs-auart.c
+@@ -369,6 +369,8 @@ static void mxs_auart_settermios(struct uart_port *u,
+ 
+ 	writel(ctrl, u->membase + AUART_LINECTRL);
+ 	writel(ctrl2, u->membase + AUART_CTRL2);
++
++	uart_update_timeout(u, termios->c_cflag, baud);
+ }
+ 
+ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index 1305618..8f5d0d8 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -2283,6 +2283,7 @@ void uart_unregister_driver(struct uart_driver *drv)
+ 	tty_unregister_driver(p);
+ 	put_tty_driver(p);
+ 	kfree(drv->state);
++	drv->state = NULL;
+ 	drv->tty_driver = NULL;
+ }
+ 
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index 7b45f66..e55adbb 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -500,7 +500,7 @@ static int wdm_flush(struct file *file, fl_owner_t id)
+ 		dev_err(&desc->intf->dev, "Error in flush path: %d\n",
+ 			desc->werr);
+ 
+-	return desc->werr;
++	return usb_translate_errors(desc->werr);
+ }
+ 
+ static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait)
+@@ -511,7 +511,7 @@ static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait)
+ 
+ 	spin_lock_irqsave(&desc->iuspin, flags);
+ 	if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+-		mask = POLLERR;
++		mask = POLLHUP | POLLERR;
+ 		spin_unlock_irqrestore(&desc->iuspin, flags);
+ 		goto desc_out;
+ 	}
+diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
+index 8df4b76..4e57772 100644
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -333,17 +333,14 @@ static struct async *async_getcompleted(struct dev_state *ps)
+ static struct async *async_getpending(struct dev_state *ps,
+ 					     void __user *userurb)
+ {
+-	unsigned long flags;
+ 	struct async *as;
+ 
+-	spin_lock_irqsave(&ps->lock, flags);
+ 	list_for_each_entry(as, &ps->async_pending, asynclist)
+ 		if (as->userurb == userurb) {
+ 			list_del_init(&as->asynclist);
+-			spin_unlock_irqrestore(&ps->lock, flags);
+ 			return as;
+ 		}
+-	spin_unlock_irqrestore(&ps->lock, flags);
++
+ 	return NULL;
+ }
+ 
+@@ -398,6 +395,7 @@ static void cancel_bulk_urbs(struct dev_state *ps, unsigned bulk_addr)
+ __releases(ps->lock)
+ __acquires(ps->lock)
+ {
++	struct urb *urb;
+ 	struct async *as;
+ 
+ 	/* Mark all the pending URBs that match bulk_addr, up to but not
+@@ -420,8 +418,11 @@ __acquires(ps->lock)
+ 	list_for_each_entry(as, &ps->async_pending, asynclist) {
+ 		if (as->bulk_status == AS_UNLINK) {
+ 			as->bulk_status = 0;		/* Only once */
++			urb = as->urb;
++			usb_get_urb(urb);
+ 			spin_unlock(&ps->lock);		/* Allow completions */
+-			usb_unlink_urb(as->urb);
++			usb_unlink_urb(urb);
++			usb_put_urb(urb);
+ 			spin_lock(&ps->lock);
+ 			goto rescan;
+ 		}
+@@ -472,6 +473,7 @@ static void async_completed(struct urb *urb)
+ 
+ static void destroy_async(struct dev_state *ps, struct list_head *list)
+ {
++	struct urb *urb;
+ 	struct async *as;
+ 	unsigned long flags;
+ 
+@@ -479,10 +481,13 @@ static void destroy_async(struct dev_state *ps, struct list_head *list)
+ 	while (!list_empty(list)) {
+ 		as = list_entry(list->next, struct async, asynclist);
+ 		list_del_init(&as->asynclist);
++		urb = as->urb;
++		usb_get_urb(urb);
+ 
+ 		/* drop the spinlock so the completion handler can run */
+ 		spin_unlock_irqrestore(&ps->lock, flags);
+-		usb_kill_urb(as->urb);
++		usb_kill_urb(urb);
++		usb_put_urb(urb);
+ 		spin_lock_irqsave(&ps->lock, flags);
+ 	}
+ 	spin_unlock_irqrestore(&ps->lock, flags);
+@@ -1410,12 +1415,24 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)
+ 
+ static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
+ {
++	struct urb *urb;
+ 	struct async *as;
++	unsigned long flags;
+ 
++	spin_lock_irqsave(&ps->lock, flags);
+ 	as = async_getpending(ps, arg);
+-	if (!as)
++	if (!as) {
++		spin_unlock_irqrestore(&ps->lock, flags);
+ 		return -EINVAL;
+-	usb_kill_urb(as->urb);
++	}
++
++	urb = as->urb;
++	usb_get_urb(urb);
++	spin_unlock_irqrestore(&ps->lock, flags);
++
++	usb_kill_urb(urb);
++	usb_put_urb(urb);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 95baf5d..ce5e147 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2419,6 +2419,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
+ 				NULL, 0,
+ 				USB_CTRL_SET_TIMEOUT);
+ 
++		/* Try to enable USB2 hardware LPM again */
++		if (udev->usb2_hw_lpm_capable == 1)
++			usb_set_usb2_hardware_lpm(udev, 1);
++
+ 		/* System sleep transitions should never fail */
+ 		if (!PMSG_IS_AUTO(msg))
+ 			status = 0;
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 4c65eb6..32d3adc 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -123,6 +123,9 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	/* Guillemot Webcam Hercules Dualpix Exchange*/
+ 	{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
++	/* Midiman M-Audio Keystation 88es */
++	{ USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ 	/* M-Systems Flash Disk Pioneers */
+ 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
+index 909625b..0f362cc 100644
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -671,6 +671,27 @@ void usb_unpoison_urb(struct urb *urb)
+ EXPORT_SYMBOL_GPL(usb_unpoison_urb);
+ 
+ /**
++ * usb_block_urb - reliably prevent further use of an URB
++ * @urb: pointer to URB to be blocked, may be NULL
++ *
++ * After the routine has run, attempts to resubmit the URB will fail
++ * with error -EPERM.  Thus even if the URB's completion handler always
++ * tries to resubmit, it will not succeed and the URB will become idle.
++ *
++ * The URB must not be deallocated while this routine is running.  In
++ * particular, when a driver calls this routine, it must insure that the
++ * completion handler cannot deallocate the URB.
++ */
++void usb_block_urb(struct urb *urb)
++{
++	if (!urb)
++		return;
++
++	atomic_inc(&urb->reject);
++}
++EXPORT_SYMBOL_GPL(usb_block_urb);
++
++/**
+  * usb_kill_anchored_urbs - cancel transfer requests en masse
+  * @anchor: anchor the requests are bound to
+  *
+diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
+index 6b5fdf9..cd81463 100644
+--- a/drivers/usb/gadget/fsl_udc_core.c
++++ b/drivers/usb/gadget/fsl_udc_core.c
+@@ -737,6 +737,8 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
+ 		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
+ 		lastreq->tail->next_td_ptr =
+ 			cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
++		/* Ensure dTD's next dtd pointer to be updated */
++		wmb();
+ 		/* Read prime bit, if 1 goto done */
+ 		if (fsl_readl(&dr_regs->endpointprime) & bitmask)
+ 			return;
+diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
+index fe8dc06..bc94d7b 100644
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -368,7 +368,9 @@ static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
+ {
+ 	return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
+ 		pdev->vendor == PCI_VENDOR_ID_INTEL &&
+-		pdev->device == 0x1E26;
++		(pdev->device == 0x1E26 ||
++		 pdev->device == 0x8C2D ||
++		 pdev->device == 0x8C26);
+ }
+ 
+ static void ehci_enable_xhci_companion(void)
+diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
+index 70b96ec..76a70f3 100644
+--- a/drivers/usb/host/ohci-at91.c
++++ b/drivers/usb/host/ohci-at91.c
+@@ -217,7 +217,7 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+ /*-------------------------------------------------------------------------*/
+ 
+ static int __devinit
+-ohci_at91_start (struct usb_hcd *hcd)
++ohci_at91_reset (struct usb_hcd *hcd)
+ {
+ 	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
+ 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
+@@ -227,6 +227,14 @@ ohci_at91_start (struct usb_hcd *hcd)
+ 		return ret;
+ 
+ 	ohci->num_ports = board->ports;
++	return 0;
++}
++
++static int __devinit
++ohci_at91_start (struct usb_hcd *hcd)
++{
++	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
++	int			ret;
+ 
+ 	if ((ret = ohci_run(ohci)) < 0) {
+ 		err("can't start %s", hcd->self.bus_name);
+@@ -410,6 +418,7 @@ static const struct hc_driver ohci_at91_hc_driver = {
+ 	/*
+ 	 * basic lifecycle operations
+ 	 */
++	.reset =		ohci_at91_reset,
+ 	.start =		ohci_at91_start,
+ 	.stop =			ohci_stop,
+ 	.shutdown =		ohci_shutdown,
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 2afff88..833b3c6 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -9,6 +9,7 @@
+  */
+ 
+ #include <linux/types.h>
++#include <linux/kconfig.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+@@ -712,12 +713,28 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done,
+ 	return -ETIMEDOUT;
+ }
+ 
+-bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
++#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI	0x8C31
++
++bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
+ {
+ 	return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
+ 		pdev->vendor == PCI_VENDOR_ID_INTEL &&
+ 		pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI;
+ }
++
++/* The Intel Lynx Point chipset also has switchable ports. */
++bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev)
++{
++	return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
++		pdev->vendor == PCI_VENDOR_ID_INTEL &&
++		pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI;
++}
++
++bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
++{
++	return usb_is_intel_ppt_switchable_xhci(pdev) ||
++		usb_is_intel_lpt_switchable_xhci(pdev);
++}
+ EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci);
+ 
+ /*
+@@ -742,6 +759,19 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
+ {
+ 	u32		ports_available;
+ 
++	/* Don't switchover the ports if the user hasn't compiled the xHCI
++	 * driver.  Otherwise they will see "dead" USB ports that don't power
++	 * the devices.
++	 */
++	if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) {
++		dev_warn(&xhci_pdev->dev,
++				"CONFIG_USB_XHCI_HCD is turned off, "
++				"defaulting to EHCI.\n");
++		dev_warn(&xhci_pdev->dev,
++				"USB 3.0 devices will work at USB 2.0 speeds.\n");
++		return;
++	}
++
+ 	ports_available = 0xffffffff;
+ 	/* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable
+ 	 * Register, to turn on SuperSpeed terminations for all
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 4c1e721..fd7635f 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1685,6 +1685,14 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+ {
+ 	struct pci_dev	*pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+ 	struct dev_info	*dev_info, *next;
++	struct list_head *tt_list_head;
++	struct list_head *tt;
++	struct list_head *endpoints;
++	struct list_head *ep, *q;
++	struct xhci_tt_bw_info *tt_info;
++	struct xhci_interval_bw_table *bwt;
++	struct xhci_virt_ep *virt_ep;
++
+ 	unsigned long	flags;
+ 	int size;
+ 	int i;
+@@ -1701,6 +1709,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+ 	xhci->event_ring = NULL;
+ 	xhci_dbg(xhci, "Freed event ring\n");
+ 
++	xhci->cmd_ring_reserved_trbs = 0;
+ 	if (xhci->cmd_ring)
+ 		xhci_ring_free(xhci, xhci->cmd_ring);
+ 	xhci->cmd_ring = NULL;
+@@ -1743,8 +1752,26 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+ 	}
+ 	spin_unlock_irqrestore(&xhci->lock, flags);
+ 
++	bwt = &xhci->rh_bw->bw_table;
++	for (i = 0; i < XHCI_MAX_INTERVAL; i++) {
++		endpoints = &bwt->interval_bw[i].endpoints;
++		list_for_each_safe(ep, q, endpoints) {
++			virt_ep = list_entry(ep, struct xhci_virt_ep, bw_endpoint_list);
++			list_del(&virt_ep->bw_endpoint_list);
++			kfree(virt_ep);
++		}
++	}
++
++	tt_list_head = &xhci->rh_bw->tts;
++	list_for_each_safe(tt, q, tt_list_head) {
++		tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list);
++		list_del(tt);
++		kfree(tt_info);
++	}
++
+ 	xhci->num_usb2_ports = 0;
+ 	xhci->num_usb3_ports = 0;
++	xhci->num_active_eps = 0;
+ 	kfree(xhci->usb2_ports);
+ 	kfree(xhci->usb3_ports);
+ 	kfree(xhci->port_array);
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 211296a..daf5754 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -72,6 +72,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 		xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u "
+ 				"has broken MSI implementation\n",
+ 				pdev->revision);
++		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ 	}
+ 
+ 	if (pdev->vendor == PCI_VENDOR_ID_NEC)
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 6851bc2..dae7893 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1722,8 +1722,12 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ 	/* handle completion code */
+ 	switch (trb_comp_code) {
+ 	case COMP_SUCCESS:
+-		frame->status = 0;
+-		break;
++		if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
++			frame->status = 0;
++			break;
++		}
++		if ((xhci->quirks & XHCI_TRUST_TX_LENGTH))
++			trb_comp_code = COMP_SHORT_TX;
+ 	case COMP_SHORT_TX:
+ 		frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ?
+ 				-EREMOTEIO : 0;
+@@ -1739,6 +1743,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ 		break;
+ 	case COMP_DEV_ERR:
+ 	case COMP_STALL:
++	case COMP_TX_ERR:
+ 		frame->status = -EPROTO;
+ 		skip_td = true;
+ 		break;
+@@ -1819,13 +1824,16 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ 	switch (trb_comp_code) {
+ 	case COMP_SUCCESS:
+ 		/* Double check that the HW transferred everything. */
+-		if (event_trb != td->last_trb) {
++		if (event_trb != td->last_trb ||
++				TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
+ 			xhci_warn(xhci, "WARN Successful completion "
+ 					"on short TX\n");
+ 			if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
+ 				*status = -EREMOTEIO;
+ 			else
+ 				*status = 0;
++			if ((xhci->quirks & XHCI_TRUST_TX_LENGTH))
++				trb_comp_code = COMP_SHORT_TX;
+ 		} else {
+ 			*status = 0;
+ 		}
+@@ -1984,6 +1992,13 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ 	 * transfer type
+ 	 */
+ 	case COMP_SUCCESS:
++		if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
++			break;
++		if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
++			trb_comp_code = COMP_SHORT_TX;
++		else
++			xhci_warn(xhci, "WARN Successful completion on short TX: "
++					"needs XHCI_TRUST_TX_LENGTH quirk?\n");
+ 	case COMP_SHORT_TX:
+ 		break;
+ 	case COMP_STOP:
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index a947d70..d3d01c8 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1466,6 +1466,7 @@ struct xhci_hcd {
+ #define XHCI_RESET_ON_RESUME	(1 << 7)
+ #define	XHCI_SW_BW_CHECKING	(1 << 8)
+ #define XHCI_AMD_0x96_HOST	(1 << 9)
++#define XHCI_TRUST_TX_LENGTH	(1 << 10)
+ 	unsigned int		num_active_eps;
+ 	unsigned int		limit_active_eps;
+ 	/* There are two roothubs to keep track of bus suspend info for */
+diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
+index 959145b..8fe901d 100644
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -1025,7 +1025,10 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
+ 		case 13:	/* short read, resembling case 10 */
+ 			req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0);
+ 			/* last data packet "should" be DATA1, not DATA0 */
+-			len = 1024 - udev->descriptor.bMaxPacketSize0;
++			if (udev->speed == USB_SPEED_SUPER)
++				len = 1024 - 512;
++			else
++				len = 1024 - udev->descriptor.bMaxPacketSize0;
+ 			expected = -EREMOTEIO;
+ 			break;
+ 		case 14:	/* short read; try to fill the last packet */
+@@ -1384,11 +1387,15 @@ static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb)
+ 
+ static int halt_simple(struct usbtest_dev *dev)
+ {
+-	int		ep;
+-	int		retval = 0;
+-	struct urb	*urb;
++	int			ep;
++	int			retval = 0;
++	struct urb		*urb;
++	struct usb_device	*udev = testdev_to_usbdev(dev);
+ 
+-	urb = simple_alloc_urb(testdev_to_usbdev(dev), 0, 512);
++	if (udev->speed == USB_SPEED_SUPER)
++		urb = simple_alloc_urb(udev, 0, 1024);
++	else
++		urb = simple_alloc_urb(udev, 0, 512);
+ 	if (urb == NULL)
+ 		return -ENOMEM;
+ 
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 0ca65e4..f8817c1 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -809,6 +809,7 @@ static struct usb_device_id id_table_combined [] = {
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
+ 	{ USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
++	{ USB_DEVICE(PI_VID, PI_E861_PID) },
+ 	{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ 	{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 0838baf8..f3c7c78 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -785,6 +785,14 @@
+ #define RTSYSTEMS_SERIAL_VX7_PID	0x9e52	/* Serial converter for VX-7 Radios using FT232RL */
+ #define RTSYSTEMS_CT29B_PID		0x9e54	/* CT29B Radio Cable */
+ 
++
++/*
++ * Physik Instrumente
++ * http://www.physikinstrumente.com/en/products/
++ */
++#define PI_VID              0x1a72  /* Vendor ID */
++#define PI_E861_PID         0x1008  /* E-861 piezo controller USB connection */
++
+ /*
+  * Bayer Ascensia Contour blood glucose meter USB-converter cable.
+  * http://winglucofacts.com/cables/
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
+index 75b838e..1bbe5f4 100644
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -165,7 +165,7 @@ static unsigned int product_5052_count;
+ /* the array dimension is the number of default entries plus */
+ /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
+ /* null entry */
+-static struct usb_device_id ti_id_table_3410[14+TI_EXTRA_VID_PID_COUNT+1] = {
++static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = {
+ 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+ 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+ 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
+@@ -180,6 +180,7 @@ static struct usb_device_id ti_id_table_3410[14+TI_EXTRA_VID_PID_COUNT+1] = {
+ 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+ 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
+ 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
++	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+ };
+ 
+ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
+@@ -189,7 +190,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
+ 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+ };
+ 
+-static struct usb_device_id ti_id_table_combined[18+2*TI_EXTRA_VID_PID_COUNT+1] = {
++static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = {
+ 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+ 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+ 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
+@@ -208,6 +209,7 @@ static struct usb_device_id ti_id_table_combined[18+2*TI_EXTRA_VID_PID_COUNT+1]
+ 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+ 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
+ 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
++	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+ 	{ }
+ };
+ 
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
+index f140f1b..b353e7e 100644
+--- a/drivers/usb/serial/ti_usb_3410_5052.h
++++ b/drivers/usb/serial/ti_usb_3410_5052.h
+@@ -37,6 +37,7 @@
+ #define TI_5152_BOOT_PRODUCT_ID		0x5152	/* no EEPROM, no firmware */
+ #define TI_5052_EEPROM_PRODUCT_ID	0x505A	/* EEPROM, no firmware */
+ #define TI_5052_FIRMWARE_PRODUCT_ID	0x505F	/* firmware is running */
++#define FRI2_PRODUCT_ID			0x5053  /* Fish River Island II */
+ 
+ /* Multi-Tech vendor and product ids */
+ #define MTS_VENDOR_ID			0x06E0
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index 856ad92..8f3cbb8 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1885,6 +1885,13 @@ UNUSUAL_DEV(  0x1652, 0x6600, 0x0201, 0x0201,
+ 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ 		US_FL_IGNORE_RESIDUE ),
+ 
++/* Reported by Jesse Feddema <jdfeddema@gmail.com> */
++UNUSUAL_DEV(  0x177f, 0x0400, 0x0000, 0x0000,
++		"Yarvik",
++		"PMP400",
++		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++		US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ),
++
+ /* Reported by Hans de Goede <hdegoede@redhat.com>
+  * These Appotech controllers are found in Picture Frames, they provide a
+  * (buggy) emulation of a cdrom drive which contains the windows software
+diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
+index a40c05e..5fd95e0 100644
+--- a/drivers/video/udlfb.c
++++ b/drivers/video/udlfb.c
+@@ -918,10 +918,6 @@ static void dlfb_free(struct kref *kref)
+ {
+ 	struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
+ 
+-	/* this function will wait for all in-flight urbs to complete */
+-	if (dev->urbs.count > 0)
+-		dlfb_free_urb_list(dev);
+-
+ 	if (dev->backing_buffer)
+ 		vfree(dev->backing_buffer);
+ 
+@@ -940,35 +936,42 @@ static void dlfb_release_urb_work(struct work_struct *work)
+ 	up(&unode->dev->urbs.limit_sem);
+ }
+ 
+-static void dlfb_free_framebuffer_work(struct work_struct *work)
++static void dlfb_free_framebuffer(struct dlfb_data *dev)
+ {
+-	struct dlfb_data *dev = container_of(work, struct dlfb_data,
+-					     free_framebuffer_work.work);
+ 	struct fb_info *info = dev->info;
+-	int node = info->node;
+ 
+-	unregister_framebuffer(info);
++	if (info) {
++		int node = info->node;
+ 
+-	if (info->cmap.len != 0)
+-		fb_dealloc_cmap(&info->cmap);
+-	if (info->monspecs.modedb)
+-		fb_destroy_modedb(info->monspecs.modedb);
+-	if (info->screen_base)
+-		vfree(info->screen_base);
++		unregister_framebuffer(info);
+ 
+-	fb_destroy_modelist(&info->modelist);
++		if (info->cmap.len != 0)
++			fb_dealloc_cmap(&info->cmap);
++		if (info->monspecs.modedb)
++			fb_destroy_modedb(info->monspecs.modedb);
++		if (info->screen_base)
++			vfree(info->screen_base);
++
++		fb_destroy_modelist(&info->modelist);
+ 
+-	dev->info = 0;
++		dev->info = NULL;
+ 
+-	/* Assume info structure is freed after this point */
+-	framebuffer_release(info);
++		/* Assume info structure is freed after this point */
++		framebuffer_release(info);
+ 
+-	pr_warn("fb_info for /dev/fb%d has been freed\n", node);
++		pr_warn("fb_info for /dev/fb%d has been freed\n", node);
++	}
+ 
+ 	/* ref taken in probe() as part of registering framebfufer */
+ 	kref_put(&dev->kref, dlfb_free);
+ }
+ 
++static void dlfb_free_framebuffer_work(struct work_struct *work)
++{
++	struct dlfb_data *dev = container_of(work, struct dlfb_data,
++					     free_framebuffer_work.work);
++	dlfb_free_framebuffer(dev);
++}
+ /*
+  * Assumes caller is holding info->lock mutex (for open and release at least)
+  */
+@@ -1570,14 +1573,15 @@ success:
+ 	kfree(buf);
+ 	return true;
+ }
++
++static void dlfb_init_framebuffer_work(struct work_struct *work);
++
+ static int dlfb_usb_probe(struct usb_interface *interface,
+ 			const struct usb_device_id *id)
+ {
+ 	struct usb_device *usbdev;
+ 	struct dlfb_data *dev = 0;
+-	struct fb_info *info = 0;
+ 	int retval = -ENOMEM;
+-	int i;
+ 
+ 	/* usb initialization */
+ 
+@@ -1589,9 +1593,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,
+ 		goto error;
+ 	}
+ 
+-	/* we need to wait for both usb and fbdev to spin down on disconnect */
+ 	kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
+-	kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
+ 
+ 	dev->udev = usbdev;
+ 	dev->gdev = &usbdev->dev; /* our generic struct device * */
+@@ -1619,10 +1621,39 @@ static int dlfb_usb_probe(struct usb_interface *interface,
+ 		goto error;
+ 	}
+ 
++	kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
++
+ 	/* We don't register a new USB class. Our client interface is fbdev */
+ 
++	/* Workitem keep things fast & simple during USB enumeration */
++	INIT_DELAYED_WORK(&dev->init_framebuffer_work,
++			  dlfb_init_framebuffer_work);
++	schedule_delayed_work(&dev->init_framebuffer_work, 0);
++
++	return 0;
++
++error:
++	if (dev) {
++
++		kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
++		kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
++
++		/* dev has been deallocated. Do not dereference */
++	}
++
++	return retval;
++}
++
++static void dlfb_init_framebuffer_work(struct work_struct *work)
++{
++	struct dlfb_data *dev = container_of(work, struct dlfb_data,
++					     init_framebuffer_work.work);
++	struct fb_info *info;
++	int retval;
++	int i;
++
+ 	/* allocates framebuffer driver structure, not framebuffer memory */
+-	info = framebuffer_alloc(0, &interface->dev);
++	info = framebuffer_alloc(0, dev->gdev);
+ 	if (!info) {
+ 		retval = -ENOMEM;
+ 		pr_err("framebuffer_alloc failed\n");
+@@ -1668,15 +1699,13 @@ static int dlfb_usb_probe(struct usb_interface *interface,
+ 	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
+ 		retval = device_create_file(info->dev, &fb_device_attrs[i]);
+ 		if (retval) {
+-			pr_err("device_create_file failed %d\n", retval);
+-			goto err_del_attrs;
++			pr_warn("device_create_file failed %d\n", retval);
+ 		}
+ 	}
+ 
+ 	retval = device_create_bin_file(info->dev, &edid_attr);
+ 	if (retval) {
+-		pr_err("device_create_bin_file failed %d\n", retval);
+-		goto err_del_attrs;
++		pr_warn("device_create_bin_file failed %d\n", retval);
+ 	}
+ 
+ 	pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
+@@ -1684,38 +1713,10 @@ static int dlfb_usb_probe(struct usb_interface *interface,
+ 			info->var.xres, info->var.yres,
+ 			((dev->backing_buffer) ?
+ 			info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
+-	return 0;
+-
+-err_del_attrs:
+-	for (i -= 1; i >= 0; i--)
+-		device_remove_file(info->dev, &fb_device_attrs[i]);
++	return;
+ 
+ error:
+-	if (dev) {
+-
+-		if (info) {
+-			if (info->cmap.len != 0)
+-				fb_dealloc_cmap(&info->cmap);
+-			if (info->monspecs.modedb)
+-				fb_destroy_modedb(info->monspecs.modedb);
+-			if (info->screen_base)
+-				vfree(info->screen_base);
+-
+-			fb_destroy_modelist(&info->modelist);
+-
+-			framebuffer_release(info);
+-		}
+-
+-		if (dev->backing_buffer)
+-			vfree(dev->backing_buffer);
+-
+-		kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
+-		kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
+-
+-		/* dev has been deallocated. Do not dereference */
+-	}
+-
+-	return retval;
++	dlfb_free_framebuffer(dev);
+ }
+ 
+ static void dlfb_usb_disconnect(struct usb_interface *interface)
+@@ -1735,12 +1736,24 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
+ 	/* When non-active we'll update virtual framebuffer, but no new urbs */
+ 	atomic_set(&dev->usb_active, 0);
+ 
+-	/* remove udlfb's sysfs interfaces */
+-	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
+-		device_remove_file(info->dev, &fb_device_attrs[i]);
+-	device_remove_bin_file(info->dev, &edid_attr);
+-	unlink_framebuffer(info);
++	/* this function will wait for all in-flight urbs to complete */
++	dlfb_free_urb_list(dev);
++
++	if (info) {
++
++		/* remove udlfb's sysfs interfaces */
++		for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
++			device_remove_file(info->dev, &fb_device_attrs[i]);
++		device_remove_bin_file(info->dev, &edid_attr);
++
++		/* it's safe to uncomment next line if your kernel
++		   doesn't yet have this function exported */
++		unlink_framebuffer(info);
++	}
++
+ 	usb_set_intfdata(interface, NULL);
++	dev->udev = NULL;
++	dev->gdev = NULL;
+ 
+ 	/* if clients still have us open, will be freed on last close */
+ 	if (dev->fb_count == 0)
+@@ -1806,12 +1819,12 @@ static void dlfb_free_urb_list(struct dlfb_data *dev)
+ 	int ret;
+ 	unsigned long flags;
+ 
+-	pr_notice("Waiting for completes and freeing all render urbs\n");
++	pr_notice("Freeing all render urbs\n");
+ 
+ 	/* keep waiting and freeing, until we've got 'em all */
+ 	while (count--) {
+ 
+-		/* Getting interrupted means a leak, but ok at shutdown*/
++		/* Getting interrupted means a leak, but ok at disconnect */
+ 		ret = down_interruptible(&dev->urbs.limit_sem);
+ 		if (ret)
+ 			break;
+@@ -1833,6 +1846,7 @@ static void dlfb_free_urb_list(struct dlfb_data *dev)
+ 		kfree(node);
+ 	}
+ 
++	dev->urbs.count = 0;
+ }
+ 
+ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index e5e5812..25ea05a 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -604,7 +604,7 @@ static void disable_pirq(struct irq_data *data)
+ 	disable_dynirq(data);
+ }
+ 
+-static int find_irq_by_gsi(unsigned gsi)
++int xen_irq_from_gsi(unsigned gsi)
+ {
+ 	struct irq_info *info;
+ 
+@@ -618,6 +618,7 @@ static int find_irq_by_gsi(unsigned gsi)
+ 
+ 	return -1;
+ }
++EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
+ 
+ /*
+  * Do not make any assumptions regarding the relationship between the
+@@ -637,7 +638,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
+ 
+ 	mutex_lock(&irq_mapping_update_lock);
+ 
+-	irq = find_irq_by_gsi(gsi);
++	irq = xen_irq_from_gsi(gsi);
+ 	if (irq != -1) {
+ 		printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n",
+ 		       irq, gsi);
+diff --git a/fs/aio.c b/fs/aio.c
+index b9d64d8..3b65ee7 100644
+--- a/fs/aio.c
++++ b/fs/aio.c
+@@ -1477,6 +1477,10 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
+ 	if (ret < 0)
+ 		goto out;
+ 
++	ret = rw_verify_area(type, kiocb->ki_filp, &kiocb->ki_pos, ret);
++	if (ret < 0)
++		goto out;
++
+ 	kiocb->ki_nr_segs = kiocb->ki_nbytes;
+ 	kiocb->ki_cur_seg = 0;
+ 	/* ki_nbytes/left now reflect bytes instead of segs */
+@@ -1488,11 +1492,17 @@ out:
+ 	return ret;
+ }
+ 
+-static ssize_t aio_setup_single_vector(struct kiocb *kiocb)
++static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb)
+ {
++	int bytes;
++
++	bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left);
++	if (bytes < 0)
++		return bytes;
++
+ 	kiocb->ki_iovec = &kiocb->ki_inline_vec;
+ 	kiocb->ki_iovec->iov_base = kiocb->ki_buf;
+-	kiocb->ki_iovec->iov_len = kiocb->ki_left;
++	kiocb->ki_iovec->iov_len = bytes;
+ 	kiocb->ki_nr_segs = 1;
+ 	kiocb->ki_cur_seg = 0;
+ 	return 0;
+@@ -1517,10 +1527,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
+ 		if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
+ 			kiocb->ki_left)))
+ 			break;
+-		ret = security_file_permission(file, MAY_READ);
+-		if (unlikely(ret))
+-			break;
+-		ret = aio_setup_single_vector(kiocb);
++		ret = aio_setup_single_vector(READ, file, kiocb);
+ 		if (ret)
+ 			break;
+ 		ret = -EINVAL;
+@@ -1535,10 +1542,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
+ 		if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
+ 			kiocb->ki_left)))
+ 			break;
+-		ret = security_file_permission(file, MAY_WRITE);
+-		if (unlikely(ret))
+-			break;
+-		ret = aio_setup_single_vector(kiocb);
++		ret = aio_setup_single_vector(WRITE, file, kiocb);
+ 		if (ret)
+ 			break;
+ 		ret = -EINVAL;
+@@ -1549,9 +1553,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
+ 		ret = -EBADF;
+ 		if (unlikely(!(file->f_mode & FMODE_READ)))
+ 			break;
+-		ret = security_file_permission(file, MAY_READ);
+-		if (unlikely(ret))
+-			break;
+ 		ret = aio_setup_vectored_rw(READ, kiocb, compat);
+ 		if (ret)
+ 			break;
+@@ -1563,9 +1564,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
+ 		ret = -EBADF;
+ 		if (unlikely(!(file->f_mode & FMODE_WRITE)))
+ 			break;
+-		ret = security_file_permission(file, MAY_WRITE);
+-		if (unlikely(ret))
+-			break;
+ 		ret = aio_setup_vectored_rw(WRITE, kiocb, compat);
+ 		if (ret)
+ 			break;
+diff --git a/fs/bio.c b/fs/bio.c
+index b980ecd..4fc4dbb 100644
+--- a/fs/bio.c
++++ b/fs/bio.c
+@@ -505,9 +505,14 @@ EXPORT_SYMBOL(bio_clone);
+ int bio_get_nr_vecs(struct block_device *bdev)
+ {
+ 	struct request_queue *q = bdev_get_queue(bdev);
+-	return min_t(unsigned,
++	int nr_pages;
++
++	nr_pages = min_t(unsigned,
+ 		     queue_max_segments(q),
+ 		     queue_max_sectors(q) / (PAGE_SIZE >> 9) + 1);
++
++	return min_t(unsigned, nr_pages, BIO_MAX_PAGES);
++
+ }
+ EXPORT_SYMBOL(bio_get_nr_vecs);
+ 
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 5e9f198..236dd6c 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -69,7 +69,7 @@ static void bdev_inode_switch_bdi(struct inode *inode,
+ 	spin_unlock(&dst->wb.list_lock);
+ }
+ 
+-static sector_t max_block(struct block_device *bdev)
++sector_t blkdev_max_block(struct block_device *bdev)
+ {
+ 	sector_t retval = ~((sector_t)0);
+ 	loff_t sz = i_size_read(bdev->bd_inode);
+@@ -162,7 +162,7 @@ static int
+ blkdev_get_block(struct inode *inode, sector_t iblock,
+ 		struct buffer_head *bh, int create)
+ {
+-	if (iblock >= max_block(I_BDEV(inode))) {
++	if (iblock >= blkdev_max_block(I_BDEV(inode))) {
+ 		if (create)
+ 			return -EIO;
+ 
+@@ -184,7 +184,7 @@ static int
+ blkdev_get_blocks(struct inode *inode, sector_t iblock,
+ 		struct buffer_head *bh, int create)
+ {
+-	sector_t end_block = max_block(I_BDEV(inode));
++	sector_t end_block = blkdev_max_block(I_BDEV(inode));
+ 	unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
+ 
+ 	if ((iblock + max_blocks) > end_block) {
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 1a30db7..8a53000 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -921,6 +921,7 @@ init_page_buffers(struct page *page, struct block_device *bdev,
+ 	struct buffer_head *head = page_buffers(page);
+ 	struct buffer_head *bh = head;
+ 	int uptodate = PageUptodate(page);
++	sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode));
+ 
+ 	do {
+ 		if (!buffer_mapped(bh)) {
+@@ -929,7 +930,8 @@ init_page_buffers(struct page *page, struct block_device *bdev,
+ 			bh->b_blocknr = block;
+ 			if (uptodate)
+ 				set_buffer_uptodate(bh);
+-			set_buffer_mapped(bh);
++			if (block < end_block)
++				set_buffer_mapped(bh);
+ 		}
+ 		block++;
+ 		bh = bh->b_this_page;
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index f4b6e06..fd65e0d 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2058,6 +2058,7 @@ extern void unregister_blkdev(unsigned int, const char *);
+ extern struct block_device *bdget(dev_t);
+ extern struct block_device *bdgrab(struct block_device *bdev);
+ extern void bd_set_size(struct block_device *, loff_t size);
++extern sector_t blkdev_max_block(struct block_device *bdev);
+ extern void bd_forget(struct inode *inode);
+ extern void bdput(struct block_device *);
+ extern void invalidate_bdev(struct block_device *);
+diff --git a/include/linux/genhd.h b/include/linux/genhd.h
+index e61d319..017a7fb 100644
+--- a/include/linux/genhd.h
++++ b/include/linux/genhd.h
+@@ -222,12 +222,6 @@ static inline void part_pack_uuid(const u8 *uuid_str, u8 *to)
+ 	}
+ }
+ 
+-static inline char *part_unpack_uuid(const u8 *uuid, char *out)
+-{
+-	sprintf(out, "%pU", uuid);
+-	return out;
+-}
+-
+ static inline int disk_max_parts(struct gendisk *disk)
+ {
+ 	if (disk->flags & GENHD_FL_EXT_DEVT)
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index ee2b036..557aa4c 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -323,6 +323,7 @@ struct mmc_host {
+ 
+ 	unsigned int		sdio_irqs;
+ 	struct task_struct	*sdio_irq_thread;
++	bool			sdio_irq_pending;
+ 	atomic_t		sdio_irq_thread_abort;
+ 
+ 	mmc_pm_flag_t		pm_flags;	/* requested pm features */
+@@ -378,6 +379,7 @@ extern int mmc_cache_ctrl(struct mmc_host *, u8);
+ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
+ {
+ 	host->ops->enable_sdio_irq(host, 0);
++	host->sdio_irq_pending = true;
+ 	wake_up_process(host->sdio_irq_thread);
+ }
+ 
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 69d8457..c3ba767 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1371,6 +1371,7 @@ extern int usb_unlink_urb(struct urb *urb);
+ extern void usb_kill_urb(struct urb *urb);
+ extern void usb_poison_urb(struct urb *urb);
+ extern void usb_unpoison_urb(struct urb *urb);
++extern void usb_block_urb(struct urb *urb);
+ extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
+ extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
+ extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
+@@ -1383,6 +1384,8 @@ extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor);
+ extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor);
+ extern int usb_anchor_empty(struct usb_anchor *anchor);
+ 
++#define usb_unblock_urb	usb_unpoison_urb
++
+ /**
+  * usb_urb_dir_in - check if an URB describes an IN transfer
+  * @urb: URB to be checked
+diff --git a/include/video/udlfb.h b/include/video/udlfb.h
+index c41f308..f9466fa 100644
+--- a/include/video/udlfb.h
++++ b/include/video/udlfb.h
+@@ -41,6 +41,7 @@ struct dlfb_data {
+ 	char *backing_buffer;
+ 	int fb_count;
+ 	bool virtualized; /* true when physical usb device not present */
++	struct delayed_work init_framebuffer_work;
+ 	struct delayed_work free_framebuffer_work;
+ 	atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
+ 	atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
+diff --git a/include/xen/events.h b/include/xen/events.h
+index 0f77370..04399b2 100644
+--- a/include/xen/events.h
++++ b/include/xen/events.h
+@@ -103,6 +103,9 @@ int xen_irq_from_pirq(unsigned pirq);
+ /* Return the pirq allocated to the irq. */
+ int xen_pirq_from_irq(unsigned irq);
+ 
++/* Return the irq allocated to the gsi */
++int xen_irq_from_gsi(unsigned gsi);
++
+ /* Determine whether to ignore this IRQ if it is passed to a guest. */
+ int xen_test_irq_shared(int irq);
+ 
+diff --git a/init/main.c b/init/main.c
+index ff49a6d..45a7bf5 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -558,9 +558,6 @@ asmlinkage void __init start_kernel(void)
+ 	early_boot_irqs_disabled = false;
+ 	local_irq_enable();
+ 
+-	/* Interrupts are enabled now so all GFP allocations are safe. */
+-	gfp_allowed_mask = __GFP_BITS_MASK;
+-
+ 	kmem_cache_init_late();
+ 
+ 	/*
+@@ -792,6 +789,10 @@ static int __init kernel_init(void * unused)
+ 	 * Wait until kthreadd is all set-up.
+ 	 */
+ 	wait_for_completion(&kthreadd_done);
++
++	/* Now the scheduler is fully set up and can do blocking allocations */
++	gfp_allowed_mask = __GFP_BITS_MASK;
++
+ 	/*
+ 	 * init can allocate pages on any node
+ 	 */
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index f2c5638..0c0af4a 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -1215,8 +1215,13 @@ static void worker_enter_idle(struct worker *worker)
+ 	} else
+ 		wake_up_all(&gcwq->trustee_wait);
+ 
+-	/* sanity check nr_running */
+-	WARN_ON_ONCE(gcwq->nr_workers == gcwq->nr_idle &&
++	/*
++	 * Sanity check nr_running.  Because trustee releases gcwq->lock
++	 * between setting %WORKER_ROGUE and zapping nr_running, the
++	 * warning may trigger spuriously.  Check iff trustee is idle.
++	 */
++	WARN_ON_ONCE(gcwq->trustee_state == TRUSTEE_DONE &&
++		     gcwq->nr_workers == gcwq->nr_idle &&
+ 		     atomic_read(get_gcwq_nr_running(gcwq->cpu)));
+ }
+ 
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index 0a37570..a8f97d5 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -607,27 +607,6 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
+ 	return first;
+ }
+ 
+-/* Apply policy to a single VMA */
+-static int policy_vma(struct vm_area_struct *vma, struct mempolicy *new)
+-{
+-	int err = 0;
+-	struct mempolicy *old = vma->vm_policy;
+-
+-	pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
+-		 vma->vm_start, vma->vm_end, vma->vm_pgoff,
+-		 vma->vm_ops, vma->vm_file,
+-		 vma->vm_ops ? vma->vm_ops->set_policy : NULL);
+-
+-	if (vma->vm_ops && vma->vm_ops->set_policy)
+-		err = vma->vm_ops->set_policy(vma, new);
+-	if (!err) {
+-		mpol_get(new);
+-		vma->vm_policy = new;
+-		mpol_put(old);
+-	}
+-	return err;
+-}
+-
+ /* Step 2: apply policy to a range and do splits. */
+ static int mbind_range(struct mm_struct *mm, unsigned long start,
+ 		       unsigned long end, struct mempolicy *new_pol)
+@@ -676,9 +655,23 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
+ 			if (err)
+ 				goto out;
+ 		}
+-		err = policy_vma(vma, new_pol);
+-		if (err)
+-			goto out;
++
++		/*
++		 * Apply policy to a single VMA. The reference counting of
++		 * policy for vma_policy linkages has already been handled by
++		 * vma_merge and split_vma as necessary. If this is a shared
++		 * policy then ->set_policy will increment the reference count
++		 * for an sp node.
++		 */
++		pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
++			vma->vm_start, vma->vm_end, vma->vm_pgoff,
++			vma->vm_ops, vma->vm_file,
++			vma->vm_ops ? vma->vm_ops->set_policy : NULL);
++		if (vma->vm_ops && vma->vm_ops->set_policy) {
++			err = vma->vm_ops->set_policy(vma, new_pol);
++			if (err)
++				goto out;
++		}
+ 	}
+ 
+  out:
+diff --git a/mm/swapfile.c b/mm/swapfile.c
+index f31b29d..099c209 100644
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -2103,7 +2103,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
+ 			p->flags |= SWP_SOLIDSTATE;
+ 			p->cluster_next = 1 + (random32() % p->highest_bit);
+ 		}
+-		if (discard_swap(p) == 0 && (swap_flags & SWAP_FLAG_DISCARD))
++		if ((swap_flags & SWAP_FLAG_DISCARD) && discard_swap(p) == 0)
+ 			p->flags |= SWP_DISCARDABLE;
+ 	}
+ 
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index f65feaa..00777da 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -388,7 +388,15 @@ static void reg_regdb_query(const char *alpha2)
+ 
+ 	schedule_work(&reg_regdb_work);
+ }
++
++/* Feel free to add any other sanity checks here */
++static void reg_regdb_size_check(void)
++{
++	/* We should ideally BUILD_BUG_ON() but then random builds would fail */
++	WARN_ONCE(!reg_regdb_size, "db.txt is empty, you should update it...");
++}
+ #else
++static inline void reg_regdb_size_check(void) {}
+ static inline void reg_regdb_query(const char *alpha2) {}
+ #endif /* CONFIG_CFG80211_INTERNAL_REGDB */
+ 
+@@ -2337,6 +2345,8 @@ int __init regulatory_init(void)
+ 	spin_lock_init(&reg_requests_lock);
+ 	spin_lock_init(&reg_pending_beacons_lock);
+ 
++	reg_regdb_size_check();
++
+ 	cfg80211_regdomain = cfg80211_world_regdom;
+ 
+ 	user_alpha2[0] = '9';
+diff --git a/scripts/Makefile b/scripts/Makefile
+index df7678f..3626666 100644
+--- a/scripts/Makefile
++++ b/scripts/Makefile
+@@ -8,6 +8,8 @@
+ # conmakehash:	 Create arrays for initializing the kernel console tables
+ # docproc:       Used in Documentation/DocBook
+ 
++HOST_EXTRACFLAGS += -I$(srctree)/tools/include
++
+ hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
+ hostprogs-$(CONFIG_LOGO)         += pnmtologo
+ hostprogs-$(CONFIG_VT)           += conmakehash
+diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
+index 48a7d00..ac1e99e 100644
+--- a/security/selinux/selinuxfs.c
++++ b/security/selinux/selinuxfs.c
+@@ -1232,6 +1232,7 @@ static int sel_make_bools(void)
+ 		kfree(bool_pending_names[i]);
+ 	kfree(bool_pending_names);
+ 	kfree(bool_pending_values);
++	bool_num = 0;
+ 	bool_pending_names = NULL;
+ 	bool_pending_values = NULL;
+ 
+diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c
+index b9c7986..f17dfee 100644
+--- a/tools/usb/ffs-test.c
++++ b/tools/usb/ffs-test.c
+@@ -324,7 +324,7 @@ static void *start_thread_helper(void *arg)
+ 
+ 		ret = t->in(t, t->buf, t->buf_size);
+ 		if (ret > 0) {
+-			ret = t->out(t, t->buf, t->buf_size);
++			ret = t->out(t, t->buf, ret);
+ 			name = out_name;
+ 			op = "write";
+ 		} else {




^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-06-06  0:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-06  0:39 [gentoo-commits] linux-patches r2149 - genpatches-2.6/trunk/3.3 Mike Pagano (mpagano)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox