[kernel] r15415 - dists/trunk/linux-2.6/debian/patches/bugfix/all/stable

Maximilian Attems maks at alioth.debian.org
Wed Mar 17 16:13:28 UTC 2010


Author: maks
Date: Wed Mar 17 16:13:26 2010
New Revision: 15415

Log:
really add stable 2.6.33.1

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.33.1.patch

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.33.1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.33.1.patch	Wed Mar 17 16:13:26 2010	(r15415)
@@ -0,0 +1,5513 @@
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index e7848a0..e2c7487 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -2703,6 +2703,13 @@ and is between 256 and 4096 characters. It is defined in the file
+ 					medium is write-protected).
+ 			Example: quirks=0419:aaf5:rl,0421:0433:rc
+ 
++	userpte=
++			[X86] Flags controlling user PTE allocations.
++
++				nohigh = do not allocate PTE pages in
++					HIGHMEM regardless of setting
++					of CONFIG_HIGHPTE.
++
+ 	vdso=		[X86,SH]
+ 			vdso=2: enable compat VDSO (default with COMPAT_VDSO)
+ 			vdso=1: enable VDSO (default)
+diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
+index 75afa12..39c0a09 100644
+--- a/Documentation/laptops/thinkpad-acpi.txt
++++ b/Documentation/laptops/thinkpad-acpi.txt
+@@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The following commands are available:
+ 	echo expand_toggle > /proc/acpi/ibm/video
+ 	echo video_switch > /proc/acpi/ibm/video
+ 
++NOTE: Access to this feature is restricted to processes owning the
++CAP_SYS_ADMIN capability for safety reasons, as it can interact badly
++enough with some versions of X.org to crash it.
++
+ Each video output device can be enabled or disabled individually.
+ Reading /proc/acpi/ibm/video shows the status of each device.
+ 
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 9d055b4..25e69f7 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -6,8 +6,6 @@ config OPROFILE
+ 	tristate "OProfile system profiling (EXPERIMENTAL)"
+ 	depends on PROFILING
+ 	depends on HAVE_OPROFILE
+-	depends on TRACING_SUPPORT
+-	select TRACING
+ 	select RING_BUFFER
+ 	select RING_BUFFER_ALLOW_SWAP
+ 	help
+diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
+index f9f4724..14531ab 100644
+--- a/arch/x86/ia32/ia32_aout.c
++++ b/arch/x86/ia32/ia32_aout.c
+@@ -327,7 +327,6 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+ 	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
+ 	current->mm->cached_hole_size = 0;
+ 
+-	current->mm->mmap = NULL;
+ 	install_exec_creds(bprm);
+ 	current->flags &= ~PF_FORKNOEXEC;
+ 
+diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
+index 7c7c16c..5f61f6e 100644
+--- a/arch/x86/include/asm/io_apic.h
++++ b/arch/x86/include/asm/io_apic.h
+@@ -160,6 +160,7 @@ extern int io_apic_get_redir_entries(int ioapic);
+ struct io_apic_irq_attr;
+ extern int io_apic_set_pci_routing(struct device *dev, int irq,
+ 		 struct io_apic_irq_attr *irq_attr);
++void setup_IO_APIC_irq_extra(u32 gsi);
+ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
+ extern void ioapic_init_mappings(void);
+ extern void ioapic_insert_resources(void);
+diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
+index 0e8c2a0..271de94 100644
+--- a/arch/x86/include/asm/pgalloc.h
++++ b/arch/x86/include/asm/pgalloc.h
+@@ -23,6 +23,11 @@ static inline void paravirt_release_pud(unsigned long pfn) {}
+ #endif
+ 
+ /*
++ * Flags to use when allocating a user page table page.
++ */
++extern gfp_t __userpte_alloc_gfp;
++
++/*
+  * Allocate and free page tables.
+  */
+ extern pgd_t *pgd_alloc(struct mm_struct *);
+diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
+index 40be813..14cc74b 100644
+--- a/arch/x86/include/asm/uv/uv_hub.h
++++ b/arch/x86/include/asm/uv/uv_hub.h
+@@ -329,7 +329,8 @@ static inline unsigned long uv_read_global_mmr64(int pnode, unsigned long offset
+  */
+ static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long offset)
+ {
+-	return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
++	return UV_GLOBAL_GRU_MMR_BASE | offset |
++		((unsigned long)pnode << uv_hub_info->m_val);
+ }
+ 
+ static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val)
+diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
+index 2b49454..8f6b011 100644
+--- a/arch/x86/include/asm/vmx.h
++++ b/arch/x86/include/asm/vmx.h
+@@ -251,6 +251,7 @@ enum vmcs_field {
+ #define EXIT_REASON_MSR_READ            31
+ #define EXIT_REASON_MSR_WRITE           32
+ #define EXIT_REASON_MWAIT_INSTRUCTION   36
++#define EXIT_REASON_MONITOR_INSTRUCTION 39
+ #define EXIT_REASON_PAUSE_INSTRUCTION   40
+ #define EXIT_REASON_MCE_DURING_VMENTRY	 41
+ #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index af1c583..0a2b21a 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -446,6 +446,12 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
+ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
+ {
+ 	*irq = gsi;
++
++#ifdef CONFIG_X86_IO_APIC
++	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
++		setup_IO_APIC_irq_extra(gsi);
++#endif
++
+ 	return 0;
+ }
+ 
+@@ -473,7 +479,8 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+ 		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
+ 	}
+ #endif
+-	acpi_gsi_to_irq(plat_gsi, &irq);
++	irq = plat_gsi;
++
+ 	return irq;
+ }
+ 
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index 53243ca..be37059 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -1539,6 +1539,56 @@ static void __init setup_IO_APIC_irqs(void)
+ }
+ 
+ /*
++ * for the gsit that is not in first ioapic
++ * but could not use acpi_register_gsi()
++ * like some special sci in IBM x3330
++ */
++void setup_IO_APIC_irq_extra(u32 gsi)
++{
++	int apic_id = 0, pin, idx, irq;
++	int node = cpu_to_node(boot_cpu_id);
++	struct irq_desc *desc;
++	struct irq_cfg *cfg;
++
++	/*
++	 * Convert 'gsi' to 'ioapic.pin'.
++	 */
++	apic_id = mp_find_ioapic(gsi);
++	if (apic_id < 0)
++		return;
++
++	pin = mp_find_ioapic_pin(apic_id, gsi);
++	idx = find_irq_entry(apic_id, pin, mp_INT);
++	if (idx == -1)
++		return;
++
++	irq = pin_2_irq(idx, apic_id, pin);
++#ifdef CONFIG_SPARSE_IRQ
++	desc = irq_to_desc(irq);
++	if (desc)
++		return;
++#endif
++	desc = irq_to_desc_alloc_node(irq, node);
++	if (!desc) {
++		printk(KERN_INFO "can not get irq_desc for %d\n", irq);
++		return;
++	}
++
++	cfg = desc->chip_data;
++	add_pin_to_irq_node(cfg, node, apic_id, pin);
++
++	if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
++		pr_debug("Pin %d-%d already programmed\n",
++			 mp_ioapics[apic_id].apicid, pin);
++		return;
++	}
++	set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
++
++	setup_IO_APIC_irq(apic_id, pin, irq, desc,
++			irq_trigger(idx), irq_polarity(idx));
++}
++
++/*
+  * Set up the timer pin, possibly with the 8259A-master behind.
+  */
+ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,
+@@ -3228,12 +3278,9 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
+ 	}
+ 	spin_unlock_irqrestore(&vector_lock, flags);
+ 
+-	if (irq > 0) {
+-		dynamic_irq_init(irq);
+-		/* restore it, in case dynamic_irq_init clear it */
+-		if (desc_new)
+-			desc_new->chip_data = cfg_new;
+-	}
++	if (irq > 0)
++		dynamic_irq_init_keep_chip_data(irq);
++
+ 	return irq;
+ }
+ 
+@@ -3256,17 +3303,12 @@ void destroy_irq(unsigned int irq)
+ {
+ 	unsigned long flags;
+ 	struct irq_cfg *cfg;
+-	struct irq_desc *desc;
+ 
+-	/* store it, in case dynamic_irq_cleanup clear it */
+-	desc = irq_to_desc(irq);
+-	cfg = desc->chip_data;
+-	dynamic_irq_cleanup(irq);
+-	/* connect back irq_cfg */
+-	desc->chip_data = cfg;
++	dynamic_irq_cleanup_keep_chip_data(irq);
+ 
+ 	free_irte(irq);
+ 	spin_lock_irqsave(&vector_lock, flags);
++	cfg = irq_to_desc(irq)->chip_data;
+ 	__clear_irq_vector(irq, cfg);
+ 	spin_unlock_irqrestore(&vector_lock, flags);
+ }
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index 704bddc..8e1aac8 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -461,6 +461,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"),
+ 		},
+ 	},
++	{	/* Handle problems with rebooting on the iMac9,1. */
++		.callback = set_pci_reboot,
++		.ident = "Apple iMac9,1",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
++		},
++	},
+ 	{ }
+ };
+ 
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 7e8faea..c998d27 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -76,6 +76,7 @@
+ #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
+ #define GroupMask   0xff        /* Group number stored in bits 0:7 */
+ /* Misc flags */
++#define Priv        (1<<27) /* instruction generates #GP if current CPL != 0 */
+ #define No64	    (1<<28)
+ /* Source 2 operand type */
+ #define Src2None    (0<<29)
+@@ -88,6 +89,7 @@
+ enum {
+ 	Group1_80, Group1_81, Group1_82, Group1_83,
+ 	Group1A, Group3_Byte, Group3, Group4, Group5, Group7,
++	Group8, Group9,
+ };
+ 
+ static u32 opcode_table[256] = {
+@@ -210,7 +212,7 @@ static u32 opcode_table[256] = {
+ 	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
+ 	/* 0xF0 - 0xF7 */
+ 	0, 0, 0, 0,
+-	ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
++	ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3,
+ 	/* 0xF8 - 0xFF */
+ 	ImplicitOps, 0, ImplicitOps, ImplicitOps,
+ 	ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
+@@ -218,16 +220,20 @@ static u32 opcode_table[256] = {
+ 
+ static u32 twobyte_table[256] = {
+ 	/* 0x00 - 0x0F */
+-	0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0,
+-	ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
++	0, Group | GroupDual | Group7, 0, 0,
++	0, ImplicitOps, ImplicitOps | Priv, 0,
++	ImplicitOps | Priv, ImplicitOps | Priv, 0, 0,
++	0, ImplicitOps | ModRM, 0, 0,
+ 	/* 0x10 - 0x1F */
+ 	0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
+ 	/* 0x20 - 0x2F */
+-	ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
++	ModRM | ImplicitOps | Priv, ModRM | Priv,
++	ModRM | ImplicitOps | Priv, ModRM | Priv,
++	0, 0, 0, 0,
+ 	0, 0, 0, 0, 0, 0, 0, 0,
+ 	/* 0x30 - 0x3F */
+-	ImplicitOps, 0, ImplicitOps, 0,
+-	ImplicitOps, ImplicitOps, 0, 0,
++	ImplicitOps | Priv, 0, ImplicitOps | Priv, 0,
++	ImplicitOps, ImplicitOps | Priv, 0, 0,
+ 	0, 0, 0, 0, 0, 0, 0, 0,
+ 	/* 0x40 - 0x47 */
+ 	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+@@ -267,11 +273,12 @@ static u32 twobyte_table[256] = {
+ 	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
+ 	    DstReg | SrcMem16 | ModRM | Mov,
+ 	/* 0xB8 - 0xBF */
+-	0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp,
++	0, 0, Group | Group8, DstMem | SrcReg | ModRM | BitOp,
+ 	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
+ 	    DstReg | SrcMem16 | ModRM | Mov,
+ 	/* 0xC0 - 0xCF */
+-	0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
++	0, 0, 0, DstMem | SrcReg | ModRM | Mov,
++	0, 0, 0, Group | GroupDual | Group9,
+ 	0, 0, 0, 0, 0, 0, 0, 0,
+ 	/* 0xD0 - 0xDF */
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+@@ -320,16 +327,24 @@ static u32 group_table[] = {
+ 	SrcMem | ModRM | Stack, 0,
+ 	SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0,
+ 	[Group7*8] =
+-	0, 0, ModRM | SrcMem, ModRM | SrcMem,
++	0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv,
+ 	SrcNone | ModRM | DstMem | Mov, 0,
+-	SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp,
++	SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv,
++	[Group8*8] =
++	0, 0, 0, 0,
++	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
++	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
++	[Group9*8] =
++	0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0,
+ };
+ 
+ static u32 group2_table[] = {
+ 	[Group7*8] =
+-	SrcNone | ModRM, 0, 0, SrcNone | ModRM,
++	SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM,
+ 	SrcNone | ModRM | DstMem | Mov, 0,
+ 	SrcMem16 | ModRM | Mov, 0,
++	[Group9*8] =
++	0, 0, 0, 0, 0, 0, 0, 0,
+ };
+ 
+ /* EFLAGS bit definitions. */
+@@ -1640,12 +1655,6 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
+ 		return -1;
+ 	}
+ 
+-	/* sysexit must be called from CPL 0 */
+-	if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) {
+-		kvm_inject_gp(ctxt->vcpu, 0);
+-		return -1;
+-	}
+-
+ 	setup_syscalls_segments(ctxt, &cs, &ss);
+ 
+ 	if ((c->rex_prefix & 0x8) != 0x0)
+@@ -1709,6 +1718,12 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+ 	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
+ 	saved_eip = c->eip;
+ 
++	/* Privileged instruction can be executed only in CPL=0 */
++	if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) {
++		kvm_inject_gp(ctxt->vcpu, 0);
++		goto done;
++	}
++
+ 	if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
+ 		memop = c->modrm_ea;
+ 
+@@ -1982,6 +1997,12 @@ special_insn:
+ 		int err;
+ 
+ 		sel = c->src.val;
++
++		if (c->modrm_reg == VCPU_SREG_CS) {
++			kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
++			goto done;
++		}
++
+ 		if (c->modrm_reg == VCPU_SREG_SS)
+ 			toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
+ 
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index d4918d6..8a8e139 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1224,6 +1224,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
+ 	      CPU_BASED_USE_IO_BITMAPS |
+ 	      CPU_BASED_MOV_DR_EXITING |
+ 	      CPU_BASED_USE_TSC_OFFSETING |
++	      CPU_BASED_MWAIT_EXITING |
++	      CPU_BASED_MONITOR_EXITING |
+ 	      CPU_BASED_INVLPG_EXITING;
+ 	opt = CPU_BASED_TPR_SHADOW |
+ 	      CPU_BASED_USE_MSR_BITMAPS |
+@@ -3416,6 +3418,12 @@ static int handle_pause(struct kvm_vcpu *vcpu)
+ 	return 1;
+ }
+ 
++static int handle_invalid_op(struct kvm_vcpu *vcpu)
++{
++	kvm_queue_exception(vcpu, UD_VECTOR);
++	return 1;
++}
++
+ /*
+  * The exit handlers return 1 if the exit was handled fully and guest execution
+  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
+@@ -3453,6 +3461,8 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
+ 	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
+ 	[EXIT_REASON_EPT_MISCONFIG]           = handle_ept_misconfig,
+ 	[EXIT_REASON_PAUSE_INSTRUCTION]       = handle_pause,
++	[EXIT_REASON_MWAIT_INSTRUCTION]	      = handle_invalid_op,
++	[EXIT_REASON_MONITOR_INSTRUCTION]     = handle_invalid_op,
+ };
+ 
+ static const int kvm_vmx_max_exit_handlers =
+diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
+index ed34f5e..c9ba9de 100644
+--- a/arch/x86/mm/pgtable.c
++++ b/arch/x86/mm/pgtable.c
+@@ -6,6 +6,14 @@
+ 
+ #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO
+ 
++#ifdef CONFIG_HIGHPTE
++#define PGALLOC_USER_GFP __GFP_HIGHMEM
++#else
++#define PGALLOC_USER_GFP 0
++#endif
++
++gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP;
++
+ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+ {
+ 	return (pte_t *)__get_free_page(PGALLOC_GFP);
+@@ -15,16 +23,29 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+ {
+ 	struct page *pte;
+ 
+-#ifdef CONFIG_HIGHPTE
+-	pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
+-#else
+-	pte = alloc_pages(PGALLOC_GFP, 0);
+-#endif
++	pte = alloc_pages(__userpte_alloc_gfp, 0);
+ 	if (pte)
+ 		pgtable_page_ctor(pte);
+ 	return pte;
+ }
+ 
++static int __init setup_userpte(char *arg)
++{
++	if (!arg)
++		return -EINVAL;
++
++	/*
++	 * "userpte=nohigh" disables allocation of user pagetables in
++	 * high memory.
++	 */
++	if (strcmp(arg, "nohigh") == 0)
++		__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
++	else
++		return -EINVAL;
++	return 0;
++}
++early_param("userpte", setup_userpte);
++
+ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
+ {
+ 	pgtable_page_dtor(pte);
+diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
+index 3347f69..2c505ee 100644
+--- a/arch/x86/oprofile/nmi_int.c
++++ b/arch/x86/oprofile/nmi_int.c
+@@ -159,7 +159,7 @@ static int nmi_setup_mux(void)
+ 
+ 	for_each_possible_cpu(i) {
+ 		per_cpu(cpu_msrs, i).multiplex =
+-			kmalloc(multiplex_size, GFP_KERNEL);
++			kzalloc(multiplex_size, GFP_KERNEL);
+ 		if (!per_cpu(cpu_msrs, i).multiplex)
+ 			return 0;
+ 	}
+@@ -179,7 +179,6 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs)
+ 		if (counter_config[i].enabled) {
+ 			multiplex[i].saved = -(u64)counter_config[i].count;
+ 		} else {
+-			multiplex[i].addr  = 0;
+ 			multiplex[i].saved = 0;
+ 		}
+ 	}
+@@ -189,25 +188,27 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs)
+ 
+ static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs)
+ {
++	struct op_msr *counters = msrs->counters;
+ 	struct op_msr *multiplex = msrs->multiplex;
+ 	int i;
+ 
+ 	for (i = 0; i < model->num_counters; ++i) {
+ 		int virt = op_x86_phys_to_virt(i);
+-		if (multiplex[virt].addr)
+-			rdmsrl(multiplex[virt].addr, multiplex[virt].saved);
++		if (counters[i].addr)
++			rdmsrl(counters[i].addr, multiplex[virt].saved);
+ 	}
+ }
+ 
+ static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs)
+ {
++	struct op_msr *counters = msrs->counters;
+ 	struct op_msr *multiplex = msrs->multiplex;
+ 	int i;
+ 
+ 	for (i = 0; i < model->num_counters; ++i) {
+ 		int virt = op_x86_phys_to_virt(i);
+-		if (multiplex[virt].addr)
+-			wrmsrl(multiplex[virt].addr, multiplex[virt].saved);
++		if (counters[i].addr)
++			wrmsrl(counters[i].addr, multiplex[virt].saved);
+ 	}
+ }
+ 
+@@ -303,11 +304,11 @@ static int allocate_msrs(void)
+ 
+ 	int i;
+ 	for_each_possible_cpu(i) {
+-		per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
++		per_cpu(cpu_msrs, i).counters = kzalloc(counters_size,
+ 							GFP_KERNEL);
+ 		if (!per_cpu(cpu_msrs, i).counters)
+ 			return 0;
+-		per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
++		per_cpu(cpu_msrs, i).controls = kzalloc(controls_size,
+ 							GFP_KERNEL);
+ 		if (!per_cpu(cpu_msrs, i).controls)
+ 			return 0;
+diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
+index 39686c2..1ed963d 100644
+--- a/arch/x86/oprofile/op_model_amd.c
++++ b/arch/x86/oprofile/op_model_amd.c
+@@ -76,19 +76,6 @@ static struct op_ibs_config ibs_config;
+ 
+ #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
+ 
+-static void op_mux_fill_in_addresses(struct op_msrs * const msrs)
+-{
+-	int i;
+-
+-	for (i = 0; i < NUM_VIRT_COUNTERS; i++) {
+-		int hw_counter = op_x86_virt_to_phys(i);
+-		if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
+-			msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter;
+-		else
+-			msrs->multiplex[i].addr = 0;
+-	}
+-}
+-
+ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
+ 			       struct op_msrs const * const msrs)
+ {
+@@ -98,7 +85,7 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
+ 	/* enable active counters */
+ 	for (i = 0; i < NUM_COUNTERS; ++i) {
+ 		int virt = op_x86_phys_to_virt(i);
+-		if (!counter_config[virt].enabled)
++		if (!reset_value[virt])
+ 			continue;
+ 		rdmsrl(msrs->controls[i].addr, val);
+ 		val &= model->reserved;
+@@ -107,10 +94,6 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
+ 	}
+ }
+ 
+-#else
+-
+-static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { }
+-
+ #endif
+ 
+ /* functions for op_amd_spec */
+@@ -122,18 +105,12 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
+ 	for (i = 0; i < NUM_COUNTERS; i++) {
+ 		if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
+ 			msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
+-		else
+-			msrs->counters[i].addr = 0;
+ 	}
+ 
+ 	for (i = 0; i < NUM_CONTROLS; i++) {
+ 		if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
+ 			msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
+-		else
+-			msrs->controls[i].addr = 0;
+ 	}
+-
+-	op_mux_fill_in_addresses(msrs);
+ }
+ 
+ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
+@@ -144,7 +121,8 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
+ 
+ 	/* setup reset_value */
+ 	for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
+-		if (counter_config[i].enabled)
++		if (counter_config[i].enabled
++		    && msrs->counters[op_x86_virt_to_phys(i)].addr)
+ 			reset_value[i] = counter_config[i].count;
+ 		else
+ 			reset_value[i] = 0;
+@@ -169,9 +147,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
+ 	/* enable active counters */
+ 	for (i = 0; i < NUM_COUNTERS; ++i) {
+ 		int virt = op_x86_phys_to_virt(i);
+-		if (!counter_config[virt].enabled)
+-			continue;
+-		if (!msrs->counters[i].addr)
++		if (!reset_value[virt])
+ 			continue;
+ 
+ 		/* setup counter registers */
+@@ -405,16 +381,6 @@ static int init_ibs_nmi(void)
+ 		return 1;
+ 	}
+ 
+-#ifdef CONFIG_NUMA
+-	/* Sanity check */
+-	/* Works only for 64bit with proper numa implementation. */
+-	if (nodes != num_possible_nodes()) {
+-		printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, "
+-			"found: %d, expected %d",
+-			nodes, num_possible_nodes());
+-		return 1;
+-	}
+-#endif
+ 	return 0;
+ }
+ 
+diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
+index ac6b354..e6a160a 100644
+--- a/arch/x86/oprofile/op_model_p4.c
++++ b/arch/x86/oprofile/op_model_p4.c
+@@ -394,12 +394,6 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
+ 	setup_num_counters();
+ 	stag = get_stagger();
+ 
+-	/* initialize some registers */
+-	for (i = 0; i < num_counters; ++i)
+-		msrs->counters[i].addr = 0;
+-	for (i = 0; i < num_controls; ++i)
+-		msrs->controls[i].addr = 0;
+-
+ 	/* the counter & cccr registers we pay attention to */
+ 	for (i = 0; i < num_counters; ++i) {
+ 		addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
+diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
+index 8eb0587..2873c00 100644
+--- a/arch/x86/oprofile/op_model_ppro.c
++++ b/arch/x86/oprofile/op_model_ppro.c
+@@ -37,15 +37,11 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs)
+ 	for (i = 0; i < num_counters; i++) {
+ 		if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
+ 			msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
+-		else
+-			msrs->counters[i].addr = 0;
+ 	}
+ 
+ 	for (i = 0; i < num_counters; i++) {
+ 		if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
+ 			msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
+-		else
+-			msrs->controls[i].addr = 0;
+ 	}
+ }
+ 
+@@ -57,7 +53,7 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
+ 	int i;
+ 
+ 	if (!reset_value) {
+-		reset_value = kmalloc(sizeof(reset_value[0]) * num_counters,
++		reset_value = kzalloc(sizeof(reset_value[0]) * num_counters,
+ 					GFP_ATOMIC);
+ 		if (!reset_value)
+ 			return;
+diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
+index b19d1e5..8f3f9a5 100644
+--- a/arch/x86/pci/mmconfig-shared.c
++++ b/arch/x86/pci/mmconfig-shared.c
+@@ -303,22 +303,17 @@ static void __init pci_mmcfg_check_end_bus_number(void)
+ {
+ 	struct pci_mmcfg_region *cfg, *cfgx;
+ 
+-	/* last one*/
+-	cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list);
+-	if (cfg)
+-		if (cfg->end_bus < cfg->start_bus)
+-			cfg->end_bus = 255;
+-
+-	if (list_is_singular(&pci_mmcfg_list))
+-		return;
+-
+-	/* don't overlap please */
++	/* Fixup overlaps */
+ 	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+ 		if (cfg->end_bus < cfg->start_bus)
+ 			cfg->end_bus = 255;
+ 
++		/* Don't access the list head ! */
++		if (cfg->list.next == &pci_mmcfg_list)
++			break;
++
+ 		cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
+-		if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus)
++		if (cfg->end_bus >= cfgx->start_bus)
+ 			cfg->end_bus = cfgx->start_bus - 1;
+ 	}
+ }
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 36daccb..b607239 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -50,6 +50,7 @@
+ #include <asm/traps.h>
+ #include <asm/setup.h>
+ #include <asm/desc.h>
++#include <asm/pgalloc.h>
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
+ #include <asm/reboot.h>
+@@ -1094,6 +1095,12 @@ asmlinkage void __init xen_start_kernel(void)
+ 
+ 	__supported_pte_mask |= _PAGE_IOMAP;
+ 
++	/*
++	 * Prevent page tables from being allocated in highmem, even
++	 * if CONFIG_HIGHPTE is enabled.
++	 */
++	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
++
+ 	/* Work out if we support NX */
+ 	x86_configure_nx();
+ 
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
+index bf4cd6b..350a3de 100644
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -1432,14 +1432,15 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
+ {
+ 	pgprot_t prot = PAGE_KERNEL;
+ 
++	/*
++	 * We disable highmem allocations for page tables so we should never
++	 * see any calls to kmap_atomic_pte on a highmem page.
++	 */
++	BUG_ON(PageHighMem(page));
++
+ 	if (PagePinned(page))
+ 		prot = PAGE_KERNEL_RO;
+ 
+-	if (0 && PageHighMem(page))
+-		printk("mapping highpte %lx type %d prot %s\n",
+-		       page_to_pfn(page), type,
+-		       (unsigned long)pgprot_val(prot) & _PAGE_RW ? "WRITE" : "READ");
+-
+ 	return kmap_atomic_prot(page, type, prot);
+ }
+ #endif
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index b343903..a6a736a 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -3082,8 +3082,16 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	ahci_save_initial_config(pdev, hpriv);
+ 
+ 	/* prepare host */
+-	if (hpriv->cap & HOST_CAP_NCQ)
+-		pi.flags |= ATA_FLAG_NCQ | ATA_FLAG_FPDMA_AA;
++	if (hpriv->cap & HOST_CAP_NCQ) {
++		pi.flags |= ATA_FLAG_NCQ;
++		/* Auto-activate optimization is supposed to be supported on
++		   all AHCI controllers indicating NCQ support, but it seems
++		   to be broken at least on some NVIDIA MCP79 chipsets.
++		   Until we get info on which NVIDIA chipsets don't have this
++		   issue, if any, disable AA on all NVIDIA AHCIs. */
++		if (pdev->vendor != PCI_VENDOR_ID_NVIDIA)
++			pi.flags |= ATA_FLAG_FPDMA_AA;
++	}
+ 
+ 	if (hpriv->cap & HOST_CAP_PMP)
+ 		pi.flags |= ATA_FLAG_PMP;
+diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
+index dd26bc7..269b5db 100644
+--- a/drivers/ata/pata_hpt3x2n.c
++++ b/drivers/ata/pata_hpt3x2n.c
+@@ -25,7 +25,7 @@
+ #include <linux/libata.h>
+ 
+ #define DRV_NAME	"pata_hpt3x2n"
+-#define DRV_VERSION	"0.3.8"
++#define DRV_VERSION	"0.3.9"
+ 
+ enum {
+ 	HPT_PCI_FAST	=	(1 << 31),
+@@ -544,16 +544,16 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+ 	       pci_mhz);
+ 	/* Set our private data up. We only need a few flags so we use
+ 	   it directly */
+-	if (pci_mhz > 60) {
++	if (pci_mhz > 60)
+ 		hpriv = (void *)(PCI66 | USE_DPLL);
+-		/*
+-		 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
+-		 * the MISC. register to stretch the UltraDMA Tss timing.
+-		 * NOTE: This register is only writeable via I/O space.
+-		 */
+-		if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
+-			outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
+-	}
++
++	/*
++	 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
++	 * the MISC. register to stretch the UltraDMA Tss timing.
++	 * NOTE: This register is only writeable via I/O space.
++	 */
++	if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
++		outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
+ 
+ 	/* Now kick off ATA set up */
+ 	return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 2820257..fb4bc4f 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -607,6 +607,7 @@ static struct kobject *get_device_parent(struct device *dev,
+ 	int retval;
+ 
+ 	if (dev->class) {
++		static DEFINE_MUTEX(gdp_mutex);
+ 		struct kobject *kobj = NULL;
+ 		struct kobject *parent_kobj;
+ 		struct kobject *k;
+@@ -623,6 +624,8 @@ static struct kobject *get_device_parent(struct device *dev,
+ 		else
+ 			parent_kobj = &parent->kobj;
+ 
++		mutex_lock(&gdp_mutex);
++
+ 		/* find our class-directory at the parent and reference it */
+ 		spin_lock(&dev->class->p->class_dirs.list_lock);
+ 		list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
+@@ -631,20 +634,26 @@ static struct kobject *get_device_parent(struct device *dev,
+ 				break;
+ 			}
+ 		spin_unlock(&dev->class->p->class_dirs.list_lock);
+-		if (kobj)
++		if (kobj) {
++			mutex_unlock(&gdp_mutex);
+ 			return kobj;
++		}
+ 
+ 		/* or create a new class-directory at the parent device */
+ 		k = kobject_create();
+-		if (!k)
++		if (!k) {
++			mutex_unlock(&gdp_mutex);
+ 			return NULL;
++		}
+ 		k->kset = &dev->class->p->class_dirs;
+ 		retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
+ 		if (retval < 0) {
++			mutex_unlock(&gdp_mutex);
+ 			kobject_put(k);
+ 			return NULL;
+ 		}
+ 		/* do not emit an uevent for this simple "glue" directory */
++		mutex_unlock(&gdp_mutex);
+ 		return k;
+ 	}
+ 
+diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
+index 42ae452..dac478c 100644
+--- a/drivers/base/devtmpfs.c
++++ b/drivers/base/devtmpfs.c
+@@ -301,6 +301,19 @@ int devtmpfs_delete_node(struct device *dev)
+ 		if (dentry->d_inode) {
+ 			err = vfs_getattr(nd.path.mnt, dentry, &stat);
+ 			if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
++				struct iattr newattrs;
++				/*
++				 * before unlinking this node, reset permissions
++				 * of possible references like hardlinks
++				 */
++				newattrs.ia_uid = 0;
++				newattrs.ia_gid = 0;
++				newattrs.ia_mode = stat.mode & ~0777;
++				newattrs.ia_valid =
++					ATTR_UID|ATTR_GID|ATTR_MODE;
++				mutex_lock(&dentry->d_inode->i_mutex);
++				notify_change(dentry, &newattrs);
++				mutex_unlock(&dentry->d_inode->i_mutex);
+ 				err = vfs_unlink(nd.path.dentry->d_inode,
+ 						 dentry);
+ 				if (!err || err == -ENOENT)
+diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
+index 3f653f7..500e740 100644
+--- a/drivers/char/tty_ldisc.c
++++ b/drivers/char/tty_ldisc.c
+@@ -706,12 +706,13 @@ static void tty_reset_termios(struct tty_struct *tty)
+ /**
+  *	tty_ldisc_reinit	-	reinitialise the tty ldisc
+  *	@tty: tty to reinit
++ *	@ldisc: line discipline to reinitialize
+  *
+- *	Switch the tty back to N_TTY line discipline and leave the
+- *	ldisc state closed
++ *	Switch the tty to a line discipline and leave the ldisc
++ *	state closed
+  */
+ 
+-static void tty_ldisc_reinit(struct tty_struct *tty)
++static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
+ {
+ 	struct tty_ldisc *ld;
+ 
+@@ -721,10 +722,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty)
+ 	/*
+ 	 *	Switch the line discipline back
+ 	 */
+-	ld = tty_ldisc_get(N_TTY);
++	ld = tty_ldisc_get(ldisc);
+ 	BUG_ON(IS_ERR(ld));
+ 	tty_ldisc_assign(tty, ld);
+-	tty_set_termios_ldisc(tty, N_TTY);
++	tty_set_termios_ldisc(tty, ldisc);
+ }
+ 
+ /**
+@@ -745,6 +746,8 @@ static void tty_ldisc_reinit(struct tty_struct *tty)
+ void tty_ldisc_hangup(struct tty_struct *tty)
+ {
+ 	struct tty_ldisc *ld;
++	int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
++	int err = 0;
+ 
+ 	/*
+ 	 * FIXME! What are the locking issues here? This may me overdoing
+@@ -772,25 +775,32 @@ void tty_ldisc_hangup(struct tty_struct *tty)
+ 	wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+ 	/*
+ 	 * Shutdown the current line discipline, and reset it to
+-	 * N_TTY.
++	 * N_TTY if need be.
++	 *
++	 * Avoid racing set_ldisc or tty_ldisc_release
+ 	 */
+-	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
+-		/* Avoid racing set_ldisc or tty_ldisc_release */
+-		mutex_lock(&tty->ldisc_mutex);
+-		tty_ldisc_halt(tty);
+-		if (tty->ldisc) {	/* Not yet closed */
+-			/* Switch back to N_TTY */
+-			tty_ldisc_reinit(tty);
+-			/* At this point we have a closed ldisc and we want to
+-			   reopen it. We could defer this to the next open but
+-			   it means auditing a lot of other paths so this is
+-			   a FIXME */
++	mutex_lock(&tty->ldisc_mutex);
++	tty_ldisc_halt(tty);
++	/* At this point we have a closed ldisc and we want to
++	   reopen it. We could defer this to the next open but
++	   it means auditing a lot of other paths so this is
++	   a FIXME */
++	if (tty->ldisc) {	/* Not yet closed */
++		if (reset == 0) {
++			tty_ldisc_reinit(tty, tty->termios->c_line);
++			err = tty_ldisc_open(tty, tty->ldisc);
++		}
++		/* If the re-open fails or we reset then go to N_TTY. The
++		   N_TTY open cannot fail */
++		if (reset || err) {
++			tty_ldisc_reinit(tty, N_TTY);
+ 			WARN_ON(tty_ldisc_open(tty, tty->ldisc));
+-			tty_ldisc_enable(tty);
+ 		}
+-		mutex_unlock(&tty->ldisc_mutex);
+-		tty_reset_termios(tty);
++		tty_ldisc_enable(tty);
+ 	}
++	mutex_unlock(&tty->ldisc_mutex);
++	if (reset)
++		tty_reset_termios(tty);
+ }
+ 
+ /**
+diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
+index 6b3e0c2..6fe4f77 100644
+--- a/drivers/clocksource/sh_cmt.c
++++ b/drivers/clocksource/sh_cmt.c
+@@ -603,18 +603,13 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+ 	p->irqaction.handler = sh_cmt_interrupt;
+ 	p->irqaction.dev_id = p;
+ 	p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+-	ret = setup_irq(irq, &p->irqaction);
+-	if (ret) {
+-		pr_err("sh_cmt: failed to request irq %d\n", irq);
+-		goto err1;
+-	}
+ 
+ 	/* get hold of clock */
+ 	p->clk = clk_get(&p->pdev->dev, cfg->clk);
+ 	if (IS_ERR(p->clk)) {
+ 		pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
+ 		ret = PTR_ERR(p->clk);
+-		goto err2;
++		goto err1;
+ 	}
+ 
+ 	if (resource_size(res) == 6) {
+@@ -627,14 +622,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+ 		p->clear_bits = ~0xc000;
+ 	}
+ 
+-	return sh_cmt_register(p, cfg->name,
+-			       cfg->clockevent_rating,
+-			       cfg->clocksource_rating);
+- err2:
+-	remove_irq(irq, &p->irqaction);
+- err1:
++	ret = sh_cmt_register(p, cfg->name,
++			      cfg->clockevent_rating,
++			      cfg->clocksource_rating);
++	if (ret) {
++		pr_err("sh_cmt: registration failed\n");
++		goto err1;
++	}
++
++	ret = setup_irq(irq, &p->irqaction);
++	if (ret) {
++		pr_err("sh_cmt: failed to request irq %d\n", irq);
++		goto err1;
++	}
++
++	return 0;
++
++err1:
+ 	iounmap(p->mapbase);
+- err0:
++err0:
+ 	return ret;
+ }
+ 
+diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
+index 973e714..4c8a759 100644
+--- a/drivers/clocksource/sh_mtu2.c
++++ b/drivers/clocksource/sh_mtu2.c
+@@ -221,15 +221,15 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
+ 	ced->cpumask = cpumask_of(0);
+ 	ced->set_mode = sh_mtu2_clock_event_mode;
+ 
++	pr_info("sh_mtu2: %s used for clock events\n", ced->name);
++	clockevents_register_device(ced);
++
+ 	ret = setup_irq(p->irqaction.irq, &p->irqaction);
+ 	if (ret) {
+ 		pr_err("sh_mtu2: failed to request irq %d\n",
+ 		       p->irqaction.irq);
+ 		return;
+ 	}
+-
+-	pr_info("sh_mtu2: %s used for clock events\n", ced->name);
+-	clockevents_register_device(ced);
+ }
+ 
+ static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name,
+diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
+index 93c2322..961f5b5 100644
+--- a/drivers/clocksource/sh_tmu.c
++++ b/drivers/clocksource/sh_tmu.c
+@@ -323,15 +323,15 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
+ 	ced->set_next_event = sh_tmu_clock_event_next;
+ 	ced->set_mode = sh_tmu_clock_event_mode;
+ 
++	pr_info("sh_tmu: %s used for clock events\n", ced->name);
++	clockevents_register_device(ced);
++
+ 	ret = setup_irq(p->irqaction.irq, &p->irqaction);
+ 	if (ret) {
+ 		pr_err("sh_tmu: failed to request irq %d\n",
+ 		       p->irqaction.irq);
+ 		return;
+ 	}
+-
+-	pr_info("sh_tmu: %s used for clock events\n", ced->name);
+-	clockevents_register_device(ced);
+ }
+ 
+ static int sh_tmu_register(struct sh_tmu_priv *p, char *name,
+diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
+index 0fdbe94..0c3c498 100644
+--- a/drivers/gpio/cs5535-gpio.c
++++ b/drivers/gpio/cs5535-gpio.c
+@@ -154,7 +154,7 @@ static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
+ 
+ static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
+ {
+-	return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
++	return cs5535_gpio_isset(offset, GPIO_READ_BACK);
+ }
+ 
+ static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+@@ -172,6 +172,7 @@ static int chip_direction_input(struct gpio_chip *c, unsigned offset)
+ 
+ 	spin_lock_irqsave(&chip->lock, flags);
+ 	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
++	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
+ 	spin_unlock_irqrestore(&chip->lock, flags);
+ 
+ 	return 0;
+@@ -184,6 +185,7 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
+ 
+ 	spin_lock_irqsave(&chip->lock, flags);
+ 
++	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
+ 	__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
+ 	if (val)
+ 		__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
+diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c
+index b4468b6..c5a00f7 100644
+--- a/drivers/gpio/wm831x-gpio.c
++++ b/drivers/gpio/wm831x-gpio.c
+@@ -60,23 +60,31 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
+ 		return 0;
+ }
+ 
+-static int wm831x_gpio_direction_out(struct gpio_chip *chip,
+-				     unsigned offset, int value)
++static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+ {
+ 	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+ 	struct wm831x *wm831x = wm831x_gpio->wm831x;
+ 
+-	return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
+-			       WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
++	wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
++			value << offset);
+ }
+ 
+-static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
++static int wm831x_gpio_direction_out(struct gpio_chip *chip,
++				     unsigned offset, int value)
+ {
+ 	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+ 	struct wm831x *wm831x = wm831x_gpio->wm831x;
++	int ret;
+ 
+-	wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
+-			value << offset);
++	ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
++			      WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
++	if (ret < 0)
++		return ret;
++
++	/* Can only set GPIO state once it's in output mode */
++	wm831x_gpio_set(chip, offset, value);
++
++	return 0;
+ }
+ 
+ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
+index c2e8a45..93031a7 100644
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -655,8 +655,15 @@ static const struct dmi_system_id bad_lid_status[] = {
+  */
+ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
+ {
++	struct drm_device *dev = connector->dev;
+ 	enum drm_connector_status status = connector_status_connected;
+ 
++	/* ACPI lid methods were generally unreliable in this generation, so
++	 * don't even bother.
++	 */
++	if (IS_I8XX(dev))
++		return connector_status_connected;
++
+ 	if (!dmi_check_system(bad_lid_status) && !acpi_lid_open())
+ 		status = connector_status_disconnected;
+ 
+diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
+index 82678d3..48daee5 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -35,6 +35,7 @@
+ #include "i915_drm.h"
+ #include "i915_drv.h"
+ #include "intel_sdvo_regs.h"
++#include <linux/dmi.h>
+ 
+ static char *tv_format_names[] = {
+ 	"NTSC_M"   , "NTSC_J"  , "NTSC_443",
+@@ -2283,6 +2284,25 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
+ 		return 0x72;
+ }
+ 
++static int intel_sdvo_bad_tv_callback(const struct dmi_system_id *id)
++{
++	DRM_DEBUG_KMS("Ignoring bad SDVO TV connector for %s\n", id->ident);
++	return 1;
++}
++
++static struct dmi_system_id intel_sdvo_bad_tv[] = {
++	{
++		.callback = intel_sdvo_bad_tv_callback,
++		.ident = "IntelG45/ICH10R/DME1737",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "IBM CORPORATION"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "4800784"),
++		},
++	},
++
++	{ }	/* terminating entry */
++};
++
+ static bool
+ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+ {
+@@ -2323,7 +2343,8 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+ 					(1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+ 					(1 << INTEL_ANALOG_CLONE_BIT);
+ 		}
+-	} else if (flags & SDVO_OUTPUT_SVID0) {
++	} else if ((flags & SDVO_OUTPUT_SVID0) &&
++		   !dmi_check_system(intel_sdvo_bad_tv)) {
+ 
+ 		sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
+ 		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
+diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
+index 7f152f6..d75788f 100644
+--- a/drivers/gpu/drm/radeon/atom.c
++++ b/drivers/gpu/drm/radeon/atom.c
+@@ -881,8 +881,6 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
+ 	uint8_t attr = U8((*ptr)++), shift;
+ 	uint32_t saved, dst;
+ 	int dptr = *ptr;
+-	attr &= 0x38;
+-	attr |= atom_def_dst[attr >> 3] << 6;
+ 	SDEBUG("   dst: ");
+ 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+ 	shift = atom_get_src(ctx, attr, ptr);
+@@ -897,8 +895,6 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
+ 	uint8_t attr = U8((*ptr)++), shift;
+ 	uint32_t saved, dst;
+ 	int dptr = *ptr;
+-	attr &= 0x38;
+-	attr |= atom_def_dst[attr >> 3] << 6;
+ 	SDEBUG("   dst: ");
+ 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+ 	shift = atom_get_src(ctx, attr, ptr);
+diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
+index 3d47a2c..a759170 100644
+--- a/drivers/gpu/drm/ttm/ttm_tt.c
++++ b/drivers/gpu/drm/ttm/ttm_tt.c
+@@ -480,7 +480,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm)
+ 	void *from_virtual;
+ 	void *to_virtual;
+ 	int i;
+-	int ret;
++	int ret = -ENOMEM;
+ 
+ 	if (ttm->page_flags & TTM_PAGE_FLAG_USER) {
+ 		ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start,
+@@ -499,8 +499,10 @@ static int ttm_tt_swapin(struct ttm_tt *ttm)
+ 
+ 	for (i = 0; i < ttm->num_pages; ++i) {
+ 		from_page = read_mapping_page(swap_space, i, NULL);
+-		if (IS_ERR(from_page))
++		if (IS_ERR(from_page)) {
++			ret = PTR_ERR(from_page);
+ 			goto out_err;
++		}
+ 		to_page = __ttm_tt_get_page(ttm, i);
+ 		if (unlikely(to_page == NULL))
+ 			goto out_err;
+@@ -523,7 +525,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm)
+ 	return 0;
+ out_err:
+ 	ttm_tt_free_alloced_pages(ttm);
+-	return -ENOMEM;
++	return ret;
+ }
+ 
+ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage)
+@@ -535,6 +537,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage)
+ 	void *from_virtual;
+ 	void *to_virtual;
+ 	int i;
++	int ret = -ENOMEM;
+ 
+ 	BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated);
+ 	BUG_ON(ttm->caching_state != tt_cached);
+@@ -557,7 +560,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage)
+ 						0);
+ 		if (unlikely(IS_ERR(swap_storage))) {
+ 			printk(KERN_ERR "Failed allocating swap storage.\n");
+-			return -ENOMEM;
++			return PTR_ERR(swap_storage);
+ 		}
+ 	} else
+ 		swap_storage = persistant_swap_storage;
+@@ -569,9 +572,10 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage)
+ 		if (unlikely(from_page == NULL))
+ 			continue;
+ 		to_page = read_mapping_page(swap_space, i, NULL);
+-		if (unlikely(to_page == NULL))
++		if (unlikely(IS_ERR(to_page))) {
++			ret = PTR_ERR(to_page);
+ 			goto out_err;
+-
++		}
+ 		preempt_disable();
+ 		from_virtual = kmap_atomic(from_page, KM_USER0);
+ 		to_virtual = kmap_atomic(to_page, KM_USER1);
+@@ -595,5 +599,5 @@ out_err:
+ 	if (!persistant_swap_storage)
+ 		fput(swap_storage);
+ 
+-	return -ENOMEM;
++	return ret;
+ }
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index eabe5f8..8455f3d 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1661,8 +1661,6 @@ static const struct hid_device_id hid_ignore_list[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
+-	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
+-	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 010368e..793691f 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -402,10 +402,6 @@
+ #define USB_VENDOR_ID_SUNPLUS		0x04fc
+ #define USB_DEVICE_ID_SUNPLUS_WDESKTOP	0x05d8
+ 
+-#define USB_VENDOR_ID_TENX		0x1130
+-#define USB_DEVICE_ID_TENX_IBUDDY1	0x0001
+-#define USB_DEVICE_ID_TENX_IBUDDY2	0x0002
+-
+ #define USB_VENDOR_ID_THRUSTMASTER	0x044f
+ 
+ #define USB_VENDOR_ID_TOPMAX		0x0663
+diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
+index e2997a8..2f84237 100644
+--- a/drivers/hid/usbhid/hid-core.c
++++ b/drivers/hid/usbhid/hid-core.c
+@@ -316,6 +316,7 @@ static int hid_submit_out(struct hid_device *hid)
+ 			err_hid("usb_submit_urb(out) failed");
+ 			return -1;
+ 		}
++		usbhid->last_out = jiffies;
+ 	} else {
+ 		/*
+ 		 * queue work to wake up the device.
+@@ -377,6 +378,7 @@ static int hid_submit_ctrl(struct hid_device *hid)
+ 			err_hid("usb_submit_urb(ctrl) failed");
+ 			return -1;
+ 		}
++		usbhid->last_ctrl = jiffies;
+ 	} else {
+ 		/*
+ 		 * queue work to wake up the device.
+@@ -512,9 +514,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
+ 		usbhid->out[usbhid->outhead].report = report;
+ 		usbhid->outhead = head;
+ 
+-		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
++		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
+ 			if (hid_submit_out(hid))
+ 				clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
++		} else {
++			/*
++			 * 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
++			 * spinlock
++			 */
++			if (time_after(jiffies, usbhid->last_out + HZ * 5))
++				usb_unlink_urb(usbhid->urbout);
++		}
+ 		return;
+ 	}
+ 
+@@ -535,9 +548,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
+ 	usbhid->ctrl[usbhid->ctrlhead].dir = dir;
+ 	usbhid->ctrlhead = head;
+ 
+-	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
++	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
+ 		if (hid_submit_ctrl(hid))
+ 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
++	} else {
++		/*
++		 * 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
++		 * spinlock
++		 */
++		if (time_after(jiffies, usbhid->last_ctrl + HZ * 5))
++			usb_unlink_urb(usbhid->urbctrl);
++	}
+ }
+ 
+ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
+index 08f505c..ec20400 100644
+--- a/drivers/hid/usbhid/usbhid.h
++++ b/drivers/hid/usbhid/usbhid.h
+@@ -80,12 +80,14 @@ struct usbhid_device {
+ 	unsigned char ctrlhead, ctrltail;                               /* Control fifo head & tail */
+ 	char *ctrlbuf;                                                  /* Control buffer */
+ 	dma_addr_t ctrlbuf_dma;                                         /* Control buffer dma */
++	unsigned long last_ctrl;						/* record of last output for timeouts */
+ 
+ 	struct urb *urbout;                                             /* Output URB */
+ 	struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE];              /* Output pipe fifo */
+ 	unsigned char outhead, outtail;                                 /* Output pipe fifo head & tail */
+ 	char *outbuf;                                                   /* Output buffer */
+ 	dma_addr_t outbuf_dma;                                          /* Output buffer dma */
++	unsigned long last_out;							/* record of last output for timeouts */
+ 
+ 	spinlock_t lock;						/* fifo spinlock */
+ 	unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
+diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
+index 6c9ace1..2ad62c3 100644
+--- a/drivers/hwmon/ams/ams-core.c
++++ b/drivers/hwmon/ams/ams-core.c
+@@ -213,7 +213,7 @@ int __init ams_init(void)
+ 	return -ENODEV;
+ }
+ 
+-void ams_exit(void)
++void ams_sensor_detach(void)
+ {
+ 	/* Remove input device */
+ 	ams_input_exit();
+@@ -221,9 +221,6 @@ void ams_exit(void)
+ 	/* Remove attributes */
+ 	device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+ 
+-	/* Shut down implementation */
+-	ams_info.exit();
+-
+ 	/* Flush interrupt worker
+ 	 *
+ 	 * We do this after ams_info.exit(), because an interrupt might
+@@ -239,6 +236,12 @@ void ams_exit(void)
+ 	pmf_unregister_irq_client(&ams_freefall_client);
+ }
+ 
++static void __exit ams_exit(void)
++{
++	/* Shut down implementation */
++	ams_info.exit();
++}
++
+ MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
+ MODULE_DESCRIPTION("Apple Motion Sensor driver");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
+index 2cbf8a6..abeecd2 100644
+--- a/drivers/hwmon/ams/ams-i2c.c
++++ b/drivers/hwmon/ams/ams-i2c.c
+@@ -238,6 +238,8 @@ static int ams_i2c_probe(struct i2c_client *client,
+ static int ams_i2c_remove(struct i2c_client *client)
+ {
+ 	if (ams_info.has_device) {
++		ams_sensor_detach();
++
+ 		/* Disable interrupts */
+ 		ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+ 
+diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
+index fb18b3d..4f61b3e 100644
+--- a/drivers/hwmon/ams/ams-pmu.c
++++ b/drivers/hwmon/ams/ams-pmu.c
+@@ -133,6 +133,8 @@ static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
+ 
+ static void ams_pmu_exit(void)
+ {
++	ams_sensor_detach();
++
+ 	/* Disable interrupts */
+ 	ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+ 
+diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
+index 5ed387b..b28d7e2 100644
+--- a/drivers/hwmon/ams/ams.h
++++ b/drivers/hwmon/ams/ams.h
+@@ -61,6 +61,7 @@ extern struct ams ams_info;
+ 
+ extern void ams_sensors(s8 *x, s8 *y, s8 *z);
+ extern int ams_sensor_attach(void);
++extern void ams_sensor_detach(void);
+ 
+ extern int ams_pmu_init(struct device_node *np);
+ extern int ams_i2c_init(struct device_node *np);
+diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
+index fa07282..0627f7a 100644
+--- a/drivers/hwmon/fschmd.c
++++ b/drivers/hwmon/fschmd.c
+@@ -267,7 +267,7 @@ struct fschmd_data {
+ 	struct list_head list; /* member of the watchdog_data_list */
+ 	struct kref kref;
+ 	struct miscdevice watchdog_miscdev;
+-	int kind;
++	enum chips kind;
+ 	unsigned long watchdog_is_open;
+ 	char watchdog_expect_close;
+ 	char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
+@@ -325,8 +325,7 @@ static ssize_t show_in_value(struct device *dev,
+ 	int index = to_sensor_dev_attr(devattr)->index;
+ 	struct fschmd_data *data = fschmd_update_device(dev);
+ 
+-	/* fscher / fschrc - 1 as data->kind is an array index, not a chips */
+-	if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
++	if (data->kind == fscher || data->kind >= fschrc)
+ 		return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
+ 			dmi_mult[index]) / 255 + dmi_offset[index]);
+ 	else
+@@ -492,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
+ 	int val = data->fan_min[index];
+ 
+ 	/* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+-	if (val || data->kind == fscsyl - 1)
++	if (val || data->kind == fscsyl)
+ 		val = val / 2 + 128;
+ 
+ 	return sprintf(buf, "%d\n", val);
+@@ -506,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
+ 	unsigned long v = simple_strtoul(buf, NULL, 10);
+ 
+ 	/* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+-	if (v || data->kind == fscsyl - 1) {
++	if (v || data->kind == fscsyl) {
+ 		v = SENSORS_LIMIT(v, 128, 255);
+ 		v = (v - 128) * 2 + 1;
+ 	}
+@@ -1037,7 +1036,7 @@ static int fschmd_detect(struct i2c_client *client,
+ 	else
+ 		return -ENODEV;
+ 
+-	strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
++	strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE);
+ 
+ 	return 0;
+ }
+@@ -1065,6 +1064,7 @@ static int fschmd_probe(struct i2c_client *client,
+ 	   (where the client is found through a data ptr instead of the
+ 	   otherway around) */
+ 	data->client = client;
++	data->kind = kind;
+ 
+ 	if (kind == fscpos) {
+ 		/* The Poseidon has hardwired temp limits, fill these
+@@ -1085,9 +1085,6 @@ static int fschmd_probe(struct i2c_client *client,
+ 		}
+ 	}
+ 
+-	/* i2c kind goes from 1-6, we want from 0-5 to address arrays */
+-	data->kind = kind - 1;
+-
+ 	/* Read in some never changing registers */
+ 	data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
+ 	data->global_control = i2c_smbus_read_byte_data(client,
+diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
+index a13b30e..d14a1af 100644
+--- a/drivers/hwmon/tmp401.c
++++ b/drivers/hwmon/tmp401.c
+@@ -134,7 +134,7 @@ struct tmp401_data {
+ 	struct mutex update_lock;
+ 	char valid; /* zero until following fields are valid */
+ 	unsigned long last_updated; /* in jiffies */
+-	int kind;
++	enum chips kind;
+ 
+ 	/* register values */
+ 	u8 status;
+@@ -524,7 +524,7 @@ static int tmp401_detect(struct i2c_client *client,
+ 	if (reg > 15)
+ 		return -ENODEV;
+ 
+-	strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
++	strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
+ 
+ 	return 0;
+ }
+@@ -572,8 +572,7 @@ static int tmp401_probe(struct i2c_client *client,
+ 		goto exit_remove;
+ 	}
+ 
+-	dev_info(&client->dev, "Detected TI %s chip\n",
+-		 names[data->kind - 1]);
++	dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]);
+ 
+ 	return 0;
+ 
+diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
+index 4f7c051..738c472 100644
+--- a/drivers/hwmon/tmp421.c
++++ b/drivers/hwmon/tmp421.c
+@@ -61,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
+ #define TMP423_DEVICE_ID			0x23
+ 
+ static const struct i2c_device_id tmp421_id[] = {
+-	{ "tmp421", tmp421 },
+-	{ "tmp422", tmp422 },
+-	{ "tmp423", tmp423 },
++	{ "tmp421", 2 },
++	{ "tmp422", 3 },
++	{ "tmp423", 4 },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(i2c, tmp421_id);
+@@ -73,21 +73,23 @@ struct tmp421_data {
+ 	struct mutex update_lock;
+ 	char valid;
+ 	unsigned long last_updated;
+-	int kind;
++	int channels;
+ 	u8 config;
+ 	s16 temp[4];
+ };
+ 
+ static int temp_from_s16(s16 reg)
+ {
+-	int temp = reg;
++	/* Mask out status bits */
++	int temp = reg & ~0xf;
+ 
+ 	return (temp * 1000 + 128) / 256;
+ }
+ 
+ static int temp_from_u16(u16 reg)
+ {
+-	int temp = reg;
++	/* Mask out status bits */
++	int temp = reg & ~0xf;
+ 
+ 	/* Add offset for extended temperature range. */
+ 	temp -= 64 * 256;
+@@ -107,7 +109,7 @@ static struct tmp421_data *tmp421_update_device(struct device *dev)
+ 		data->config = i2c_smbus_read_byte_data(client,
+ 			TMP421_CONFIG_REG_1);
+ 
+-		for (i = 0; i <= data->kind; i++) {
++		for (i = 0; i < data->channels; i++) {
+ 			data->temp[i] = i2c_smbus_read_byte_data(client,
+ 				TMP421_TEMP_MSB[i]) << 8;
+ 			data->temp[i] |= i2c_smbus_read_byte_data(client,
+@@ -166,7 +168,7 @@ static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
+ 	devattr = container_of(a, struct device_attribute, attr);
+ 	index = to_sensor_dev_attr(devattr)->index;
+ 
+-	if (data->kind > index)
++	if (index < data->channels)
+ 		return a->mode;
+ 
+ 	return 0;
+@@ -252,9 +254,9 @@ static int tmp421_detect(struct i2c_client *client,
+ 		return -ENODEV;
+ 	}
+ 
+-	strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
++	strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
+ 	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
+-		 names[kind - 1], client->addr);
++		 names[kind], client->addr);
+ 
+ 	return 0;
+ }
+@@ -271,7 +273,7 @@ static int tmp421_probe(struct i2c_client *client,
+ 
+ 	i2c_set_clientdata(client, data);
+ 	mutex_init(&data->update_lock);
+-	data->kind = id->driver_data;
++	data->channels = id->driver_data;
+ 
+ 	err = tmp421_init_client(client);
+ 	if (err)
+diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
+index 5ff47ba..58809b0 100644
+--- a/drivers/macintosh/therm_adt746x.c
++++ b/drivers/macintosh/therm_adt746x.c
+@@ -90,6 +90,8 @@ static struct task_struct *thread_therm = NULL;
+ 
+ static void write_both_fan_speed(struct thermostat *th, int speed);
+ static void write_fan_speed(struct thermostat *th, int speed, int fan);
++static void thermostat_create_files(void);
++static void thermostat_remove_files(void);
+ 
+ static int
+ write_reg(struct thermostat* th, int reg, u8 data)
+@@ -161,6 +163,8 @@ remove_thermostat(struct i2c_client *client)
+ 	struct thermostat *th = i2c_get_clientdata(client);
+ 	int i;
+ 	
++	thermostat_remove_files();
++
+ 	if (thread_therm != NULL) {
+ 		kthread_stop(thread_therm);
+ 	}
+@@ -449,6 +453,8 @@ static int probe_thermostat(struct i2c_client *client,
+ 		return -ENOMEM;
+ 	}
+ 
++	thermostat_create_files();
++
+ 	return 0;
+ }
+ 
+@@ -566,7 +572,6 @@ thermostat_init(void)
+ 	struct device_node* np;
+ 	const u32 *prop;
+ 	int i = 0, offset = 0;
+-	int err;
+ 
+ 	np = of_find_node_by_name(NULL, "fan");
+ 	if (!np)
+@@ -633,6 +638,17 @@ thermostat_init(void)
+ 		return -ENODEV;
+ 	}
+ 
++#ifndef CONFIG_I2C_POWERMAC
++	request_module("i2c-powermac");
++#endif
++
++	return i2c_add_driver(&thermostat_driver);
++}
++
++static void thermostat_create_files(void)
++{
++	int err;
++
+ 	err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
+ 	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
+ 	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
+@@ -647,16 +663,9 @@ thermostat_init(void)
+ 	if (err)
+ 		printk(KERN_WARNING
+ 			"Failed to create tempertaure attribute file(s).\n");
+-
+-#ifndef CONFIG_I2C_POWERMAC
+-	request_module("i2c-powermac");
+-#endif
+-
+-	return i2c_add_driver(&thermostat_driver);
+ }
+ 
+-static void __exit
+-thermostat_exit(void)
++static void thermostat_remove_files(void)
+ {
+ 	if (of_dev) {
+ 		device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature);
+@@ -673,9 +682,14 @@ thermostat_exit(void)
+ 			device_remove_file(&of_dev->dev,
+ 					   &dev_attr_sensor2_fan_speed);
+ 
+-		of_device_unregister(of_dev);
+ 	}
++}
++
++static void __exit
++thermostat_exit(void)
++{
+ 	i2c_del_driver(&thermostat_driver);
++	of_device_unregister(of_dev);
+ }
+ 
+ module_init(thermostat_init);
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 1d66932..e3cf568 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -897,16 +897,17 @@ static int do_resume(struct dm_ioctl *param)
+ 			set_disk_ro(dm_disk(md), 1);
+ 	}
+ 
+-	if (dm_suspended_md(md))
++	if (dm_suspended_md(md)) {
+ 		r = dm_resume(md);
++		if (!r)
++			dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
++	}
+ 
+ 	if (old_map)
+ 		dm_table_destroy(old_map);
+ 
+-	if (!r) {
+-		dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
++	if (!r)
+ 		r = __dev_status(md, param);
+-	}
+ 
+ 	dm_put(md);
+ 	return r;
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index aa4e2aa..fa786b9 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -635,8 +635,10 @@ static void dec_pending(struct dm_io *io, int error)
+ 			if (!md->barrier_error && io_error != -EOPNOTSUPP)
+ 				md->barrier_error = io_error;
+ 			end_io_acct(io);
++			free_io(md, io);
+ 		} else {
+ 			end_io_acct(io);
++			free_io(md, io);
+ 
+ 			if (io_error != DM_ENDIO_REQUEUE) {
+ 				trace_block_bio_complete(md->queue, bio);
+@@ -644,8 +646,6 @@ static void dec_pending(struct dm_io *io, int error)
+ 				bio_endio(bio, io_error);
+ 			}
+ 		}
+-
+-		free_io(md, io);
+ 	}
+ }
+ 
+diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
+index 8b8558f..b11533f 100644
+--- a/drivers/media/dvb/dvb-core/dvb_net.c
++++ b/drivers/media/dvb/dvb-core/dvb_net.c
+@@ -504,6 +504,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
+ 				       "bytes left in TS.  Resyncing.\n", ts_remain);
+ 				priv->ule_sndu_len = 0;
+ 				priv->need_pusi = 1;
++				ts += TS_SZ;
+ 				continue;
+ 			}
+ 
+diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
+index 9154870..0493e40 100644
+--- a/drivers/media/video/gspca/mr97310a.c
++++ b/drivers/media/video/gspca/mr97310a.c
+@@ -697,6 +697,12 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
+ 			{0x13, 0x00, {0x01}, 1},
+ 			{0, 0, {0}, 0}
+ 		};
++		/* Without this command the cam won't work with USB-UHCI */
++		gspca_dev->usb_buf[0] = 0x0a;
++		gspca_dev->usb_buf[1] = 0x00;
++		err_code = mr_write(gspca_dev, 2);
++		if (err_code < 0)
++			return err_code;
+ 		err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
+ 					 ARRAY_SIZE(cif_sensor1_init_data));
+ 	}
+diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
+index f8d5c87..a4c0ef4 100644
+--- a/drivers/media/video/soc_mediabus.c
++++ b/drivers/media/video/soc_mediabus.c
+@@ -134,7 +134,8 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line);
+ const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
+ 	enum v4l2_mbus_pixelcode code)
+ {
+-	if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt))
++	if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) ||
++	    code <= V4L2_MBUS_FMT_FIXED)
+ 		return NULL;
+ 	return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
+ }
+diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
+index d96e1ab..2fdf768 100644
+--- a/drivers/mmc/host/s3cmci.c
++++ b/drivers/mmc/host/s3cmci.c
+@@ -1179,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc)
+ 	struct s3c24xx_mci_pdata *pdata = host->pdata;
+ 	int ret;
+ 
+-	if (pdata->gpio_detect == 0)
++	if (pdata->no_detect)
+ 		return -ENOSYS;
+ 
+ 	ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
+@@ -1360,6 +1360,8 @@ static struct mmc_host_ops s3cmci_ops = {
+ static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
+ 	/* This is currently here to avoid a number of if (host->pdata)
+ 	 * checks. Any zero fields to ensure reasonable defaults are picked. */
++	 .no_wprotect = 1,
++	 .no_detect = 1,
+ };
+ 
+ #ifdef CONFIG_CPU_FREQ
+diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
+index 4331d67..2a9f029 100644
+--- a/drivers/net/wireless/airo.c
++++ b/drivers/net/wireless/airo.c
+@@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
+ 	WepKeyRid wkr;
+ 	int rc;
+ 
+-	if (keylen == 0) {
+-		airo_print_err(ai->dev->name, "%s: key length to set was zero",
+-			       __func__);
+-		return -1;
+-	}
++	WARN_ON(keylen == 0);
+ 
+ 	memset(&wkr, 0, sizeof(wkr));
+ 	wkr.len = cpu_to_le16(sizeof(wkr));
+@@ -6405,11 +6401,7 @@ static int airo_set_encode(struct net_device *dev,
+ 		if (dwrq->length > MIN_KEY_SIZE)
+ 			key.len = MAX_KEY_SIZE;
+ 		else
+-			if (dwrq->length > 0)
+-				key.len = MIN_KEY_SIZE;
+-			else
+-				/* Disable the key */
+-				key.len = 0;
++			key.len = MIN_KEY_SIZE;
+ 		/* Check if the key is not marked as invalid */
+ 		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
+ 			/* Cleanup */
+@@ -6590,12 +6582,22 @@ static int airo_set_encodeext(struct net_device *dev,
+ 		default:
+ 			return -EINVAL;
+ 		}
+-		/* Send the key to the card */
+-		rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
+-		if (rc < 0) {
+-			airo_print_err(local->dev->name, "failed to set WEP key"
+-			               " at index %d: %d.", idx, rc);
+-			return rc;
++		if (key.len == 0) {
++			rc = set_wep_tx_idx(local, idx, perm, 1);
++			if (rc < 0) {
++				airo_print_err(local->dev->name,
++					       "failed to set WEP transmit index to %d: %d.",
++					       idx, rc);
++				return rc;
++			}
++		} else {
++			rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
++			if (rc < 0) {
++				airo_print_err(local->dev->name,
++					       "failed to set WEP key at index %d: %d.",
++					       idx, rc);
++				return rc;
++			}
+ 		}
+ 	}
+ 
+diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
+index 6a2a967..bbd2f31 100644
+--- a/drivers/net/wireless/ath/ath5k/ath5k.h
++++ b/drivers/net/wireless/ath/ath5k/ath5k.h
+@@ -541,7 +541,6 @@ struct ath5k_txq_info {
+ /*
+  * Transmit packet types.
+  * used on tx control descriptor
+- * TODO: Use them inside base.c corectly
+  */
+ enum ath5k_pkt_type {
+ 	AR5K_PKT_TYPE_NORMAL		= 0,
+diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
+index e63b7c4..d6ee8ac 100644
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -1246,6 +1246,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ 	return 0;
+ }
+ 
++static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
++{
++	struct ieee80211_hdr *hdr;
++	enum ath5k_pkt_type htype;
++	__le16 fc;
++
++	hdr = (struct ieee80211_hdr *)skb->data;
++	fc = hdr->frame_control;
++
++	if (ieee80211_is_beacon(fc))
++		htype = AR5K_PKT_TYPE_BEACON;
++	else if (ieee80211_is_probe_resp(fc))
++		htype = AR5K_PKT_TYPE_PROBE_RESP;
++	else if (ieee80211_is_atim(fc))
++		htype = AR5K_PKT_TYPE_ATIM;
++	else if (ieee80211_is_pspoll(fc))
++		htype = AR5K_PKT_TYPE_PSPOLL;
++	else
++		htype = AR5K_PKT_TYPE_NORMAL;
++
++	return htype;
++}
++
+ static int
+ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+ 		  struct ath5k_txq *txq)
+@@ -1300,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+ 			sc->vif, pktlen, info));
+ 	}
+ 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
+-		ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
++		ieee80211_get_hdrlen_from_skb(skb),
++		get_hw_packet_type(skb),
+ 		(sc->power_level * 2),
+ 		hw_rate,
+ 		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
+index 1660ef1..06eaaa9 100644
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
+@@ -525,16 +525,13 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
+ {
+ 	u32 nexttbtt, intval;
+ 
+-	/* Configure the timers only when the TSF has to be reset */
+-
+-	if (!(sc->sc_flags & SC_OP_TSF_RESET))
+-		return;
+-
+ 	/* NB: the beacon interval is kept internally in TU's */
+ 	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+ 	intval /= ATH_BCBUF;    /* for staggered beacons */
+ 	nexttbtt = intval;
+-	intval |= ATH9K_BEACON_RESET_TSF;
++
++	if (sc->sc_flags & SC_OP_TSF_RESET)
++		intval |= ATH9K_BEACON_RESET_TSF;
+ 
+ 	/*
+ 	 * In AP mode we enable the beacon timers and SWBA interrupts to
+diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
+index ae37144..7c64aa5 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1345,6 +1345,16 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
+ 	 * Necessary to avoid issues on AR5416 2.0
+ 	 */
+ 	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
++
++	/*
++	 * Disable RIFS search on some chips to avoid baseband
++	 * hang issues.
++	 */
++	if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
++		val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
++		val &= ~AR_PHY_RIFS_INIT_DELAY;
++		REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
++	}
+ }
+ 
+ static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index 643bea3..4faafbd 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -928,6 +928,7 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf
+ 
+ 	clear_bit(key->hw_key_idx + 64, common->keymap);
+ 	if (common->splitmic) {
++		ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
+ 		clear_bit(key->hw_key_idx + 32, common->keymap);
+ 		clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
+ 	}
+@@ -1848,6 +1849,8 @@ bad_free_hw:
+ 
+ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+ {
++	struct ath_hw *ah = sc->sc_ah;
++
+ 	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ 		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ 		IEEE80211_HW_SIGNAL_DBM |
+@@ -1865,7 +1868,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+ 		BIT(NL80211_IFTYPE_ADHOC) |
+ 		BIT(NL80211_IFTYPE_MESH_POINT);
+ 
+-	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
++	if (AR_SREV_5416(ah))
++		hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ 
+ 	hw->queues = 4;
+ 	hw->max_rates = 4;
+diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
+index 31de27d..0999a49 100644
+--- a/drivers/net/wireless/ath/ath9k/phy.h
++++ b/drivers/net/wireless/ath/ath9k/phy.h
+@@ -384,6 +384,9 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
+ 
+ #define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
+ 
++#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
++#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
++
+ #define AR_PHY_M_SLEEP      0x99f0
+ #define AR_PHY_REFCLKDLY    0x99f4
+ #define AR_PHY_REFCLKPD     0x99f8
+diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
+index 70fdb9d..1d6cf7d 100644
+--- a/drivers/net/wireless/ath/ath9k/rc.c
++++ b/drivers/net/wireless/ath/ath9k/rc.c
+@@ -668,7 +668,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+ 	struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	__le16 fc = hdr->frame_control;
+-	u8 try_per_rate, i = 0, rix, nrix;
++	u8 try_per_rate, i = 0, rix;
+ 	int is_probe = 0;
+ 
+ 	if (rate_control_send_low(sta, priv_sta, txrc))
+@@ -688,26 +688,25 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+ 
+ 	rate_table = sc->cur_rate_table;
+ 	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
+-	nrix = rix;
+ 
+ 	if (is_probe) {
+ 		/* set one try for probe rates. For the
+ 		 * probes don't enable rts */
+ 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+-				       1, nrix, 0);
++				       1, rix, 0);
+ 
+ 		/* Get the next tried/allowed rate. No RTS for the next series
+ 		 * after the probe rate
+ 		 */
+-		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
++		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
+ 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+-				       try_per_rate, nrix, 0);
++				       try_per_rate, rix, 0);
+ 
+ 		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+ 	} else {
+ 		/* Set the choosen rate. No RTS for first series entry. */
+ 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+-				       try_per_rate, nrix, 0);
++				       try_per_rate, rix, 0);
+ 	}
+ 
+ 	/* Fill in the other rates for multirate retry */
+@@ -716,10 +715,10 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+ 		if (i + 1 == 4)
+ 			try_per_rate = 4;
+ 
+-		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
++		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
+ 		/* All other rates in the series have RTS enabled */
+ 		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+-				       try_per_rate, nrix, 1);
++				       try_per_rate, rix, 1);
+ 	}
+ 
+ 	/*
+diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
+index 490fb45..b59166c 100644
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -3970,6 +3970,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
+ 	}
+ 
+ 	/* We are ready to run. */
++	ieee80211_wake_queues(dev->wl->hw);
+ 	b43_set_status(dev, B43_STAT_STARTED);
+ 
+ 	/* Start data flow (TX/RX). */
+@@ -4379,8 +4380,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
+ 
+ 	ieee80211_wake_queues(dev->wl->hw);
+ 
+-	ieee80211_wake_queues(dev->wl->hw);
+-
+ 	b43_set_status(dev, B43_STAT_INITIALIZED);
+ 
+ out:
+diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
+index 4a905b6..6d21b49 100644
+--- a/drivers/net/wireless/b43legacy/main.c
++++ b/drivers/net/wireless/b43legacy/main.c
+@@ -2921,6 +2921,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
+ 		goto out;
+ 	}
+ 	/* We are ready to run. */
++	ieee80211_wake_queues(dev->wl->hw);
+ 	b43legacy_set_status(dev, B43legacy_STAT_STARTED);
+ 
+ 	/* Start data flow (TX/RX) */
+@@ -3341,6 +3342,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
+ 	b43legacy_security_init(dev);
+ 	b43legacy_rng_init(wl);
+ 
++	ieee80211_wake_queues(dev->wl->hw);
+ 	b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
+ 
+ 	b43legacy_leds_init(dev);
+diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
+index a72f7c2..4bf4c21 100644
+--- a/drivers/net/wireless/p54/p54pci.c
++++ b/drivers/net/wireless/p54/p54pci.c
+@@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
+ 						 skb_tail_pointer(skb),
+ 						 priv->common.rx_mtu + 32,
+ 						 PCI_DMA_FROMDEVICE);
++
++			if (pci_dma_mapping_error(priv->pdev, mapping)) {
++				dev_kfree_skb_any(skb);
++				dev_err(&priv->pdev->dev,
++					"RX DMA Mapping error\n");
++				break;
++			}
++
+ 			desc->host_addr = cpu_to_le32(mapping);
+ 			desc->device_addr = 0;	// FIXME: necessary?
+ 			desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
+@@ -325,14 +333,20 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
+ 	u32 device_idx, idx, i;
+ 
+ 	spin_lock_irqsave(&priv->lock, flags);
+-
+ 	device_idx = le32_to_cpu(ring_control->device_idx[1]);
+ 	idx = le32_to_cpu(ring_control->host_idx[1]);
+ 	i = idx % ARRAY_SIZE(ring_control->tx_data);
+ 
+-	priv->tx_buf_data[i] = skb;
+ 	mapping = pci_map_single(priv->pdev, skb->data, skb->len,
+ 				 PCI_DMA_TODEVICE);
++	if (pci_dma_mapping_error(priv->pdev, mapping)) {
++		spin_unlock_irqrestore(&priv->lock, flags);
++		p54_free_skb(dev, skb);
++		dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
++		return ;
++	}
++	priv->tx_buf_data[i] = skb;
++
+ 	desc = &ring_control->tx_data[i];
+ 	desc->host_addr = cpu_to_le32(mapping);
+ 	desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
+diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
+index 92af9b9..8742640 100644
+--- a/drivers/net/wireless/p54/p54usb.c
++++ b/drivers/net/wireless/p54/p54usb.c
+@@ -60,6 +60,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
+ 	{USB_DEVICE(0x06b9, 0x0121)},	/* Thomson SpeedTouch 121g */
+ 	{USB_DEVICE(0x0707, 0xee13)},   /* SMC 2862W-G version 2 */
+ 	{USB_DEVICE(0x083a, 0x4521)},   /* Siemens Gigaset USB Adapter 54 version 2 */
++	{USB_DEVICE(0x083a, 0xf503)},	/* Accton FD7050E ver 1010ec  */
+ 	{USB_DEVICE(0x0846, 0x4240)},	/* Netgear WG111 (v2) */
+ 	{USB_DEVICE(0x0915, 0x2000)},	/* Cohiba Proto board */
+ 	{USB_DEVICE(0x0915, 0x2002)},	/* Cohiba Proto board */
+diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
+index c1abac8..5becbde 100644
+--- a/drivers/pci/hotplug/ibmphp_ebda.c
++++ b/drivers/pci/hotplug/ibmphp_ebda.c
+@@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void)
+ 
+ int __init ibmphp_access_ebda (void)
+ {
+-	u8 format, num_ctlrs, rio_complete, hs_complete;
++	u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz;
+ 	u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base;
+ 	int rc = 0;
+ 
+@@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void)
+ 	iounmap (io_mem);
+ 	debug ("returned ebda segment: %x\n", ebda_seg);
+ 	
+-	io_mem = ioremap(ebda_seg<<4, 1024);
++	io_mem = ioremap(ebda_seg<<4, 1);
++	if (!io_mem)
++		return -ENOMEM;
++	ebda_sz = readb(io_mem);
++	iounmap(io_mem);
++	debug("ebda size: %d(KiB)\n", ebda_sz);
++	if (ebda_sz == 0)
++		return -ENOMEM;
++
++	io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024));
+ 	if (!io_mem )
+ 		return -ENOMEM;
+ 	next_offset = 0x180;
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index f526e73..11fce79 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -319,9 +319,15 @@ config THINKPAD_ACPI_VIDEO
+ 	  server running, phase of the moon, and the current mood of
+ 	  Schroedinger's cat.  If you can use X.org's RandR to control
+ 	  your ThinkPad's video output ports instead of this feature,
+-	  don't think twice: do it and say N here to save some memory.
++	  don't think twice: do it and say N here to save memory and avoid
++	  bad interactions with X.org.
+ 
+-	  If you are not sure, say Y here.
++	  NOTE: access to this feature is limited to processes with the
++	  CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms
++	  where it interacts badly with X.org.
++
++	  If you are not sure, say Y here but do try to check if you could
++	  be using X.org RandR instead.
+ 
+ config THINKPAD_ACPI_HOTKEY_POLL
+ 	bool "Support NVRAM polling for hot keys"
+diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
+index e2be6bb..6a47bb7 100644
+--- a/drivers/platform/x86/eeepc-laptop.c
++++ b/drivers/platform/x86/eeepc-laptop.c
+@@ -1277,7 +1277,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
+ 	 * hotplug code. In fact, current hotplug code seems to unplug another
+ 	 * device...
+ 	 */
+-	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) {
++	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
++	    strcmp(model, "1005PE") == 0) {
+ 		eeepc->hotplug_disabled = true;
+ 		pr_info("wlan hotplug disabled\n");
+ 	}
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index eb603f1..e7b0c3b 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -286,6 +286,7 @@ struct ibm_init_struct {
+ 	char param[32];
+ 
+ 	int (*init) (struct ibm_init_struct *);
++	mode_t base_procfs_mode;
+ 	struct ibm_struct *data;
+ };
+ 
+@@ -2082,6 +2083,7 @@ static struct attribute_set *hotkey_dev_attributes;
+ 
+ static void tpacpi_driver_event(const unsigned int hkey_event);
+ static void hotkey_driver_event(const unsigned int scancode);
++static void hotkey_poll_setup(const bool may_warn);
+ 
+ /* HKEY.MHKG() return bits */
+ #define TP_HOTKEY_TABLET_MASK (1 << 3)
+@@ -2264,6 +2266,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask)
+ 
+ 	rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
+ 							~hotkey_source_mask);
++	hotkey_poll_setup(true);
++
+ 	mutex_unlock(&hotkey_mutex);
+ 
+ 	return rc;
+@@ -2548,7 +2552,7 @@ static void hotkey_poll_stop_sync(void)
+ }
+ 
+ /* call with hotkey_mutex held */
+-static void hotkey_poll_setup(bool may_warn)
++static void hotkey_poll_setup(const bool may_warn)
+ {
+ 	const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
+ 	const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
+@@ -2579,7 +2583,7 @@ static void hotkey_poll_setup(bool may_warn)
+ 	}
+ }
+ 
+-static void hotkey_poll_setup_safe(bool may_warn)
++static void hotkey_poll_setup_safe(const bool may_warn)
+ {
+ 	mutex_lock(&hotkey_mutex);
+ 	hotkey_poll_setup(may_warn);
+@@ -2597,7 +2601,11 @@ static void hotkey_poll_set_freq(unsigned int freq)
+ 
+ #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+ 
+-static void hotkey_poll_setup_safe(bool __unused)
++static void hotkey_poll_setup(const bool __unused)
++{
++}
++
++static void hotkey_poll_setup_safe(const bool __unused)
+ {
+ }
+ 
+@@ -2607,16 +2615,11 @@ static int hotkey_inputdev_open(struct input_dev *dev)
+ {
+ 	switch (tpacpi_lifecycle) {
+ 	case TPACPI_LIFE_INIT:
+-		/*
+-		 * hotkey_init will call hotkey_poll_setup_safe
+-		 * at the appropriate moment
+-		 */
+-		return 0;
+-	case TPACPI_LIFE_EXITING:
+-		return -EBUSY;
+ 	case TPACPI_LIFE_RUNNING:
+ 		hotkey_poll_setup_safe(false);
+ 		return 0;
++	case TPACPI_LIFE_EXITING:
++		return -EBUSY;
+ 	}
+ 
+ 	/* Should only happen if tpacpi_lifecycle is corrupt */
+@@ -2627,7 +2630,7 @@ static int hotkey_inputdev_open(struct input_dev *dev)
+ static void hotkey_inputdev_close(struct input_dev *dev)
+ {
+ 	/* disable hotkey polling when possible */
+-	if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING &&
++	if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&
+ 	    !(hotkey_source_mask & hotkey_driver_mask))
+ 		hotkey_poll_setup_safe(false);
+ }
+@@ -3655,13 +3658,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
+ 			break;
+ 		case 3:
+ 			/* 0x3000-0x3FFF: bay-related wakeups */
+-			if (hkey == TP_HKEY_EV_BAYEJ_ACK) {
++			switch (hkey) {
++			case TP_HKEY_EV_BAYEJ_ACK:
+ 				hotkey_autosleep_ack = 1;
+ 				printk(TPACPI_INFO
+ 				       "bay ejected\n");
+ 				hotkey_wakeup_hotunplug_complete_notify_change();
+ 				known_ev = true;
+-			} else {
++				break;
++			case TP_HKEY_EV_OPTDRV_EJ:
++				/* FIXME: kick libata if SATA link offline */
++				known_ev = true;
++				break;
++			default:
+ 				known_ev = false;
+ 			}
+ 			break;
+@@ -3870,7 +3879,7 @@ enum {
+ 	TP_ACPI_BLUETOOTH_HWPRESENT	= 0x01,	/* Bluetooth hw available */
+ 	TP_ACPI_BLUETOOTH_RADIOSSW	= 0x02,	/* Bluetooth radio enabled */
+ 	TP_ACPI_BLUETOOTH_RESUMECTRL	= 0x04,	/* Bluetooth state at resume:
+-						   off / last state */
++						   0 = disable, 1 = enable */
+ };
+ 
+ enum {
+@@ -3916,10 +3925,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
+ 	}
+ #endif
+ 
+-	/* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
+-	status = TP_ACPI_BLUETOOTH_RESUMECTRL;
+ 	if (state == TPACPI_RFK_RADIO_ON)
+-		status |= TP_ACPI_BLUETOOTH_RADIOSSW;
++		status = TP_ACPI_BLUETOOTH_RADIOSSW
++			  | TP_ACPI_BLUETOOTH_RESUMECTRL;
++	else
++		status = 0;
+ 
+ 	if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
+ 		return -EIO;
+@@ -4070,7 +4080,7 @@ enum {
+ 	TP_ACPI_WANCARD_HWPRESENT	= 0x01,	/* Wan hw available */
+ 	TP_ACPI_WANCARD_RADIOSSW	= 0x02,	/* Wan radio enabled */
+ 	TP_ACPI_WANCARD_RESUMECTRL	= 0x04,	/* Wan state at resume:
+-						   off / last state */
++						   0 = disable, 1 = enable */
+ };
+ 
+ #define TPACPI_RFK_WWAN_SW_NAME		"tpacpi_wwan_sw"
+@@ -4107,10 +4117,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
+ 	}
+ #endif
+ 
+-	/* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
+-	status = TP_ACPI_WANCARD_RESUMECTRL;
+ 	if (state == TPACPI_RFK_RADIO_ON)
+-		status |= TP_ACPI_WANCARD_RADIOSSW;
++		status = TP_ACPI_WANCARD_RADIOSSW
++			 | TP_ACPI_WANCARD_RESUMECTRL;
++	else
++		status = 0;
+ 
+ 	if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
+ 		return -EIO;
+@@ -4619,6 +4630,10 @@ static int video_read(struct seq_file *m)
+ 		return 0;
+ 	}
+ 
++	/* Even reads can crash X.org, so... */
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++
+ 	status = video_outputsw_get();
+ 	if (status < 0)
+ 		return status;
+@@ -4652,6 +4667,10 @@ static int video_write(char *buf)
+ 	if (video_supported == TPACPI_VIDEO_NONE)
+ 		return -ENODEV;
+ 
++	/* Even reads can crash X.org, let alone writes... */
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++
+ 	enable = 0;
+ 	disable = 0;
+ 
+@@ -6133,13 +6152,13 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
+ 	TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC),	/* T43/p ATI */
+ 
+ 	/* Models with ATI GPUs that can use ECNVRAM */
+-	TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),
++	TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),	/* R50,51 T40-42 */
+ 	TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+-	TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
++	TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC),	/* R52 */
+ 	TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+ 
+ 	/* Models with Intel Extreme Graphics 2 */
+-	TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
++	TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),	/* X40 */
+ 	TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+ 	TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+ 
+@@ -6522,7 +6541,8 @@ static int volume_set_status(const u8 status)
+ 	return volume_set_status_ec(status);
+ }
+ 
+-static int volume_set_mute_ec(const bool mute)
++/* returns < 0 on error, 0 on no change, 1 on change */
++static int __volume_set_mute_ec(const bool mute)
+ {
+ 	int rc;
+ 	u8 s, n;
+@@ -6537,22 +6557,37 @@ static int volume_set_mute_ec(const bool mute)
+ 	n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
+ 		     s & ~TP_EC_AUDIO_MUTESW_MSK;
+ 
+-	if (n != s)
++	if (n != s) {
+ 		rc = volume_set_status_ec(n);
++		if (!rc)
++			rc = 1;
++	}
+ 
+ unlock:
+ 	mutex_unlock(&volume_mutex);
+ 	return rc;
+ }
+ 
++static int volume_alsa_set_mute(const bool mute)
++{
++	dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",
++		   (mute) ? "" : "un");
++	return __volume_set_mute_ec(mute);
++}
++
+ static int volume_set_mute(const bool mute)
+ {
++	int rc;
++
+ 	dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
+ 		   (mute) ? "" : "un");
+-	return volume_set_mute_ec(mute);
++
++	rc = __volume_set_mute_ec(mute);
++	return (rc < 0) ? rc : 0;
+ }
+ 
+-static int volume_set_volume_ec(const u8 vol)
++/* returns < 0 on error, 0 on no change, 1 on change */
++static int __volume_set_volume_ec(const u8 vol)
+ {
+ 	int rc;
+ 	u8 s, n;
+@@ -6569,19 +6604,22 @@ static int volume_set_volume_ec(const u8 vol)
+ 
+ 	n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
+ 
+-	if (n != s)
++	if (n != s) {
+ 		rc = volume_set_status_ec(n);
++		if (!rc)
++			rc = 1;
++	}
+ 
+ unlock:
+ 	mutex_unlock(&volume_mutex);
+ 	return rc;
+ }
+ 
+-static int volume_set_volume(const u8 vol)
++static int volume_alsa_set_volume(const u8 vol)
+ {
+ 	dbg_printk(TPACPI_DBG_MIXER,
+-		   "trying to set volume level to %hu\n", vol);
+-	return volume_set_volume_ec(vol);
++		   "ALSA: trying to set volume level to %hu\n", vol);
++	return __volume_set_volume_ec(vol);
+ }
+ 
+ static void volume_alsa_notify_change(void)
+@@ -6628,7 +6666,7 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
+ static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
+ 				struct snd_ctl_elem_value *ucontrol)
+ {
+-	return volume_set_volume(ucontrol->value.integer.value[0]);
++	return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
+ }
+ 
+ #define volume_alsa_mute_info snd_ctl_boolean_mono_info
+@@ -6651,7 +6689,7 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
+ static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
+ 				struct snd_ctl_elem_value *ucontrol)
+ {
+-	return volume_set_mute(!ucontrol->value.integer.value[0]);
++	return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
+ }
+ 
+ static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
+@@ -8477,9 +8515,10 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
+ 		"%s installed\n", ibm->name);
+ 
+ 	if (ibm->read) {
+-		mode_t mode;
++		mode_t mode = iibm->base_procfs_mode;
+ 
+-		mode = S_IRUGO;
++		if (!mode)
++			mode = S_IRUGO;
+ 		if (ibm->write)
+ 			mode |= S_IWUSR;
+ 		entry = proc_create_data(ibm->name, mode, proc_dir,
+@@ -8670,6 +8709,7 @@ static struct ibm_init_struct ibms_init[] __initdata = {
+ #ifdef CONFIG_THINKPAD_ACPI_VIDEO
+ 	{
+ 		.init = video_init,
++		.base_procfs_mode = S_IRUSR,
+ 		.data = &video_driver_data,
+ 	},
+ #endif
+@@ -9032,6 +9072,9 @@ static int __init thinkpad_acpi_module_init(void)
+ 			return ret;
+ 		}
+ 	}
++
++	tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
++
+ 	ret = input_register_device(tpacpi_inputdev);
+ 	if (ret < 0) {
+ 		printk(TPACPI_ERR "unable to register input device\n");
+@@ -9041,7 +9084,6 @@ static int __init thinkpad_acpi_module_init(void)
+ 		tp_features.input_device_registered = 1;
+ 	}
+ 
+-	tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
+index be5a6b7..40845c7 100644
+--- a/drivers/rtc/class.c
++++ b/drivers/rtc/class.c
+@@ -226,6 +226,7 @@ static void __exit rtc_exit(void)
+ {
+ 	rtc_dev_exit();
+ 	class_destroy(rtc_class);
++	idr_destroy(&rtc_idr);
+ }
+ 
+ subsys_initcall(rtc_init);
+diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
+index 03ea530..44c4399 100644
+--- a/drivers/rtc/rtc-coh901331.c
++++ b/drivers/rtc/rtc-coh901331.c
+@@ -271,12 +271,13 @@ static int coh901331_resume(struct platform_device *pdev)
+ {
+ 	struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
+ 
+-	if (device_may_wakeup(&pdev->dev))
++	if (device_may_wakeup(&pdev->dev)) {
+ 		disable_irq_wake(rtap->irq);
+-	else
++	} else {
+ 		clk_enable(rtap->clk);
+ 		writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
+ 		clk_disable(rtap->clk);
++	}
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+index efabea1..cd55176 100644
+--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
++++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+@@ -5998,6 +5998,8 @@ _scsih_remove(struct pci_dev *pdev)
+ 	struct _sas_port *mpt2sas_port;
+ 	struct _sas_device *sas_device;
+ 	struct _sas_node *expander_sibling;
++	struct _raid_device *raid_device, *next;
++	struct MPT2SAS_TARGET *sas_target_priv_data;
+ 	struct workqueue_struct	*wq;
+ 	unsigned long flags;
+ 
+@@ -6011,6 +6013,21 @@ _scsih_remove(struct pci_dev *pdev)
+ 	if (wq)
+ 		destroy_workqueue(wq);
+ 
++	/* release all the volumes */
++	list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
++	    list) {
++		if (raid_device->starget) {
++			sas_target_priv_data =
++			    raid_device->starget->hostdata;
++			sas_target_priv_data->deleted = 1;
++			scsi_remove_target(&raid_device->starget->dev);
++		}
++		printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
++		    "(0x%016llx)\n", ioc->name,  raid_device->handle,
++		    (unsigned long long) raid_device->wwid);
++		_scsih_raid_device_remove(ioc, raid_device);
++	}
++
+ 	/* free ports attached to the sas_host */
+  retry_again:
+ 	list_for_each_entry(mpt2sas_port,
+diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
+index 8371d91..49ac414 100644
+--- a/drivers/scsi/qla1280.c
++++ b/drivers/scsi/qla1280.c
+@@ -1640,8 +1640,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
+ 	uint16_t mb[MAILBOX_REGISTER_COUNT], i;
+ 	int err;
+ 
++	spin_unlock_irq(ha->host->host_lock);
+ 	err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
+ 			       &ha->pdev->dev);
++	spin_lock_irq(ha->host->host_lock);
+ 	if (err) {
+ 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ 		       ql1280_board_tbl[ha->devnum].fwname, err);
+@@ -1699,8 +1701,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
+ 		return -ENOMEM;
+ #endif
+ 
++	spin_unlock_irq(ha->host->host_lock);
+ 	err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
+ 			       &ha->pdev->dev);
++	spin_lock_irq(ha->host->host_lock);
+ 	if (err) {
+ 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ 		       ql1280_board_tbl[ha->devnum].fwname, err);
+diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
+index 60d665a..d00fcf8 100644
+--- a/drivers/serial/imx.c
++++ b/drivers/serial/imx.c
+@@ -1279,7 +1279,7 @@ static int serial_imx_probe(struct platform_device *pdev)
+ 		sport->use_irda = 1;
+ #endif
+ 
+-	if (pdata->init) {
++	if (pdata && pdata->init) {
+ 		ret = pdata->init(pdev);
+ 		if (ret)
+ 			goto clkput;
+@@ -1292,7 +1292,7 @@ static int serial_imx_probe(struct platform_device *pdev)
+ 
+ 	return 0;
+ deinit:
+-	if (pdata->exit)
++	if (pdata && pdata->exit)
+ 		pdata->exit(pdev);
+ clkput:
+ 	clk_put(sport->clk);
+@@ -1321,7 +1321,7 @@ static int serial_imx_remove(struct platform_device *pdev)
+ 
+ 	clk_disable(sport->clk);
+ 
+-	if (pdata->exit)
++	if (pdata && pdata->exit)
+ 		pdata->exit(pdev);
+ 
+ 	iounmap(sport->port.membase);
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+index fc2e963..ed77d88 100644
+--- a/drivers/staging/Kconfig
++++ b/drivers/staging/Kconfig
+@@ -81,8 +81,6 @@ source "drivers/staging/rtl8192u/Kconfig"
+ 
+ source "drivers/staging/rtl8192e/Kconfig"
+ 
+-source "drivers/staging/mimio/Kconfig"
+-
+ source "drivers/staging/frontier/Kconfig"
+ 
+ source "drivers/staging/dream/Kconfig"
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
+index b5e67b8..6035bff 100644
+--- a/drivers/staging/Makefile
++++ b/drivers/staging/Makefile
+@@ -23,7 +23,6 @@ obj-$(CONFIG_R8187SE)		+= rtl8187se/
+ obj-$(CONFIG_RTL8192SU)		+= rtl8192su/
+ obj-$(CONFIG_RTL8192U)		+= rtl8192u/
+ obj-$(CONFIG_RTL8192E)		+= rtl8192e/
+-obj-$(CONFIG_INPUT_MIMIO)	+= mimio/
+ obj-$(CONFIG_TRANZPORT)		+= frontier/
+ obj-$(CONFIG_DREAM)		+= dream/
+ obj-$(CONFIG_POHMELFS)		+= pohmelfs/
+diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
+index 894eecf..6acc49a 100644
+--- a/drivers/staging/hv/vmbus_drv.c
++++ b/drivers/staging/hv/vmbus_drv.c
+@@ -24,6 +24,8 @@
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+ #include <linux/sysctl.h>
++#include <linux/pci.h>
++#include <linux/dmi.h>
+ #include "osd.h"
+ #include "logging.h"
+ #include "vmbus.h"
+@@ -946,6 +948,19 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
+ 	}
+ }
+ 
++static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
++	{
++		.ident = "Hyper-V",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
++			DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
++		},
++	},
++	{ },
++};
++MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
++
+ static int __init vmbus_init(void)
+ {
+ 	int ret = 0;
+@@ -957,6 +972,9 @@ static int __init vmbus_init(void)
+ 		vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
+ 	/* Todo: it is used for loglevel, to be ported to new kernel. */
+ 
++	if (!dmi_check_system(microsoft_hv_dmi_table))
++		return -ENODEV;
++
+ 	ret = vmbus_bus_init(VmbusInitialize);
+ 
+ 	DPRINT_EXIT(VMBUS_DRV);
+@@ -973,6 +991,18 @@ static void __exit vmbus_exit(void)
+ 	return;
+ }
+ 
++/*
++ * We use a PCI table to determine if we should autoload this driver  This is
++ * needed by distro tools to determine if the hyperv drivers should be
++ * installed and/or configured.  We don't do anything else with the table, but
++ * it needs to be present.
++ */
++const static struct pci_device_id microsoft_hv_pci_table[] = {
++	{ PCI_DEVICE(0x1414, 0x5353) },	/* VGA compatible controller */
++	{ 0 }
++};
++MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
++
+ MODULE_LICENSE("GPL");
+ module_param(vmbus_irq, int, S_IRUGO);
+ module_param(vmbus_loglevel, int, S_IRUGO);
+diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig
+deleted file mode 100644
+index 505dcb2..0000000
+--- a/drivers/staging/mimio/Kconfig
++++ /dev/null
+@@ -1,10 +0,0 @@
+-config INPUT_MIMIO
+-	tristate "Mimio Xi interactive whiteboard support"
+-	depends on USB && INPUT
+-	default N
+-	help
+-	  Say Y here if you want to use a Mimio Xi interactive
+-	  whiteboard device.
+-
+-	  To compile this driver as a module, choose M here: the
+-	  module will be called mimio.
+diff --git a/drivers/staging/mimio/Makefile b/drivers/staging/mimio/Makefile
+deleted file mode 100644
+index 77807ee..0000000
+--- a/drivers/staging/mimio/Makefile
++++ /dev/null
+@@ -1 +0,0 @@
+-obj-$(CONFIG_INPUT_MIMIO)	+= mimio.o
+diff --git a/drivers/staging/mimio/mimio.c b/drivers/staging/mimio/mimio.c
+deleted file mode 100644
+index 1ba8103..0000000
+--- a/drivers/staging/mimio/mimio.c
++++ /dev/null
+@@ -1,914 +0,0 @@
+-/*
+- * Hardware event => input event mapping:
+- *
+- *
+- *
+- input.h:#define BTN_TOOL_PEN            0x140 black
+- input.h:#define BTN_TOOL_RUBBER         0x141 blue
+- input.h:#define BTN_TOOL_BRUSH          0x142 green
+- input.h:#define BTN_TOOL_PENCIL         0x143 red
+- input.h:#define BTN_TOOL_AIRBRUSH       0x144 eraser
+- input.h:#define BTN_TOOL_FINGER         0x145 small eraser
+- input.h:#define BTN_TOOL_MOUSE          0x146 mimio interactive
+- input.h:#define BTN_TOOL_LENS           0x147 mimio interactive but1
+- input.h:#define LOCALBTN_TOOL_EXTRA1    0x14a mimio interactive but2 == BTN_TOUCH
+- input.h:#define LOCALBTN_TOOL_EXTRA2    0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS
+- input.h:#define LOCALBTN_TOOL_EXTRA3    0x14c unused == BTN_STYLUS2
+- input.h:#define BTN_TOOL_DOUBLETAP      0x14d unused
+- input.h:#define BTN_TOOL_TRIPLETAP      0x14e unused
+- *
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_K)     => EV_KEY BIT(BTN_TOOL_PEN)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_B)     => EV_KEY BIT(BTN_TOOL_RUBBER)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_G)     => EV_KEY BIT(BTN_TOOL_BRUSH)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_R)     => EV_KEY BIT(BTN_TOOL_PENCIL)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_E)     => EV_KEY BIT(BTN_TOOL_AIRBRUSH)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_ES)    => EV_KEY BIT(BTN_TOOL_FINGER)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_I)     => EV_KEY BIT(BTN_TOOL_MOUSE)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_IL)    => EV_KEY BIT(BTN_TOOL_LENS)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_IR)    => EV_KEY BIT(BTN_TOOL_DOUBLETAP)
+- * MIMIO_EV_PENDOWN(MIMIO_PEN_EX)    => EV_KEY BIT(BTN_TOOL_TRIPLETAP)
+- * MIMIO_EV_PENDATA                 => EV_ABS BIT(ABS_X), BIT(ABS_Y)
+- * MIMIO_EV_MEMRESET              => EV_KEY BIT(BTN_0)
+- * MIMIO_EV_ACC(ACC_NEWPAGE)       => EV_KEY BIT(BTN_1)
+- * MIMIO_EV_ACC(ACC_TAGPAGE)      => EV_KEY BIT(BTN_2)
+- * MIMIO_EV_ACC(ACC_PRINTPAGE)      => EV_KEY BIT(BTN_3)
+- * MIMIO_EV_ACC(ACC_MAXIMIZE)      => EV_KEY BIT(BTN_4)
+- * MIMIO_EV_ACC(ACC_FINDCTLPNL)      => EV_KEY BIT(BTN_5)
+- *
+- *
+- * open issues:
+- *      - cold-load of data captured when mimio in standalone mode not yet
+- *         supported; need to snoop Win32 box to see datastream for this.
+- *       - mimio mouse not yet supported; need to snoop Win32 box to see the
+- *         datastream for this.
+- */
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/spinlock.h>
+-#include <linux/input.h>
+-#include <linux/usb.h>
+-
+-#define DRIVER_VERSION		"v0.031"
+-#define DRIVER_AUTHOR		"mwilder at cs.nmsu.edu"
+-#define DRIVER_DESC		"USB mimio-xi driver"
+-
+-enum {UPVALUE, DOWNVALUE, MOVEVALUE};
+-
+-#define MIMIO_XRANGE_MAX	9600
+-#define MIMIO_YRANGE_MAX	4800
+-
+-#define LOCALBTN_TOOL_EXTRA1	BTN_TOUCH
+-#define LOCALBTN_TOOL_EXTRA2	BTN_STYLUS
+-#define LOCALBTN_TOOL_EXTRA3	BTN_STYLUS2
+-
+-#define MIMIO_VENDOR_ID		0x08d3
+-#define MIMIO_PRODUCT_ID	0x0001
+-#define MIMIO_MAXPAYLOAD	(8)
+-#define MIMIO_MAXNAMELEN	(64)
+-#define MIMIO_TXWAIT		(1)
+-#define MIMIO_TXDONE		(2)
+-
+-#define MIMIO_EV_PENDOWN	(0x22)
+-#define MIMIO_EV_PENDATA	(0x24)
+-#define MIMIO_EV_PENUP		(0x51)
+-#define MIMIO_EV_MEMRESET	(0x45)
+-#define MIMIO_EV_ACC		(0xb2)
+-
+-#define MIMIO_PEN_K		(1)	/* black pen */
+-#define MIMIO_PEN_B		(2)	/* blue pen */
+-#define MIMIO_PEN_G		(3)	/* green pen */
+-#define MIMIO_PEN_R		(4)	/* red pen */
+-/* 5, 6, 7, 8 are extra pens */
+-#define MIMIO_PEN_E		(9)	/* big eraser */
+-#define MIMIO_PEN_ES		(10)	/* lil eraser */
+-#define MIMIO_PENJUMP_START	(10)
+-#define MIMIO_PENJUMP		(6)
+-#define MIMIO_PEN_I		(17)	/* mimio interactive */
+-#define MIMIO_PEN_IL		(18)	/* mimio interactive button 1 */
+-#define MIMIO_PEN_IR		(19)	/* mimio interactive button 2 */
+-
+-#define MIMIO_PEN_MAX		(MIMIO_PEN_IR)
+-
+-#define ACC_DONE		(0)
+-#define ACC_NEWPAGE		(1)
+-#define ACC_TAGPAGE		(2)
+-#define ACC_PRINTPAGE		(4)
+-#define ACC_MAXIMIZE		(8)
+-#define ACC_FINDCTLPNL		(16)
+-
+-#define isvalidtxsize(n)	((n) > 0 && (n) <= MIMIO_MAXPAYLOAD)
+-
+-
+-struct pktbuf {
+-	unsigned char instr;
+-	unsigned char buf[16];
+-	unsigned char *p;
+-	unsigned char *q;
+-};
+-
+-struct usbintendpt {
+-	dma_addr_t dma;
+-	struct urb *urb;
+-	unsigned char *buf;
+-	struct usb_endpoint_descriptor *desc;
+-};
+-
+-struct mimio {
+-	struct input_dev *idev;
+-	struct usb_device *udev;
+-	struct usb_interface *uifc;
+-	int open;
+-	int present;
+-	int greeted;
+-	int txflags;
+-	char phys[MIMIO_MAXNAMELEN];
+-	struct usbintendpt in;
+-	struct usbintendpt out;
+-	struct pktbuf pktbuf;
+-	unsigned char minor;
+-	wait_queue_head_t waitq;
+-	spinlock_t txlock;
+-	void (*rxhandler)(struct mimio *, unsigned char *, unsigned int);
+-	int last_pen_down;
+-};
+-
+-static void mimio_close(struct input_dev *);
+-static void mimio_dealloc(struct mimio *);
+-static void mimio_disconnect(struct usb_interface *);
+-static int mimio_greet(struct mimio *);
+-static void mimio_irq_in(struct urb *);
+-static void mimio_irq_out(struct urb *);
+-static int mimio_open(struct input_dev *);
+-static int mimio_probe(struct usb_interface *, const struct usb_device_id *);
+-static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int);
+-static int mimio_tx(struct mimio *, const char *, int);
+-
+-static char mimio_name[] = "VirtualInk mimio-Xi";
+-static struct usb_device_id mimio_table [] = {
+-	{ USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) },
+-	{ USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */
+-	{ }
+-};
+-
+-MODULE_DEVICE_TABLE(usb, mimio_table);
+-
+-static struct usb_driver mimio_driver = {
+-	.name = "mimio",
+-	.probe = mimio_probe,
+-	.disconnect = mimio_disconnect,
+-	.id_table = mimio_table,
+-};
+-
+-static DECLARE_MUTEX(disconnect_sem);
+-
+-static void mimio_close(struct input_dev *idev)
+-{
+-	struct mimio *mimio;
+-
+-	mimio = input_get_drvdata(idev);
+-	if (!mimio) {
+-		dev_err(&idev->dev, "null mimio attached to input device\n");
+-		return;
+-	}
+-
+-	if (mimio->open <= 0)
+-		dev_err(&idev->dev, "mimio not open.\n");
+-	else
+-		mimio->open--;
+-
+-	if (mimio->present == 0 && mimio->open == 0)
+-		mimio_dealloc(mimio);
+-}
+-
+-static void mimio_dealloc(struct mimio *mimio)
+-{
+-	if (mimio == NULL)
+-		return;
+-
+-	usb_kill_urb(mimio->in.urb);
+-
+-	usb_kill_urb(mimio->out.urb);
+-
+-	if (mimio->idev) {
+-		input_unregister_device(mimio->idev);
+-		if (mimio->idev->grab)
+-			input_close_device(mimio->idev->grab);
+-		else
+-			dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL"
+-				" -- didn't call input_close_device\n");
+-	}
+-
+-	usb_free_urb(mimio->in.urb);
+-
+-	usb_free_urb(mimio->out.urb);
+-
+-	if (mimio->in.buf) {
+-		usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf,
+-				mimio->in.dma);
+-	}
+-
+-	if (mimio->out.buf)
+-		usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf,
+-				mimio->out.dma);
+-
+-	if (mimio->idev)
+-		input_free_device(mimio->idev);
+-
+-	kfree(mimio);
+-}
+-
+-static void mimio_disconnect(struct usb_interface *ifc)
+-{
+-	struct mimio *mimio;
+-
+-	down(&disconnect_sem);
+-
+-	mimio = usb_get_intfdata(ifc);
+-	usb_set_intfdata(ifc, NULL);
+-	dev_dbg(&mimio->idev->dev, "disconnect\n");
+-
+-	if (mimio) {
+-		mimio->present = 0;
+-
+-		if (mimio->open <= 0)
+-			mimio_dealloc(mimio);
+-	}
+-
+-	up(&disconnect_sem);
+-}
+-
+-static int mimio_greet(struct mimio *mimio)
+-{
+-	const struct grtpkt {
+-		int nbytes;
+-		unsigned delay;
+-		char data[8];
+-	} grtpkts[] = {
+-		{ 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } },
+-		{ 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } },
+-		{ 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } },
+-		{ 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+-		{ 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } },
+-		{ 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+-	};
+-	int rslt;
+-	const struct grtpkt *pkt;
+-
+-	for (pkt = grtpkts; pkt->nbytes; pkt++) {
+-		rslt = mimio_tx(mimio, pkt->data, pkt->nbytes);
+-		if (rslt)
+-			return rslt;
+-		if (pkt->delay)
+-			msleep(pkt->delay);
+-	}
+-
+-	return 0;
+-}
+-
+-static void mimio_irq_in(struct urb *urb)
+-{
+-	int rslt;
+-	char *data;
+-	const char *reason = "going down";
+-	struct mimio *mimio;
+-
+-	mimio = urb->context;
+-
+-	if (mimio == NULL)
+-		/* paranoia */
+-		return;
+-
+-	switch (urb->status) {
+-	case 0:
+-		/* success */
+-		break;
+-	case -ETIMEDOUT:
+-		reason = "timeout -- unplugged?";
+-	case -ECONNRESET:
+-	case -ENOENT:
+-	case -ESHUTDOWN:
+-		dev_dbg(&mimio->idev->dev, "%s.\n", reason);
+-		return;
+-	default:
+-		dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n",
+-			urb->status);
+-		goto exit;
+-	}
+-	data = mimio->in.buf;
+-
+-	if (mimio->rxhandler)
+-		mimio->rxhandler(mimio, data, urb->actual_length);
+-exit:
+-	/*
+-	 * Keep listening to device on same urb.
+-	 */
+-	rslt = usb_submit_urb(urb, GFP_ATOMIC);
+-	if (rslt)
+-		dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
+-			rslt);
+-}
+-
+-static void mimio_irq_out(struct urb *urb)
+-{
+-	unsigned long flags;
+-	struct mimio *mimio;
+-
+-	mimio = urb->context;
+-
+-	if (urb->status)
+-		dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status);
+-
+-	spin_lock_irqsave(&mimio->txlock, flags);
+-	mimio->txflags |= MIMIO_TXDONE;
+-	spin_unlock_irqrestore(&mimio->txlock, flags);
+-	wmb();
+-	wake_up(&mimio->waitq);
+-}
+-
+-static int mimio_open(struct input_dev *idev)
+-{
+-	int rslt;
+-	struct mimio *mimio;
+-
+-	rslt = 0;
+-	down(&disconnect_sem);
+-	mimio = input_get_drvdata(idev);
+-	dev_dbg(&idev->dev, "mimio_open\n");
+-
+-	if (mimio == NULL) {
+-		dev_err(&idev->dev, "null mimio.\n");
+-		rslt = -ENODEV;
+-		goto exit;
+-	}
+-
+-	if (mimio->open++)
+-		goto exit;
+-
+-	if (mimio->present && !mimio->greeted) {
+-		struct urb *urb = mimio->in.urb;
+-		mimio->in.urb->dev = mimio->udev;
+-		rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
+-		if (rslt) {
+-			dev_err(&idev->dev, "usb_submit_urb failure "
+-				"(res = %d: %s). Not greeting.\n",
+-				rslt,
+-				(!urb ? "urb is NULL" :
+-				 (urb->hcpriv ? "urb->hcpriv is non-NULL" :
+-				  (!urb->complete ? "urb is not complete" :
+-				   (urb->number_of_packets <= 0 ? "urb has no packets" :
+-				    (urb->interval <= 0 ? "urb interval too small" :
+-				     "urb interval too large or some other error"))))));
+-			rslt = -EIO;
+-			goto exit;
+-		}
+-		rslt = mimio_greet(mimio);
+-		if (rslt == 0) {
+-			dev_dbg(&idev->dev, "Mimio greeted OK.\n");
+-			mimio->greeted = 1;
+-		} else {
+-			dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n",
+-				rslt);
+-		}
+-	}
+-
+-exit:
+-	up(&disconnect_sem);
+-	return rslt;
+-}
+-
+-static int mimio_probe(struct usb_interface *ifc,
+-		       const struct usb_device_id *id)
+-{
+-	char path[64];
+-	int pipe, maxp;
+-	struct mimio *mimio;
+-	struct usb_device *udev;
+-	struct usb_host_interface *hostifc;
+-	struct input_dev *input_dev;
+-	int res = 0;
+-	int i;
+-
+-	udev = interface_to_usbdev(ifc);
+-
+-	mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL);
+-	if (!mimio)
+-		return -ENOMEM;
+-
+-	input_dev = input_allocate_device();
+-	if (!input_dev) {
+-		mimio_dealloc(mimio);
+-		return -ENOMEM;
+-	}
+-
+-	mimio->uifc = ifc;
+-	mimio->udev = udev;
+-	mimio->pktbuf.p = mimio->pktbuf.buf;
+-	mimio->pktbuf.q = mimio->pktbuf.buf;
+-	/* init_input_dev(mimio->idev); */
+-	mimio->idev = input_dev;
+-	init_waitqueue_head(&mimio->waitq);
+-	spin_lock_init(&mimio->txlock);
+-	hostifc = ifc->cur_altsetting;
+-
+-	if (hostifc->desc.bNumEndpoints != 2) {
+-		dev_err(&udev->dev, "Unexpected endpoint count: %d.\n",
+-			hostifc->desc.bNumEndpoints);
+-		mimio_dealloc(mimio);
+-		return -ENODEV;
+-	}
+-
+-	mimio->in.desc = &(hostifc->endpoint[0].desc);
+-	mimio->out.desc = &(hostifc->endpoint[1].desc);
+-
+-	mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
+-					 &mimio->in.dma);
+-	mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
+-					  &mimio->out.dma);
+-
+-	if (mimio->in.buf == NULL || mimio->out.buf == NULL) {
+-		dev_err(&udev->dev, "usb_buffer_alloc failure.\n");
+-		mimio_dealloc(mimio);
+-		return -ENOMEM;
+-	}
+-
+-	mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL);
+-	mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL);
+-
+-	if (mimio->in.urb == NULL || mimio->out.urb == NULL) {
+-		dev_err(&udev->dev, "usb_alloc_urb failure.\n");
+-		mimio_dealloc(mimio);
+-		return -ENOMEM;
+-	}
+-
+-	/*
+-	 * Build the input urb.
+-	 */
+-	pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress);
+-	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+-	if (maxp > MIMIO_MAXPAYLOAD)
+-		maxp = MIMIO_MAXPAYLOAD;
+-	usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp,
+-			 mimio_irq_in, mimio, mimio->in.desc->bInterval);
+-	mimio->in.urb->transfer_dma = mimio->in.dma;
+-	mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+-
+-	/*
+-	 * Build the output urb.
+-	 */
+-	pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress);
+-	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+-	if (maxp > MIMIO_MAXPAYLOAD)
+-		maxp = MIMIO_MAXPAYLOAD;
+-	usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp,
+-			 mimio_irq_out, mimio, mimio->out.desc->bInterval);
+-	mimio->out.urb->transfer_dma = mimio->out.dma;
+-	mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+-
+-	/*
+-	 * Build input device info
+-	 */
+-	usb_make_path(udev, path, 64);
+-	snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path);
+-	input_set_drvdata(input_dev, mimio);
+-	/* input_dev->dev = &ifc->dev; */
+-	input_dev->open = mimio_open;
+-	input_dev->close = mimio_close;
+-	input_dev->name = mimio_name;
+-	input_dev->phys = mimio->phys;
+-	input_dev->dev.parent = &ifc->dev;
+-
+-	input_dev->id.bustype = BUS_USB;
+-	input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+-	input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct);
+-	input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice);
+-
+-	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
+-	for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i)
+-		set_bit(i, input_dev->keybit);
+-
+-	input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
+-						 BIT_MASK(BTN_1) |
+-						 BIT_MASK(BTN_2) |
+-						 BIT_MASK(BTN_3) |
+-						 BIT_MASK(BTN_4) |
+-						 BIT_MASK(BTN_5);
+-	/*   input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */
+-	input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+-	input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0);
+-	input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0);
+-	input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
+-
+-#if 0
+-	input_dev->absmin[ABS_X] = 0;
+-	input_dev->absmin[ABS_Y] = 0;
+-	input_dev->absmax[ABS_X] = 9600;
+-	input_dev->absmax[ABS_Y] = 4800;
+-	input_dev->absfuzz[ABS_X] = 0;
+-	input_dev->absfuzz[ABS_Y] = 0;
+-	input_dev->absflat[ABS_X] = 0;
+-	input_dev->absflat[ABS_Y] = 0;
+-#endif
+-
+-#if 0
+-	/* this will just reduce the precision */
+-	input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */
+-	input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */
+-#endif
+-
+-	/*
+-	 * Register the input device.
+-	 */
+-	res = input_register_device(mimio->idev);
+-	if (res) {
+-		dev_err(&udev->dev, "input_register_device failure (%d)\n",
+-			res);
+-		mimio_dealloc(mimio);
+-		return -EIO;
+-	}
+-	dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n",
+-		input_dev->name, input_dev->phys, res);
+-
+-	usb_set_intfdata(ifc, mimio);
+-	mimio->present = 1;
+-
+-	/*
+-	 * Submit the input urb to the usb subsystem.
+-	 */
+-	mimio->in.urb->dev = mimio->udev;
+-	res = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
+-	if (res) {
+-		dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n",
+-			res);
+-		mimio_dealloc(mimio);
+-		return -EIO;
+-	}
+-
+-	/*
+-	 * Attempt to greet the mimio after giving
+-	 * it some post-init settling time.
+-	 *
+-	 * note: sometimes this sleep interval isn't
+-	 * long enough to permit the device to re-init
+-	 * after a hot-swap; maybe need to bump it up.
+-	 *
+-	 * As it is, this probably breaks module unloading support!
+-	 */
+-	msleep(1024);
+-
+-	res = mimio_greet(mimio);
+-	if (res == 0) {
+-		dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n");
+-		mimio->greeted = 1;
+-		mimio->rxhandler = mimio_rx_handler;
+-	} else {
+-		dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res);
+-	}
+-
+-	return 0;
+-}
+-
+-static int handle_mimio_rx_penupdown(struct mimio *mimio,
+-				     int down,
+-				     const char *const instr[],
+-				     const int instr_ofst[])
+-{
+-	int penid, x;
+-	if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3))
+-		return 1; 		/* partial pkt */
+-
+-	if (down) {
+-		x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
+-			*(mimio->pktbuf.p + 2);
+-		if (x != *(mimio->pktbuf.p + 3)) {
+-			dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n",
+-				down ? "DOWN":"UP");
+-			/* skip this event data */
+-			mimio->pktbuf.p += 4;
+-			/* decode any remaining events */
+-			return 0;
+-		}
+-		penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2);
+-		if (penid > MIMIO_PEN_MAX) {
+-			dev_dbg(&mimio->idev->dev,
+-				"Unmapped penID (not in [0, %d]): %d\n",
+-				MIMIO_PEN_MAX, (int)mimio->pktbuf.instr);
+-			penid = mimio->pktbuf.instr = 0;
+-		}
+-		mimio->last_pen_down = penid;
+-	} else {
+-		penid = mimio->last_pen_down;
+-	}
+-	dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid],
+-		instr_ofst[penid], penid, down ? "down" : "up");
+-
+-	if (instr_ofst[penid] >= 0) {
+-		int code = BTN_TOOL_PEN + instr_ofst[penid];
+-		int value = down ? DOWNVALUE : UPVALUE;
+-		if (code > KEY_MAX)
+-			dev_dbg(&mimio->idev->dev, "input_event will ignore "
+-				"-- code (%d) > KEY_MAX\n", code);
+-		if (!test_bit(code, mimio->idev->keybit))
+-			dev_dbg(&mimio->idev->dev, "input_event will ignore "
+-				"-- bit for code (%d) not enabled\n", code);
+-		if (!!test_bit(code, mimio->idev->key) == value)
+-			dev_dbg(&mimio->idev->dev, "input_event will ignore "
+-				"-- bit for code (%d) already set to %d\n",
+-				code, value);
+-		if (value != DOWNVALUE) {
+-			/* input_regs(mimio->idev, regs); */
+-			input_report_key(mimio->idev, code, value);
+-			input_sync(mimio->idev);
+-		} else {
+-			/* wait until we get some coordinates */
+-		}
+-	} else {
+-		dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 "
+-			"- not sending\n", penid, instr_ofst[penid]);
+-	}
+-	mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */
+-	return 0;
+-}
+-
+-/*
+- * Stay tuned for partial-packet excitement.
+- *
+- * This routine buffers data packets received from the mimio device
+- * in the mimio's data space.  This buffering is necessary because
+- * the mimio's in endpoint can serve us partial packets of data, and
+- * we want the driver to support the servicing of multiple mimios.
+- * Empirical evidence gathered so far suggests that the method of
+- * buffering packet data in the mimio's data space works.  Previous
+- * versions of this driver did not buffer packet data in each mimio's
+- * data-space, and were therefore not able to service multiple mimios.
+- * Note that since the caller of this routine is running in interrupt
+- * context, care needs to be taken to ensure that this routine does not
+- * become bloated, and it may be that another spinlock is needed in each
+- * mimio to guard the buffered packet data properly.
+- */
+-static void mimio_rx_handler(struct mimio *mimio,
+-			     unsigned char *data,
+-			     unsigned int nbytes)
+-{
+-	struct device *dev = &mimio->idev->dev;
+-	unsigned int x;
+-	unsigned int y;
+-	static const char * const instr[] = {
+-		"?0",
+-		"black pen", "blue pen", "green pen", "red pen",
+-		"brown pen", "orange pen", "purple pen", "yellow pen",
+-		"big eraser", "lil eraser",
+-		"?11", "?12", "?13", "?14", "?15", "?16",
+-		"mimio interactive", "interactive button1",
+-		"interactive button2"
+-	};
+-
+-	/* Mimio Interactive gives:
+-	 * down: [0x22 0x01 0x11 0x32 0x24]
+-	 * b1  : [0x22 0x01 0x12 0x31 0x24]
+-	 * b2  : [0x22 0x01 0x13 0x30 0x24]
+-	 */
+-	static const int instr_ofst[] = {
+-		-1,
+-		0, 1, 2, 3,
+-		9, 9, 9, 9,
+-		4, 5,
+-		-1, -1, -1, -1, -1, -1,
+-		6, 7, 8,
+-	};
+-
+-	memcpy(mimio->pktbuf.q, data, nbytes);
+-	mimio->pktbuf.q += nbytes;
+-
+-	while (mimio->pktbuf.p < mimio->pktbuf.q) {
+-		int t = *mimio->pktbuf.p;
+-		switch (t) {
+-		case MIMIO_EV_PENUP:
+-		case MIMIO_EV_PENDOWN:
+-			if (handle_mimio_rx_penupdown(mimio,
+-						      t == MIMIO_EV_PENDOWN,
+-						      instr, instr_ofst))
+-				return; /* partial packet */
+-			break;
+-
+-		case MIMIO_EV_PENDATA:
+-			if (mimio->pktbuf.q - mimio->pktbuf.p < 6)
+-				/* partial pkt */
+-				return;
+-			x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
+-				*(mimio->pktbuf.p + 2) ^
+-				*(mimio->pktbuf.p + 3) ^
+-				*(mimio->pktbuf.p + 4);
+-			if (x != *(mimio->pktbuf.p + 5)) {
+-				dev_dbg(dev, "EV_PENDATA: bad xsum.\n");
+-				mimio->pktbuf.p += 6; /* skip this event data */
+-				break; /* decode any remaining events */
+-			}
+-			x = *(mimio->pktbuf.p + 1);
+-			x <<= 8;
+-			x |= *(mimio->pktbuf.p + 2);
+-			y = *(mimio->pktbuf.p + 3);
+-			y <<= 8;
+-			y |= *(mimio->pktbuf.p + 4);
+-			dev_dbg(dev, "coord: (%d, %d)\n", x, y);
+-			if (instr_ofst[mimio->pktbuf.instr] >= 0) {
+-				int code = BTN_TOOL_PEN +
+-					   instr_ofst[mimio->last_pen_down];
+-#if 0
+-				/* Utter hack to ensure we get forwarded _AND_
+-				 * so we can identify when a complete signal is
+-				 * received */
+-				mimio->idev->abs[ABS_Y] = -1;
+-				mimio->idev->abs[ABS_X] = -1;
+-#endif
+-				/* input_regs(mimio->idev, regs); */
+-				input_report_abs(mimio->idev, ABS_X, x);
+-				input_report_abs(mimio->idev, ABS_Y, y);
+-				/* fake a penup */
+-				change_bit(code, mimio->idev->key);
+-				input_report_key(mimio->idev,
+-						 code,
+-						 DOWNVALUE);
+-				/* always sync here */
+-				mimio->idev->sync = 0;
+-				input_sync(mimio->idev);
+-			}
+-			mimio->pktbuf.p += 6;
+-			break;
+-		case MIMIO_EV_MEMRESET:
+-			if (mimio->pktbuf.q - mimio->pktbuf.p < 7)
+-				/* partial pkt */
+-				return;
+-			dev_dbg(dev, "mem-reset.\n");
+-			/* input_regs(mimio->idev, regs); */
+-			input_event(mimio->idev, EV_KEY, BTN_0, 1);
+-			input_event(mimio->idev, EV_KEY, BTN_0, 0);
+-			input_sync(mimio->idev);
+-			mimio->pktbuf.p += 7;
+-			break;
+-		case MIMIO_EV_ACC:
+-			if (mimio->pktbuf.q - mimio->pktbuf.p < 4)
+-				/* partial pkt */
+-				return;
+-			x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
+-				*(mimio->pktbuf.p + 2);
+-			if (x != *(mimio->pktbuf.p + 3)) {
+-				dev_dbg(dev, "EV_ACC: bad xsum.\n");
+-				mimio->pktbuf.p += 4; /* skip this event data */
+-				break; /* decode any remaining events */
+-			}
+-			switch (*(mimio->pktbuf.p + 2)) {
+-			case ACC_NEWPAGE:
+-				dev_dbg(&mimio->idev->dev, "new-page.\n");
+-				/* input_regs(mimio->idev, regs); */
+-				input_event(mimio->idev, EV_KEY, BTN_1, 1);
+-				input_event(mimio->idev, EV_KEY, BTN_1, 0);
+-				input_sync(mimio->idev);
+-				break;
+-			case ACC_TAGPAGE:
+-				dev_dbg(&mimio->idev->dev, "tag-page.\n");
+-				/* input_regs(mimio->idev, regs); */
+-				input_event(mimio->idev, EV_KEY, BTN_2, 1);
+-				input_event(mimio->idev, EV_KEY, BTN_2, 0);
+-				input_sync(mimio->idev);
+-				break;
+-			case ACC_PRINTPAGE:
+-				dev_dbg(&mimio->idev->dev, "print-page.\n");
+-				/* input_regs(mimio->idev, regs);*/
+-				input_event(mimio->idev, EV_KEY, BTN_3, 1);
+-				input_event(mimio->idev, EV_KEY, BTN_3, 0);
+-				input_sync(mimio->idev);
+-				break;
+-			case ACC_MAXIMIZE:
+-				dev_dbg(&mimio->idev->dev,
+-					"maximize-window.\n");
+-				/* input_regs(mimio->idev, regs); */
+-				input_event(mimio->idev, EV_KEY, BTN_4, 1);
+-				input_event(mimio->idev, EV_KEY, BTN_4, 0);
+-				input_sync(mimio->idev);
+-				break;
+-			case ACC_FINDCTLPNL:
+-				dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n");
+-				/* input_regs(mimio->idev, regs); */
+-				input_event(mimio->idev, EV_KEY, BTN_5, 1);
+-				input_event(mimio->idev, EV_KEY, BTN_5, 0);
+-				input_sync(mimio->idev);
+-				break;
+-			case ACC_DONE:
+-				dev_dbg(&mimio->idev->dev, "acc-done.\n");
+-				/* no event is dispatched to the input
+-				 * subsystem for this device event.
+-				 */
+-				break;
+-			default:
+-				dev_dbg(dev, "unknown acc event.\n");
+-				break;
+-			}
+-			mimio->pktbuf.p += 4;
+-			break;
+-		default:
+-			mimio->pktbuf.p++;
+-			break;
+-		}
+-	}
+-
+-	/*
+-	 * No partial event was received, so reset mimio's pktbuf ptrs.
+-	 */
+-	mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf;
+-}
+-
+-static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes)
+-{
+-	int rslt;
+-	int timeout;
+-	unsigned long flags;
+-	DECLARE_WAITQUEUE(wait, current);
+-
+-	if (!(isvalidtxsize(nbytes))) {
+-		dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n",
+-			nbytes);
+-		return -EINVAL;
+-	}
+-
+-	/*
+-	 * Init the out urb and copy the data to send.
+-	 */
+-	mimio->out.urb->dev = mimio->udev;
+-	mimio->out.urb->transfer_buffer_length = nbytes;
+-	memcpy(mimio->out.urb->transfer_buffer, buf, nbytes);
+-
+-	/*
+-	 * Send the data.
+-	 */
+-	spin_lock_irqsave(&mimio->txlock, flags);
+-	mimio->txflags = MIMIO_TXWAIT;
+-	rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC);
+-	spin_unlock_irqrestore(&mimio->txlock, flags);
+-	dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt);
+-
+-	if (rslt) {
+-		dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
+-			rslt);
+-		return rslt;
+-	}
+-
+-	/*
+-	 * Wait for completion to be signalled (the mimio_irq_out
+-	 * completion routine will or MIMIO_TXDONE in with txflags).
+-	 */
+-	timeout = HZ;
+-	set_current_state(TASK_INTERRUPTIBLE);
+-	add_wait_queue(&mimio->waitq, &wait);
+-
+-	while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) {
+-		timeout = schedule_timeout(timeout);
+-		rmb();
+-	}
+-
+-	if ((mimio->txflags & MIMIO_TXDONE) == 0)
+-		dev_dbg(&mimio->idev->dev, "tx timed out.\n");
+-
+-	/*
+-	 * Now that completion has been signalled,
+-	 * unlink the urb so that it can be recycled.
+-	 */
+-	set_current_state(TASK_RUNNING);
+-	remove_wait_queue(&mimio->waitq, &wait);
+-	usb_unlink_urb(mimio->out.urb);
+-
+-	return rslt;
+-}
+-
+-static int __init mimio_init(void)
+-{
+-	int rslt;
+-
+-	rslt = usb_register(&mimio_driver);
+-	if (rslt != 0) {
+-		err("%s: usb_register failure: %d", __func__, rslt);
+-		return rslt;
+-	}
+-
+-	printk(KERN_INFO KBUILD_MODNAME ":"
+-	       DRIVER_DESC " " DRIVER_VERSION "\n");
+-	return rslt;
+-}
+-
+-static void __exit mimio_exit(void)
+-{
+-	usb_deregister(&mimio_driver);
+-}
+-
+-module_init(mimio_init);
+-module_exit(mimio_exit);
+-
+-MODULE_AUTHOR(DRIVER_AUTHOR);
+-MODULE_DESCRIPTION(DRIVER_DESC);
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
+index f69b778..cd25811 100644
+--- a/drivers/staging/pohmelfs/inode.c
++++ b/drivers/staging/pohmelfs/inode.c
+@@ -36,6 +36,7 @@
+ #define POHMELFS_MAGIC_NUM	0x504f482e
+ 
+ static struct kmem_cache *pohmelfs_inode_cache;
++static atomic_t psb_bdi_num = ATOMIC_INIT(0);
+ 
+ /*
+  * Removes inode from all trees, drops local name cache and removes all queued
+@@ -1331,6 +1332,8 @@ static void pohmelfs_put_super(struct super_block *sb)
+ 	pohmelfs_crypto_exit(psb);
+ 	pohmelfs_state_exit(psb);
+ 
++	bdi_destroy(&psb->bdi);
++
+ 	kfree(psb);
+ 	sb->s_fs_info = NULL;
+ }
+@@ -1815,11 +1818,22 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
+ 	if (!psb)
+ 		goto err_out_exit;
+ 
++	err = bdi_init(&psb->bdi);
++	if (err)
++		goto err_out_free_sb;
++
++	err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num));
++	if (err) {
++		bdi_destroy(&psb->bdi);
++		goto err_out_free_sb;
++	}
++
+ 	sb->s_fs_info = psb;
+ 	sb->s_op = &pohmelfs_sb_ops;
+ 	sb->s_magic = POHMELFS_MAGIC_NUM;
+ 	sb->s_maxbytes = MAX_LFS_FILESIZE;
+ 	sb->s_blocksize = PAGE_SIZE;
++	sb->s_bdi = &psb->bdi;
+ 
+ 	psb->sb = sb;
+ 
+@@ -1863,11 +1877,11 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
+ 
+ 	err = pohmelfs_parse_options((char *) data, psb, 0);
+ 	if (err)
+-		goto err_out_free_sb;
++		goto err_out_free_bdi;
+ 
+ 	err = pohmelfs_copy_crypto(psb);
+ 	if (err)
+-		goto err_out_free_sb;
++		goto err_out_free_bdi;
+ 
+ 	err = pohmelfs_state_init(psb);
+ 	if (err)
+@@ -1916,6 +1930,8 @@ err_out_state_exit:
+ err_out_free_strings:
+ 	kfree(psb->cipher_string);
+ 	kfree(psb->hash_string);
++err_out_free_bdi:
++	bdi_destroy(&psb->bdi);
+ err_out_free_sb:
+ 	kfree(psb);
+ err_out_exit:
+diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
+index 623a07d..01cba00 100644
+--- a/drivers/staging/pohmelfs/netfs.h
++++ b/drivers/staging/pohmelfs/netfs.h
+@@ -18,6 +18,7 @@
+ 
+ #include <linux/types.h>
+ #include <linux/connector.h>
++#include <linux/backing-dev.h>
+ 
+ #define POHMELFS_CN_IDX			5
+ #define POHMELFS_CN_VAL			0
+@@ -624,6 +625,8 @@ struct pohmelfs_sb {
+ 
+ 	struct super_block	*sb;
+ 
++	struct backing_dev_info	bdi;
++
+ 	/*
+ 	 * Algorithm strings.
+ 	 */
+diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig
+index f44294b..f1af507 100644
+--- a/drivers/staging/wlan-ng/Kconfig
++++ b/drivers/staging/wlan-ng/Kconfig
+@@ -1,6 +1,7 @@
+ config PRISM2_USB
+ 	tristate "Prism2.5/3 USB driver"
+ 	depends on WLAN && USB && WIRELESS_EXT
++	select WEXT_PRIV
+ 	default n
+ 	---help---
+ 	  This is the wlan-ng prism 2.5/3 USB driver for a wide range of
+diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
+index 60a45f1..ca479a7 100644
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -691,9 +691,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
+ {
+ 	struct usb_device *usb_dev;
+ 
+-	/* driver is often null here; dev_dbg() would oops */
+-	pr_debug("usb %s: uevent\n", dev_name(dev));
+-
+ 	if (is_usb_device(dev)) {
+ 		usb_dev = to_usb_device(dev);
+ 	} else if (is_usb_interface(dev)) {
+@@ -705,6 +702,7 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
+ 	}
+ 
+ 	if (usb_dev->devnum < 0) {
++		/* driver is often null here; dev_dbg() would oops */
+ 		pr_debug("usb %s: already deleted?\n", dev_name(dev));
+ 		return -ENODEV;
+ 	}
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 80995ef..0477616 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -141,7 +141,7 @@ static const u8 usb3_rh_dev_descriptor[18] = {
+ 	0x09,       /*  __u8  bMaxPacketSize0; 2^9 = 512 Bytes */
+ 
+ 	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
+-	0x02, 0x00, /*  __le16 idProduct; device 0x0002 */
++	0x03, 0x00, /*  __le16 idProduct; device 0x0003 */
+ 	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
+ 
+ 	0x03,       /*  __u8  iManufacturer; */
+diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
+index bbe2b92..89613a7 100644
+--- a/drivers/usb/core/hcd.h
++++ b/drivers/usb/core/hcd.h
+@@ -248,7 +248,7 @@ struct hc_driver {
+ 	/* xHCI specific functions */
+ 		/* Called by usb_alloc_dev to alloc HC device structures */
+ 	int	(*alloc_dev)(struct usb_hcd *, struct usb_device *);
+-		/* Called by usb_release_dev to free HC device structures */
++		/* Called by usb_disconnect to free HC device structures */
+ 	void	(*free_dev)(struct usb_hcd *, struct usb_device *);
+ 
+ 	/* Bandwidth computation functions */
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 35cc8b9..9cc0aba 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1554,6 +1554,15 @@ static inline void usb_stop_pm(struct usb_device *udev)
+ 
+ #endif
+ 
++static void hub_free_dev(struct usb_device *udev)
++{
++	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
++
++	/* Root hubs aren't real devices, so don't free HCD resources */
++	if (hcd->driver->free_dev && udev->parent)
++		hcd->driver->free_dev(hcd, udev);
++}
++
+ /**
+  * usb_disconnect - disconnect a device (usbcore-internal)
+  * @pdev: pointer to device being disconnected
+@@ -1624,6 +1633,8 @@ void usb_disconnect(struct usb_device **pdev)
+ 
+ 	usb_stop_pm(udev);
+ 
++	hub_free_dev(udev);
++
+ 	put_device(&udev->dev);
+ }
+ 
+@@ -3191,6 +3202,7 @@ loop_disable:
+ loop:
+ 		usb_ep0_reinit(udev);
+ 		release_address(udev);
++		hub_free_dev(udev);
+ 		usb_put_dev(udev);
+ 		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
+ 			break;
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 0daff0d..ced0776 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -228,9 +228,6 @@ static void usb_release_dev(struct device *dev)
+ 	hcd = bus_to_hcd(udev->bus);
+ 
+ 	usb_destroy_configuration(udev);
+-	/* Root hubs aren't real devices, so don't free HCD resources */
+-	if (hcd->driver->free_dev && udev->parent)
+-		hcd->driver->free_dev(hcd, udev);
+ 	usb_put_hcd(hcd);
+ 	kfree(udev->product);
+ 	kfree(udev->manufacturer);
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index a37640e..73f9bbd 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2852,7 +2852,6 @@ error_release:
+ 	/* Call fsg_common_release() directly, ref might be not
+ 	 * initialised */
+ 	fsg_common_release(&common->ref);
+-	complete(&common->thread_notifier);
+ 	return ERR_PTR(rc);
+ }
+ 
+diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
+index 2769326..cd74bbd 100644
+--- a/drivers/usb/host/ohci-pnx4008.c
++++ b/drivers/usb/host/ohci-pnx4008.c
+@@ -327,7 +327,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
+ 	}
+ 	i2c_adap = i2c_get_adapter(2);
+ 	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
+-	strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
++	strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE);
+ 	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
+ 						   normal_i2c);
+ 	i2c_put_adapter(i2c_adap);
+@@ -411,7 +411,7 @@ out3:
+ out2:
+ 	clk_put(usb_clk);
+ out1:
+-	i2c_unregister_client(isp1301_i2c_client);
++	i2c_unregister_device(isp1301_i2c_client);
+ 	isp1301_i2c_client = NULL;
+ out_i2c_driver:
+ 	i2c_del_driver(&isp1301_driver);
+@@ -430,7 +430,7 @@ static int usb_hcd_pnx4008_remove(struct platform_device *pdev)
+ 	pnx4008_unset_usb_bits();
+ 	clk_disable(usb_clk);
+ 	clk_put(usb_clk);
+-	i2c_unregister_client(isp1301_i2c_client);
++	i2c_unregister_device(isp1301_i2c_client);
+ 	isp1301_i2c_client = NULL;
+ 	i2c_del_driver(&isp1301_driver);
+ 
+diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
+index 99cd00f..0919706 100644
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -735,6 +735,7 @@ static void uhci_stop(struct usb_hcd *hcd)
+ 		uhci_hc_died(uhci);
+ 	uhci_scan_schedule(uhci);
+ 	spin_unlock_irq(&uhci->lock);
++	synchronize_irq(hcd->irq);
+ 
+ 	del_timer_sync(&uhci->fsbr_timer);
+ 	release_uhci(uhci);
+diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h
+index ecc131c..78c4eda 100644
+--- a/drivers/usb/host/xhci-ext-caps.h
++++ b/drivers/usb/host/xhci-ext-caps.h
+@@ -101,12 +101,15 @@ static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset)
+ 
+ 	next = readl(base + ext_offset);
+ 
+-	if (ext_offset == XHCI_HCC_PARAMS_OFFSET)
++	if (ext_offset == XHCI_HCC_PARAMS_OFFSET) {
+ 		/* Find the first extended capability */
+ 		next = XHCI_HCC_EXT_CAPS(next);
+-	else
++		ext_offset = 0;
++	} else {
+ 		/* Find the next extended capability */
+ 		next = XHCI_EXT_CAPS_NEXT(next);
++	}
++
+ 	if (!next)
+ 		return 0;
+ 	/*
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index bd254ec..7d920f2 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -91,11 +91,12 @@ static struct usb_device_id id_table [] = {
+ 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
+ 	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
+ 	{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
++	{ USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */
+ 	{ USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */
+ 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
+ 	{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
+ 	{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */
+-	{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
++	{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */
+ 	{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
+ 	{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
+ 	{ USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 7638828..34acf6c 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -614,6 +614,7 @@ static struct usb_device_id id_table_combined [] = {
+ 	{ USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
+ 	{ USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
++	{ USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
+ 	{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
+ 	{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
+ 	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
+@@ -737,6 +738,10 @@ static struct usb_device_id id_table_combined [] = {
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
+ 	{ USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
++	{ USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) },
++	{ USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) },
++	{ USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) },
++	{ USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) },
+ 	{ },					/* Optional parameter entry */
+ 	{ }					/* Terminating entry */
+ };
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index c8951ae..d10b5a8 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -494,6 +494,13 @@
+ #define RATOC_PRODUCT_ID_USB60F	0xb020
+ 
+ /*
++ * Contec products (http://www.contec.com)
++ * Submitted by Daniel Sangorrin
++ */
++#define CONTEC_VID		0x06CE	/* Vendor ID */
++#define CONTEC_COM1USBH_PID	0x8311	/* COM-1(USB)H */
++
++/*
+  * Definitions for B&B Electronics products.
+  */
+ #define BANDB_VID		0x0856	/* B&B Electronics Vendor ID */
+@@ -1002,3 +1009,11 @@
+ #define EVO_8U232AM_PID	0x02FF	/* Evolution robotics RCM2 (FT232AM)*/
+ #define EVO_HYBRID_PID		0x0302	/* Evolution robotics RCM4 PID (FT232BM)*/
+ #define EVO_RCM4_PID		0x0303	/* Evolution robotics RCM4 PID */
++
++/*
++ * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403)
++ */
++#define MJSG_GENERIC_PID	0x9378
++#define MJSG_SR_RADIO_PID	0x9379
++#define MJSG_XM_RADIO_PID	0x937A
++#define MJSG_HD_RADIO_PID	0x937C
+diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
+index 3eb6143..0cfd621 100644
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -604,14 +604,17 @@ static void sierra_indat_callback(struct urb *urb)
+ 	} else {
+ 		if (urb->actual_length) {
+ 			tty = tty_port_tty_get(&port->port);
+-
+-			tty_buffer_request_room(tty, urb->actual_length);
+-			tty_insert_flip_string(tty, data, urb->actual_length);
+-			tty_flip_buffer_push(tty);
+-
+-			tty_kref_put(tty);
+-			usb_serial_debug_data(debug, &port->dev, __func__,
+-				urb->actual_length, data);
++			if (tty) {
++				tty_buffer_request_room(tty,
++					urb->actual_length);
++				tty_insert_flip_string(tty, data,
++					urb->actual_length);
++				tty_flip_buffer_push(tty);
++
++				tty_kref_put(tty);
++				usb_serial_debug_data(debug, &port->dev,
++					__func__, urb->actual_length, data);
++			}
+ 		} else {
+ 			dev_dbg(&port->dev, "%s: empty read urb"
+ 				" received\n", __func__);
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index 49575fb..98b549b 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1147,8 +1147,8 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
+ 		0 ),
+ 
+ /* Reported by Jan Dumon <j.dumon at option.com>
+- * This device (wrongly) has a vendor-specific device descriptor.
+- * The entry is needed so usb-storage can bind to it's mass-storage
++ * These devices (wrongly) have a vendor-specific device descriptor.
++ * These entries are needed so usb-storage can bind to their mass-storage
+  * interface as an interface driver */
+ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
+ 		"Option",
+@@ -1156,6 +1156,90 @@ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		0 ),
+ 
++UNUSUAL_DEV( 0x0af0, 0x7701, 0x0000, 0x0000,
++		"Option",
++		"GI 0451 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x7706, 0x0000, 0x0000,
++		"Option",
++		"GI 0451 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x7901, 0x0000, 0x0000,
++		"Option",
++		"GI 0452 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x7A01, 0x0000, 0x0000,
++		"Option",
++		"GI 0461 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x7A05, 0x0000, 0x0000,
++		"Option",
++		"GI 0461 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x8300, 0x0000, 0x0000,
++		"Option",
++		"GI 033x SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x8302, 0x0000, 0x0000,
++		"Option",
++		"GI 033x SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0000,
++		"Option",
++		"GI 033x SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000,
++		"Option",
++		"GI 070x SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0xd057, 0x0000, 0x0000,
++		"Option",
++		"GI 1505 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0xd058, 0x0000, 0x0000,
++		"Option",
++		"GI 1509 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0xd157, 0x0000, 0x0000,
++		"Option",
++		"GI 1515 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0xd257, 0x0000, 0x0000,
++		"Option",
++		"GI 1215 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
++UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000,
++		"Option",
++		"GI 1505 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
+ /* Reported by Ben Efros <ben at pc-doctor.com> */
+ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
+ 		"Seagate",
+diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
+index 18b9507..4cd5049 100644
+--- a/drivers/video/sunxvr500.c
++++ b/drivers/video/sunxvr500.c
+@@ -400,6 +400,7 @@ static void __devexit e3d_pci_unregister(struct pci_dev *pdev)
+ 
+ static struct pci_device_id e3d_pci_table[] = {
+ 	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0),	},
++	{	PCI_DEVICE(0x1091, 0x7a0),			},
+ 	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2),	},
+ 	{	.vendor = PCI_VENDOR_ID_3DLABS,
+ 		.device = PCI_ANY_ID,
+diff --git a/fs/file_table.c b/fs/file_table.c
+index b98404b..32d12b7 100644
+--- a/fs/file_table.c
++++ b/fs/file_table.c
+@@ -393,7 +393,9 @@ retry:
+ 			continue;
+ 		if (!(f->f_mode & FMODE_WRITE))
+ 			continue;
++		spin_lock(&f->f_lock);
+ 		f->f_mode &= ~FMODE_WRITE;
++		spin_unlock(&f->f_lock);
+ 		if (file_check_writeable(f) != 0)
+ 			continue;
+ 		file_release_write(f);
+diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
+index 95e1ca7..3f0cd4d 100644
+--- a/fs/nfs/dns_resolve.c
++++ b/fs/nfs/dns_resolve.c
+@@ -36,6 +36,19 @@ struct nfs_dns_ent {
+ };
+ 
+ 
++static void nfs_dns_ent_update(struct cache_head *cnew,
++		struct cache_head *ckey)
++{
++	struct nfs_dns_ent *new;
++	struct nfs_dns_ent *key;
++
++	new = container_of(cnew, struct nfs_dns_ent, h);
++	key = container_of(ckey, struct nfs_dns_ent, h);
++
++	memcpy(&new->addr, &key->addr, key->addrlen);
++	new->addrlen = key->addrlen;
++}
++
+ static void nfs_dns_ent_init(struct cache_head *cnew,
+ 		struct cache_head *ckey)
+ {
+@@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
+ 	new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
+ 	if (new->hostname) {
+ 		new->namelen = key->namelen;
+-		memcpy(&new->addr, &key->addr, key->addrlen);
+-		new->addrlen = key->addrlen;
++		nfs_dns_ent_update(cnew, ckey);
+ 	} else {
+ 		new->namelen = 0;
+ 		new->addrlen = 0;
+@@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = {
+ 	.cache_show = nfs_dns_show,
+ 	.match = nfs_dns_match,
+ 	.init = nfs_dns_ent_init,
+-	.update = nfs_dns_ent_init,
++	.update = nfs_dns_ent_update,
+ 	.alloc = nfs_dns_ent_alloc,
+ };
+ 
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index f19ed86..fcafe60 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1998,7 +1998,9 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
+ {
+ 	if (share_access & NFS4_SHARE_ACCESS_WRITE) {
+ 		drop_file_write_access(filp);
++		spin_lock(&filp->f_lock);
+ 		filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
++		spin_unlock(&filp->f_lock);
+ 	}
+ }
+ 
+diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
+index 7e9df11..4c2a6d2 100644
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -577,8 +577,9 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
+ 		goto bail;
+ 	}
+ 
+-	/* We should already CoW the refcounted extent. */
+-	BUG_ON(ext_flags & OCFS2_EXT_REFCOUNTED);
++	/* We should already CoW the refcounted extent in case of create. */
++	BUG_ON(create && (ext_flags & OCFS2_EXT_REFCOUNTED));
++
+ 	/*
+ 	 * get_more_blocks() expects us to describe a hole by clearing
+ 	 * the mapped bit on bh_result().
+diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
+index 699f371..5c4703d 100644
+--- a/fs/sysfs/dir.c
++++ b/fs/sysfs/dir.c
+@@ -837,11 +837,46 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd)
+ 	return (sd->s_mode >> 12) & 15;
+ }
+ 
++static int sysfs_dir_release(struct inode *inode, struct file *filp)
++{
++	sysfs_put(filp->private_data);
++	return 0;
++}
++
++static struct sysfs_dirent *sysfs_dir_pos(struct sysfs_dirent *parent_sd,
++	ino_t ino, struct sysfs_dirent *pos)
++{
++	if (pos) {
++		int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
++			pos->s_parent == parent_sd &&
++			ino == pos->s_ino;
++		sysfs_put(pos);
++		if (valid)
++			return pos;
++	}
++	pos = NULL;
++	if ((ino > 1) && (ino < INT_MAX)) {
++		pos = parent_sd->s_dir.children;
++		while (pos && (ino > pos->s_ino))
++			pos = pos->s_sibling;
++	}
++	return pos;
++}
++
++static struct sysfs_dirent *sysfs_dir_next_pos(struct sysfs_dirent *parent_sd,
++	ino_t ino, struct sysfs_dirent *pos)
++{
++	pos = sysfs_dir_pos(parent_sd, ino, pos);
++	if (pos)
++		pos = pos->s_sibling;
++	return pos;
++}
++
+ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
+ {
+ 	struct dentry *dentry = filp->f_path.dentry;
+ 	struct sysfs_dirent * parent_sd = dentry->d_fsdata;
+-	struct sysfs_dirent *pos;
++	struct sysfs_dirent *pos = filp->private_data;
+ 	ino_t ino;
+ 
+ 	if (filp->f_pos == 0) {
+@@ -857,29 +892,31 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
+ 		if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
+ 			filp->f_pos++;
+ 	}
+-	if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) {
+-		mutex_lock(&sysfs_mutex);
+-
+-		/* Skip the dentries we have already reported */
+-		pos = parent_sd->s_dir.children;
+-		while (pos && (filp->f_pos > pos->s_ino))
+-			pos = pos->s_sibling;
+-
+-		for ( ; pos; pos = pos->s_sibling) {
+-			const char * name;
+-			int len;
+-
+-			name = pos->s_name;
+-			len = strlen(name);
+-			filp->f_pos = ino = pos->s_ino;
++	mutex_lock(&sysfs_mutex);
++	for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos);
++	     pos;
++	     pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) {
++		const char * name;
++		unsigned int type;
++		int len, ret;
++
++		name = pos->s_name;
++		len = strlen(name);
++		ino = pos->s_ino;
++		type = dt_type(pos);
++		filp->f_pos = ino;
++		filp->private_data = sysfs_get(pos);
+ 
+-			if (filldir(dirent, name, len, filp->f_pos, ino,
+-					 dt_type(pos)) < 0)
+-				break;
+-		}
+-		if (!pos)
+-			filp->f_pos = INT_MAX;
+ 		mutex_unlock(&sysfs_mutex);
++		ret = filldir(dirent, name, len, filp->f_pos, ino, type);
++		mutex_lock(&sysfs_mutex);
++		if (ret < 0)
++			break;
++	}
++	mutex_unlock(&sysfs_mutex);
++	if ((filp->f_pos > 1) && !pos) { /* EOF */
++		filp->f_pos = INT_MAX;
++		filp->private_data = NULL;
+ 	}
+ 	return 0;
+ }
+@@ -888,5 +925,6 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
+ const struct file_operations sysfs_dir_operations = {
+ 	.read		= generic_read_dir,
+ 	.readdir	= sysfs_readdir,
++	.release	= sysfs_dir_release,
+ 	.llseek		= generic_file_llseek,
+ };
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index ebb1cd5..f2f68ce 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -87,6 +87,9 @@ struct inodes_stat_t {
+  */
+ #define FMODE_NOCMTIME		((__force fmode_t)2048)
+ 
++/* Expect random access pattern */
++#define FMODE_RANDOM		((__force fmode_t)4096)
++
+ /*
+  * The below are the various read and write types that we support. Some of
+  * them include behavioral modifiers that send information down to the
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index 451481c..4d9b26e 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -400,7 +400,9 @@ static inline int irq_has_action(unsigned int irq)
+ 
+ /* Dynamic irq helper functions */
+ extern void dynamic_irq_init(unsigned int irq);
++void dynamic_irq_init_keep_chip_data(unsigned int irq);
+ extern void dynamic_irq_cleanup(unsigned int irq);
++void dynamic_irq_cleanup_keep_chip_data(unsigned int irq);
+ 
+ /* Set/get chip/data for an IRQ: */
+ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index a3fccc8..99914e6 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -136,7 +136,7 @@ static inline bool dev_xmit_complete(int rc)
+  *	used.
+  */
+ 
+-#if defined(CONFIG_WLAN_80211) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
++#if defined(CONFIG_WLAN) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+ # if defined(CONFIG_MAC80211_MESH)
+ #  define LL_MAX_HEADER 128
+ # else
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index a177698..c8ea0c7 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -496,9 +496,8 @@ struct hw_perf_event {
+ 	atomic64_t			period_left;
+ 	u64				interrupts;
+ 
+-	u64				freq_count;
+-	u64				freq_interrupts;
+-	u64				freq_stamp;
++	u64				freq_time_stamp;
++	u64				freq_count_stamp;
+ #endif
+ };
+ 
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 78efe7c..1f5fa53 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -878,7 +878,10 @@ static inline int sd_balance_for_mc_power(void)
+ 	if (sched_smt_power_savings)
+ 		return SD_POWERSAVINGS_BALANCE;
+ 
+-	return SD_PREFER_SIBLING;
++	if (!sched_mc_power_savings)
++		return SD_PREFER_SIBLING;
++
++	return 0;
+ }
+ 
+ static inline int sd_balance_for_package_power(void)
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index ae836fd..ec226a2 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -315,22 +315,23 @@ struct sk_buff {
+ 	struct sk_buff		*next;
+ 	struct sk_buff		*prev;
+ 
+-	struct sock		*sk;
+ 	ktime_t			tstamp;
++
++	struct sock		*sk;
+ 	struct net_device	*dev;
+ 
+-	unsigned long		_skb_dst;
+-#ifdef CONFIG_XFRM
+-	struct	sec_path	*sp;
+-#endif
+ 	/*
+ 	 * This is the control buffer. It is free to use for every
+ 	 * layer. Please put your private variables there. If you
+ 	 * want to keep them across layers you have to do a skb_clone()
+ 	 * first. This is owned by whoever has the skb queued ATM.
+ 	 */
+-	char			cb[48];
++	char			cb[48] __aligned(8);
+ 
++	unsigned long		_skb_dst;
++#ifdef CONFIG_XFRM
++	struct	sec_path	*sp;
++#endif
+ 	unsigned int		len,
+ 				data_len;
+ 	__u16			mac_len,
+diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
+index 207466a..2540770 100644
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -132,7 +132,8 @@ struct perf_event_attr;
+ 
+ #define SYSCALL_TRACE_ENTER_EVENT(sname)				\
+ 	static const struct syscall_metadata __syscall_meta_##sname;	\
+-	static struct ftrace_event_call event_enter_##sname;		\
++	static struct ftrace_event_call					\
++	__attribute__((__aligned__(4))) event_enter_##sname;		\
+ 	static struct trace_event enter_syscall_print_##sname = {	\
+ 		.trace                  = print_syscall_enter,		\
+ 	};								\
+@@ -154,7 +155,8 @@ struct perf_event_attr;
+ 
+ #define SYSCALL_TRACE_EXIT_EVENT(sname)					\
+ 	static const struct syscall_metadata __syscall_meta_##sname;	\
+-	static struct ftrace_event_call event_exit_##sname;		\
++	static struct ftrace_event_call					\
++	__attribute__((__aligned__(4))) event_exit_##sname;		\
+ 	static struct trace_event exit_syscall_print_##sname = {	\
+ 		.trace                  = print_syscall_exit,		\
+ 	};								\
+diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
+index c6fe03e..1ca4990 100644
+--- a/include/trace/ftrace.h
++++ b/include/trace/ftrace.h
+@@ -65,7 +65,8 @@
+ 	};
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)	\
+-	static struct ftrace_event_call event_##name
++	static struct ftrace_event_call			\
++	__attribute__((__aligned__(4))) event_##name
+ 
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)	\
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
+index ecc3fa2..d70394f 100644
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -18,11 +18,7 @@
+ 
+ #include "internals.h"
+ 
+-/**
+- *	dynamic_irq_init - initialize a dynamically allocated irq
+- *	@irq:	irq number to initialize
+- */
+-void dynamic_irq_init(unsigned int irq)
++static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data)
+ {
+ 	struct irq_desc *desc;
+ 	unsigned long flags;
+@@ -41,7 +37,8 @@ void dynamic_irq_init(unsigned int irq)
+ 	desc->depth = 1;
+ 	desc->msi_desc = NULL;
+ 	desc->handler_data = NULL;
+-	desc->chip_data = NULL;
++	if (!keep_chip_data)
++		desc->chip_data = NULL;
+ 	desc->action = NULL;
+ 	desc->irq_count = 0;
+ 	desc->irqs_unhandled = 0;
+@@ -55,10 +52,26 @@ void dynamic_irq_init(unsigned int irq)
+ }
+ 
+ /**
+- *	dynamic_irq_cleanup - cleanup a dynamically allocated irq
++ *	dynamic_irq_init - initialize a dynamically allocated irq
+  *	@irq:	irq number to initialize
+  */
+-void dynamic_irq_cleanup(unsigned int irq)
++void dynamic_irq_init(unsigned int irq)
++{
++	dynamic_irq_init_x(irq, false);
++}
++
++/**
++ *	dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq
++ *	@irq:	irq number to initialize
++ *
++ *	does not set irq_to_desc(irq)->chip_data to NULL
++ */
++void dynamic_irq_init_keep_chip_data(unsigned int irq)
++{
++	dynamic_irq_init_x(irq, true);
++}
++
++static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data)
+ {
+ 	struct irq_desc *desc = irq_to_desc(irq);
+ 	unsigned long flags;
+@@ -77,7 +90,8 @@ void dynamic_irq_cleanup(unsigned int irq)
+ 	}
+ 	desc->msi_desc = NULL;
+ 	desc->handler_data = NULL;
+-	desc->chip_data = NULL;
++	if (!keep_chip_data)
++		desc->chip_data = NULL;
+ 	desc->handle_irq = handle_bad_irq;
+ 	desc->chip = &no_irq_chip;
+ 	desc->name = NULL;
+@@ -85,6 +99,26 @@ void dynamic_irq_cleanup(unsigned int irq)
+ 	raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+ 
++/**
++ *	dynamic_irq_cleanup - cleanup a dynamically allocated irq
++ *	@irq:	irq number to initialize
++ */
++void dynamic_irq_cleanup(unsigned int irq)
++{
++	dynamic_irq_cleanup_x(irq, false);
++}
++
++/**
++ *	dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq
++ *	@irq:	irq number to initialize
++ *
++ *	does not set irq_to_desc(irq)->chip_data to NULL
++ */
++void dynamic_irq_cleanup_keep_chip_data(unsigned int irq)
++{
++	dynamic_irq_cleanup_x(irq, true);
++}
++
+ 
+ /**
+  *	set_irq_chip - set the irq chip for an irq
+diff --git a/kernel/perf_event.c b/kernel/perf_event.c
+index 2ae7409..b707465 100644
+--- a/kernel/perf_event.c
++++ b/kernel/perf_event.c
+@@ -248,7 +248,7 @@ static void perf_unpin_context(struct perf_event_context *ctx)
+ 
+ static inline u64 perf_clock(void)
+ {
+-	return cpu_clock(smp_processor_id());
++	return cpu_clock(raw_smp_processor_id());
+ }
+ 
+ /*
+@@ -1350,14 +1350,83 @@ static void perf_event_cpu_sched_in(struct perf_cpu_context *cpuctx, int cpu)
+ 
+ static void perf_log_throttle(struct perf_event *event, int enable);
+ 
+-static void perf_adjust_period(struct perf_event *event, u64 events)
++static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count)
++{
++	u64 frequency = event->attr.sample_freq;
++	u64 sec = NSEC_PER_SEC;
++	u64 divisor, dividend;
++
++	int count_fls, nsec_fls, frequency_fls, sec_fls;
++
++	count_fls = fls64(count);
++	nsec_fls = fls64(nsec);
++	frequency_fls = fls64(frequency);
++	sec_fls = 30;
++
++	/*
++	 * We got @count in @nsec, with a target of sample_freq HZ
++	 * the target period becomes:
++	 *
++	 *             @count * 10^9
++	 * period = -------------------
++	 *          @nsec * sample_freq
++	 *
++	 */
++
++	/*
++	 * Reduce accuracy by one bit such that @a and @b converge
++	 * to a similar magnitude.
++	 */
++#define REDUCE_FLS(a, b) 		\
++do {					\
++	if (a##_fls > b##_fls) {	\
++		a >>= 1;		\
++		a##_fls--;		\
++	} else {			\
++		b >>= 1;		\
++		b##_fls--;		\
++	}				\
++} while (0)
++
++	/*
++	 * Reduce accuracy until either term fits in a u64, then proceed with
++	 * the other, so that finally we can do a u64/u64 division.
++	 */
++	while (count_fls + sec_fls > 64 && nsec_fls + frequency_fls > 64) {
++		REDUCE_FLS(nsec, frequency);
++		REDUCE_FLS(sec, count);
++	}
++
++	if (count_fls + sec_fls > 64) {
++		divisor = nsec * frequency;
++
++		while (count_fls + sec_fls > 64) {
++			REDUCE_FLS(count, sec);
++			divisor >>= 1;
++		}
++
++		dividend = count * sec;
++	} else {
++		dividend = count * sec;
++
++		while (nsec_fls + frequency_fls > 64) {
++			REDUCE_FLS(nsec, frequency);
++			dividend >>= 1;
++		}
++
++		divisor = nsec * frequency;
++	}
++
++	return div64_u64(dividend, divisor);
++}
++
++static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
+ {
+ 	struct hw_perf_event *hwc = &event->hw;
+ 	u64 period, sample_period;
+ 	s64 delta;
+ 
+-	events *= hwc->sample_period;
+-	period = div64_u64(events, event->attr.sample_freq);
++	period = perf_calculate_period(event, nsec, count);
+ 
+ 	delta = (s64)(period - hwc->sample_period);
+ 	delta = (delta + 7) / 8; /* low pass filter */
+@@ -1368,13 +1437,22 @@ static void perf_adjust_period(struct perf_event *event, u64 events)
+ 		sample_period = 1;
+ 
+ 	hwc->sample_period = sample_period;
++
++	if (atomic64_read(&hwc->period_left) > 8*sample_period) {
++		perf_disable();
++		event->pmu->disable(event);
++		atomic64_set(&hwc->period_left, 0);
++		event->pmu->enable(event);
++		perf_enable();
++	}
+ }
+ 
+ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
+ {
+ 	struct perf_event *event;
+ 	struct hw_perf_event *hwc;
+-	u64 interrupts, freq;
++	u64 interrupts, now;
++	s64 delta;
+ 
+ 	raw_spin_lock(&ctx->lock);
+ 	list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+@@ -1395,44 +1473,18 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
+ 		if (interrupts == MAX_INTERRUPTS) {
+ 			perf_log_throttle(event, 1);
+ 			event->pmu->unthrottle(event);
+-			interrupts = 2*sysctl_perf_event_sample_rate/HZ;
+ 		}
+ 
+ 		if (!event->attr.freq || !event->attr.sample_freq)
+ 			continue;
+ 
+-		/*
+-		 * if the specified freq < HZ then we need to skip ticks
+-		 */
+-		if (event->attr.sample_freq < HZ) {
+-			freq = event->attr.sample_freq;
+-
+-			hwc->freq_count += freq;
+-			hwc->freq_interrupts += interrupts;
+-
+-			if (hwc->freq_count < HZ)
+-				continue;
+-
+-			interrupts = hwc->freq_interrupts;
+-			hwc->freq_interrupts = 0;
+-			hwc->freq_count -= HZ;
+-		} else
+-			freq = HZ;
+-
+-		perf_adjust_period(event, freq * interrupts);
++		event->pmu->read(event);
++		now = atomic64_read(&event->count);
++		delta = now - hwc->freq_count_stamp;
++		hwc->freq_count_stamp = now;
+ 
+-		/*
+-		 * In order to avoid being stalled by an (accidental) huge
+-		 * sample period, force reset the sample period if we didn't
+-		 * get any events in this freq period.
+-		 */
+-		if (!interrupts) {
+-			perf_disable();
+-			event->pmu->disable(event);
+-			atomic64_set(&hwc->period_left, 0);
+-			event->pmu->enable(event);
+-			perf_enable();
+-		}
++		if (delta > 0)
++			perf_adjust_period(event, TICK_NSEC, delta);
+ 	}
+ 	raw_spin_unlock(&ctx->lock);
+ }
+@@ -3688,12 +3740,12 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
+ 
+ 	if (event->attr.freq) {
+ 		u64 now = perf_clock();
+-		s64 delta = now - hwc->freq_stamp;
++		s64 delta = now - hwc->freq_time_stamp;
+ 
+-		hwc->freq_stamp = now;
++		hwc->freq_time_stamp = now;
+ 
+-		if (delta > 0 && delta < TICK_NSEC)
+-			perf_adjust_period(event, NSEC_PER_SEC / (int)delta);
++		if (delta > 0 && delta < 2*TICK_NSEC)
++			perf_adjust_period(event, delta, hwc->last_period);
+ 	}
+ 
+ 	/*
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+index 36cb168..fc9ed15 100644
+--- a/kernel/power/snapshot.c
++++ b/kernel/power/snapshot.c
+@@ -1181,7 +1181,7 @@ static void free_unnecessary_pages(void)
+ 
+ 	memory_bm_position_reset(&copy_bm);
+ 
+-	while (to_free_normal > 0 && to_free_highmem > 0) {
++	while (to_free_normal > 0 || to_free_highmem > 0) {
+ 		unsigned long pfn = memory_bm_next_pfn(&copy_bm);
+ 		struct page *page = pfn_to_page(pfn);
+ 
+diff --git a/kernel/sched.c b/kernel/sched.c
+index 3a8fb30..00a59b0 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -4119,12 +4119,23 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
+ 			continue;
+ 
+ 		rq = cpu_rq(i);
+-		wl = weighted_cpuload(i) * SCHED_LOAD_SCALE;
+-		wl /= power;
++		wl = weighted_cpuload(i);
+ 
++		/*
++		 * When comparing with imbalance, use weighted_cpuload()
++		 * which is not scaled with the cpu power.
++		 */
+ 		if (capacity && rq->nr_running == 1 && wl > imbalance)
+ 			continue;
+ 
++		/*
++		 * For the load comparisons with the other cpu's, consider
++		 * the weighted_cpuload() scaled with the cpu power, so that
++		 * the load can be moved away from the cpu that is potentially
++		 * running at a lower capacity.
++		 */
++		wl = (wl * SCHED_LOAD_SCALE) / power;
++
+ 		if (wl > max_load) {
+ 			max_load = wl;
+ 			busiest = rq;
+@@ -6054,7 +6065,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
+ 	unsigned long flags;
+ 	int oldprio, on_rq, running;
+ 	struct rq *rq;
+-	const struct sched_class *prev_class = p->sched_class;
++	const struct sched_class *prev_class;
+ 
+ 	BUG_ON(prio < 0 || prio > MAX_PRIO);
+ 
+@@ -6062,6 +6073,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
+ 	update_rq_clock(rq);
+ 
+ 	oldprio = p->prio;
++	prev_class = p->sched_class;
+ 	on_rq = p->se.on_rq;
+ 	running = task_current(rq, p);
+ 	if (on_rq)
+@@ -6281,7 +6293,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
+ {
+ 	int retval, oldprio, oldpolicy = -1, on_rq, running;
+ 	unsigned long flags;
+-	const struct sched_class *prev_class = p->sched_class;
++	const struct sched_class *prev_class;
+ 	struct rq *rq;
+ 	int reset_on_fork;
+ 
+@@ -6395,6 +6407,7 @@ recheck:
+ 	p->sched_reset_on_fork = reset_on_fork;
+ 
+ 	oldprio = p->prio;
++	prev_class = p->sched_class;
+ 	__setscheduler(rq, p, policy, param->sched_priority);
+ 
+ 	if (running)
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 4df6a77..a1edaa8 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -791,7 +791,8 @@ extern const char *__stop___trace_bprintk_fmt[];
+ 
+ #undef FTRACE_ENTRY
+ #define FTRACE_ENTRY(call, struct_name, id, tstruct, print)		\
+-	extern struct ftrace_event_call event_##call;
++	extern struct ftrace_event_call					\
++	__attribute__((__aligned__(4))) event_##call;
+ #undef FTRACE_ENTRY_DUP
+ #define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print)		\
+ 	FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
+diff --git a/mm/fadvise.c b/mm/fadvise.c
+index e433592..8d723c9 100644
+--- a/mm/fadvise.c
++++ b/mm/fadvise.c
+@@ -77,12 +77,20 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
+ 	switch (advice) {
+ 	case POSIX_FADV_NORMAL:
+ 		file->f_ra.ra_pages = bdi->ra_pages;
++		spin_lock(&file->f_lock);
++		file->f_mode &= ~FMODE_RANDOM;
++		spin_unlock(&file->f_lock);
+ 		break;
+ 	case POSIX_FADV_RANDOM:
+-		file->f_ra.ra_pages = 0;
++		spin_lock(&file->f_lock);
++		file->f_mode |= FMODE_RANDOM;
++		spin_unlock(&file->f_lock);
+ 		break;
+ 	case POSIX_FADV_SEQUENTIAL:
+ 		file->f_ra.ra_pages = bdi->ra_pages * 2;
++		spin_lock(&file->f_lock);
++		file->f_mode &= ~FMODE_RANDOM;
++		spin_unlock(&file->f_lock);
+ 		break;
+ 	case POSIX_FADV_WILLNEED:
+ 		if (!mapping->a_ops->readpage) {
+diff --git a/mm/readahead.c b/mm/readahead.c
+index 033bc13..337b20e 100644
+--- a/mm/readahead.c
++++ b/mm/readahead.c
+@@ -501,6 +501,12 @@ void page_cache_sync_readahead(struct address_space *mapping,
+ 	if (!ra->ra_pages)
+ 		return;
+ 
++	/* be dumb */
++	if (filp->f_mode & FMODE_RANDOM) {
++		force_page_cache_readahead(mapping, filp, offset, req_size);
++		return;
++	}
++
+ 	/* do read-ahead */
+ 	ondemand_readahead(mapping, ra, filp, false, offset, req_size);
+ }
+diff --git a/mm/slab.c b/mm/slab.c
+index 7451bda..ff44eb2 100644
+--- a/mm/slab.c
++++ b/mm/slab.c
+@@ -983,13 +983,11 @@ static struct array_cache **alloc_alien_cache(int node, int limit, gfp_t gfp)
+ 
+ 	if (limit > 1)
+ 		limit = 12;
+-	ac_ptr = kmalloc_node(memsize, gfp, node);
++	ac_ptr = kzalloc_node(memsize, gfp, node);
+ 	if (ac_ptr) {
+ 		for_each_node(i) {
+-			if (i == node || !node_online(i)) {
+-				ac_ptr[i] = NULL;
++			if (i == node || !node_online(i))
+ 				continue;
+-			}
+ 			ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d, gfp);
+ 			if (!ac_ptr[i]) {
+ 				for (i--; i >= 0; i--)
+diff --git a/net/core/scm.c b/net/core/scm.c
+index b7ba91b..9b26463 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -156,6 +156,8 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
+ 		switch (cmsg->cmsg_type)
+ 		{
+ 		case SCM_RIGHTS:
++			if (!sock->ops || sock->ops->family != PF_UNIX)
++				goto error;
+ 			err=scm_fp_copy(cmsg, &p->fp);
+ 			if (err<0)
+ 				goto error;
+diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
+index 5e3a7ec..304b0b6 100644
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -179,7 +179,8 @@ static void sta_addba_resp_timer_expired(unsigned long data)
+ 
+ 	/* check if the TID waits for addBA response */
+ 	spin_lock_bh(&sta->lock);
+-	if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
++	if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK |
++		       HT_AGG_STATE_REQ_STOP_BA_MSK)) !=
+ 						HT_ADDBA_REQUESTED_MSK) {
+ 		spin_unlock_bh(&sta->lock);
+ 		*state = HT_AGG_STATE_IDLE;
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 82a30c1..da92cde 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1788,6 +1788,7 @@ static ieee80211_rx_result debug_noinline
+ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
+ {
+ 	struct ieee80211_sub_if_data *sdata = rx->sdata;
++	struct ieee80211_local *local = rx->local;
+ 	struct net_device *dev = sdata->dev;
+ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
+ 	__le16 fc = hdr->frame_control;
+@@ -1819,6 +1820,13 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
+ 	dev->stats.rx_packets++;
+ 	dev->stats.rx_bytes += rx->skb->len;
+ 
++	if (ieee80211_is_data(hdr->frame_control) &&
++	    !is_multicast_ether_addr(hdr->addr1) &&
++	    local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) {
++			mod_timer(&local->dynamic_ps_timer, jiffies +
++			 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
++	}
++
+ 	ieee80211_deliver_skb(rx);
+ 
+ 	return RX_QUEUED;
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index ac210b5..70c79c3 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1052,8 +1052,11 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
+ 
+ 	hdr = (struct ieee80211_hdr *) skb->data;
+ 
+-	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ 		tx->sta = rcu_dereference(sdata->u.vlan.sta);
++		if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
++			return TX_DROP;
++	}
+ 	if (!tx->sta)
+ 		tx->sta = sta_info_get(local, hdr->addr1);
+ 
+diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
+index fc70a49..43e83a4 100644
+--- a/net/netfilter/xt_recent.c
++++ b/net/netfilter/xt_recent.c
+@@ -173,10 +173,10 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
+ 
+ static void recent_entry_update(struct recent_table *t, struct recent_entry *e)
+ {
++	e->index %= ip_pkt_list_tot;
+ 	e->stamps[e->index++] = jiffies;
+ 	if (e->index > e->nstamps)
+ 		e->nstamps = e->index;
+-	e->index %= ip_pkt_list_tot;
+ 	list_move_tail(&e->lru_list, &t->lru_list);
+ }
+ 
+@@ -260,7 +260,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
+ 		for (i = 0; i < e->nstamps; i++) {
+ 			if (info->seconds && time_after(time, e->stamps[i]))
+ 				continue;
+-			if (++hits >= info->hit_count) {
++			if (info->hit_count && ++hits >= info->hit_count) {
+ 				ret = !ret;
+ 				break;
+ 			}
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index 7d1f9e9..4f30336 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -889,11 +889,8 @@ void svc_delete_xprt(struct svc_xprt *xprt)
+ 	if (test_bit(XPT_TEMP, &xprt->xpt_flags))
+ 		serv->sv_tmpcnt--;
+ 
+-	for (dr = svc_deferred_dequeue(xprt); dr;
+-	     dr = svc_deferred_dequeue(xprt)) {
+-		svc_xprt_put(xprt);
++	while ((dr = svc_deferred_dequeue(xprt)) != NULL)
+ 		kfree(dr);
+-	}
+ 
+ 	svc_xprt_put(xprt);
+ 	spin_unlock_bh(&serv->sv_lock);
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index 3d739e5..4df801d 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -1912,6 +1912,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
+ 	case -EALREADY:
+ 		xprt_clear_connecting(xprt);
+ 		return;
++	case -EINVAL:
++		/* Happens, for instance, if the user specified a link
++		 * local IPv6 address without a scope-id.
++		 */
++		goto out;
+ 	}
+ out_eagain:
+ 	status = -EAGAIN;
+diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
+index 2f3230d..049c419 100755
+--- a/scripts/get_maintainer.pl
++++ b/scripts/get_maintainer.pl
+@@ -314,6 +314,7 @@ foreach my $file (@files) {
+ 		if ($type eq 'X') {
+ 		    if (file_match_pattern($file, $value)) {
+ 			$exclude = 1;
++			last;
+ 		    }
+ 		}
+ 	    }
+@@ -340,8 +341,7 @@ foreach my $file (@files) {
+ 	    }
+ 	}
+ 
+-	$tvi += ($end - $start);
+-
++	$tvi = $end + 1;
+     }
+ 
+     foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
+diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
+index 0d83edc..2d4d05d 100644
+--- a/security/integrity/ima/ima_iint.c
++++ b/security/integrity/ima/ima_iint.c
+@@ -63,12 +63,11 @@ int ima_inode_alloc(struct inode *inode)
+ 	spin_lock(&ima_iint_lock);
+ 	rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
+ 	spin_unlock(&ima_iint_lock);
++	radix_tree_preload_end();
+ out:
+ 	if (rc < 0)
+ 		kmem_cache_free(iint_cache, iint);
+ 
+-	radix_tree_preload_end();
+-
+ 	return rc;
+ }
+ 
+diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
+index 68c7348..04b6145 100644
+--- a/security/selinux/ss/ebitmap.c
++++ b/security/selinux/ss/ebitmap.c
+@@ -128,7 +128,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
+ 			cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
+ 			cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
+ 			c_iter->bitmap[cmap_idx]
+-				|= e_iter->maps[cmap_idx] << cmap_sft;
++				|= e_iter->maps[i] << cmap_sft;
+ 		}
+ 		e_iter = e_iter->next;
+ 	}
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index 25b0641..f7e1c9f 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -315,10 +315,10 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
+ 	if (!params->info)
+ 		params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
+ 	if (!params->fifo_size) {
+-		if (snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) ==
+-		    snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) &&
+-                    snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) ==
+-                    snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) {
++		m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
++		i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
++		if (snd_mask_min(m) == snd_mask_max(m) &&
++                    snd_interval_min(i) == snd_interval_max(i)) {
+ 			changed = substream->ops->ioctl(substream,
+ 					SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
+ 			if (changed < 0)
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index ff6da6f..6d6e307 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2261,9 +2261,12 @@ static int azx_dev_free(struct snd_device *device)
+ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
+ 	SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
+ 	SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
++	SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
+ 	SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
++	SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
+ 	SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
+ 	SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
++	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
+ 	{}
+ };
+ 
+diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
+index 69a941c..7069441 100644
+--- a/sound/pci/hda/patch_analog.c
++++ b/sound/pci/hda/patch_analog.c
+@@ -1008,7 +1008,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
+ 	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
+ 	SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
+ 	SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
+-	SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
++	SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
+ 	SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
+ 	SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
+ 	SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
+diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
+index 8a332d2..03d6aea 100644
+--- a/sound/pci/via82xx.c
++++ b/sound/pci/via82xx.c
+@@ -1791,6 +1791,12 @@ static struct ac97_quirk ac97_quirks[] = {
+ 		.type = AC97_TUNE_HP_ONLY
+ 	},
+ 	{
++		.subvendor = 0x110a,
++		.subdevice = 0x0079,
++		.name = "Fujitsu Siemens D1289",
++		.type = AC97_TUNE_HP_ONLY
++	},
++	{
+ 		.subvendor = 0x1019,
+ 		.subdevice = 0x0a81,
+ 		.name = "ECS K7VTA3",
+diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
+index 3a14c6f..0f439ab 100644
+--- a/sound/soc/codecs/ak4104.c
++++ b/sound/soc/codecs/ak4104.c
+@@ -90,12 +90,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
+ 	if (reg >= codec->reg_cache_size)
+ 		return -EINVAL;
+ 
+-	reg &= AK4104_REG_MASK;
+-	reg |= AK4104_WRITE;
+-
+ 	/* only write to the hardware if value has changed */
+ 	if (cache[reg] != value) {
+-		u8 tmp[2] = { reg, value };
++		u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
++
+ 		if (spi_write(spi, tmp, sizeof(tmp))) {
+ 			dev_err(&spi->dev, "SPI write failed\n");
+ 			return -EIO;
+diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
+index 9edef46..3c81add 100644
+--- a/sound/usb/usbaudio.c
++++ b/sound/usb/usbaudio.c
+@@ -3327,6 +3327,32 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
+ }
+ 
+ /*
++ * This call will put the synth in "USB send" mode, i.e it will send MIDI
++ * messages through USB (this is disabled at startup). The synth will
++ * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
++ * sign on its LCD. Values here are chosen based on sniffing USB traffic
++ * under Windows.
++ */
++static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
++{
++	int err, actual_length;
++
++	/* "midi send" enable */
++	static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
++
++	void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++	err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
++			ARRAY_SIZE(seq), &actual_length, 1000);
++	kfree(buf);
++	if (err < 0)
++		return err;
++
++	return 0;
++}
++
++/*
+  * Setup quirks
+  */
+ #define AUDIOPHILE_SET			0x01 /* if set, parse device_setup */
+@@ -3624,6 +3650,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
+ 			goto __err_val;
+ 	}
+ 
++	/* Access Music VirusTI Desktop */
++	if (id == USB_ID(0x133e, 0x0815)) {
++		if (snd_usb_accessmusic_boot_quirk(dev) < 0)
++			goto __err_val;
++	}
++
+ 	/*
+ 	 * found a config.  now register to ALSA
+ 	 */
+diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
+index 6e89b83..b2da478 100644
+--- a/sound/usb/usbmidi.c
++++ b/sound/usb/usbmidi.c
+@@ -1162,10 +1162,22 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
+ 		pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
+ 	else
+ 		pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
+-	if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
+-		ep->max_transfer = 4;
+-	else
++	switch (umidi->usb_id) {
++	default:
+ 		ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
++		break;
++		/*
++		 * Various chips declare a packet size larger than 4 bytes, but
++		 * do not actually work with larger packets:
++		 */
++	case USB_ID(0x0a92, 0x1020): /* ESI M4U */
++	case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
++	case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
++	case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */
++	case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
++		ep->max_transfer = 4;
++		break;
++	}
+ 	for (i = 0; i < OUTPUT_URBS; ++i) {
+ 		buffer = usb_buffer_alloc(umidi->dev,
+ 					  ep->max_transfer, GFP_KERNEL,
+@@ -1407,6 +1419,12 @@ static struct port_info {
+ 	EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
+ 	EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
+ 	EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
++	/* Access Music Virus TI */
++	EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
++	PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
++		SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
++		SNDRV_SEQ_PORT_TYPE_HARDWARE |
++		SNDRV_SEQ_PORT_TYPE_SYNTHESIZER),
+ };
+ 
+ static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
+diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
+index a892bda..406b74b 100644
+--- a/sound/usb/usbquirks.h
++++ b/sound/usb/usbquirks.h
+@@ -2073,6 +2073,33 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ 	}
+ },
+ 
++/* Access Music devices */
++{
++	/* VirusTI Desktop */
++	USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815),
++	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++		.ifnum = QUIRK_ANY_INTERFACE,
++		.type = QUIRK_COMPOSITE,
++		.data = &(const struct snd_usb_audio_quirk[]) {
++			{
++				.ifnum = 3,
++				.type = QUIRK_MIDI_FIXED_ENDPOINT,
++				.data = &(const struct snd_usb_midi_endpoint_info) {
++					.out_cables = 0x0003,
++					.in_cables  = 0x0003
++				}
++			},
++			{
++				.ifnum = 4,
++				.type = QUIRK_IGNORE_INTERFACE
++			},
++			{
++				.ifnum = -1
++			}
++		}
++	}
++},
++
+ /* */
+ {
+ 	/* aka. Serato Scratch Live DJ Box */
+diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
+index ab92763..72547b9 100644
+--- a/tools/perf/util/symbol.c
++++ b/tools/perf/util/symbol.c
+@@ -503,7 +503,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
+ 				return -1;
+ 
+ 			curr_map = map__new2(pos->start, dso, map->type);
+-			if (map == NULL) {
++			if (curr_map == NULL) {
+ 				dso__delete(dso);
+ 				return -1;
+ 			}



More information about the Kernel-svn-changes mailing list