summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '3.2.51/1043_linux-3.2.44.patch')
-rw-r--r--3.2.51/1043_linux-3.2.44.patch2808
1 files changed, 2808 insertions, 0 deletions
diff --git a/3.2.51/1043_linux-3.2.44.patch b/3.2.51/1043_linux-3.2.44.patch
new file mode 100644
index 0000000..3d5e6ff
--- /dev/null
+++ b/3.2.51/1043_linux-3.2.44.patch
@@ -0,0 +1,2808 @@
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index ddbf18e..897f223 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -948,6 +948,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
+ capability is set.
+
++ i915.invert_brightness=
++ [DRM] Invert the sense of the variable that is used to
++ set the brightness of the panel backlight. Normally a
++ brightness value of 0 indicates backlight switched off,
++ and the maximum of the brightness value sets the backlight
++ to maximum brightness. If this parameter is set to 0
++ (default) and the machine requires it, or this parameter
++ is set to 1, a brightness value of 0 sets the backlight
++ to maximum brightness, and the maximum of the brightness
++ value switches the backlight off.
++ -1 -- never invert brightness
++ 0 -- machine default
++ 1 -- force brightness inversion
++
+ icn= [HW,ISDN]
+ Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
+
+diff --git a/Makefile b/Makefile
+index 59130db..566750c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 2
+-SUBLEVEL = 43
++SUBLEVEL = 44
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+
+diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
+index 4112200..c52a8ef 100644
+--- a/arch/alpha/kernel/sys_nautilus.c
++++ b/arch/alpha/kernel/sys_nautilus.c
+@@ -189,6 +189,10 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
+ extern void free_reserved_mem(void *, void *);
+ extern void pcibios_claim_one_bus(struct pci_bus *);
+
++static struct resource irongate_io = {
++ .name = "Irongate PCI IO",
++ .flags = IORESOURCE_IO,
++};
+ static struct resource irongate_mem = {
+ .name = "Irongate PCI MEM",
+ .flags = IORESOURCE_MEM,
+@@ -210,6 +214,7 @@ nautilus_init_pci(void)
+
+ irongate = pci_get_bus_and_slot(0, 0);
+ bus->self = irongate;
++ bus->resource[0] = &irongate_io;
+ bus->resource[1] = &irongate_mem;
+
+ pci_bus_size_bridges(bus);
+diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
+index ecebb89..a559ee7 100644
+--- a/arch/arm/kernel/perf_event.c
++++ b/arch/arm/kernel/perf_event.c
+@@ -326,7 +326,10 @@ validate_event(struct pmu_hw_events *hw_events,
+ struct hw_perf_event fake_event = event->hw;
+ struct pmu *leader_pmu = event->group_leader->pmu;
+
+- if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
++ if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
++ return 1;
++
++ if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
+ return 1;
+
+ return armpmu->get_event_idx(hw_events, &fake_event) >= 0;
+diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
+index e0b0e7a..09f8851 100644
+--- a/arch/arm/mm/cache-feroceon-l2.c
++++ b/arch/arm/mm/cache-feroceon-l2.c
+@@ -342,6 +342,7 @@ void __init feroceon_l2_init(int __l2_wt_override)
+ outer_cache.inv_range = feroceon_l2_inv_range;
+ outer_cache.clean_range = feroceon_l2_clean_range;
+ outer_cache.flush_range = feroceon_l2_flush_range;
++ outer_cache.inv_all = l2_inv_all;
+
+ enable_l2();
+
+diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
+index 88fb3d9..927a639 100644
+--- a/arch/arm/mm/proc-arm920.S
++++ b/arch/arm/mm/proc-arm920.S
+@@ -380,7 +380,7 @@ ENTRY(cpu_arm920_set_pte_ext)
+ /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+ .globl cpu_arm920_suspend_size
+ .equ cpu_arm920_suspend_size, 4 * 3
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_ARM_CPU_SUSPEND
+ ENTRY(cpu_arm920_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
+index 9f8fd91..090f18f 100644
+--- a/arch/arm/mm/proc-arm926.S
++++ b/arch/arm/mm/proc-arm926.S
+@@ -395,7 +395,7 @@ ENTRY(cpu_arm926_set_pte_ext)
+ /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+ .globl cpu_arm926_suspend_size
+ .equ cpu_arm926_suspend_size, 4 * 3
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_ARM_CPU_SUSPEND
+ ENTRY(cpu_arm926_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
+index 7d91545..6594aef 100644
+--- a/arch/arm/mm/proc-sa1100.S
++++ b/arch/arm/mm/proc-sa1100.S
+@@ -169,7 +169,7 @@ ENTRY(cpu_sa1100_set_pte_ext)
+
+ .globl cpu_sa1100_suspend_size
+ .equ cpu_sa1100_suspend_size, 4 * 3
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_ARM_CPU_SUSPEND
+ ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r6, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
+index d061d2f..8168d99 100644
+--- a/arch/arm/mm/proc-v6.S
++++ b/arch/arm/mm/proc-v6.S
+@@ -129,7 +129,7 @@ ENTRY(cpu_v6_set_pte_ext)
+ /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+ .globl cpu_v6_suspend_size
+ .equ cpu_v6_suspend_size, 4 * 6
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_ARM_CPU_SUSPEND
+ ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r9, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
+index abf0507..5c4969d 100644
+--- a/arch/arm/mm/proc-xsc3.S
++++ b/arch/arm/mm/proc-xsc3.S
+@@ -407,7 +407,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
+
+ .globl cpu_xsc3_suspend_size
+ .equ cpu_xsc3_suspend_size, 4 * 6
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_ARM_CPU_SUSPEND
+ ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r9, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
+index 3277904..b09d036 100644
+--- a/arch/arm/mm/proc-xscale.S
++++ b/arch/arm/mm/proc-xscale.S
+@@ -521,7 +521,7 @@ ENTRY(cpu_xscale_set_pte_ext)
+
+ .globl cpu_xscale_suspend_size
+ .equ cpu_xscale_suspend_size, 4 * 6
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_ARM_CPU_SUSPEND
+ ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r9, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index dc36ea6..eb19b6c 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -186,7 +186,13 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
+ (0x1UL << 4), &dummy1, &dummy2);
+ if (lpar_rc == H_SUCCESS)
+ return i;
+- BUG_ON(lpar_rc != H_NOT_FOUND);
++
++ /*
++ * The test for adjunct partition is performed before the
++ * ANDCOND test. H_RESOURCE may be returned, so we need to
++ * check for that as well.
++ */
++ BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE);
+
+ slot_offset++;
+ slot_offset &= 0x7;
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index b4973f4..cfb5a40 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -393,8 +393,8 @@ struct kvm_vcpu_arch {
+ gpa_t time;
+ struct pvclock_vcpu_time_info hv_clock;
+ unsigned int hw_tsc_khz;
+- unsigned int time_offset;
+- struct page *time_page;
++ struct gfn_to_hva_cache pv_time;
++ bool pv_time_enabled;
+
+ struct {
+ u64 msr_val;
+diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
+index a7d2db9..91e758b 100644
+--- a/arch/x86/include/asm/paravirt.h
++++ b/arch/x86/include/asm/paravirt.h
+@@ -740,7 +740,10 @@ static inline void arch_leave_lazy_mmu_mode(void)
+ PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
+ }
+
+-void arch_flush_lazy_mmu_mode(void);
++static inline void arch_flush_lazy_mmu_mode(void)
++{
++ PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush);
++}
+
+ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
+ phys_addr_t phys, pgprot_t flags)
+diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
+index 8e8b9a4..faf2c04 100644
+--- a/arch/x86/include/asm/paravirt_types.h
++++ b/arch/x86/include/asm/paravirt_types.h
+@@ -91,6 +91,7 @@ struct pv_lazy_ops {
+ /* Set deferred update mode, used for batching operations. */
+ void (*enter)(void);
+ void (*leave)(void);
++ void (*flush)(void);
+ };
+
+ struct pv_time_ops {
+@@ -680,6 +681,7 @@ void paravirt_end_context_switch(struct task_struct *next);
+
+ void paravirt_enter_lazy_mmu(void);
+ void paravirt_leave_lazy_mmu(void);
++void paravirt_flush_lazy_mmu(void);
+
+ void _paravirt_nop(void);
+ u32 _paravirt_ident_32(u32);
+diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
+index d90272e..84c938f 100644
+--- a/arch/x86/kernel/paravirt.c
++++ b/arch/x86/kernel/paravirt.c
+@@ -261,6 +261,18 @@ void paravirt_leave_lazy_mmu(void)
+ leave_lazy(PARAVIRT_LAZY_MMU);
+ }
+
++void paravirt_flush_lazy_mmu(void)
++{
++ preempt_disable();
++
++ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
++ arch_leave_lazy_mmu_mode();
++ arch_enter_lazy_mmu_mode();
++ }
++
++ preempt_enable();
++}
++
+ void paravirt_start_context_switch(struct task_struct *prev)
+ {
+ BUG_ON(preemptible());
+@@ -290,18 +302,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
+ return percpu_read(paravirt_lazy_mode);
+ }
+
+-void arch_flush_lazy_mmu_mode(void)
+-{
+- preempt_disable();
+-
+- if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
+- arch_leave_lazy_mmu_mode();
+- arch_enter_lazy_mmu_mode();
+- }
+-
+- preempt_enable();
+-}
+-
+ struct pv_info pv_info = {
+ .name = "bare hardware",
+ .paravirt_enabled = 0,
+@@ -475,6 +475,7 @@ struct pv_mmu_ops pv_mmu_ops = {
+ .lazy_mode = {
+ .enter = paravirt_nop,
+ .leave = paravirt_nop,
++ .flush = paravirt_nop,
+ },
+
+ .set_fixmap = native_set_fixmap,
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index f4063fd..e82a53a 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1105,7 +1105,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
+ {
+ unsigned long flags;
+ struct kvm_vcpu_arch *vcpu = &v->arch;
+- void *shared_kaddr;
+ unsigned long this_tsc_khz;
+ s64 kernel_ns, max_kernel_ns;
+ u64 tsc_timestamp;
+@@ -1141,7 +1140,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
+
+ local_irq_restore(flags);
+
+- if (!vcpu->time_page)
++ if (!vcpu->pv_time_enabled)
+ return 0;
+
+ /*
+@@ -1199,14 +1198,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
+ */
+ vcpu->hv_clock.version += 2;
+
+- shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0);
+-
+- memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
+- sizeof(vcpu->hv_clock));
+-
+- kunmap_atomic(shared_kaddr, KM_USER0);
+-
+- mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
++ kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
++ &vcpu->hv_clock,
++ sizeof(vcpu->hv_clock));
+ return 0;
+ }
+
+@@ -1486,7 +1480,8 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
+ return 0;
+ }
+
+- if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa))
++ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa,
++ sizeof(u32)))
+ return 1;
+
+ vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS);
+@@ -1496,10 +1491,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
+
+ static void kvmclock_reset(struct kvm_vcpu *vcpu)
+ {
+- if (vcpu->arch.time_page) {
+- kvm_release_page_dirty(vcpu->arch.time_page);
+- vcpu->arch.time_page = NULL;
+- }
++ vcpu->arch.pv_time_enabled = false;
+ }
+
+ static void accumulate_steal_time(struct kvm_vcpu *vcpu)
+@@ -1591,6 +1583,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+ break;
+ case MSR_KVM_SYSTEM_TIME_NEW:
+ case MSR_KVM_SYSTEM_TIME: {
++ u64 gpa_offset;
+ kvmclock_reset(vcpu);
+
+ vcpu->arch.time = data;
+@@ -1600,16 +1593,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+ if (!(data & 1))
+ break;
+
+- /* ...but clean it before doing the actual write */
+- vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
++ gpa_offset = data & ~(PAGE_MASK | 1);
+
+- vcpu->arch.time_page =
+- gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
+-
+- if (is_error_page(vcpu->arch.time_page)) {
+- kvm_release_page_clean(vcpu->arch.time_page);
+- vcpu->arch.time_page = NULL;
+- }
++ if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
++ &vcpu->arch.pv_time, data & ~1ULL,
++ sizeof(struct pvclock_vcpu_time_info)))
++ vcpu->arch.pv_time_enabled = false;
++ else
++ vcpu->arch.pv_time_enabled = true;
+ break;
+ }
+ case MSR_KVM_ASYNC_PF_EN:
+@@ -1625,7 +1616,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+ return 1;
+
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime,
+- data & KVM_STEAL_VALID_BITS))
++ data & KVM_STEAL_VALID_BITS,
++ sizeof(struct kvm_steal_time)))
+ return 1;
+
+ vcpu->arch.st.msr_val = data;
+@@ -6549,6 +6541,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+ if (!zalloc_cpumask_var(&vcpu->arch.wbinvd_dirty_mask, GFP_KERNEL))
+ goto fail_free_mce_banks;
+
++ vcpu->arch.pv_time_enabled = false;
+ kvm_async_pf_hash_reset(vcpu);
+
+ return 0;
+diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
+index cf4603b..8f4fda4 100644
+--- a/arch/x86/lguest/boot.c
++++ b/arch/x86/lguest/boot.c
+@@ -1328,6 +1328,7 @@ __init void lguest_init(void)
+ pv_mmu_ops.read_cr3 = lguest_read_cr3;
+ pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
+ pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
++ pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu;
+ pv_mmu_ops.pte_update = lguest_pte_update;
+ pv_mmu_ops.pte_update_defer = lguest_pte_update;
+
+diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
+index 7b73c88..53a7b69 100644
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -377,10 +377,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
+ if (pgd_none(*pgd_ref))
+ return -1;
+
+- if (pgd_none(*pgd))
++ if (pgd_none(*pgd)) {
+ set_pgd(pgd, *pgd_ref);
+- else
++ arch_flush_lazy_mmu_mode();
++ } else {
+ BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
++ }
+
+ /*
+ * Below here mismatches are bugs because these lower tables
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
+index 2b8b0de..fe00be6 100644
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -2079,6 +2079,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
+ .lazy_mode = {
+ .enter = paravirt_enter_lazy_mmu,
+ .leave = xen_leave_lazy_mmu,
++ .flush = paravirt_flush_lazy_mmu,
+ },
+
+ .set_fixmap = xen_set_fixmap,
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index f0b2ca8..1789e7a 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -200,6 +200,8 @@ queue_store_##name(struct request_queue *q, const char *page, size_t count) \
+ unsigned long val; \
+ ssize_t ret; \
+ ret = queue_var_store(&val, page, count); \
++ if (ret < 0) \
++ return ret; \
+ if (neg) \
+ val = !val; \
+ \
+diff --git a/crypto/gcm.c b/crypto/gcm.c
+index 1a25263..b97b186 100644
+--- a/crypto/gcm.c
++++ b/crypto/gcm.c
+@@ -44,6 +44,7 @@ struct crypto_rfc4543_ctx {
+
+ struct crypto_rfc4543_req_ctx {
+ u8 auth_tag[16];
++ u8 assocbuf[32];
+ struct scatterlist cipher[1];
+ struct scatterlist payload[2];
+ struct scatterlist assoc[2];
+@@ -1142,9 +1143,19 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
+ scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2);
+ assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);
+
+- sg_init_table(assoc, 2);
+- sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
+- req->assoc->offset);
++ if (req->assoc->length == req->assoclen) {
++ sg_init_table(assoc, 2);
++ sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
++ req->assoc->offset);
++ } else {
++ BUG_ON(req->assoclen > sizeof(rctx->assocbuf));
++
++ scatterwalk_map_and_copy(rctx->assocbuf, req->assoc, 0,
++ req->assoclen, 0);
++
++ sg_init_table(assoc, 2);
++ sg_set_buf(assoc, rctx->assocbuf, req->assoclen);
++ }
+ scatterwalk_crypto_chain(assoc, payload, 0, 2);
+
+ aead_request_set_tfm(subreq, ctx->child);
+diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
+index df47397..ddfc1c1 100644
+--- a/drivers/ata/ata_piix.c
++++ b/drivers/ata/ata_piix.c
+@@ -150,6 +150,7 @@ enum piix_controller_ids {
+ tolapai_sata,
+ piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */
+ ich8_sata_snb,
++ ich8_2port_sata_snb,
+ };
+
+ struct piix_map_db {
+@@ -326,7 +327,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
+ /* SATA Controller IDE (Lynx Point) */
+ { 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
+ /* SATA Controller IDE (Lynx Point) */
+- { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
++ { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
+ /* SATA Controller IDE (Lynx Point) */
+ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+ /* SATA Controller IDE (Lynx Point-LP) */
+@@ -519,6 +520,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
+ [ich8m_apple_sata] = &ich8m_apple_map_db,
+ [tolapai_sata] = &tolapai_map_db,
+ [ich8_sata_snb] = &ich8_map_db,
++ [ich8_2port_sata_snb] = &ich8_2port_map_db,
+ };
+
+ static struct ata_port_info piix_port_info[] = {
+@@ -660,6 +662,16 @@ static struct ata_port_info piix_port_info[] = {
+ .port_ops = &piix_sata_ops,
+ },
+
++ [ich8_2port_sata_snb] =
++ {
++ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR
++ | PIIX_FLAG_PIO16,
++ .pio_mask = ATA_PIO4,
++ .mwdma_mask = ATA_MWDMA2,
++ .udma_mask = ATA_UDMA6,
++ .port_ops = &piix_sata_ops,
++ },
++
+ };
+
+ static struct pci_bits piix_enable_bits[] = {
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index c9540c0..288b635 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -2401,6 +2401,9 @@ int ata_dev_configure(struct ata_device *dev)
+ dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
+ dev->max_sectors);
+
++ if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48)
++ dev->max_sectors = ATA_MAX_SECTORS_LBA48;
++
+ if (ap->ops->dev_config)
+ ap->ops->dev_config(dev);
+
+@@ -4057,6 +4060,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
+ /* Weird ATAPI devices */
+ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
+ { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA },
++ { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 },
+
+ /* Devices we expect to fail diagnostics */
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index 012a9d2..144d37c 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -274,6 +274,7 @@ enum intel_pch {
+
+ #define QUIRK_PIPEA_FORCE (1<<0)
+ #define QUIRK_LVDS_SSC_DISABLE (1<<1)
++#define QUIRK_INVERT_BRIGHTNESS (1<<2)
+
+ struct intel_fbdev;
+ struct intel_fbc_work;
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 17961df..897ca06 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -25,6 +25,7 @@
+ */
+
+ #include <linux/cpufreq.h>
++#include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <linux/input.h>
+ #include <linux/i2c.h>
+@@ -8831,6 +8832,16 @@ static void quirk_ssc_force_disable(struct drm_device *dev)
+ dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE;
+ }
+
++/*
++ * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
++ * brightness value
++ */
++static void quirk_invert_brightness(struct drm_device *dev)
++{
++ struct drm_i915_private *dev_priv = dev->dev_private;
++ dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS;
++}
++
+ struct intel_quirk {
+ int device;
+ int subsystem_vendor;
+@@ -8838,6 +8849,34 @@ struct intel_quirk {
+ void (*hook)(struct drm_device *dev);
+ };
+
++/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
++struct intel_dmi_quirk {
++ void (*hook)(struct drm_device *dev);
++ const struct dmi_system_id (*dmi_id_list)[];
++};
++
++static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
++{
++ DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
++ return 1;
++}
++
++static const struct intel_dmi_quirk intel_dmi_quirks[] = {
++ {
++ .dmi_id_list = &(const struct dmi_system_id[]) {
++ {
++ .callback = intel_dmi_reverse_brightness,
++ .ident = "NCR Corporation",
++ .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
++ DMI_MATCH(DMI_PRODUCT_NAME, ""),
++ },
++ },
++ { } /* terminating entry */
++ },
++ .hook = quirk_invert_brightness,
++ },
++};
++
+ struct intel_quirk intel_quirks[] = {
+ /* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */
+ { 0x2a42, 0x103c, 0x30eb, quirk_pipea_force },
+@@ -8865,6 +8904,18 @@ struct intel_quirk intel_quirks[] = {
+
+ /* Sony Vaio Y cannot use SSC on LVDS */
+ { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
++
++ /* Acer Aspire 5734Z must invert backlight brightness */
++ { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
++
++ /* Acer/eMachines G725 */
++ { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
++
++ /* Acer/eMachines e725 */
++ { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
++
++ /* Acer/Packard Bell NCL20 */
++ { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
+ };
+
+ static void intel_init_quirks(struct drm_device *dev)
+@@ -8882,6 +8933,10 @@ static void intel_init_quirks(struct drm_device *dev)
+ q->subsystem_device == PCI_ANY_ID))
+ q->hook(dev);
+ }
++ for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
++ if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
++ intel_dmi_quirks[i].hook(dev);
++ }
+ }
+
+ /* Disable the VGA plane that we never use */
+diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
+index 04d79fd..72b8949 100644
+--- a/drivers/gpu/drm/i915/intel_panel.c
++++ b/drivers/gpu/drm/i915/intel_panel.c
+@@ -28,6 +28,7 @@
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
++#include <linux/moduleparam.h>
+ #include "intel_drv.h"
+
+ #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */
+@@ -191,6 +192,27 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev)
+ return max;
+ }
+
++static int i915_panel_invert_brightness;
++MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
++ "(-1 force normal, 0 machine defaults, 1 force inversion), please "
++ "report PCI device ID, subsystem vendor and subsystem device ID "
++ "to dri-devel@lists.freedesktop.org, if your machine needs it. "
++ "It will then be included in an upcoming module version.");
++module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
++static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
++{
++ struct drm_i915_private *dev_priv = dev->dev_private;
++
++ if (i915_panel_invert_brightness < 0)
++ return val;
++
++ if (i915_panel_invert_brightness > 0 ||
++ dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS)
++ return intel_panel_get_max_backlight(dev) - val;
++
++ return val;
++}
++
+ u32 intel_panel_get_backlight(struct drm_device *dev)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+@@ -211,6 +233,7 @@ u32 intel_panel_get_backlight(struct drm_device *dev)
+ }
+ }
+
++ val = intel_panel_compute_brightness(dev, val);
+ DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
+ return val;
+ }
+@@ -228,6 +251,7 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level
+ u32 tmp;
+
+ DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
++ level = intel_panel_compute_brightness(dev, level);
+
+ if (HAS_PCH_SPLIT(dev))
+ return intel_pch_panel_set_backlight(dev, level);
+diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
+index 58434e8..37fe246 100644
+--- a/drivers/gpu/vga/vga_switcheroo.c
++++ b/drivers/gpu/vga/vga_switcheroo.c
+@@ -26,6 +26,7 @@
+ #include <linux/fb.h>
+
+ #include <linux/pci.h>
++#include <linux/console.h>
+ #include <linux/vga_switcheroo.h>
+
+ struct vga_switcheroo_client {
+@@ -256,8 +257,10 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
+
+ if (new_client->fb_info) {
+ struct fb_event event;
++ console_lock();
+ event.info = new_client->fb_info;
+ fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
++ console_unlock();
+ }
+
+ ret = vgasr_priv.handler->switchto(new_client->id);
+diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
+index 1201a15..08e7e72 100644
+--- a/drivers/hwspinlock/hwspinlock_core.c
++++ b/drivers/hwspinlock/hwspinlock_core.c
+@@ -416,6 +416,8 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "%s: can't power on device\n", __func__);
++ pm_runtime_put_noidle(dev);
++ module_put(dev->driver->owner);
+ return ret;
+ }
+
+diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
+index e7dc732..1d90e26 100644
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
+@@ -1154,7 +1154,11 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
+ unsigned long off;
+ u32 len;
+
+- if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
++ /* This is broken because it assumes the MTD device is map-based
++ and that mtd->priv is a valid struct map_info. It should be
++ replaced with something that uses the mtd_get_unmapped_area()
++ operation properly. */
++ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ start = map->phys;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
+diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
+index c3dd9d0..1ee5f0c 100644
+--- a/drivers/net/can/sja1000/sja1000_of_platform.c
++++ b/drivers/net/can/sja1000/sja1000_of_platform.c
+@@ -94,8 +94,8 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev)
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct resource res;
+- const u32 *prop;
+- int err, irq, res_size, prop_size;
++ u32 prop;
++ int err, irq, res_size;
+ void __iomem *base;
+
+ err = of_address_to_resource(np, 0, &res);
+@@ -136,27 +136,27 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev)
+ priv->read_reg = sja1000_ofp_read_reg;
+ priv->write_reg = sja1000_ofp_write_reg;
+
+- prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
+- if (prop && (prop_size == sizeof(u32)))
+- priv->can.clock.freq = *prop / 2;
++ err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop);
++ if (!err)
++ priv->can.clock.freq = prop / 2;
+ else
+ priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
+
+- prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
+- if (prop && (prop_size == sizeof(u32)))
+- priv->ocr |= *prop & OCR_MODE_MASK;
++ err = of_property_read_u32(np, "nxp,tx-output-mode", &prop);
++ if (!err)
++ priv->ocr |= prop & OCR_MODE_MASK;
+ else
+ priv->ocr |= OCR_MODE_NORMAL; /* default */
+
+- prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
+- if (prop && (prop_size == sizeof(u32)))
+- priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
++ err = of_property_read_u32(np, "nxp,tx-output-config", &prop);
++ if (!err)
++ priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+ else
+ priv->ocr |= OCR_TX0_PULLDOWN; /* default */
+
+- prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
+- if (prop && (prop_size == sizeof(u32)) && *prop) {
+- u32 divider = priv->can.clock.freq * 2 / *prop;
++ err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop);
++ if (!err && prop) {
++ u32 divider = priv->can.clock.freq * 2 / prop;
+
+ if (divider > 1)
+ priv->cdr |= divider / 2 - 1;
+@@ -166,8 +166,7 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev)
+ priv->cdr |= CDR_CLK_OFF; /* default */
+ }
+
+- prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
+- if (!prop)
++ if (!of_property_read_bool(np, "nxp,no-comparator-bypass"))
+ priv->cdr |= CDR_CBP; /* default */
+
+ priv->irq_flags = IRQF_SHARED;
+diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
+index a6153f1..d812790 100644
+--- a/drivers/net/ethernet/realtek/r8169.c
++++ b/drivers/net/ethernet/realtek/r8169.c
+@@ -3516,6 +3516,30 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
+ }
+ }
+
++static void rtl_speed_down(struct rtl8169_private *tp)
++{
++ u32 adv;
++ int lpa;
++
++ rtl_writephy(tp, 0x1f, 0x0000);
++ lpa = rtl_readphy(tp, MII_LPA);
++
++ if (lpa & (LPA_10HALF | LPA_10FULL))
++ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full;
++ else if (lpa & (LPA_100HALF | LPA_100FULL))
++ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
++ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
++ else
++ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
++ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
++ (tp->mii.supports_gmii ?
++ ADVERTISED_1000baseT_Half |
++ ADVERTISED_1000baseT_Full : 0);
++
++ rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL,
++ adv);
++}
++
+ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
+ {
+ void __iomem *ioaddr = tp->mmio_addr;
+@@ -3541,9 +3565,7 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp)
+ if (!(__rtl8169_get_wol(tp) & WAKE_ANY))
+ return false;
+
+- rtl_writephy(tp, 0x1f, 0x0000);
+- rtl_writephy(tp, MII_BMCR, 0x0000);
+-
++ rtl_speed_down(tp);
+ rtl_wol_suspend_quirk(tp);
+
+ return true;
+diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+index 06b3f0d..c16bea4 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+@@ -648,7 +648,7 @@ static const u32 ar9580_1p0_mac_core[][2] = {
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x40000000},
+ {0x00008260, 0x00080922},
+- {0x00008264, 0x9bc00010},
++ {0x00008264, 0x9d400010},
+ {0x00008268, 0xffffffff},
+ {0x0000826c, 0x0000ffff},
+ {0x00008270, 0x00000000},
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+index 966661c..84890d5 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+@@ -801,7 +801,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
+ * required version.
+ */
+ if (priv->fw_version_major != MAJOR_VERSION_REQ ||
+- priv->fw_version_minor != MINOR_VERSION_REQ) {
++ priv->fw_version_minor < MINOR_VERSION_REQ) {
+ dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
+ MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
+ return -EINVAL;
+diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
+index 17148bb..10fe07d 100644
+--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
+@@ -52,8 +52,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+- ERROR(rt2x00dev, "Indirect register access failed: "
+- "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
++ printk_once(KERN_ERR "%s() Indirect register access failed: "
++ "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
+ *reg = ~0;
+
+ return 0;
+diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c
+index 2264331..b96766b 100644
+--- a/drivers/platform/x86/msi-wmi.c
++++ b/drivers/platform/x86/msi-wmi.c
+@@ -176,7 +176,7 @@ static void msi_wmi_notify(u32 value, void *context)
+ pr_debug("Suppressed key event 0x%X - "
+ "Last press was %lld us ago\n",
+ key->code, ktime_to_us(diff));
+- return;
++ goto msi_wmi_notify_exit;
+ }
+ last_pressed[key->code - SCANCODE_BASE] = cur;
+
+@@ -195,6 +195,8 @@ static void msi_wmi_notify(u32 value, void *context)
+ pr_info("Unknown key pressed - %x\n", eventcode);
+ } else
+ pr_info("Unknown event received\n");
++
++msi_wmi_notify_exit:
+ kfree(response.pointer);
+ }
+
+diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
+index 0364ca2..d5f4eb8 100644
+--- a/drivers/target/target_core_alua.c
++++ b/drivers/target/target_core_alua.c
+@@ -393,8 +393,9 @@ static inline int core_alua_state_standby(
+ case REPORT_LUNS:
+ case RECEIVE_DIAGNOSTIC:
+ case SEND_DIAGNOSTIC:
++ return 0;
+ case MAINTENANCE_IN:
+- switch (cdb[1]) {
++ switch (cdb[1] & 0x1f) {
+ case MI_REPORT_TARGET_PGS:
+ return 0;
+ default:
+@@ -435,8 +436,9 @@ static inline int core_alua_state_unavailable(
+ switch (cdb[0]) {
+ case INQUIRY:
+ case REPORT_LUNS:
++ return 0;
+ case MAINTENANCE_IN:
+- switch (cdb[1]) {
++ switch (cdb[1] & 0x1f) {
+ case MI_REPORT_TARGET_PGS:
+ return 0;
+ default:
+@@ -475,8 +477,9 @@ static inline int core_alua_state_transition(
+ switch (cdb[0]) {
+ case INQUIRY:
+ case REPORT_LUNS:
++ return 0;
+ case MAINTENANCE_IN:
+- switch (cdb[1]) {
++ switch (cdb[1] & 0x1f) {
+ case MI_REPORT_TARGET_PGS:
+ return 0;
+ default:
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 9176b2e..898c1de 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -1445,6 +1445,7 @@ static inline void transport_generic_prepare_cdb(
+ case VERIFY_16: /* SBC - VRProtect */
+ case WRITE_VERIFY: /* SBC - VRProtect */
+ case WRITE_VERIFY_12: /* SBC - VRProtect */
++ case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */
+ break;
+ default:
+ cdb[1] &= 0x1f; /* clear logical unit number */
+@@ -2683,7 +2684,7 @@ static int transport_generic_cmd_sequencer(
+ /*
+ * Check for emulated MI_REPORT_TARGET_PGS.
+ */
+- if (cdb[1] == MI_REPORT_TARGET_PGS &&
++ if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS &&
+ su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+ cmd->execute_task =
+ target_emulate_report_target_port_groups;
+diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
+index dd9a574..f6fb292 100644
+--- a/drivers/thermal/thermal_sys.c
++++ b/drivers/thermal/thermal_sys.c
+@@ -1399,6 +1399,7 @@ static int __init thermal_init(void)
+ idr_destroy(&thermal_cdev_idr);
+ mutex_destroy(&thermal_idr_lock);
+ mutex_destroy(&thermal_list_lock);
++ return result;
+ }
+ result = genetlink_init();
+ return result;
+diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
+index 18e875b..3ca6c0d 100644
+--- a/drivers/usb/serial/ark3116.c
++++ b/drivers/usb/serial/ark3116.c
+@@ -68,7 +68,6 @@ static int is_irda(struct usb_serial *serial)
+ }
+
+ struct ark3116_private {
+- wait_queue_head_t delta_msr_wait;
+ struct async_icount icount;
+ int irda; /* 1 for irda device */
+
+@@ -148,7 +147,6 @@ static int ark3116_attach(struct usb_serial *serial)
+ if (!priv)
+ return -ENOMEM;
+
+- init_waitqueue_head(&priv->delta_msr_wait);
+ mutex_init(&priv->hw_lock);
+ spin_lock_init(&priv->status_lock);
+
+@@ -460,10 +458,14 @@ static int ark3116_ioctl(struct tty_struct *tty,
+ case TIOCMIWAIT:
+ for (;;) {
+ struct async_icount prev = priv->icount;
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ if ((prev.rng == priv->icount.rng) &&
+ (prev.dsr == priv->icount.dsr) &&
+ (prev.dcd == priv->icount.dcd) &&
+@@ -584,7 +586,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
+ priv->icount.dcd++;
+ if (msr & UART_MSR_TERI)
+ priv->icount.rng++;
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+ }
+
+diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
+index 6ae1c06..c4d95b0 100644
+--- a/drivers/usb/serial/ch341.c
++++ b/drivers/usb/serial/ch341.c
+@@ -82,7 +82,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
+
+ struct ch341_private {
+ spinlock_t lock; /* access lock */
+- wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
+ unsigned baud_rate; /* set baud rate */
+ u8 line_control; /* set line control value RTS/DTR */
+ u8 line_status; /* active status of modem control inputs */
+@@ -262,7 +261,6 @@ static int ch341_attach(struct usb_serial *serial)
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+ priv->baud_rate = DEFAULT_BAUD_RATE;
+ priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
+
+@@ -299,7 +297,7 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on)
+ priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_handshake(port->serial->dev, priv->line_control);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+
+ static void ch341_close(struct usb_serial_port *port)
+@@ -503,7 +501,7 @@ static void ch341_read_int_callback(struct urb *urb)
+ tty_kref_put(tty);
+ }
+
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+
+ exit:
+@@ -529,11 +527,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (!multi_change) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ multi_change = priv->multi_status_change;
+diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
+index d9906eb..01a44d3 100644
+--- a/drivers/usb/serial/cypress_m8.c
++++ b/drivers/usb/serial/cypress_m8.c
+@@ -150,7 +150,6 @@ struct cypress_private {
+ int baud_rate; /* stores current baud rate in
+ integer form */
+ int isthrottled; /* if throttled, discard reads */
+- wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
+ char prev_status, diff_status; /* used for TIOCMIWAIT */
+ /* we pass a pointer to this as the argument sent to
+ cypress_set_termios old_termios */
+@@ -488,7 +487,6 @@ static int generic_startup(struct usb_serial *serial)
+ kfree(priv);
+ return -ENOMEM;
+ }
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ usb_reset_configuration(serial->dev);
+
+@@ -928,12 +926,16 @@ static int cypress_ioctl(struct tty_struct *tty,
+ switch (cmd) {
+ /* This code comes from drivers/char/serial.c and ftdi_sio.c */
+ case TIOCMIWAIT:
+- while (priv != NULL) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ for (;;) {
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+- else {
++
++ if (port->serial->disconnected)
++ return -EIO;
++
++ {
+ char diff = priv->diff_status;
+ if (diff == 0)
+ return -EIO; /* no change => error */
+@@ -1261,7 +1263,7 @@ static void cypress_read_int_callback(struct urb *urb)
+ if (priv->current_status != priv->prev_status) {
+ priv->diff_status |= priv->current_status ^
+ priv->prev_status;
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ priv->prev_status = priv->current_status;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 878ff05..06394e5a 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -74,9 +74,7 @@ struct ftdi_private {
+ int flags; /* some ASYNC_xxxx flags are supported */
+ unsigned long last_dtr_rts; /* saved modem control outputs */
+ struct async_icount icount;
+- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ char prev_status; /* Used for TIOCMIWAIT */
+- bool dev_gone; /* Used to abort TIOCMIWAIT */
+ char transmit_empty; /* If transmitter is empty or not */
+ struct usb_serial_port *port;
+ __u16 interface; /* FT2232C, FT2232H or FT4232H port interface
+@@ -1708,10 +1706,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ kref_init(&priv->kref);
+ mutex_init(&priv->cfg_lock);
+ memset(&priv->icount, 0x00, sizeof(priv->icount));
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ priv->flags = ASYNC_LOW_LATENCY;
+- priv->dev_gone = false;
+
+ if (quirk && quirk->port_probe)
+ quirk->port_probe(priv);
+@@ -1869,8 +1865,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
+
+ dbg("%s", __func__);
+
+- priv->dev_gone = true;
+- wake_up_interruptible_all(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ remove_sysfs_attrs(port);
+
+@@ -2025,7 +2020,7 @@ static int ftdi_process_packet(struct tty_struct *tty,
+ if (diff_status & FTDI_RS0_RLSD)
+ priv->icount.dcd++;
+
+- wake_up_interruptible_all(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ priv->prev_status = status;
+ }
+
+@@ -2424,11 +2419,15 @@ static int ftdi_ioctl(struct tty_struct *tty,
+ */
+ case TIOCMIWAIT:
+ cprev = priv->icount;
+- while (!priv->dev_gone) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ for (;;) {
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = priv->icount;
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+@@ -2438,8 +2437,6 @@ static int ftdi_ioctl(struct tty_struct *tty,
+ }
+ cprev = cnow;
+ }
+- return -EIO;
+- break;
+ case TIOCSERGETLSR:
+ return get_lsr_info(port, (struct serial_struct __user *)arg);
+ break;
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+index 2ee8075..0af0b41 100644
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -114,7 +114,6 @@ struct edgeport_port {
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+ wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */
+ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
+- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
+
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+@@ -885,7 +884,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
+ /* initialize our wait queues */
+ init_waitqueue_head(&edge_port->wait_open);
+ init_waitqueue_head(&edge_port->wait_chase);
+- init_waitqueue_head(&edge_port->delta_msr_wait);
+ init_waitqueue_head(&edge_port->wait_command);
+
+ /* initialize our icount structure */
+@@ -1703,13 +1701,17 @@ static int edge_ioctl(struct tty_struct *tty,
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = edge_port->icount;
+ while (1) {
+- prepare_to_wait(&edge_port->delta_msr_wait,
++ prepare_to_wait(&port->delta_msr_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ schedule();
+- finish_wait(&edge_port->delta_msr_wait, &wait);
++ finish_wait(&port->delta_msr_wait, &wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = edge_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+@@ -2090,7 +2092,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
+ icount->dcd++;
+ if (newMsr & EDGEPORT_MSR_DELTA_RI)
+ icount->rng++;
+- wake_up_interruptible(&edge_port->delta_msr_wait);
++ wake_up_interruptible(&edge_port->port->delta_msr_wait);
+ }
+
+ /* Save the new modem status */
+diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
+index 1f145bf..f42119d 100644
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -98,9 +98,6 @@ struct edgeport_port {
+ int close_pending;
+ int lsr_event;
+ struct async_icount icount;
+- wait_queue_head_t delta_msr_wait; /* for handling sleeping while
+- waiting for msr change to
+- happen */
+ struct edgeport_serial *edge_serial;
+ struct usb_serial_port *port;
+ __u8 bUartMode; /* Port type, 0: RS232, etc. */
+@@ -1557,7 +1554,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
+ icount->dcd++;
+ if (msr & EDGEPORT_MSR_DELTA_RI)
+ icount->rng++;
+- wake_up_interruptible(&edge_port->delta_msr_wait);
++ wake_up_interruptible(&edge_port->port->delta_msr_wait);
+ }
+
+ /* Save the new modem status */
+@@ -1876,7 +1873,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
+ dev = port->serial->dev;
+
+ memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
+- init_waitqueue_head(&edge_port->delta_msr_wait);
+
+ /* turn off loopback */
+ status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
+@@ -2574,10 +2570,14 @@ static int edge_ioctl(struct tty_struct *tty,
+ dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = edge_port->icount;
+ while (1) {
+- interruptible_sleep_on(&edge_port->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = edge_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
+index de0bb8e..96a62dd 100644
+--- a/drivers/usb/serial/mct_u232.c
++++ b/drivers/usb/serial/mct_u232.c
+@@ -168,8 +168,6 @@ struct mct_u232_private {
+ unsigned char last_msr; /* Modem Status Register */
+ unsigned int rx_flags; /* Throttling flags */
+ struct async_icount icount;
+- wait_queue_head_t msr_wait; /* for handling sleeping while waiting
+- for msr change to happen */
+ };
+
+ #define THROTTLED 0x01
+@@ -449,7 +447,6 @@ static int mct_u232_startup(struct usb_serial *serial)
+ if (!priv)
+ return -ENOMEM;
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->msr_wait);
+ usb_set_serial_port_data(serial->port[0], priv);
+
+ init_waitqueue_head(&serial->port[0]->write_wait);
+@@ -675,7 +672,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
+ tty_kref_put(tty);
+ }
+ #endif
+- wake_up_interruptible(&priv->msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ exit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+@@ -896,13 +893,17 @@ static int mct_u232_ioctl(struct tty_struct *tty,
+ cprev = mct_u232_port->icount;
+ spin_unlock_irqrestore(&mct_u232_port->lock, flags);
+ for ( ; ; ) {
+- prepare_to_wait(&mct_u232_port->msr_wait,
++ prepare_to_wait(&port->delta_msr_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ schedule();
+- finish_wait(&mct_u232_port->msr_wait, &wait);
++ finish_wait(&port->delta_msr_wait, &wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&mct_u232_port->lock, flags);
+ cnow = mct_u232_port->icount;
+ spin_unlock_irqrestore(&mct_u232_port->lock, flags);
+diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
+index 43a38aa..e89ee48 100644
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -240,7 +240,6 @@ struct moschip_port {
+ char open;
+ char open_ports;
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
+ int delta_msr_cond;
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+@@ -453,6 +452,9 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
+ icount->rng++;
+ smp_wmb();
+ }
++
++ mos7840_port->delta_msr_cond = 1;
++ wake_up_interruptible(&port->port->delta_msr_wait);
+ }
+ }
+
+@@ -1115,7 +1117,6 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
+
+ /* initialize our wait queues */
+ init_waitqueue_head(&mos7840_port->wait_chase);
+- init_waitqueue_head(&mos7840_port->delta_msr_wait);
+
+ /* initialize our icount structure */
+ memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
+@@ -2073,8 +2074,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
+ mos7840_port->read_urb_busy = false;
+ }
+ }
+- wake_up(&mos7840_port->delta_msr_wait);
+- mos7840_port->delta_msr_cond = 1;
+ dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x",
+ mos7840_port->shadowLCR);
+ }
+@@ -2284,13 +2283,18 @@ static int mos7840_ioctl(struct tty_struct *tty,
+ while (1) {
+ /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
+ mos7840_port->delta_msr_cond = 0;
+- wait_event_interruptible(mos7840_port->delta_msr_wait,
+- (mos7840_port->
++ wait_event_interruptible(port->delta_msr_wait,
++ (port->serial->disconnected ||
++ mos7840_port->
+ delta_msr_cond == 1));
+
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = mos7840_port->icount;
+ smp_rmb();
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
+index 4c29e6c..8ceaa89 100644
+--- a/drivers/usb/serial/oti6858.c
++++ b/drivers/usb/serial/oti6858.c
+@@ -196,7 +196,6 @@ struct oti6858_private {
+ u8 setup_done;
+ struct delayed_work delayed_setup_work;
+
+- wait_queue_head_t intr_wait;
+ struct usb_serial_port *port; /* USB port with which associated */
+ };
+
+@@ -357,7 +356,6 @@ static int oti6858_startup(struct usb_serial *serial)
+ break;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->intr_wait);
+ /* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
+ /* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
+ priv->port = port;
+@@ -705,11 +703,15 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (1) {
+- wait_event_interruptible(priv->intr_wait,
++ wait_event_interruptible(port->delta_msr_wait,
++ port->serial->disconnected ||
+ priv->status.pin_state != prev);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->status.pin_state & PIN_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -821,7 +823,7 @@ static void oti6858_read_int_callback(struct urb *urb)
+
+ if (!priv->transient) {
+ if (xs->pin_state != priv->status.pin_state)
+- wake_up_interruptible(&priv->intr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
+ }
+
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+index 5532ea5..fd86e0e 100644
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -150,7 +150,6 @@ enum pl2303_type {
+
+ struct pl2303_private {
+ spinlock_t lock;
+- wait_queue_head_t delta_msr_wait;
+ u8 line_control;
+ u8 line_status;
+ enum pl2303_type type;
+@@ -204,7 +203,6 @@ static int pl2303_startup(struct usb_serial *serial)
+ if (!priv)
+ goto cleanup;
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+ priv->type = type;
+ usb_set_serial_port_data(serial->port[i], priv);
+ }
+@@ -599,11 +597,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (1) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -725,7 +726,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
+ spin_unlock_irqrestore(&priv->lock, flags);
+ if (priv->line_status & UART_BREAK_ERROR)
+ usb_serial_handle_break(port);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+@@ -792,7 +793,7 @@ static void pl2303_process_read_urb(struct urb *urb)
+ line_status = priv->line_status;
+ priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ if (!urb->actual_length)
+ return;
+diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
+index 180ea6c..ba6b438 100644
+--- a/drivers/usb/serial/spcp8x5.c
++++ b/drivers/usb/serial/spcp8x5.c
+@@ -163,7 +163,6 @@ static struct usb_driver spcp8x5_driver = {
+ struct spcp8x5_private {
+ spinlock_t lock;
+ enum spcp8x5_type type;
+- wait_queue_head_t delta_msr_wait;
+ u8 line_control;
+ u8 line_status;
+ };
+@@ -197,7 +196,6 @@ static int spcp8x5_startup(struct usb_serial *serial)
+ goto cleanup;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+ priv->type = type;
+ usb_set_serial_port_data(serial->port[i] , priv);
+ }
+@@ -502,7 +500,7 @@ static void spcp8x5_process_read_urb(struct urb *urb)
+ priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /* wake up the wait for termios */
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ if (!urb->actual_length)
+ return;
+@@ -552,12 +550,15 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port,
+
+ while (1) {
+ /* wake up in bulk read */
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
+index fff7f17..bf1f8ea 100644
+--- a/drivers/usb/serial/ssu100.c
++++ b/drivers/usb/serial/ssu100.c
+@@ -78,7 +78,6 @@ struct ssu100_port_private {
+ spinlock_t status_lock;
+ u8 shadowLSR;
+ u8 shadowMSR;
+- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ struct async_icount icount;
+ };
+
+@@ -387,8 +386,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+
+ while (1) {
+- wait_event_interruptible(priv->delta_msr_wait,
+- ((priv->icount.rng != prev.rng) ||
++ wait_event_interruptible(port->delta_msr_wait,
++ (port->serial->disconnected ||
++ (priv->icount.rng != prev.rng) ||
+ (priv->icount.dsr != prev.dsr) ||
+ (priv->icount.dcd != prev.dcd) ||
+ (priv->icount.cts != prev.cts)));
+@@ -396,6 +396,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->status_lock, flags);
+ cur = priv->icount;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+@@ -478,7 +481,6 @@ static int ssu100_attach(struct usb_serial *serial)
+ }
+
+ spin_lock_init(&priv->status_lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+ usb_set_serial_port_data(port, priv);
+
+ return ssu100_initdevice(serial->dev);
+@@ -564,7 +566,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
+ priv->icount.dcd++;
+ if (msr & UART_MSR_TERI)
+ priv->icount.rng++;
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+ }
+
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
+index 2856474..4b805be 100644
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -75,7 +75,6 @@ struct ti_port {
+ int tp_flags;
+ int tp_closing_wait;/* in .01 secs */
+ struct async_icount tp_icount;
+- wait_queue_head_t tp_msr_wait; /* wait for msr change */
+ wait_queue_head_t tp_write_wait;
+ struct ti_device *tp_tdev;
+ struct usb_serial_port *tp_port;
+@@ -447,7 +446,6 @@ static int ti_startup(struct usb_serial *serial)
+ tport->tp_uart_base_addr = (i == 0 ?
+ TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
+ tport->tp_closing_wait = closing_wait;
+- init_waitqueue_head(&tport->tp_msr_wait);
+ init_waitqueue_head(&tport->tp_write_wait);
+ if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
+ GFP_KERNEL)) {
+@@ -848,9 +846,13 @@ static int ti_ioctl(struct tty_struct *tty,
+ dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = tport->tp_icount;
+ while (1) {
+- interruptible_sleep_on(&tport->tp_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = tport->tp_icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+@@ -1481,7 +1483,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
+ icount->dcd++;
+ if (msr & TI_MSR_DELTA_RI)
+ icount->rng++;
+- wake_up_interruptible(&tport->tp_msr_wait);
++ wake_up_interruptible(&tport->tp_port->delta_msr_wait);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ }
+
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index 2482d5e..850faa4 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -905,6 +905,7 @@ int usb_serial_probe(struct usb_interface *interface,
+ port->port.ops = &serial_port_ops;
+ port->serial = serial;
+ spin_lock_init(&port->lock);
++ init_waitqueue_head(&port->delta_msr_wait);
+ /* Keep this for private driver use for the moment but
+ should probably go away */
+ INIT_WORK(&port->work, usb_serial_port_work);
+diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
+index 9b8bcab..7a36dff 100644
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -843,6 +843,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
+ *
+ * Maps a virtual console @unit to a frame buffer device
+ * @newidx.
++ *
++ * This should be called with the console lock held.
+ */
+ static int set_con2fb_map(int unit, int newidx, int user)
+ {
+@@ -860,7 +862,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
+
+ if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
+ info_idx = newidx;
+- return fbcon_takeover(0);
++ return do_fbcon_takeover(0);
+ }
+
+ if (oldidx != -1)
+@@ -868,7 +870,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
+
+ found = search_fb_in_map(newidx);
+
+- console_lock();
+ con2fb_map[unit] = newidx;
+ if (!err && !found)
+ err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
+@@ -895,7 +896,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
+ if (!search_fb_in_map(info_idx))
+ info_idx = newidx;
+
+- console_unlock();
+ return err;
+ }
+
+@@ -3026,6 +3026,7 @@ static inline int fbcon_unbind(void)
+ }
+ #endif /* CONFIG_VT_HW_CONSOLE_BINDING */
+
++/* called with console_lock held */
+ static int fbcon_fb_unbind(int idx)
+ {
+ int i, new_idx = -1, ret = 0;
+@@ -3052,6 +3053,7 @@ static int fbcon_fb_unbind(int idx)
+ return ret;
+ }
+
++/* called with console_lock held */
+ static int fbcon_fb_unregistered(struct fb_info *info)
+ {
+ int i, idx;
+@@ -3089,6 +3091,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
+ return 0;
+ }
+
++/* called with console_lock held */
+ static void fbcon_remap_all(int idx)
+ {
+ int i;
+@@ -3133,6 +3136,7 @@ static inline void fbcon_select_primary(struct fb_info *info)
+ }
+ #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
+
++/* called with console_lock held */
+ static int fbcon_fb_registered(struct fb_info *info)
+ {
+ int ret = 0, i, idx;
+@@ -3285,6 +3289,7 @@ static int fbcon_event_notify(struct notifier_block *self,
+ ret = fbcon_fb_unregistered(info);
+ break;
+ case FB_EVENT_SET_CONSOLE_MAP:
++ /* called with console lock held */
+ con2fb = event->data;
+ ret = set_con2fb_map(con2fb->console - 1,
+ con2fb->framebuffer, 1);
+diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
+index c133dde..babbb07 100644
+--- a/drivers/video/fbmem.c
++++ b/drivers/video/fbmem.c
+@@ -1154,8 +1154,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
+ event.data = &con2fb;
+ if (!lock_fb_info(info))
+ return -ENODEV;
++ console_lock();
+ event.info = info;
+ ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
++ console_unlock();
+ unlock_fb_info(info);
+ break;
+ case FBIOBLANK:
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 49f3c9d..73e4cbc 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -1209,6 +1209,39 @@ int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask)
+ mask);
+ }
+
++int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
++{
++ unsigned long index = start >> PAGE_CACHE_SHIFT;
++ unsigned long end_index = end >> PAGE_CACHE_SHIFT;
++ struct page *page;
++
++ while (index <= end_index) {
++ page = find_get_page(inode->i_mapping, index);
++ BUG_ON(!page); /* Pages should be in the extent_io_tree */
++ clear_page_dirty_for_io(page);
++ page_cache_release(page);
++ index++;
++ }
++ return 0;
++}
++
++int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
++{
++ unsigned long index = start >> PAGE_CACHE_SHIFT;
++ unsigned long end_index = end >> PAGE_CACHE_SHIFT;
++ struct page *page;
++
++ while (index <= end_index) {
++ page = find_get_page(inode->i_mapping, index);
++ BUG_ON(!page); /* Pages should be in the extent_io_tree */
++ account_page_redirty(page);
++ __set_page_dirty_nobuffers(page);
++ page_cache_release(page);
++ index++;
++ }
++ return 0;
++}
++
+ /*
+ * helper function to set both pages and extents in the tree writeback
+ */
+diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
+index 7604c30..2e32510 100644
+--- a/fs/btrfs/extent_io.h
++++ b/fs/btrfs/extent_io.h
+@@ -304,6 +304,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset,
+ unsigned long *map_len);
+ int extent_range_uptodate(struct extent_io_tree *tree,
+ u64 start, u64 end);
++int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end);
++int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end);
+ int extent_clear_unlock_delalloc(struct inode *inode,
+ struct extent_io_tree *tree,
+ u64 start, u64 end, struct page *locked_page,
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index fd1a06d..1372634 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -343,6 +343,7 @@ static noinline int compress_file_range(struct inode *inode,
+ int i;
+ int will_compress;
+ int compress_type = root->fs_info->compress_type;
++ int redirty = 0;
+
+ /* if this is a small write inside eof, kick off a defragbot */
+ if (end <= BTRFS_I(inode)->disk_i_size && (end - start + 1) < 16 * 1024)
+@@ -404,6 +405,17 @@ again:
+ if (BTRFS_I(inode)->force_compress)
+ compress_type = BTRFS_I(inode)->force_compress;
+
++ /*
++ * we need to call clear_page_dirty_for_io on each
++ * page in the range. Otherwise applications with the file
++ * mmap'd can wander in and change the page contents while
++ * we are compressing them.
++ *
++ * If the compression fails for any reason, we set the pages
++ * dirty again later on.
++ */
++ extent_range_clear_dirty_for_io(inode, start, end);
++ redirty = 1;
+ ret = btrfs_compress_pages(compress_type,
+ inode->i_mapping, start,
+ total_compressed, pages,
+@@ -541,6 +553,8 @@ cleanup_and_bail_uncompressed:
+ __set_page_dirty_nobuffers(locked_page);
+ /* unlocked later on in the async handlers */
+ }
++ if (redirty)
++ extent_range_redirty_for_io(inode, start, end);
+ add_async_extent(async_cow, start, end - start + 1,
+ 0, NULL, 0, BTRFS_COMPRESS_NONE);
+ *num_added += 1;
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 19b127c..21faa12 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -316,6 +316,7 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans,
+ unsigned long src_ptr;
+ unsigned long dst_ptr;
+ int overwrite_root = 0;
++ bool inode_item = key->type == BTRFS_INODE_ITEM_KEY;
+
+ if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
+ overwrite_root = 1;
+@@ -325,6 +326,9 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans,
+
+ /* look for the key in the destination tree */
+ ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
++ if (ret < 0)
++ return ret;
++
+ if (ret == 0) {
+ char *src_copy;
+ char *dst_copy;
+@@ -366,6 +370,30 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans,
+ return 0;
+ }
+
++ /*
++ * We need to load the old nbytes into the inode so when we
++ * replay the extents we've logged we get the right nbytes.
++ */
++ if (inode_item) {
++ struct btrfs_inode_item *item;
++ u64 nbytes;
++
++ item = btrfs_item_ptr(path->nodes[0], path->slots[0],
++ struct btrfs_inode_item);
++ nbytes = btrfs_inode_nbytes(path->nodes[0], item);
++ item = btrfs_item_ptr(eb, slot,
++ struct btrfs_inode_item);
++ btrfs_set_inode_nbytes(eb, item, nbytes);
++ }
++ } else if (inode_item) {
++ struct btrfs_inode_item *item;
++
++ /*
++ * New inode, set nbytes to 0 so that the nbytes comes out
++ * properly when we replay the extents.
++ */
++ item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item);
++ btrfs_set_inode_nbytes(eb, item, 0);
+ }
+ insert:
+ btrfs_release_path(path);
+@@ -488,7 +516,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
+ u64 extent_end;
+ u64 alloc_hint;
+ u64 start = key->offset;
+- u64 saved_nbytes;
++ u64 nbytes = 0;
+ struct btrfs_file_extent_item *item;
+ struct inode *inode = NULL;
+ unsigned long size;
+@@ -498,10 +526,19 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
+ found_type = btrfs_file_extent_type(eb, item);
+
+ if (found_type == BTRFS_FILE_EXTENT_REG ||
+- found_type == BTRFS_FILE_EXTENT_PREALLOC)
+- extent_end = start + btrfs_file_extent_num_bytes(eb, item);
+- else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
++ found_type == BTRFS_FILE_EXTENT_PREALLOC) {
++ nbytes = btrfs_file_extent_num_bytes(eb, item);
++ extent_end = start + nbytes;
++
++ /*
++ * We don't add to the inodes nbytes if we are prealloc or a
++ * hole.
++ */
++ if (btrfs_file_extent_disk_bytenr(eb, item) == 0)
++ nbytes = 0;
++ } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
+ size = btrfs_file_extent_inline_len(eb, item);
++ nbytes = btrfs_file_extent_ram_bytes(eb, item);
+ extent_end = (start + size + mask) & ~mask;
+ } else {
+ ret = 0;
+@@ -550,7 +587,6 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
+ }
+ btrfs_release_path(path);
+
+- saved_nbytes = inode_get_bytes(inode);
+ /* drop any overlapping extents */
+ ret = btrfs_drop_extents(trans, inode, start, extent_end,
+ &alloc_hint, 1);
+@@ -638,7 +674,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
+ BUG_ON(ret);
+ }
+
+- inode_set_bytes(inode, saved_nbytes);
++ inode_add_bytes(inode, nbytes);
+ btrfs_update_inode(trans, root, inode);
+ out:
+ if (inode)
+diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
+index 5849e3e..32b12e5 100644
+--- a/fs/hfsplus/extents.c
++++ b/fs/hfsplus/extents.c
+@@ -517,7 +517,7 @@ void hfsplus_file_truncate(struct inode *inode)
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page;
+ void *fsdata;
+- u32 size = inode->i_size;
++ loff_t size = inode->i_size;
+
+ res = pagecache_write_begin(NULL, mapping, size, 0,
+ AOP_FLAG_UNINTERRUPTIBLE,
+diff --git a/fs/inode.c b/fs/inode.c
+index ee4e66b..e2d3633 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -634,7 +634,7 @@ void prune_icache_sb(struct super_block *sb, int nr_to_scan)
+ * inode to the back of the list so we don't spin on it.
+ */
+ if (!spin_trylock(&inode->i_lock)) {
+- list_move_tail(&inode->i_lru, &sb->s_inode_lru);
++ list_move(&inode->i_lru, &sb->s_inode_lru);
+ continue;
+ }
+
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+index 32df2b6..5856c9e 100644
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -937,7 +937,7 @@ static inline int atapi_cdb_len(const u16 *dev_id)
+ }
+ }
+
+-static inline bool atapi_command_packet_set(const u16 *dev_id)
++static inline int atapi_command_packet_set(const u16 *dev_id)
+ {
+ return (dev_id[ATA_ID_CONFIG] >> 8) & 0x1f;
+ }
+diff --git a/include/linux/kref.h b/include/linux/kref.h
+index d4a62ab..d064502 100644
+--- a/include/linux/kref.h
++++ b/include/linux/kref.h
+@@ -16,6 +16,7 @@
+ #define _KREF_H_
+
+ #include <linux/types.h>
++#include <linux/atomic.h>
+
+ struct kref {
+ atomic_t refcount;
+@@ -27,4 +28,24 @@ int kref_put(struct kref *kref, void (*release) (struct kref *kref));
+ int kref_sub(struct kref *kref, unsigned int count,
+ void (*release) (struct kref *kref));
+
++/**
++ * kref_get_unless_zero - Increment refcount for object unless it is zero.
++ * @kref: object.
++ *
++ * Return non-zero if the increment succeeded. Otherwise return 0.
++ *
++ * This function is intended to simplify locking around refcounting for
++ * objects that can be looked up from a lookup structure, and which are
++ * removed from that lookup structure in the object destructor.
++ * Operations on such objects require at least a read lock around
++ * lookup + kref_get, and a write lock around kref_put + remove from lookup
++ * structure. Furthermore, RCU implementations become extremely tricky.
++ * With a lookup followed by a kref_get_unless_zero *with return value check*
++ * locking in the kref_put path can be deferred to the actual removal from
++ * the lookup structure and RCU lookups become trivial.
++ */
++static inline int __must_check kref_get_unless_zero(struct kref *kref)
++{
++ return atomic_add_unless(&kref->refcount, 1, 0);
++}
+ #endif /* _KREF_H_ */
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index 6136821..e6796c1 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -396,7 +396,7 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
+ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ void *data, unsigned long len);
+ int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+- gpa_t gpa);
++ gpa_t gpa, unsigned long len);
+ int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
+ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
+ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
+diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
+index fa7cc72..b0bcce0 100644
+--- a/include/linux/kvm_types.h
++++ b/include/linux/kvm_types.h
+@@ -71,6 +71,7 @@ struct gfn_to_hva_cache {
+ u64 generation;
+ gpa_t gpa;
+ unsigned long hva;
++ unsigned long len;
+ struct kvm_memory_slot *memslot;
+ };
+
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index cafc09a..62467ca 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -392,6 +392,7 @@ enum {
+ ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */
+ ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */
+ ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */
++ ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */
+
+ /* DMA mask for user DMA control: User visible values; DO NOT
+ renumber */
+diff --git a/include/linux/of.h b/include/linux/of.h
+index 4948552..9bf9611 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -336,6 +336,22 @@ static inline int of_machine_is_compatible(const char *compat)
+ #define of_match_node(_matches, _node) NULL
+ #endif /* CONFIG_OF */
+
++/**
++ * of_property_read_bool - Findfrom a property
++ * @np: device node from which the property value is to be read.
++ * @propname: name of the property to be searched.
++ *
++ * Search for a property in a device node.
++ * Returns true if the property exist false otherwise.
++ */
++static inline bool of_property_read_bool(const struct device_node *np,
++ const char *propname)
++{
++ struct property *prop = of_find_property(np, propname, NULL);
++
++ return prop ? true : false;
++}
++
+ static inline int of_property_read_u32(const struct device_node *np,
+ const char *propname,
+ u32 *out_value)
+diff --git a/include/linux/preempt.h b/include/linux/preempt.h
+index 58969b2..e86bf01 100644
+--- a/include/linux/preempt.h
++++ b/include/linux/preempt.h
+@@ -91,13 +91,19 @@ do { \
+
+ #else /* !CONFIG_PREEMPT_COUNT */
+
+-#define preempt_disable() do { } while (0)
+-#define preempt_enable_no_resched() do { } while (0)
+-#define preempt_enable() do { } while (0)
++/*
++ * Even if we don't have any preemption, we need preempt disable/enable
++ * to be barriers, so that we don't have things like get_user/put_user
++ * that can cause faults and scheduling migrate into our preempt-protected
++ * region.
++ */
++#define preempt_disable() barrier()
++#define preempt_enable_no_resched() barrier()
++#define preempt_enable() barrier()
+
+-#define preempt_disable_notrace() do { } while (0)
+-#define preempt_enable_no_resched_notrace() do { } while (0)
+-#define preempt_enable_notrace() do { } while (0)
++#define preempt_disable_notrace() barrier()
++#define preempt_enable_no_resched_notrace() barrier()
++#define preempt_enable_notrace() barrier()
+
+ #endif /* CONFIG_PREEMPT_COUNT */
+
+diff --git a/include/linux/socket.h b/include/linux/socket.h
+index ad919e0..2acd2e2 100644
+--- a/include/linux/socket.h
++++ b/include/linux/socket.h
+@@ -317,6 +317,7 @@ struct ucred {
+ #define IPX_TYPE 1
+
+ extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
++extern void cred_real_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
+
+ extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
+ extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
+index a26e2fb..e2369c1 100644
+--- a/include/linux/spinlock_up.h
++++ b/include/linux/spinlock_up.h
+@@ -16,7 +16,10 @@
+ * In the debug case, 1 means unlocked, 0 means locked. (the values
+ * are inverted, to catch initialization bugs)
+ *
+- * No atomicity anywhere, we are on UP.
++ * No atomicity anywhere, we are on UP. However, we still need
++ * the compiler barriers, because we do not want the compiler to
++ * move potentially faulting instructions (notably user accesses)
++ * into the locked sequence, resulting in non-atomic execution.
+ */
+
+ #ifdef CONFIG_DEBUG_SPINLOCK
+@@ -25,6 +28,7 @@
+ static inline void arch_spin_lock(arch_spinlock_t *lock)
+ {
+ lock->slock = 0;
++ barrier();
+ }
+
+ static inline void
+@@ -32,6 +36,7 @@ arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
+ {
+ local_irq_save(flags);
+ lock->slock = 0;
++ barrier();
+ }
+
+ static inline int arch_spin_trylock(arch_spinlock_t *lock)
+@@ -39,32 +44,34 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
+ char oldval = lock->slock;
+
+ lock->slock = 0;
++ barrier();
+
+ return oldval > 0;
+ }
+
+ static inline void arch_spin_unlock(arch_spinlock_t *lock)
+ {
++ barrier();
+ lock->slock = 1;
+ }
+
+ /*
+ * Read-write spinlocks. No debug version.
+ */
+-#define arch_read_lock(lock) do { (void)(lock); } while (0)
+-#define arch_write_lock(lock) do { (void)(lock); } while (0)
+-#define arch_read_trylock(lock) ({ (void)(lock); 1; })
+-#define arch_write_trylock(lock) ({ (void)(lock); 1; })
+-#define arch_read_unlock(lock) do { (void)(lock); } while (0)
+-#define arch_write_unlock(lock) do { (void)(lock); } while (0)
++#define arch_read_lock(lock) do { barrier(); (void)(lock); } while (0)
++#define arch_write_lock(lock) do { barrier(); (void)(lock); } while (0)
++#define arch_read_trylock(lock) ({ barrier(); (void)(lock); 1; })
++#define arch_write_trylock(lock) ({ barrier(); (void)(lock); 1; })
++#define arch_read_unlock(lock) do { barrier(); (void)(lock); } while (0)
++#define arch_write_unlock(lock) do { barrier(); (void)(lock); } while (0)
+
+ #else /* DEBUG_SPINLOCK */
+ #define arch_spin_is_locked(lock) ((void)(lock), 0)
+ /* for sched.c and kernel_lock.c: */
+-# define arch_spin_lock(lock) do { (void)(lock); } while (0)
+-# define arch_spin_lock_flags(lock, flags) do { (void)(lock); } while (0)
+-# define arch_spin_unlock(lock) do { (void)(lock); } while (0)
+-# define arch_spin_trylock(lock) ({ (void)(lock); 1; })
++# define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0)
++# define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0)
++# define arch_spin_unlock(lock) do { barrier(); (void)(lock); } while (0)
++# define arch_spin_trylock(lock) ({ barrier(); (void)(lock); 1; })
+ #endif /* DEBUG_SPINLOCK */
+
+ #define arch_spin_is_contended(lock) (((void)(lock), 0))
+diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
+index b29f70b..237d5f8 100644
+--- a/include/linux/usb/serial.h
++++ b/include/linux/usb/serial.h
+@@ -71,6 +71,7 @@ enum port_dev_state {
+ * port.
+ * @flags: usb serial port flags
+ * @write_wait: a wait_queue_head_t used by the port.
++ * @delta_msr_wait: modem-status-change wait queue
+ * @work: work queue entry for the line discipline waking up.
+ * @throttled: nonzero if the read urb is inactive to throttle the device
+ * @throttle_req: nonzero if the tty wants to throttle us
+@@ -114,6 +115,7 @@ struct usb_serial_port {
+
+ unsigned long flags;
+ wait_queue_head_t write_wait;
++ wait_queue_head_t delta_msr_wait;
+ struct work_struct work;
+ char throttled;
+ char throttle_req;
+diff --git a/include/linux/writeback.h b/include/linux/writeback.h
+index a378c29..7e85d45 100644
+--- a/include/linux/writeback.h
++++ b/include/linux/writeback.h
+@@ -195,6 +195,8 @@ void writeback_set_ratelimit(void);
+ void tag_pages_for_writeback(struct address_space *mapping,
+ pgoff_t start, pgoff_t end);
+
++void account_page_redirty(struct page *page);
++
+ /* pdflush.c */
+ extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
+ read-only. */
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 0c0017c..5da0a7b 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -50,7 +50,7 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
+ {
+ scm->pid = get_pid(pid);
+ scm->cred = cred ? get_cred(cred) : NULL;
+- cred_to_ucred(pid, cred, &scm->creds);
++ cred_real_to_ucred(pid, cred, &scm->creds);
+ }
+
+ static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
+diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
+index cdd5607..e4cee8d 100644
+--- a/kernel/hrtimer.c
++++ b/kernel/hrtimer.c
+@@ -61,6 +61,7 @@
+ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
+ {
+
++ .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock),
+ .clock_base =
+ {
+ {
+@@ -1640,8 +1641,6 @@ static void __cpuinit init_hrtimers_cpu(int cpu)
+ struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
+ int i;
+
+- raw_spin_lock_init(&cpu_base->lock);
+-
+ for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
+ cpu_base->clock_base[i].cpu_base = cpu_base;
+ timerqueue_init_head(&cpu_base->clock_base[i].active);
+diff --git a/kernel/sched.c b/kernel/sched.c
+index eeeec4e..d08c9f4 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -2889,8 +2889,10 @@ static void try_to_wake_up_local(struct task_struct *p)
+ {
+ struct rq *rq = task_rq(p);
+
+- BUG_ON(rq != this_rq());
+- BUG_ON(p == current);
++ if (WARN_ON_ONCE(rq != this_rq()) ||
++ WARN_ON_ONCE(p == current))
++ return;
++
+ lockdep_assert_held(&rq->lock);
+
+ if (!raw_spin_trylock(&p->pi_lock)) {
+diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
+index c685e31..c3ae144 100644
+--- a/kernel/sched_clock.c
++++ b/kernel/sched_clock.c
+@@ -176,10 +176,36 @@ static u64 sched_clock_remote(struct sched_clock_data *scd)
+ u64 this_clock, remote_clock;
+ u64 *ptr, old_val, val;
+
++#if BITS_PER_LONG != 64
++again:
++ /*
++ * Careful here: The local and the remote clock values need to
++ * be read out atomic as we need to compare the values and
++ * then update either the local or the remote side. So the
++ * cmpxchg64 below only protects one readout.
++ *
++ * We must reread via sched_clock_local() in the retry case on
++ * 32bit as an NMI could use sched_clock_local() via the
++ * tracer and hit between the readout of
++ * the low32bit and the high 32bit portion.
++ */
++ this_clock = sched_clock_local(my_scd);
++ /*
++ * We must enforce atomic readout on 32bit, otherwise the
++ * update on the remote cpu can hit inbetween the readout of
++ * the low32bit and the high 32bit portion.
++ */
++ remote_clock = cmpxchg64(&scd->clock, 0, 0);
++#else
++ /*
++ * On 64bit the read of [my]scd->clock is atomic versus the
++ * update, so we can avoid the above 32bit dance.
++ */
+ sched_clock_local(my_scd);
+ again:
+ this_clock = my_scd->clock;
+ remote_clock = scd->clock;
++#endif
+
+ /*
+ * Use the opportunity that we have both locks
+diff --git a/kernel/signal.c b/kernel/signal.c
+index ea76d30..3ecf574 100644
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -2790,7 +2790,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
+
+ static int do_tkill(pid_t tgid, pid_t pid, int sig)
+ {
+- struct siginfo info;
++ struct siginfo info = {};
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+diff --git a/kernel/sys.c b/kernel/sys.c
+index f5939c2..be5fa8b 100644
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -320,7 +320,6 @@ void kernel_restart_prepare(char *cmd)
+ system_state = SYSTEM_RESTART;
+ usermodehelper_disable();
+ device_shutdown();
+- syscore_shutdown();
+ }
+
+ /**
+@@ -366,6 +365,7 @@ void kernel_restart(char *cmd)
+ {
+ kernel_restart_prepare(cmd);
+ disable_nonboot_cpus();
++ syscore_shutdown();
+ if (!cmd)
+ printk(KERN_EMERG "Restarting system.\n");
+ else
+@@ -391,6 +391,7 @@ static void kernel_shutdown_prepare(enum system_states state)
+ void kernel_halt(void)
+ {
+ kernel_shutdown_prepare(SYSTEM_HALT);
++ disable_nonboot_cpus();
+ syscore_shutdown();
+ printk(KERN_EMERG "System halted.\n");
+ kmsg_dump(KMSG_DUMP_HALT);
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 0943d2a..5527211 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -572,7 +572,6 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
+ free_page(tmp);
+ }
+
+- free_page((unsigned long)stat->pages);
+ stat->pages = NULL;
+ stat->start = NULL;
+
+@@ -2317,7 +2316,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
+ }
+
+ static loff_t
+-ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
++ftrace_filter_lseek(struct file *file, loff_t offset, int origin)
+ {
+ loff_t ret;
+
+@@ -3135,7 +3134,7 @@ static const struct file_operations ftrace_filter_fops = {
+ .open = ftrace_filter_open,
+ .read = seq_read,
+ .write = ftrace_filter_write,
+- .llseek = ftrace_regex_lseek,
++ .llseek = ftrace_filter_lseek,
+ .release = ftrace_regex_release,
+ };
+
+@@ -3143,7 +3142,7 @@ static const struct file_operations ftrace_notrace_fops = {
+ .open = ftrace_notrace_open,
+ .read = seq_read,
+ .write = ftrace_notrace_write,
+- .llseek = ftrace_regex_lseek,
++ .llseek = ftrace_filter_lseek,
+ .release = ftrace_regex_release,
+ };
+
+@@ -3351,8 +3350,8 @@ static const struct file_operations ftrace_graph_fops = {
+ .open = ftrace_graph_open,
+ .read = seq_read,
+ .write = ftrace_graph_write,
++ .llseek = ftrace_filter_lseek,
+ .release = ftrace_graph_release,
+- .llseek = seq_lseek,
+ };
+ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+@@ -3844,7 +3843,7 @@ static const struct file_operations ftrace_pid_fops = {
+ .open = ftrace_pid_open,
+ .write = ftrace_pid_write,
+ .read = seq_read,
+- .llseek = seq_lseek,
++ .llseek = ftrace_filter_lseek,
+ .release = ftrace_pid_release,
+ };
+
+@@ -3964,12 +3963,8 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
+ ftrace_startup_sysctl();
+
+ /* we are starting ftrace again */
+- if (ftrace_ops_list != &ftrace_list_end) {
+- if (ftrace_ops_list->next == &ftrace_list_end)
+- ftrace_trace_function = ftrace_ops_list->func;
+- else
+- ftrace_trace_function = ftrace_ops_list_func;
+- }
++ if (ftrace_ops_list != &ftrace_list_end)
++ update_ftrace_function();
+
+ } else {
+ /* stopping ftrace calls (just send to ftrace_stub) */
+diff --git a/lib/kobject.c b/lib/kobject.c
+index 640bd98..83bd5b3 100644
+--- a/lib/kobject.c
++++ b/lib/kobject.c
+@@ -531,6 +531,13 @@ struct kobject *kobject_get(struct kobject *kobj)
+ return kobj;
+ }
+
++static struct kobject *kobject_get_unless_zero(struct kobject *kobj)
++{
++ if (!kref_get_unless_zero(&kobj->kref))
++ kobj = NULL;
++ return kobj;
++}
++
+ /*
+ * kobject_cleanup - free kobject resources.
+ * @kobj: object to cleanup
+@@ -785,7 +792,7 @@ struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
+ slow_search:
+ list_for_each_entry(k, &kset->list, entry) {
+ if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
+- ret = kobject_get(k);
++ ret = kobject_get_unless_zero(k);
+ break;
+ }
+ }
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 4c7d42a..70b4733 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -2889,7 +2889,17 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ break;
+ }
+
+- if (absent ||
++ /*
++ * We need call hugetlb_fault for both hugepages under migration
++ * (in which case hugetlb_fault waits for the migration,) and
++ * hwpoisoned hugepages (in which case we need to prevent the
++ * caller from accessing to them.) In order to do this, we use
++ * here is_swap_pte instead of is_hugetlb_entry_migration and
++ * is_hugetlb_entry_hwpoisoned. This is because it simply covers
++ * both cases, and because we can't follow correct pages
++ * directly from any kind of swap entries.
++ */
++ if (absent || is_swap_pte(huge_ptep_get(pte)) ||
+ ((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) {
+ int ret;
+
+diff --git a/mm/page-writeback.c b/mm/page-writeback.c
+index 50f0824..ea3f83b 100644
+--- a/mm/page-writeback.c
++++ b/mm/page-writeback.c
+@@ -1801,6 +1801,24 @@ int __set_page_dirty_nobuffers(struct page *page)
+ EXPORT_SYMBOL(__set_page_dirty_nobuffers);
+
+ /*
++ * Call this whenever redirtying a page, to de-account the dirty counters
++ * (NR_DIRTIED, BDI_DIRTIED, tsk->nr_dirtied), so that they match the written
++ * counters (NR_WRITTEN, BDI_WRITTEN) in long term. The mismatches will lead to
++ * systematic errors in balanced_dirty_ratelimit and the dirty pages position
++ * control.
++ */
++void account_page_redirty(struct page *page)
++{
++ struct address_space *mapping = page->mapping;
++ if (mapping && mapping_cap_account_dirty(mapping)) {
++ current->nr_dirtied--;
++ dec_zone_page_state(page, NR_DIRTIED);
++ dec_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED);
++ }
++}
++EXPORT_SYMBOL(account_page_redirty);
++
++/*
+ * When a writepage implementation decides that it doesn't want to write this
+ * page for some reason, it should redirty the locked page via
+ * redirty_page_for_writepage() and it should then unlock the page and return 0
+@@ -1808,6 +1826,7 @@ EXPORT_SYMBOL(__set_page_dirty_nobuffers);
+ int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page)
+ {
+ wbc->pages_skipped++;
++ account_page_redirty(page);
+ return __set_page_dirty_nobuffers(page);
+ }
+ EXPORT_SYMBOL(redirty_page_for_writepage);
+diff --git a/net/can/gw.c b/net/can/gw.c
+index 3d79b12..f78f898 100644
+--- a/net/can/gw.c
++++ b/net/can/gw.c
+@@ -436,7 +436,7 @@ static int cgw_notifier(struct notifier_block *nb,
+ if (gwj->src.dev == dev || gwj->dst.dev == dev) {
+ hlist_del(&gwj->list);
+ cgw_unregister_filter(gwj);
+- kfree(gwj);
++ kmem_cache_free(cgw_cache, gwj);
+ }
+ }
+ }
+@@ -850,7 +850,7 @@ static void cgw_remove_all_jobs(void)
+ hlist_for_each_entry_safe(gwj, n, nx, &cgw_list, list) {
+ hlist_del(&gwj->list);
+ cgw_unregister_filter(gwj);
+- kfree(gwj);
++ kmem_cache_free(cgw_cache, gwj);
+ }
+ }
+
+@@ -903,7 +903,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+
+ hlist_del(&gwj->list);
+ cgw_unregister_filter(gwj);
+- kfree(gwj);
++ kmem_cache_free(cgw_cache, gwj);
+ err = 0;
+ break;
+ }
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 1e8a882..2c73adf 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -761,6 +761,20 @@ void cred_to_ucred(struct pid *pid, const struct cred *cred,
+ }
+ EXPORT_SYMBOL_GPL(cred_to_ucred);
+
++void cred_real_to_ucred(struct pid *pid, const struct cred *cred,
++ struct ucred *ucred)
++{
++ ucred->pid = pid_vnr(pid);
++ ucred->uid = ucred->gid = -1;
++ if (cred) {
++ struct user_namespace *current_ns = current_user_ns();
++
++ ucred->uid = user_ns_map_uid(current_ns, cred, cred->uid);
++ ucred->gid = user_ns_map_gid(current_ns, cred, cred->gid);
++ }
++}
++EXPORT_SYMBOL_GPL(cred_real_to_ucred);
++
+ int sock_getsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int __user *optlen)
+ {
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 7747d26..4707b6c 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -163,7 +163,7 @@ const char *snd_hda_get_jack_type(u32 cfg)
+ "Line Out", "Speaker", "HP Out", "CD",
+ "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
+ "Line In", "Aux", "Mic", "Telephony",
+- "SPDIF In", "Digitial In", "Reserved", "Other"
++ "SPDIF In", "Digital In", "Reserved", "Other"
+ };
+
+ return jack_types[(cfg & AC_DEFCFG_DEVICE)
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f3e0b24..1b43fde 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5595,7 +5595,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
+ const hda_nid_t *ssids;
+
+ if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
+- codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
++ codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
++ codec->vendor_id == 0x10ec0671)
+ ssids = alc663_ssids;
+ else
+ ssids = alc662_ssids;
+@@ -6045,6 +6046,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
+ { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
+ { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
+ { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
++ { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
+ { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
+ { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
+ { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
+diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
+index 4ad8ebd..4352ffb 100644
+--- a/sound/soc/codecs/wm8903.c
++++ b/sound/soc/codecs/wm8903.c
+@@ -1101,6 +1101,8 @@ static const struct snd_soc_dapm_route wm8903_intercon[] = {
+ { "ROP", NULL, "Right Speaker PGA" },
+ { "RON", NULL, "Right Speaker PGA" },
+
++ { "Charge Pump", NULL, "CLK_DSP" },
++
+ { "Left Headphone Output PGA", NULL, "Charge Pump" },
+ { "Right Headphone Output PGA", NULL, "Charge Pump" },
+ { "Left Line Output PGA", NULL, "Charge Pump" },
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index 38a607a..fb95069 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -396,7 +396,7 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
+ else
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+- 0, cpu_to_le16(wIndex),
++ 0, wIndex,
+ &tmp, sizeof(tmp), 1000);
+ up_read(&mixer->chip->shutdown_rwsem);
+
+@@ -427,7 +427,7 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
+ else
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+- cpu_to_le16(wValue), cpu_to_le16(wIndex),
++ wValue, wIndex,
+ NULL, 0, 1000);
+ up_read(&mixer->chip->shutdown_rwsem);
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 1b275f0..dfbd65d 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -482,7 +482,7 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
+ {
+ int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+- cpu_to_le16(1), 0, NULL, 0, 1000);
++ 1, 0, NULL, 0, 1000);
+
+ if (ret < 0)
+ return ret;
+diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
+index 3eed61e..79647cd 100644
+--- a/virt/kvm/ioapic.c
++++ b/virt/kvm/ioapic.c
+@@ -73,9 +73,12 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
+ u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
+ u64 redir_content;
+
+- ASSERT(redir_index < IOAPIC_NUM_PINS);
++ if (redir_index < IOAPIC_NUM_PINS)
++ redir_content =
++ ioapic->redirtbl[redir_index].bits;
++ else
++ redir_content = ~0ULL;
+
+- redir_content = ioapic->redirtbl[redir_index].bits;
+ result = (ioapic->ioregsel & 0x1) ?
+ (redir_content >> 32) & 0xffffffff :
+ redir_content & 0xffffffff;
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index ec747dc..8bf05f0 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -1401,21 +1401,38 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
+ }
+
+ int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+- gpa_t gpa)
++ gpa_t gpa, unsigned long len)
+ {
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+ int offset = offset_in_page(gpa);
+- gfn_t gfn = gpa >> PAGE_SHIFT;
++ gfn_t start_gfn = gpa >> PAGE_SHIFT;
++ gfn_t end_gfn = (gpa + len - 1) >> PAGE_SHIFT;
++ gfn_t nr_pages_needed = end_gfn - start_gfn + 1;
++ gfn_t nr_pages_avail;
+
+ ghc->gpa = gpa;
+ ghc->generation = slots->generation;
+- ghc->memslot = __gfn_to_memslot(slots, gfn);
+- ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL);
+- if (!kvm_is_error_hva(ghc->hva))
++ ghc->len = len;
++ ghc->memslot = __gfn_to_memslot(slots, start_gfn);
++ ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, &nr_pages_avail);
++ if (!kvm_is_error_hva(ghc->hva) && nr_pages_avail >= nr_pages_needed) {
+ ghc->hva += offset;
+- else
+- return -EFAULT;
+-
++ } else {
++ /*
++ * If the requested region crosses two memslots, we still
++ * verify that the entire region is valid here.
++ */
++ while (start_gfn <= end_gfn) {
++ ghc->memslot = __gfn_to_memslot(slots, start_gfn);
++ ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn,
++ &nr_pages_avail);
++ if (kvm_is_error_hva(ghc->hva))
++ return -EFAULT;
++ start_gfn += nr_pages_avail;
++ }
++ /* Use the slow path for cross page reads and writes. */
++ ghc->memslot = NULL;
++ }
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
+@@ -1426,8 +1443,13 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+ int r;
+
++ BUG_ON(len > ghc->len);
++
+ if (slots->generation != ghc->generation)
+- kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
++ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
++
++ if (unlikely(!ghc->memslot))
++ return kvm_write_guest(kvm, ghc->gpa, data, len);
+
+ if (kvm_is_error_hva(ghc->hva))
+ return -EFAULT;
+@@ -1447,8 +1469,13 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+ int r;
+
++ BUG_ON(len > ghc->len);
++
+ if (slots->generation != ghc->generation)
+- kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
++ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
++
++ if (unlikely(!ghc->memslot))
++ return kvm_read_guest(kvm, ghc->gpa, data, len);
+
+ if (kvm_is_error_hva(ghc->hva))
+ return -EFAULT;