[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(©_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(©_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(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT]) ==
+- snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT]) &&
+- snd_mask_min(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) ==
+- snd_mask_max(¶ms->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