]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Aug 2013 02:02:15 +0000 (10:02 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Aug 2013 02:02:15 +0000 (10:02 +0800)
added patches:
alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch
alsa-hda-fix-missing-fixup-for-mac-mini-with-stac9221.patch
arm-7784-1-mm-ensure-smp-alternates-assemble-to-exactly-4-bytes-with-thumb-2.patch
arm-7790-1-fix-deferred-mm-switch-on-vivt-processors.patch
arm-7791-1-a.out-remove-partial-a.out-support.patch
atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch
dma-pl330-fix-cyclic-transfers.patch
hwmon-max6697-fix-max6581-ideality.patch
iwlwifi-add-dell-sku-for-5150-hmc.patch
iwlwifi-mvm-fix-bug-in-scan-ssid.patch
iwlwifi-mvm-fix-flushing-not-started-aggregation-sessions.patch
iwlwifi-mvm-fix-l2p-ba-ressources-leak.patch
iwlwifi-mvm-refuse-connection-to-aps-with-bi-16.patch
iwlwifi-pcie-clear-rfkill-interrupt-in-ampg.patch
parisc-agp-parisc-agp-allow-binding-of-user-memory-to-the-agp-gart.patch
parisc-fix-cache-routines-to-ignore-vma-s-with-an-invalid-pfn.patch
parisc-fix-interrupt-routing-for-c8000-serial-ports.patch
powerpc-vphn-topology-change-updates-all-siblings.patch
powerpc-windfarm-fix-noisy-slots-fan-on-xserve-rm31.patch
serial-arc_uart-fix-module-alias.patch
serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch
serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch
usb-mos7840-fix-device-type-detection.patch
usb-mos7840-fix-pointer-casts.patch
usb-mos7840-fix-race-in-led-handling.patch
usb-mos7840-fix-race-in-register-handling.patch

27 files changed:
queue-3.10/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch [new file with mode: 0644]
queue-3.10/alsa-hda-fix-missing-fixup-for-mac-mini-with-stac9221.patch [new file with mode: 0644]
queue-3.10/arm-7784-1-mm-ensure-smp-alternates-assemble-to-exactly-4-bytes-with-thumb-2.patch [new file with mode: 0644]
queue-3.10/arm-7790-1-fix-deferred-mm-switch-on-vivt-processors.patch [new file with mode: 0644]
queue-3.10/arm-7791-1-a.out-remove-partial-a.out-support.patch [new file with mode: 0644]
queue-3.10/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch [new file with mode: 0644]
queue-3.10/dma-pl330-fix-cyclic-transfers.patch [new file with mode: 0644]
queue-3.10/hwmon-max6697-fix-max6581-ideality.patch [new file with mode: 0644]
queue-3.10/iwlwifi-add-dell-sku-for-5150-hmc.patch [new file with mode: 0644]
queue-3.10/iwlwifi-mvm-fix-bug-in-scan-ssid.patch [new file with mode: 0644]
queue-3.10/iwlwifi-mvm-fix-flushing-not-started-aggregation-sessions.patch [new file with mode: 0644]
queue-3.10/iwlwifi-mvm-fix-l2p-ba-ressources-leak.patch [new file with mode: 0644]
queue-3.10/iwlwifi-mvm-refuse-connection-to-aps-with-bi-16.patch [new file with mode: 0644]
queue-3.10/iwlwifi-pcie-clear-rfkill-interrupt-in-ampg.patch [new file with mode: 0644]
queue-3.10/parisc-agp-parisc-agp-allow-binding-of-user-memory-to-the-agp-gart.patch [new file with mode: 0644]
queue-3.10/parisc-fix-cache-routines-to-ignore-vma-s-with-an-invalid-pfn.patch [new file with mode: 0644]
queue-3.10/parisc-fix-interrupt-routing-for-c8000-serial-ports.patch [new file with mode: 0644]
queue-3.10/powerpc-vphn-topology-change-updates-all-siblings.patch [new file with mode: 0644]
queue-3.10/powerpc-windfarm-fix-noisy-slots-fan-on-xserve-rm31.patch [new file with mode: 0644]
queue-3.10/serial-arc_uart-fix-module-alias.patch [new file with mode: 0644]
queue-3.10/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch [new file with mode: 0644]
queue-3.10/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/usb-mos7840-fix-device-type-detection.patch [new file with mode: 0644]
queue-3.10/usb-mos7840-fix-pointer-casts.patch [new file with mode: 0644]
queue-3.10/usb-mos7840-fix-race-in-led-handling.patch [new file with mode: 0644]
queue-3.10/usb-mos7840-fix-race-in-register-handling.patch [new file with mode: 0644]

diff --git a/queue-3.10/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch b/queue-3.10/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch
new file mode 100644 (file)
index 0000000..34a8e5e
--- /dev/null
@@ -0,0 +1,33 @@
+From a8d30608eaed6cc759b8e2e8a8bbbb42591f797f Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Mon, 29 Jul 2013 15:10:22 +0530
+Subject: ALSA: compress: fix the return value for SNDRV_COMPRESS_VERSION
+
+From: Vinod Koul <vinod.koul@intel.com>
+
+commit a8d30608eaed6cc759b8e2e8a8bbbb42591f797f upstream.
+
+the return value of SNDRV_COMPRESS_VERSION always return default -ENOTTY as the
+return value was never updated for this call
+assign return value from put_user()
+
+Reported-by: Haynes <hgeorge@codeaurora.org>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/compress_offload.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/core/compress_offload.c
++++ b/sound/core/compress_offload.c
+@@ -743,7 +743,7 @@ static long snd_compr_ioctl(struct file
+       mutex_lock(&stream->device->lock);
+       switch (_IOC_NR(cmd)) {
+       case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
+-              put_user(SNDRV_COMPRESS_VERSION,
++              retval = put_user(SNDRV_COMPRESS_VERSION,
+                               (int __user *)arg) ? -EFAULT : 0;
+               break;
+       case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
diff --git a/queue-3.10/alsa-hda-fix-missing-fixup-for-mac-mini-with-stac9221.patch b/queue-3.10/alsa-hda-fix-missing-fixup-for-mac-mini-with-stac9221.patch
new file mode 100644 (file)
index 0000000..dc90bd2
--- /dev/null
@@ -0,0 +1,49 @@
+From 697aebab78a88c6b164cfb74d19b86817d2ccd82 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 1 Aug 2013 08:38:27 +0200
+Subject: ALSA: hda - Fix missing fixup for Mac Mini with STAC9221
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 697aebab78a88c6b164cfb74d19b86817d2ccd82 upstream.
+
+A fixup for Apple Mac Mini was lost during the adaption to the generic
+parser because the fallback for the generic ID 8384:7680 was dropped,
+and it resulted in the silence output (and maybe other problems).
+
+Unfortunately, just adding the missing subsystem ID wasn't enough, in
+this case.  The subsystem ID of this machine is 0000:0100 (what Apple
+thought...?), and since snd_hda_pick_fixup() doesn't take the vendor
+id zero into account, the driver ignored this entry.  Now it's fixed
+to regard the vendor id zero as a valid value.
+
+Reported-and-tested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_auto_parser.c |    2 +-
+ sound/pci/hda/patch_sigmatel.c  |    1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_auto_parser.c
++++ b/sound/pci/hda/hda_auto_parser.c
+@@ -860,7 +860,7 @@ void snd_hda_pick_fixup(struct hda_codec
+               }
+       }
+       if (id < 0 && quirk) {
+-              for (q = quirk; q->subvendor; q++) {
++              for (q = quirk; q->subvendor || q->subdevice; q++) {
+                       unsigned int vendorid =
+                               q->subdevice | (q->subvendor << 16);
+                       unsigned int mask = 0xffff0000 | q->subdevice_mask;
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -2815,6 +2815,7 @@ static const struct hda_pintbl ecs202_pi
+ /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
+ static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
++      SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3),
+       SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
+       SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
+       SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
diff --git a/queue-3.10/arm-7784-1-mm-ensure-smp-alternates-assemble-to-exactly-4-bytes-with-thumb-2.patch b/queue-3.10/arm-7784-1-mm-ensure-smp-alternates-assemble-to-exactly-4-bytes-with-thumb-2.patch
new file mode 100644 (file)
index 0000000..01d71ce
--- /dev/null
@@ -0,0 +1,74 @@
+From bf3f0f332f76a85ff3a0b393aaded5a8533769c0 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Mon, 15 Jul 2013 14:26:19 +0100
+Subject: ARM: 7784/1: mm: ensure SMP alternates assemble to exactly 4 bytes with Thumb-2
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit bf3f0f332f76a85ff3a0b393aaded5a8533769c0 upstream.
+
+Commit ae8a8b9553bd ("ARM: 7691/1: mm: kill unused TLB_CAN_READ_FROM_L1_CACHE
+and use ALT_SMP instead") added early function returns for page table
+cache flushing operations on ARMv7 SMP CPUs.
+
+Unfortunately, when targetting Thumb-2, these `mov pc, lr' sequences
+assemble to 2 bytes which can lead to corruption of the instruction
+stream after code patching.
+
+This patch fixes the alternates to use wide (32-bit) instructions for
+Thumb-2, therefore ensuring that the patching code works correctly.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mm/proc-v7-2level.S |    2 +-
+ arch/arm/mm/proc-v7-3level.S |    2 +-
+ arch/arm/mm/proc-v7.S        |   11 ++++++-----
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/arch/arm/mm/proc-v7-2level.S
++++ b/arch/arm/mm/proc-v7-2level.S
+@@ -110,7 +110,7 @@ ENTRY(cpu_v7_set_pte_ext)
+  ARM( str     r3, [r0, #2048]! )
+  THUMB(       add     r0, r0, #2048 )
+  THUMB(       str     r3, [r0] )
+-      ALT_SMP(mov     pc,lr)
++      ALT_SMP(W(nop))
+       ALT_UP (mcr     p15, 0, r0, c7, c10, 1)         @ flush_pte
+ #endif
+       mov     pc, lr
+--- a/arch/arm/mm/proc-v7-3level.S
++++ b/arch/arm/mm/proc-v7-3level.S
+@@ -73,7 +73,7 @@ ENTRY(cpu_v7_set_pte_ext)
+       tst     r3, #1 << (55 - 32)             @ L_PTE_DIRTY
+       orreq   r2, #L_PTE_RDONLY
+ 1:    strd    r2, r3, [r0]
+-      ALT_SMP(mov     pc, lr)
++      ALT_SMP(W(nop))
+       ALT_UP (mcr     p15, 0, r0, c7, c10, 1)         @ flush_pte
+ #endif
+       mov     pc, lr
+--- a/arch/arm/mm/proc-v7.S
++++ b/arch/arm/mm/proc-v7.S
+@@ -75,13 +75,14 @@ ENTRY(cpu_v7_do_idle)
+ ENDPROC(cpu_v7_do_idle)
+ ENTRY(cpu_v7_dcache_clean_area)
+-      ALT_SMP(mov     pc, lr)                 @ MP extensions imply L1 PTW
+-      ALT_UP(W(nop))
+-      dcache_line_size r2, r3
+-1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      ALT_SMP(W(nop))                 @ MP extensions imply L1 PTW
++      ALT_UP_B(1f)
++      mov     pc, lr
++1:    dcache_line_size r2, r3
++2:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       add     r0, r0, r2
+       subs    r1, r1, r2
+-      bhi     1b
++      bhi     2b
+       dsb
+       mov     pc, lr
+ ENDPROC(cpu_v7_dcache_clean_area)
diff --git a/queue-3.10/arm-7790-1-fix-deferred-mm-switch-on-vivt-processors.patch b/queue-3.10/arm-7790-1-fix-deferred-mm-switch-on-vivt-processors.patch
new file mode 100644 (file)
index 0000000..e4eacce
--- /dev/null
@@ -0,0 +1,91 @@
+From bdae73cd374e28db544fdd9b77de689a36e3c129 Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Tue, 23 Jul 2013 16:15:36 +0100
+Subject: ARM: 7790/1: Fix deferred mm switch on VIVT processors
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit bdae73cd374e28db544fdd9b77de689a36e3c129 upstream.
+
+As of commit b9d4d42ad9 (ARM: Remove __ARCH_WANT_INTERRUPTS_ON_CTXSW on
+pre-ARMv6 CPUs), the mm switching on VIVT processors is done in the
+finish_arch_post_lock_switch() function to avoid whole cache flushing
+with interrupts disabled. The need for deferred mm switch is stored as a
+thread flag (TIF_SWITCH_MM). However, with preemption enabled, we can
+have another thread switch before finish_arch_post_lock_switch(). If the
+new thread has the same mm as the previous 'next' thread, the scheduler
+will not call switch_mm() and the TIF_SWITCH_MM flag won't be set for
+the new thread.
+
+This patch moves the switch pending flag to the mm_context_t structure
+since this is specific to the mm rather than thread.
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Reported-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Tested-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/include/asm/mmu.h         |    2 ++
+ arch/arm/include/asm/mmu_context.h |   20 ++++++++++++++++----
+ arch/arm/include/asm/thread_info.h |    1 -
+ 3 files changed, 18 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/include/asm/mmu.h
++++ b/arch/arm/include/asm/mmu.h
+@@ -6,6 +6,8 @@
+ typedef struct {
+ #ifdef CONFIG_CPU_HAS_ASID
+       atomic64_t      id;
++#else
++      int             switch_pending;
+ #endif
+       unsigned int    vmalloc_seq;
+       unsigned long   sigpage;
+--- a/arch/arm/include/asm/mmu_context.h
++++ b/arch/arm/include/asm/mmu_context.h
+@@ -55,7 +55,7 @@ static inline void check_and_switch_cont
+                * on non-ASID CPUs, the old mm will remain valid until the
+                * finish_arch_post_lock_switch() call.
+                */
+-              set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM);
++              mm->context.switch_pending = 1;
+       else
+               cpu_switch_mm(mm->pgd, mm);
+ }
+@@ -64,9 +64,21 @@ static inline void check_and_switch_cont
+       finish_arch_post_lock_switch
+ static inline void finish_arch_post_lock_switch(void)
+ {
+-      if (test_and_clear_thread_flag(TIF_SWITCH_MM)) {
+-              struct mm_struct *mm = current->mm;
+-              cpu_switch_mm(mm->pgd, mm);
++      struct mm_struct *mm = current->mm;
++
++      if (mm && mm->context.switch_pending) {
++              /*
++               * Preemption must be disabled during cpu_switch_mm() as we
++               * have some stateful cache flush implementations. Check
++               * switch_pending again in case we were preempted and the
++               * switch to this mm was already done.
++               */
++              preempt_disable();
++              if (mm->context.switch_pending) {
++                      mm->context.switch_pending = 0;
++                      cpu_switch_mm(mm->pgd, mm);
++              }
++              preempt_enable_no_resched();
+       }
+ }
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -156,7 +156,6 @@ extern int vfp_restore_user_hwstate(stru
+ #define TIF_USING_IWMMXT      17
+ #define TIF_MEMDIE            18      /* is terminating due to OOM killer */
+ #define TIF_RESTORE_SIGMASK   20
+-#define TIF_SWITCH_MM         22      /* deferred switch_mm */
+ #define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED     (1 << TIF_NEED_RESCHED)
diff --git a/queue-3.10/arm-7791-1-a.out-remove-partial-a.out-support.patch b/queue-3.10/arm-7791-1-a.out-remove-partial-a.out-support.patch
new file mode 100644 (file)
index 0000000..5f8a0f4
--- /dev/null
@@ -0,0 +1,177 @@
+From acfdd4b1f7590d02e9bae3b73bdbbc4a31b05d38 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Thu, 25 Jul 2013 11:44:48 +0100
+Subject: ARM: 7791/1: a.out: remove partial a.out support
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit acfdd4b1f7590d02e9bae3b73bdbbc4a31b05d38 upstream.
+
+a.out support on ARM requires that argc, argv and envp are passed in
+r0-r2 respectively, which requires hacking load_aout_binary to
+prevent argc being clobbered by the return code. Whilst mainline kernels
+do set the registers up in start_thread, the aout loader has never
+carried the hack in mainline.
+
+Initialising the registers in this way actually goes against the libc
+expectations for ELF binaries, where argc, argv and envp are passed on
+the stack, with r0 being used to hold a pointer to an exit function for
+cleaning up after the dynamic linker if required. If the pointer is
+NULL, then it is ignored. When execing an ELF binary, Linux currently
+zeroes r0, then sets it to argc and then finally clobbers it with the
+return value of the execve syscall, so we actually end up with:
+
+       r0 = 0
+       stack[0] = argc
+       r1 = stack[1] = argv
+       r2 = stack[2] = envp
+
+libc treats r1 and r2 as undefined. The clobbering of r0 by sys_execve
+works for user-spawned threads, but when executing an ELF binary from a
+kernel thread (via call_usermodehelper), the execve is performed on the
+ret_from_fork path, which restores r0 from the saved pt_regs, resulting
+in argc being presented to the C library. This has horrible consequences
+when the application exits, since we have an exit function registered
+using argc, resulting in a jump to hyperspace.
+
+This patch solves the problem by removing the partial a.out support from
+arch/arm/ altogether.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Cc: Ashish Sangwan <ashishsangwan2@gmail.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/Kconfig                  |    1 
+ arch/arm/include/asm/a.out-core.h |   45 --------------------------------------
+ arch/arm/include/asm/processor.h  |    4 ---
+ arch/arm/include/uapi/asm/Kbuild  |    1 
+ arch/arm/include/uapi/asm/a.out.h |   34 ----------------------------
+ 5 files changed, 85 deletions(-)
+
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -19,7 +19,6 @@ config ARM
+       select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
+       select HARDIRQS_SW_RESEND
+-      select HAVE_AOUT
+       select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
+       select HAVE_ARCH_KGDB
+       select HAVE_ARCH_SECCOMP_FILTER
+--- a/arch/arm/include/asm/a.out-core.h
++++ /dev/null
+@@ -1,45 +0,0 @@
+-/* a.out coredump register dumper
+- *
+- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+- * Written by David Howells (dhowells@redhat.com)
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public Licence
+- * as published by the Free Software Foundation; either version
+- * 2 of the Licence, or (at your option) any later version.
+- */
+-
+-#ifndef _ASM_A_OUT_CORE_H
+-#define _ASM_A_OUT_CORE_H
+-
+-#ifdef __KERNEL__
+-
+-#include <linux/user.h>
+-#include <linux/elfcore.h>
+-
+-/*
+- * fill in the user structure for an a.out core dump
+- */
+-static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
+-{
+-      struct task_struct *tsk = current;
+-
+-      dump->magic = CMAGIC;
+-      dump->start_code = tsk->mm->start_code;
+-      dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
+-
+-      dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
+-      dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
+-      dump->u_ssize = 0;
+-
+-      memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg));
+-
+-      if (dump->start_stack < 0x04000000)
+-              dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
+-
+-      dump->regs = *regs;
+-      dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
+-}
+-
+-#endif /* __KERNEL__ */
+-#endif /* _ASM_A_OUT_CORE_H */
+--- a/arch/arm/include/asm/processor.h
++++ b/arch/arm/include/asm/processor.h
+@@ -54,7 +54,6 @@ struct thread_struct {
+ #define start_thread(regs,pc,sp)                                      \
+ ({                                                                    \
+-      unsigned long *stack = (unsigned long *)sp;                     \
+       memset(regs->uregs, 0, sizeof(regs->uregs));                    \
+       if (current->personality & ADDR_LIMIT_32BIT)                    \
+               regs->ARM_cpsr = USR_MODE;                              \
+@@ -65,9 +64,6 @@ struct thread_struct {
+       regs->ARM_cpsr |= PSR_ENDSTATE;                                 \
+       regs->ARM_pc = pc & ~1;         /* pc */                        \
+       regs->ARM_sp = sp;              /* sp */                        \
+-      regs->ARM_r2 = stack[2];        /* r2 (envp) */                 \
+-      regs->ARM_r1 = stack[1];        /* r1 (argv) */                 \
+-      regs->ARM_r0 = stack[0];        /* r0 (argc) */                 \
+       nommu_start_thread(regs);                                       \
+ })
+--- a/arch/arm/include/uapi/asm/Kbuild
++++ b/arch/arm/include/uapi/asm/Kbuild
+@@ -1,7 +1,6 @@
+ # UAPI Header export list
+ include include/uapi/asm-generic/Kbuild.asm
+-header-y += a.out.h
+ header-y += byteorder.h
+ header-y += fcntl.h
+ header-y += hwcap.h
+--- a/arch/arm/include/uapi/asm/a.out.h
++++ /dev/null
+@@ -1,34 +0,0 @@
+-#ifndef __ARM_A_OUT_H__
+-#define __ARM_A_OUT_H__
+-
+-#include <linux/personality.h>
+-#include <linux/types.h>
+-
+-struct exec
+-{
+-  __u32 a_info;               /* Use macros N_MAGIC, etc for access */
+-  __u32 a_text;               /* length of text, in bytes */
+-  __u32 a_data;               /* length of data, in bytes */
+-  __u32 a_bss;                /* length of uninitialized data area for file, in bytes */
+-  __u32 a_syms;               /* length of symbol table data in file, in bytes */
+-  __u32 a_entry;      /* start address */
+-  __u32 a_trsize;     /* length of relocation info for text, in bytes */
+-  __u32 a_drsize;     /* length of relocation info for data, in bytes */
+-};
+-
+-/*
+- * This is always the same
+- */
+-#define N_TXTADDR(a)  (0x00008000)
+-
+-#define N_TRSIZE(a)   ((a).a_trsize)
+-#define N_DRSIZE(a)   ((a).a_drsize)
+-#define N_SYMSIZE(a)  ((a).a_syms)
+-
+-#define M_ARM 103
+-
+-#ifndef LIBRARY_START_TEXT
+-#define LIBRARY_START_TEXT    (0x00c00000)
+-#endif
+-
+-#endif /* __A_OUT_GNU_H__ */
diff --git a/queue-3.10/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch b/queue-3.10/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch
new file mode 100644 (file)
index 0000000..f5f4b45
--- /dev/null
@@ -0,0 +1,44 @@
+From ebe7fdbaf3e90ea22feade6c9f5e50f42b23b6d8 Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@tuxdriver.com>
+Date: Fri, 26 Jul 2013 12:47:14 -0400
+Subject: atl1c: Fix misuse of netdev_alloc_skb in refilling rx ring
+
+From: Neil Horman <nhorman@tuxdriver.com>
+
+commit ebe7fdbaf3e90ea22feade6c9f5e50f42b23b6d8 upstream.
+
+atl1c uses netdev_alloc_skb to refill its rx dma ring, but that call makes no
+guarantees about the suitability of the memory for use in DMA.  As a result
+we've gotten reports of atl1c drivers occasionally hanging and needing to be
+reset:
+https://bugzilla.kernel.org/show_bug.cgi?id=54021
+
+Fix this by modifying the call to use the internal version __netdev_alloc_skb,
+where you can set the gfp_mask explicitly to include GFP_DMA.
+
+Tested by two reporters in the above bug, who have the hardware to validate it.
+Both report immediate cessation of the problem with this patch
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+CC: Jay Cliburn <jcliburn@gmail.com>
+CC: "David S. Miller" <davem@davemloft.net>
+Tested-by: Luis Henriques <luis.henriques@canonical.com>
+Tested-by: Vincent Alquier <vincent.alquier@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/atheros/atl1c/atl1c_main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+@@ -1660,7 +1660,7 @@ static int atl1c_alloc_rx_buffer(struct
+       while (next_info->flags & ATL1C_BUFFER_FREE) {
+               rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
+-              skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len);
++              skb = __netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len, GFP_ATOMIC|GFP_DMA);
+               if (unlikely(!skb)) {
+                       if (netif_msg_rx_err(adapter))
+                               dev_warn(&pdev->dev, "alloc rx buffer failed\n");
diff --git a/queue-3.10/dma-pl330-fix-cyclic-transfers.patch b/queue-3.10/dma-pl330-fix-cyclic-transfers.patch
new file mode 100644 (file)
index 0000000..f9c5cea
--- /dev/null
@@ -0,0 +1,144 @@
+From fc51446021f42aca8906e701fc2292965aafcb15 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Tue, 23 Jul 2013 10:24:50 +0200
+Subject: dma: pl330: Fix cyclic transfers
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit fc51446021f42aca8906e701fc2292965aafcb15 upstream.
+
+Allocate a descriptor for each period of a cyclic transfer, not just the first.
+Also since the callback needs to be called for each finished period make sure to
+initialize the callback and callback_param fields of each descriptor in a cyclic
+transfer.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/pl330.c |   93 +++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 67 insertions(+), 26 deletions(-)
+
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2527,6 +2527,10 @@ static dma_cookie_t pl330_tx_submit(stru
+       /* Assign cookies to all nodes */
+       while (!list_empty(&last->node)) {
+               desc = list_entry(last->node.next, struct dma_pl330_desc, node);
++              if (pch->cyclic) {
++                      desc->txd.callback = last->txd.callback;
++                      desc->txd.callback_param = last->txd.callback_param;
++              }
+               dma_cookie_assign(&desc->txd);
+@@ -2710,45 +2714,82 @@ static struct dma_async_tx_descriptor *p
+               size_t period_len, enum dma_transfer_direction direction,
+               unsigned long flags, void *context)
+ {
+-      struct dma_pl330_desc *desc;
++      struct dma_pl330_desc *desc = NULL, *first = NULL;
+       struct dma_pl330_chan *pch = to_pchan(chan);
++      struct dma_pl330_dmac *pdmac = pch->dmac;
++      unsigned int i;
+       dma_addr_t dst;
+       dma_addr_t src;
+-      desc = pl330_get_desc(pch);
+-      if (!desc) {
+-              dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+-                      __func__, __LINE__);
++      if (len % period_len != 0)
+               return NULL;
+-      }
+-      switch (direction) {
+-      case DMA_MEM_TO_DEV:
+-              desc->rqcfg.src_inc = 1;
+-              desc->rqcfg.dst_inc = 0;
+-              desc->req.rqtype = MEMTODEV;
+-              src = dma_addr;
+-              dst = pch->fifo_addr;
+-              break;
+-      case DMA_DEV_TO_MEM:
+-              desc->rqcfg.src_inc = 0;
+-              desc->rqcfg.dst_inc = 1;
+-              desc->req.rqtype = DEVTOMEM;
+-              src = pch->fifo_addr;
+-              dst = dma_addr;
+-              break;
+-      default:
++      if (!is_slave_direction(direction)) {
+               dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
+               __func__, __LINE__);
+               return NULL;
+       }
+-      desc->rqcfg.brst_size = pch->burst_sz;
+-      desc->rqcfg.brst_len = 1;
++      for (i = 0; i < len / period_len; i++) {
++              desc = pl330_get_desc(pch);
++              if (!desc) {
++                      dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
++                              __func__, __LINE__);
+-      pch->cyclic = true;
++                      if (!first)
++                              return NULL;
++
++                      spin_lock_irqsave(&pdmac->pool_lock, flags);
++
++                      while (!list_empty(&first->node)) {
++                              desc = list_entry(first->node.next,
++                                              struct dma_pl330_desc, node);
++                              list_move_tail(&desc->node, &pdmac->desc_pool);
++                      }
++
++                      list_move_tail(&first->node, &pdmac->desc_pool);
++
++                      spin_unlock_irqrestore(&pdmac->pool_lock, flags);
++
++                      return NULL;
++              }
++
++              switch (direction) {
++              case DMA_MEM_TO_DEV:
++                      desc->rqcfg.src_inc = 1;
++                      desc->rqcfg.dst_inc = 0;
++                      desc->req.rqtype = MEMTODEV;
++                      src = dma_addr;
++                      dst = pch->fifo_addr;
++                      break;
++              case DMA_DEV_TO_MEM:
++                      desc->rqcfg.src_inc = 0;
++                      desc->rqcfg.dst_inc = 1;
++                      desc->req.rqtype = DEVTOMEM;
++                      src = pch->fifo_addr;
++                      dst = dma_addr;
++                      break;
++              default:
++                      break;
++              }
+-      fill_px(&desc->px, dst, src, period_len);
++              desc->rqcfg.brst_size = pch->burst_sz;
++              desc->rqcfg.brst_len = 1;
++              fill_px(&desc->px, dst, src, period_len);
++
++              if (!first)
++                      first = desc;
++              else
++                      list_add_tail(&desc->node, &first->node);
++
++              dma_addr += period_len;
++      }
++
++      if (!desc)
++              return NULL;
++
++      pch->cyclic = true;
++      desc->txd.flags = flags;
+       return &desc->txd;
+ }
diff --git a/queue-3.10/hwmon-max6697-fix-max6581-ideality.patch b/queue-3.10/hwmon-max6697-fix-max6581-ideality.patch
new file mode 100644 (file)
index 0000000..1658acf
--- /dev/null
@@ -0,0 +1,37 @@
+From 5c52add19733eb36d8619713312f5604efef3502 Mon Sep 17 00:00:00 2001
+From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+Date: Tue, 30 Jul 2013 17:14:34 -0400
+Subject: hwmon: (max6697) fix MAX6581 ideality
+
+From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+
+commit 5c52add19733eb36d8619713312f5604efef3502 upstream.
+
+Without this patch, the values for ideality (register 0x4b) and ideality
+selection mask (register 0x4c) are inverted.
+
+Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/max6697.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/hwmon/max6697.c
++++ b/drivers/hwmon/max6697.c
+@@ -605,12 +605,12 @@ static int max6697_init_chip(struct i2c_
+               if (ret < 0)
+                       return ret;
+               ret = i2c_smbus_write_byte_data(client, MAX6581_REG_IDEALITY,
+-                                              pdata->ideality_mask >> 1);
++                                              pdata->ideality_value);
+               if (ret < 0)
+                       return ret;
+               ret = i2c_smbus_write_byte_data(client,
+                                               MAX6581_REG_IDEALITY_SELECT,
+-                                              pdata->ideality_value);
++                                              pdata->ideality_mask >> 1);
+               if (ret < 0)
+                       return ret;
+       }
diff --git a/queue-3.10/iwlwifi-add-dell-sku-for-5150-hmc.patch b/queue-3.10/iwlwifi-add-dell-sku-for-5150-hmc.patch
new file mode 100644 (file)
index 0000000..15a7667
--- /dev/null
@@ -0,0 +1,31 @@
+From a1923f1d4723e5757cefdd60f7c7ab30e472007a Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Thu, 18 Jul 2013 19:11:26 +0300
+Subject: iwlwifi: add DELL SKU for 5150 HMC
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit a1923f1d4723e5757cefdd60f7c7ab30e472007a upstream.
+
+This SKU was missing in the list of supported devices
+
+https://bugzilla.kernel.org/show_bug.cgi?id=60577
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/pcie/drv.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
+@@ -129,6 +129,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_ca
+       {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
+       {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
+       {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
++      {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
+       {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
+       {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
diff --git a/queue-3.10/iwlwifi-mvm-fix-bug-in-scan-ssid.patch b/queue-3.10/iwlwifi-mvm-fix-bug-in-scan-ssid.patch
new file mode 100644 (file)
index 0000000..3530b02
--- /dev/null
@@ -0,0 +1,34 @@
+From fe04e83706037802c502ea41c0d1799ec35fc0d7 Mon Sep 17 00:00:00 2001
+From: David Spinadel <david.spinadel@intel.com>
+Date: Thu, 4 Jul 2013 15:17:48 +0300
+Subject: iwlwifi: mvm: fix bug in scan ssid
+
+From: David Spinadel <david.spinadel@intel.com>
+
+commit fe04e83706037802c502ea41c0d1799ec35fc0d7 upstream.
+
+Increment index in each iteration. Without this increment we are
+overriding the added SSIDs and we will send only the last SSId
+and (n_ssids - 1) broadcast probes.
+
+Signed-off-by: David Spinadel <david.spinadel@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/mvm/scan.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
++++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
+@@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(stru
+ {
+       int fw_idx, req_idx;
+-      fw_idx = 0;
+-      for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) {
++      for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0;
++           req_idx--, fw_idx++) {
+               cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
+               cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
+               memcpy(cmd->direct_scan[fw_idx].ssid,
diff --git a/queue-3.10/iwlwifi-mvm-fix-flushing-not-started-aggregation-sessions.patch b/queue-3.10/iwlwifi-mvm-fix-flushing-not-started-aggregation-sessions.patch
new file mode 100644 (file)
index 0000000..702d480
--- /dev/null
@@ -0,0 +1,76 @@
+From b6658ff80c43bcf84be0bbe371c88af1452e7776 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 24 Jul 2013 13:55:51 +0200
+Subject: iwlwifi: mvm: fix flushing not started aggregation sessions
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit b6658ff80c43bcf84be0bbe371c88af1452e7776 upstream.
+
+When a not fully started aggregation session is destroyed
+and flushed, we get a warning, e.g.
+
+  WARNING: at drivers/net/wireless/iwlwifi/pcie/tx.c:1142 iwl_trans_pcie_txq_disable+0x11c/0x160
+  queue 16 not used
+  Modules linked in: [...]
+  Pid: 5135, comm: hostapd Tainted: G        W  O 3.5.0 #10
+  Call Trace:
+  wlan0: driver sets block=0 for sta 00:03:7f:10:44:d3
+   [<ffffffff81036492>] warn_slowpath_common+0x72/0xa0
+   [<ffffffff81036577>] warn_slowpath_fmt+0x47/0x50
+   [<ffffffffa0368d6c>] iwl_trans_pcie_txq_disable+0x11c/0x160 [iwlwifi]
+   [<ffffffffa03a2099>] iwl_mvm_sta_tx_agg_flush+0xe9/0x150 [iwlmvm]
+   [<ffffffffa0396c43>] iwl_mvm_mac_ampdu_action+0xf3/0x1e0 [iwlmvm]
+   [<ffffffffa0293ad3>] ___ieee80211_stop_tx_ba_session+0x193/0x920 [mac80211]
+   [<ffffffffa0294ed8>] __ieee80211_stop_tx_ba_session+0x48/0x70 [mac80211]
+   [<ffffffffa029159f>] ieee80211_sta_tear_down_BA_sessions+0x4f/0x80 [mac80211]
+   [<ffffffffa028a686>] __sta_info_destroy+0x66/0x370 [mac80211]
+   [<ffffffffa028abb4>] sta_info_destroy_addr_bss+0x44/0x70 [mac80211]
+   [<ffffffffa02a3e26>] ieee80211_del_station+0x26/0x50 [mac80211]
+   [<ffffffffa01e6395>] nl80211_del_station+0x85/0x200 [cfg80211]
+
+when a station deauthenticated from us without fully setting
+up the aggregation session.
+
+Fix this by checking the aggregation state before removing
+the hardware queue.
+
+Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/mvm/sta.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
++++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
+@@ -898,6 +898,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_
+       struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
+       struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
+       u16 txq_id;
++      enum iwl_mvm_agg_state old_state;
+       /*
+        * First set the agg state to OFF to avoid calling
+@@ -907,13 +908,17 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_
+       txq_id = tid_data->txq_id;
+       IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
+                           mvmsta->sta_id, tid, txq_id, tid_data->state);
++      old_state = tid_data->state;
+       tid_data->state = IWL_AGG_OFF;
+       spin_unlock_bh(&mvmsta->lock);
+-      if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
+-              IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
++      if (old_state >= IWL_AGG_ON) {
++              if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
++                      IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
++
++              iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
++      }
+-      iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
+       mvm->queue_to_mac80211[tid_data->txq_id] =
+                               IWL_INVALID_MAC80211_QUEUE;
diff --git a/queue-3.10/iwlwifi-mvm-fix-l2p-ba-ressources-leak.patch b/queue-3.10/iwlwifi-mvm-fix-l2p-ba-ressources-leak.patch
new file mode 100644 (file)
index 0000000..aa4f02d
--- /dev/null
@@ -0,0 +1,37 @@
+From 93a426673fbfeae7fa6b27008828e2ac4c08dbee Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Tue, 2 Jul 2013 13:35:35 +0300
+Subject: iwlwifi: mvm: fix L2P BA ressources leak
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit 93a426673fbfeae7fa6b27008828e2ac4c08dbee upstream.
+
+We didn't release the Rx AMPDU ressources properly.
+This bug led to firmware assert after 16 BA sessions.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/mvm/sta.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
++++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
+@@ -621,8 +621,12 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *m
+       cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
+       cmd.sta_id = mvm_sta->sta_id;
+       cmd.add_modify = STA_MODE_MODIFY;
+-      cmd.add_immediate_ba_tid = (u8) tid;
+-      cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
++      if (start) {
++              cmd.add_immediate_ba_tid = (u8) tid;
++              cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
++      } else {
++              cmd.remove_immediate_ba_tid = (u8) tid;
++      }
+       cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
+                                 STA_MODIFY_REMOVE_BA_TID;
diff --git a/queue-3.10/iwlwifi-mvm-refuse-connection-to-aps-with-bi-16.patch b/queue-3.10/iwlwifi-mvm-refuse-connection-to-aps-with-bi-16.patch
new file mode 100644 (file)
index 0000000..8dc0d65
--- /dev/null
@@ -0,0 +1,55 @@
+From 48bc13072109ea58465542aa1ee31b4e1065468a Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 4 Jul 2013 15:55:29 +0200
+Subject: iwlwifi: mvm: refuse connection to APs with BI < 16
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 48bc13072109ea58465542aa1ee31b4e1065468a upstream.
+
+Due to a firmware bug, it crashes when the beacon interval
+is smaller than 16. Avoid this by refusing the station state
+change creating the AP station, causing mac80211 to abandon
+the attempt to connect to the AP, and eventually wpa_s to
+blacklist it.
+
+Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/mvm/mac80211.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+@@ -987,6 +987,21 @@ static int iwl_mvm_mac_sta_state(struct
+       mutex_lock(&mvm->mutex);
+       if (old_state == IEEE80211_STA_NOTEXIST &&
+           new_state == IEEE80211_STA_NONE) {
++              /*
++               * Firmware bug - it'll crash if the beacon interval is less
++               * than 16. We can't avoid connecting at all, so refuse the
++               * station state change, this will cause mac80211 to abandon
++               * attempts to connect to this AP, and eventually wpa_s will
++               * blacklist the AP...
++               */
++              if (vif->type == NL80211_IFTYPE_STATION &&
++                  vif->bss_conf.beacon_int < 16) {
++                      IWL_ERR(mvm,
++                              "AP %pM beacon interval is %d, refusing due to firmware bug!\n",
++                              sta->addr, vif->bss_conf.beacon_int);
++                      ret = -EINVAL;
++                      goto out_unlock;
++              }
+               ret = iwl_mvm_add_sta(mvm, vif, sta);
+       } else if (old_state == IEEE80211_STA_NONE &&
+                  new_state == IEEE80211_STA_AUTH) {
+@@ -1015,6 +1030,7 @@ static int iwl_mvm_mac_sta_state(struct
+       } else {
+               ret = -EIO;
+       }
++ out_unlock:
+       mutex_unlock(&mvm->mutex);
+       return ret;
diff --git a/queue-3.10/iwlwifi-pcie-clear-rfkill-interrupt-in-ampg.patch b/queue-3.10/iwlwifi-pcie-clear-rfkill-interrupt-in-ampg.patch
new file mode 100644 (file)
index 0000000..fd465be
--- /dev/null
@@ -0,0 +1,49 @@
+From a53ee0a308b16e392e0219c585b10f329345766b Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Thu, 25 Jul 2013 13:14:34 +0300
+Subject: iwlwifi: pcie: clear RFKILL interrupt in AMPG
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit a53ee0a308b16e392e0219c585b10f329345766b upstream.
+
+If we forget to do so, we can't send HCMD to firmware while
+the NIC is in RFKILL state.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-prph.h |    2 ++
+ drivers/net/wireless/iwlwifi/pcie/rx.c  |    8 ++++++++
+ 2 files changed, 10 insertions(+)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
++++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
+@@ -97,6 +97,8 @@
+ #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS                (0x00000800)
++#define APMG_RTC_INT_STT_RFKILL               (0x10000000)
++
+ /* Device system time */
+ #define DEVICE_SYSTEM_TIME_REG 0xA0206C
+--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
+@@ -886,6 +886,14 @@ irqreturn_t iwl_pcie_irq_handler(int irq
+               iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
+               if (hw_rfkill) {
++                      /*
++                       * Clear the interrupt in APMG if the NIC is going down.
++                       * Note that when the NIC exits RFkill (else branch), we
++                       * can't access prph and the NIC will be reset in
++                       * start_hw anyway.
++                       */
++                      iwl_write_prph(trans, APMG_RTC_INT_STT_REG,
++                                     APMG_RTC_INT_STT_RFKILL);
+                       set_bit(STATUS_RFKILL, &trans_pcie->status);
+                       if (test_and_clear_bit(STATUS_HCMD_ACTIVE,
+                                              &trans_pcie->status))
diff --git a/queue-3.10/parisc-agp-parisc-agp-allow-binding-of-user-memory-to-the-agp-gart.patch b/queue-3.10/parisc-agp-parisc-agp-allow-binding-of-user-memory-to-the-agp-gart.patch
new file mode 100644 (file)
index 0000000..a2286f5
--- /dev/null
@@ -0,0 +1,54 @@
+From 06f0cce43a32bd2357cea1d8733bba48693d556b Mon Sep 17 00:00:00 2001
+From: Alex Ivanov <gnidorah@p0n4ik.tk>
+Date: Wed, 10 Jul 2013 21:14:55 +0200
+Subject: parisc: agp/parisc-agp: allow binding of user memory to the AGP GART
+
+From: Alex Ivanov <gnidorah@p0n4ik.tk>
+
+commit 06f0cce43a32bd2357cea1d8733bba48693d556b upstream.
+
+Allow binding of user memory to the AGP GART on systems with HP
+Quicksilver AGP bus. This resolves 'bind memory failed' error seen in
+dmesg:
+
+ [29.365973] [TTM] AGP Bind memory failed.
+ …
+ [29.367030] [drm] Forcing AGP to PCI mode
+
+The system doesn't more fail to bind the memory, and hence not falling
+back to the PCI mode (if other failures aren't detected).
+
+This is just a simple write down from the following patches:
+agp/amd-k7: Allow binding user memory to the AGP GART
+agp/hp-agp: Allow binding user memory to the AGP GART
+
+Signed-off-by: Alex Ivanov <gnidorah@p0n4ik.tk>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/agp/parisc-agp.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/agp/parisc-agp.c
++++ b/drivers/char/agp/parisc-agp.c
+@@ -129,7 +129,8 @@ parisc_agp_insert_memory(struct agp_memo
+       off_t j, io_pg_start;
+       int io_pg_count;
+-      if (type != 0 || mem->type != 0) {
++      if (type != mem->type ||
++              agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
+               return -EINVAL;
+       }
+@@ -175,7 +176,8 @@ parisc_agp_remove_memory(struct agp_memo
+       struct _parisc_agp_info *info = &parisc_agp_info;
+       int i, io_pg_start, io_pg_count;
+-      if (type != 0 || mem->type != 0) {
++      if (type != mem->type ||
++              agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
+               return -EINVAL;
+       }
diff --git a/queue-3.10/parisc-fix-cache-routines-to-ignore-vma-s-with-an-invalid-pfn.patch b/queue-3.10/parisc-fix-cache-routines-to-ignore-vma-s-with-an-invalid-pfn.patch
new file mode 100644 (file)
index 0000000..30f09e2
--- /dev/null
@@ -0,0 +1,216 @@
+From 50861f5a02dbf939c27d35a26c472885e2844188 Mon Sep 17 00:00:00 2001
+From: John David Anglin <dave.anglin@bell.net>
+Date: Tue, 23 Jul 2013 12:27:52 -0400
+Subject: parisc: Fix cache routines to ignore vma's with an invalid pfn
+
+From: John David Anglin <dave.anglin@bell.net>
+
+commit 50861f5a02dbf939c27d35a26c472885e2844188 upstream.
+
+The parisc architecture does not have a pte special bit. As a result,
+special mappings are handled with the VM_PFNMAP and VM_MIXEDMAP flags.
+VM_MIXEDMAP mappings may or may not have a "struct page" backing. When
+pfn_valid() is false, there is no "struct page" backing. Otherwise, they
+are treated as normal pages.
+
+The FireGL driver uses the VM_MIXEDMAP without a backing "struct page".
+This treatment caused a panic due to a TLB data miss in
+update_mmu_cache. This appeared to be in the code generated for
+page_address(). We were in fact using a very circular bit of code to
+determine the physical address of the PFN in various cache routines.
+This wasn't valid when there was no "struct page" backing.  The needed
+address can in fact be determined simply from the PFN itself without
+using the "struct page".
+
+The attached patch updates update_mmu_cache(), flush_cache_mm(),
+flush_cache_range() and flush_cache_page() to check pfn_valid() and to
+directly compute the PFN physical and virtual addresses.
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/kernel/cache.c |  133 +++++++++++++++++++++++----------------------
+ 1 file changed, 70 insertions(+), 63 deletions(-)
+
+--- a/arch/parisc/kernel/cache.c
++++ b/arch/parisc/kernel/cache.c
+@@ -71,18 +71,27 @@ flush_cache_all_local(void)
+ }
+ EXPORT_SYMBOL(flush_cache_all_local);
++/* Virtual address of pfn.  */
++#define pfn_va(pfn)   __va(PFN_PHYS(pfn))
++
+ void
+ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+ {
+-      struct page *page = pte_page(*ptep);
++      unsigned long pfn = pte_pfn(*ptep);
++      struct page *page;
+-      if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
+-          test_bit(PG_dcache_dirty, &page->flags)) {
++      /* We don't have pte special.  As a result, we can be called with
++         an invalid pfn and we don't need to flush the kernel dcache page.
++         This occurs with FireGL card in C8000.  */
++      if (!pfn_valid(pfn))
++              return;
+-              flush_kernel_dcache_page(page);
++      page = pfn_to_page(pfn);
++      if (page_mapping(page) && test_bit(PG_dcache_dirty, &page->flags)) {
++              flush_kernel_dcache_page_addr(pfn_va(pfn));
+               clear_bit(PG_dcache_dirty, &page->flags);
+       } else if (parisc_requires_coherency())
+-              flush_kernel_dcache_page(page);
++              flush_kernel_dcache_page_addr(pfn_va(pfn));
+ }
+ void
+@@ -495,44 +504,42 @@ static inline pte_t *get_ptep(pgd_t *pgd
+ void flush_cache_mm(struct mm_struct *mm)
+ {
++      struct vm_area_struct *vma;
++      pgd_t *pgd;
++
+       /* Flushing the whole cache on each cpu takes forever on
+          rp3440, etc.  So, avoid it if the mm isn't too big.  */
+-      if (mm_total_size(mm) < parisc_cache_flush_threshold) {
+-              struct vm_area_struct *vma;
+-
+-              if (mm->context == mfsp(3)) {
+-                      for (vma = mm->mmap; vma; vma = vma->vm_next) {
+-                              flush_user_dcache_range_asm(vma->vm_start,
+-                                      vma->vm_end);
+-                              if (vma->vm_flags & VM_EXEC)
+-                                      flush_user_icache_range_asm(
+-                                        vma->vm_start, vma->vm_end);
+-                      }
+-              } else {
+-                      pgd_t *pgd = mm->pgd;
+-
+-                      for (vma = mm->mmap; vma; vma = vma->vm_next) {
+-                              unsigned long addr;
++      if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
++              flush_cache_all();
++              return;
++      }
+-                              for (addr = vma->vm_start; addr < vma->vm_end;
+-                                   addr += PAGE_SIZE) {
+-                                      pte_t *ptep = get_ptep(pgd, addr);
+-                                      if (ptep != NULL) {
+-                                              pte_t pte = *ptep;
+-                                              __flush_cache_page(vma, addr,
+-                                                page_to_phys(pte_page(pte)));
+-                                      }
+-                              }
+-                      }
++      if (mm->context == mfsp(3)) {
++              for (vma = mm->mmap; vma; vma = vma->vm_next) {
++                      flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
++                      if ((vma->vm_flags & VM_EXEC) == 0)
++                              continue;
++                      flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
+               }
+               return;
+       }
+-#ifdef CONFIG_SMP
+-      flush_cache_all();
+-#else
+-      flush_cache_all_local();
+-#endif
++      pgd = mm->pgd;
++      for (vma = mm->mmap; vma; vma = vma->vm_next) {
++              unsigned long addr;
++
++              for (addr = vma->vm_start; addr < vma->vm_end;
++                   addr += PAGE_SIZE) {
++                      unsigned long pfn;
++                      pte_t *ptep = get_ptep(pgd, addr);
++                      if (!ptep)
++                              continue;
++                      pfn = pte_pfn(*ptep);
++                      if (!pfn_valid(pfn))
++                              continue;
++                      __flush_cache_page(vma, addr, PFN_PHYS(pfn));
++              }
++      }
+ }
+ void
+@@ -556,33 +563,32 @@ flush_user_icache_range(unsigned long st
+ void flush_cache_range(struct vm_area_struct *vma,
+               unsigned long start, unsigned long end)
+ {
+-      BUG_ON(!vma->vm_mm->context);
++      unsigned long addr;
++      pgd_t *pgd;
+-      if ((end - start) < parisc_cache_flush_threshold) {
+-              if (vma->vm_mm->context == mfsp(3)) {
+-                      flush_user_dcache_range_asm(start, end);
+-                      if (vma->vm_flags & VM_EXEC)
+-                              flush_user_icache_range_asm(start, end);
+-              } else {
+-                      unsigned long addr;
+-                      pgd_t *pgd = vma->vm_mm->pgd;
++      BUG_ON(!vma->vm_mm->context);
+-                      for (addr = start & PAGE_MASK; addr < end;
+-                           addr += PAGE_SIZE) {
+-                              pte_t *ptep = get_ptep(pgd, addr);
+-                              if (ptep != NULL) {
+-                                      pte_t pte = *ptep;
+-                                      flush_cache_page(vma,
+-                                         addr, pte_pfn(pte));
+-                              }
+-                      }
+-              }
+-      } else {
+-#ifdef CONFIG_SMP
++      if ((end - start) >= parisc_cache_flush_threshold) {
+               flush_cache_all();
+-#else
+-              flush_cache_all_local();
+-#endif
++              return;
++      }
++
++      if (vma->vm_mm->context == mfsp(3)) {
++              flush_user_dcache_range_asm(start, end);
++              if (vma->vm_flags & VM_EXEC)
++                      flush_user_icache_range_asm(start, end);
++              return;
++      }
++
++      pgd = vma->vm_mm->pgd;
++      for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) {
++              unsigned long pfn;
++              pte_t *ptep = get_ptep(pgd, addr);
++              if (!ptep)
++                      continue;
++              pfn = pte_pfn(*ptep);
++              if (pfn_valid(pfn))
++                      __flush_cache_page(vma, addr, PFN_PHYS(pfn));
+       }
+ }
+@@ -591,9 +597,10 @@ flush_cache_page(struct vm_area_struct *
+ {
+       BUG_ON(!vma->vm_mm->context);
+-      flush_tlb_page(vma, vmaddr);
+-      __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn)));
+-
++      if (pfn_valid(pfn)) {
++              flush_tlb_page(vma, vmaddr);
++              __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
++      }
+ }
+ #ifdef CONFIG_PARISC_TMPALIAS
diff --git a/queue-3.10/parisc-fix-interrupt-routing-for-c8000-serial-ports.patch b/queue-3.10/parisc-fix-interrupt-routing-for-c8000-serial-ports.patch
new file mode 100644 (file)
index 0000000..7b2cf3f
--- /dev/null
@@ -0,0 +1,137 @@
+From dd5e6d6a3db09b16b7c222943977865eead88cc3 Mon Sep 17 00:00:00 2001
+From: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Date: Tue, 30 Jul 2013 02:02:16 +0200
+Subject: parisc: Fix interrupt routing for C8000 serial ports
+
+From: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+
+commit dd5e6d6a3db09b16b7c222943977865eead88cc3 upstream.
+
+We can't use dev->mod_index for selecting the interrupt routing entry,
+because it's not an index into interrupt routing table. It will be even
+wrong on a machine with 2 CPUs (4 cores). But all needed information is
+contained in the PAT entries for the serial ports. mod[0] contains the
+iosapic address and mod_info has some indications for the interrupt
+input (at least it looks like it). This patch implements the searching
+for the right iosapic and uses this interrupt input information.
+
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/include/asm/parisc-device.h |    3 ++
+ arch/parisc/kernel/inventory.c          |    1 
+ drivers/parisc/iosapic.c                |   38 ++++++++++++++++++++++----------
+ drivers/tty/serial/8250/8250_gsc.c      |    3 --
+ 4 files changed, 32 insertions(+), 13 deletions(-)
+
+--- a/arch/parisc/include/asm/parisc-device.h
++++ b/arch/parisc/include/asm/parisc-device.h
+@@ -23,6 +23,7 @@ struct parisc_device {
+       /* generic info returned from pdc_pat_cell_module() */
+       unsigned long   mod_info;       /* PAT specific - Misc Module info */
+       unsigned long   pmod_loc;       /* physical Module location */
++      unsigned long   mod0;
+ #endif
+       u64             dma_mask;       /* DMA mask for I/O */
+       struct device   dev;
+@@ -61,4 +62,6 @@ parisc_get_drvdata(struct parisc_device
+ extern struct bus_type parisc_bus_type;
++int iosapic_serial_irq(struct parisc_device *dev);
++
+ #endif /*_ASM_PARISC_PARISC_DEVICE_H_*/
+--- a/arch/parisc/kernel/inventory.c
++++ b/arch/parisc/kernel/inventory.c
+@@ -211,6 +211,7 @@ pat_query_module(ulong pcell_loc, ulong
+       /* REVISIT: who is the consumer of this? not sure yet... */
+       dev->mod_info = pa_pdc_cell->mod_info;  /* pass to PAT_GET_ENTITY() */
+       dev->pmod_loc = pa_pdc_cell->mod_location;
++      dev->mod0 = pa_pdc_cell->mod[0];
+       register_parisc_device(dev);    /* advertise device */
+--- a/drivers/parisc/iosapic.c
++++ b/drivers/parisc/iosapic.c
+@@ -811,18 +811,28 @@ int iosapic_fixup_irq(void *isi_obj, str
+       return pcidev->irq;
+ }
+-static struct iosapic_info *first_isi = NULL;
++static struct iosapic_info *iosapic_list;
+ #ifdef CONFIG_64BIT
+-int iosapic_serial_irq(int num)
++int iosapic_serial_irq(struct parisc_device *dev)
+ {
+-      struct iosapic_info *isi = first_isi;
+-      struct irt_entry *irte = NULL;  /* only used if PAT PDC */
++      struct iosapic_info *isi;
++      struct irt_entry *irte;
+       struct vector_info *vi;
+-      int isi_line;   /* line used by device */
++      int cnt;
++      int intin;
++
++      intin = (dev->mod_info >> 24) & 15;
+       /* lookup IRT entry for isi/slot/pin set */
+-      irte = &irt_cell[num];
++      for (cnt = 0; cnt < irt_num_entry; cnt++) {
++              irte = &irt_cell[cnt];
++              if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
++                  irte->dest_iosapic_intin == intin)
++                      break;
++      }
++      if (cnt >= irt_num_entry)
++              return 0; /* no irq found, force polling */
+       DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
+               irte,
+@@ -834,11 +844,17 @@ int iosapic_serial_irq(int num)
+               irte->src_seg_id,
+               irte->dest_iosapic_intin,
+               (u32) irte->dest_iosapic_addr);
+-      isi_line = irte->dest_iosapic_intin;
++
++      /* search for iosapic */
++      for (isi = iosapic_list; isi; isi = isi->isi_next)
++              if (isi->isi_hpa == dev->mod0)
++                      break;
++      if (!isi)
++              return 0; /* no iosapic found, force polling */
+       /* get vector info for this input line */
+-      vi = isi->isi_vector + isi_line;
+-      DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", isi_line, vi);
++      vi = isi->isi_vector + intin;
++      DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);
+       /* If this IRQ line has already been setup, skip it */
+       if (vi->irte)
+@@ -941,8 +957,8 @@ void *iosapic_register(unsigned long hpa
+               vip->irqline = (unsigned char) cnt;
+               vip->iosapic = isi;
+       }
+-      if (!first_isi)
+-              first_isi = isi;
++      isi->isi_next = iosapic_list;
++      iosapic_list = isi;
+       return isi;
+ }
+--- a/drivers/tty/serial/8250/8250_gsc.c
++++ b/drivers/tty/serial/8250/8250_gsc.c
+@@ -31,9 +31,8 @@ static int __init serial_init_chip(struc
+       int err;
+ #ifdef CONFIG_64BIT
+-      extern int iosapic_serial_irq(int cellnum);
+       if (!dev->irq && (dev->id.sversion == 0xad))
+-              dev->irq = iosapic_serial_irq(dev->mod_index-1);
++              dev->irq = iosapic_serial_irq(dev);
+ #endif
+       if (!dev->irq) {
diff --git a/queue-3.10/powerpc-vphn-topology-change-updates-all-siblings.patch b/queue-3.10/powerpc-vphn-topology-change-updates-all-siblings.patch
new file mode 100644 (file)
index 0000000..a6ca80e
--- /dev/null
@@ -0,0 +1,155 @@
+From 3be7db6ab45b21345386d1a466da133b19cde5e4 Mon Sep 17 00:00:00 2001
+From: Robert Jennings <rcj@linux.vnet.ibm.com>
+Date: Wed, 24 Jul 2013 20:13:21 -0500
+Subject: powerpc: VPHN topology change updates all siblings
+
+From: Robert Jennings <rcj@linux.vnet.ibm.com>
+
+commit 3be7db6ab45b21345386d1a466da133b19cde5e4 upstream.
+
+When an associativity level change is found for one thread, the
+siblings threads need to be updated as well.  This is done today
+for PRRN in stage_topology_update() but is missing for VPHN in
+update_cpu_associativity_changes_mask().  This patch will correctly
+update all thread siblings during a topology change.
+
+Without this patch a topology update can result in a CPU in
+init_sched_groups_power() getting stuck indefinitely in a loop.
+
+This loop is built in build_sched_groups(). As a result of the thread
+moving to a node separate from its siblings the struct sched_group will
+have its next pointer set to point to itself rather than the sched_group
+struct of the next thread.  This happens because we have a domain without
+the SD_OVERLAP flag, which is correct, and a topology that doesn't conform
+with reality (threads on the same core assigned to different numa nodes).
+When this list is traversed by init_sched_groups_power() it will reach
+the thread's sched_group structure and loop indefinitely; the cpu will
+be stuck at this point.
+
+The bug was exposed when VPHN was enabled in commit b7abef0 (v3.9).
+
+Reported-by: Jan Stancek <jstancek@redhat.com>
+Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/smp.h |    4 ++
+ arch/powerpc/mm/numa.c         |   59 ++++++++++++++++++++++++++++++-----------
+ 2 files changed, 48 insertions(+), 15 deletions(-)
+
+--- a/arch/powerpc/include/asm/smp.h
++++ b/arch/powerpc/include/asm/smp.h
+@@ -145,6 +145,10 @@ extern void __cpu_die(unsigned int cpu);
+ #define smp_setup_cpu_maps()
+ static inline void inhibit_secondary_onlining(void) {}
+ static inline void uninhibit_secondary_onlining(void) {}
++static inline const struct cpumask *cpu_sibling_mask(int cpu)
++{
++      return cpumask_of(cpu);
++}
+ #endif /* CONFIG_SMP */
+--- a/arch/powerpc/mm/numa.c
++++ b/arch/powerpc/mm/numa.c
+@@ -27,6 +27,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/uaccess.h>
+ #include <linux/slab.h>
++#include <asm/cputhreads.h>
+ #include <asm/sparsemem.h>
+ #include <asm/prom.h>
+ #include <asm/smp.h>
+@@ -1319,7 +1320,8 @@ static int update_cpu_associativity_chan
+                       }
+               }
+               if (changed) {
+-                      cpumask_set_cpu(cpu, changes);
++                      cpumask_or(changes, changes, cpu_sibling_mask(cpu));
++                      cpu = cpu_last_thread_sibling(cpu);
+               }
+       }
+@@ -1427,7 +1429,7 @@ static int update_cpu_topology(void *dat
+       if (!data)
+               return -EINVAL;
+-      cpu = get_cpu();
++      cpu = smp_processor_id();
+       for (update = data; update; update = update->next) {
+               if (cpu != update->cpu)
+@@ -1447,12 +1449,12 @@ static int update_cpu_topology(void *dat
+  */
+ int arch_update_cpu_topology(void)
+ {
+-      unsigned int cpu, changed = 0;
++      unsigned int cpu, sibling, changed = 0;
+       struct topology_update_data *updates, *ud;
+       unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
+       cpumask_t updated_cpus;
+       struct device *dev;
+-      int weight, i = 0;
++      int weight, new_nid, i = 0;
+       weight = cpumask_weight(&cpu_associativity_changes_mask);
+       if (!weight)
+@@ -1465,19 +1467,46 @@ int arch_update_cpu_topology(void)
+       cpumask_clear(&updated_cpus);
+       for_each_cpu(cpu, &cpu_associativity_changes_mask) {
+-              ud = &updates[i++];
+-              ud->cpu = cpu;
+-              vphn_get_associativity(cpu, associativity);
+-              ud->new_nid = associativity_to_nid(associativity);
+-
+-              if (ud->new_nid < 0 || !node_online(ud->new_nid))
+-                      ud->new_nid = first_online_node;
++              /*
++               * If siblings aren't flagged for changes, updates list
++               * will be too short. Skip on this update and set for next
++               * update.
++               */
++              if (!cpumask_subset(cpu_sibling_mask(cpu),
++                                      &cpu_associativity_changes_mask)) {
++                      pr_info("Sibling bits not set for associativity "
++                                      "change, cpu%d\n", cpu);
++                      cpumask_or(&cpu_associativity_changes_mask,
++                                      &cpu_associativity_changes_mask,
++                                      cpu_sibling_mask(cpu));
++                      cpu = cpu_last_thread_sibling(cpu);
++                      continue;
++              }
+-              ud->old_nid = numa_cpu_lookup_table[cpu];
+-              cpumask_set_cpu(cpu, &updated_cpus);
++              /* Use associativity from first thread for all siblings */
++              vphn_get_associativity(cpu, associativity);
++              new_nid = associativity_to_nid(associativity);
++              if (new_nid < 0 || !node_online(new_nid))
++                      new_nid = first_online_node;
++
++              if (new_nid == numa_cpu_lookup_table[cpu]) {
++                      cpumask_andnot(&cpu_associativity_changes_mask,
++                                      &cpu_associativity_changes_mask,
++                                      cpu_sibling_mask(cpu));
++                      cpu = cpu_last_thread_sibling(cpu);
++                      continue;
++              }
+-              if (i < weight)
+-                      ud->next = &updates[i];
++              for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
++                      ud = &updates[i++];
++                      ud->cpu = sibling;
++                      ud->new_nid = new_nid;
++                      ud->old_nid = numa_cpu_lookup_table[sibling];
++                      cpumask_set_cpu(sibling, &updated_cpus);
++                      if (i < weight)
++                              ud->next = &updates[i];
++              }
++              cpu = cpu_last_thread_sibling(cpu);
+       }
+       stop_machine(update_cpu_topology, &updates[0], &updated_cpus);
diff --git a/queue-3.10/powerpc-windfarm-fix-noisy-slots-fan-on-xserve-rm31.patch b/queue-3.10/powerpc-windfarm-fix-noisy-slots-fan-on-xserve-rm31.patch
new file mode 100644 (file)
index 0000000..3c5490a
--- /dev/null
@@ -0,0 +1,52 @@
+From fe956a1d4081ce1a959f87df397a15e252201f10 Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+Date: Sun, 21 Jul 2013 03:30:11 +0300
+Subject: powerpc/windfarm: Fix noisy slots-fan on Xserve (rm31)
+
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+
+commit fe956a1d4081ce1a959f87df397a15e252201f10 upstream.
+
+slots-fan on G5 Xserve is always running at full speed with windfarm_rm31
+driver, resulting in a very high acoustic noise level. It seems the fan
+parameters are incorrect, and have been copied from the Drive Bay fan
+(RPM, not present on rm31) of the legacy therm_pm72 driver. This patch
+changes the parameters to match the Slots fan (PWM) of therm_pm72. With
+the patch, slots-fan speed drops from 99% to 19% during normal use,
+and slots-temp settle to ~42'C.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/macintosh/windfarm_rm31.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/macintosh/windfarm_rm31.c
++++ b/drivers/macintosh/windfarm_rm31.c
+@@ -439,15 +439,15 @@ static void backside_setup_pid(void)
+ /* Slots fan */
+ static const struct wf_pid_param slots_param = {
+-      .interval       = 5,
+-      .history_len    = 2,
+-      .gd             = 30 << 20,
+-      .gp             = 5 << 20,
+-      .gr             = 0,
+-      .itarget        = 40 << 16,
+-      .additive       = 1,
+-      .min            = 300,
+-      .max            = 4000,
++      .interval       = 1,
++      .history_len    = 20,
++      .gd             = 0,
++      .gp             = 0,
++      .gr             = 0x00100000,
++      .itarget        = 3200000,
++      .additive       = 0,
++      .min            = 20,
++      .max            = 100,
+ };
+ static void slots_fan_tick(void)
diff --git a/queue-3.10/serial-arc_uart-fix-module-alias.patch b/queue-3.10/serial-arc_uart-fix-module-alias.patch
new file mode 100644 (file)
index 0000000..5667a1a
--- /dev/null
@@ -0,0 +1,30 @@
+From d5a12ea7a9e58d9e5c19d25cb668aadb396423ec Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Sun, 21 Jul 2013 10:14:15 +0800
+Subject: serial: arc_uart: Fix module alias
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit d5a12ea7a9e58d9e5c19d25cb668aadb396423ec upstream.
+
+Platform drivers use "platform:" prefix in module alias.
+Also use DRIVER_NAME in MODULE_ALIAS to make module autoloading work.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Acked-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/arc_uart.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/arc_uart.c
++++ b/drivers/tty/serial/arc_uart.c
+@@ -773,6 +773,6 @@ module_init(arc_serial_init);
+ module_exit(arc_serial_exit);
+ MODULE_LICENSE("GPL");
+-MODULE_ALIAS("plat-arcfpga/uart");
++MODULE_ALIAS("platform:" DRIVER_NAME);
+ MODULE_AUTHOR("Vineet Gupta");
+ MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");
diff --git a/queue-3.10/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch b/queue-3.10/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch
new file mode 100644 (file)
index 0000000..d3233e9
--- /dev/null
@@ -0,0 +1,60 @@
+From d970d7fe65adff5efe75b4a73c4ffc9be57089f7 Mon Sep 17 00:00:00 2001
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Date: Thu, 4 Jul 2013 11:28:51 +0200
+Subject: serial/mxs-auart: fix race condition in interrupt handler
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+commit d970d7fe65adff5efe75b4a73c4ffc9be57089f7 upstream.
+
+The handler needs to ack the pending events before actually handling them.
+Otherwise a new event might come in after it it considered non-pending or
+handled and is acked then without being handled. So this event is only
+noticed when the next interrupt happens.
+
+Without this patch an i.MX28 based machine running an rt-patched kernel
+regularly hangs during boot.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/mxs-auart.c |   17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/serial/mxs-auart.c
++++ b/drivers/tty/serial/mxs-auart.c
+@@ -678,11 +678,18 @@ static void mxs_auart_settermios(struct
+ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
+ {
+-      u32 istatus, istat;
++      u32 istat;
+       struct mxs_auart_port *s = context;
+       u32 stat = readl(s->port.membase + AUART_STAT);
+-      istatus = istat = readl(s->port.membase + AUART_INTR);
++      istat = readl(s->port.membase + AUART_INTR);
++
++      /* ack irq */
++      writel(istat & (AUART_INTR_RTIS
++              | AUART_INTR_TXIS
++              | AUART_INTR_RXIS
++              | AUART_INTR_CTSMIS),
++                      s->port.membase + AUART_INTR_CLR);
+       if (istat & AUART_INTR_CTSMIS) {
+               uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
+@@ -702,12 +709,6 @@ static irqreturn_t mxs_auart_irq_handle(
+               istat &= ~AUART_INTR_TXIS;
+       }
+-      writel(istatus & (AUART_INTR_RTIS
+-              | AUART_INTR_TXIS
+-              | AUART_INTR_RXIS
+-              | AUART_INTR_CTSMIS),
+-                      s->port.membase + AUART_INTR_CLR);
+-
+       return IRQ_HANDLED;
+ }
diff --git a/queue-3.10/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch b/queue-3.10/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch
new file mode 100644 (file)
index 0000000..8a8ec82
--- /dev/null
@@ -0,0 +1,71 @@
+From 079a036f4283e2b0e5c26080b8c5112bc0cc1831 Mon Sep 17 00:00:00 2001
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Date: Fri, 28 Jun 2013 11:49:41 +0200
+Subject: serial/mxs-auart: increase time to wait for transmitter to become idle
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+commit 079a036f4283e2b0e5c26080b8c5112bc0cc1831 upstream.
+
+Without this patch the driver waits ~1 ms for the UART to become idle. At
+115200n8 this time is (theoretically) enough to transfer 11.5 characters
+(= 115200 bits/s / (10 Bits/char) * 1ms). As the mxs-auart has a fifo size
+of 16 characters the clock is gated too early. The problem is worse for
+lower baud rates.
+
+This only happens to really shut down the transmitter in the middle of a
+transfer if /dev/ttyAPPx isn't opened in userspace (e.g. by a getty) but
+was at least once (because the bootloader doesn't disable the transmitter).
+
+So increase the timeout to 20 ms which should be enough for 9600n8, too.
+Moreover skip gating the clock if the timeout is elapsed.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/mxs-auart.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/serial/mxs-auart.c
++++ b/drivers/tty/serial/mxs-auart.c
+@@ -851,7 +851,7 @@ auart_console_write(struct console *co,
+       struct mxs_auart_port *s;
+       struct uart_port *port;
+       unsigned int old_ctrl0, old_ctrl2;
+-      unsigned int to = 1000;
++      unsigned int to = 20000;
+       if (co->index >= MXS_AUART_PORTS || co->index < 0)
+               return;
+@@ -872,18 +872,23 @@ auart_console_write(struct console *co,
+       uart_console_write(port, str, count, mxs_auart_console_putchar);
+-      /*
+-       * Finally, wait for transmitter to become empty
+-       * and restore the TCR
+-       */
++      /* Finally, wait for transmitter to become empty ... */
+       while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
++              udelay(1);
+               if (!to--)
+                       break;
+-              udelay(1);
+       }
+-      writel(old_ctrl0, port->membase + AUART_CTRL0);
+-      writel(old_ctrl2, port->membase + AUART_CTRL2);
++      /*
++       * ... and restore the TCR if we waited long enough for the transmitter
++       * to be idle. This might keep the transmitter enabled although it is
++       * unused, but that is better than to disable it while it is still
++       * transmitting.
++       */
++      if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) {
++              writel(old_ctrl0, port->membase + AUART_CTRL0);
++              writel(old_ctrl2, port->membase + AUART_CTRL2);
++      }
+       clk_disable(s->clk);
+ }
index e9a483ef95dd30d4dafac21be3f6f9a9bd993391..6ab3edde42d843d7ad0456d7bf6d5b6cef1e86ae 100644 (file)
@@ -8,3 +8,29 @@ arm-move-signal-handlers-into-a-vdso-like-page.patch
 arm-make-vectors-page-inaccessible-from-userspace.patch
 arm-fix-a-cockup-in-48be69a02-arm-move-signal-handlers-into-a-vdso-like-page.patch
 arm-fix-nommu-builds-with-48be69a02-arm-move-signal-handlers-into-a-vdso-like-page.patch
+powerpc-windfarm-fix-noisy-slots-fan-on-xserve-rm31.patch
+arm-7784-1-mm-ensure-smp-alternates-assemble-to-exactly-4-bytes-with-thumb-2.patch
+arm-7790-1-fix-deferred-mm-switch-on-vivt-processors.patch
+arm-7791-1-a.out-remove-partial-a.out-support.patch
+powerpc-vphn-topology-change-updates-all-siblings.patch
+parisc-agp-parisc-agp-allow-binding-of-user-memory-to-the-agp-gart.patch
+parisc-fix-cache-routines-to-ignore-vma-s-with-an-invalid-pfn.patch
+parisc-fix-interrupt-routing-for-c8000-serial-ports.patch
+hwmon-max6697-fix-max6581-ideality.patch
+alsa-hda-fix-missing-fixup-for-mac-mini-with-stac9221.patch
+alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch
+serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch
+serial-arc_uart-fix-module-alias.patch
+serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch
+dma-pl330-fix-cyclic-transfers.patch
+usb-mos7840-fix-race-in-register-handling.patch
+usb-mos7840-fix-device-type-detection.patch
+usb-mos7840-fix-race-in-led-handling.patch
+usb-mos7840-fix-pointer-casts.patch
+iwlwifi-mvm-fix-l2p-ba-ressources-leak.patch
+iwlwifi-mvm-fix-bug-in-scan-ssid.patch
+iwlwifi-mvm-refuse-connection-to-aps-with-bi-16.patch
+iwlwifi-add-dell-sku-for-5150-hmc.patch
+iwlwifi-mvm-fix-flushing-not-started-aggregation-sessions.patch
+iwlwifi-pcie-clear-rfkill-interrupt-in-ampg.patch
+atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch
diff --git a/queue-3.10/usb-mos7840-fix-device-type-detection.patch b/queue-3.10/usb-mos7840-fix-device-type-detection.patch
new file mode 100644 (file)
index 0000000..9110b06
--- /dev/null
@@ -0,0 +1,144 @@
+From 40c24f2893ba0ba7df485871f6aac0c197ceef5b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Fri, 26 Jul 2013 11:55:18 +0200
+Subject: USB: mos7840: fix device-type detection
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 40c24f2893ba0ba7df485871f6aac0c197ceef5b upstream.
+
+Fix race in device-type detection introduced by commit 0eafe4de ("USB:
+serial: mos7840: add support for MCS7810 devices") which used a static
+variable to hold the device type.
+
+Move type detection to probe and use serial data to store the device
+type.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |   75 ++++++++++++++++++++-----------------------
+ 1 file changed, 35 insertions(+), 40 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -187,8 +187,6 @@ enum mos7840_flag {
+       MOS7840_FLAG_CTRL_BUSY,
+ };
+-static int device_type;
+-
+ static const struct usb_device_id id_table[] = {
+       {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
+       {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+@@ -839,18 +837,6 @@ static void mos7840_bulk_out_data_callba
+ /************************************************************************/
+ /*       D R I V E R  T T Y  I N T E R F A C E  F U N C T I O N S       */
+ /************************************************************************/
+-#ifdef MCSSerialProbe
+-static int mos7840_serial_probe(struct usb_serial *serial,
+-                              const struct usb_device_id *id)
+-{
+-
+-      /*need to implement the mode_reg reading and updating\
+-         structures usb_serial_ device_type\
+-         (i.e num_ports, num_bulkin,bulkout etc) */
+-      /* Also we can update the changes  attach */
+-      return 1;
+-}
+-#endif
+ /*****************************************************************************
+  * mos7840_open
+@@ -2216,38 +2202,48 @@ static int mos7810_check(struct usb_seri
+       return 0;
+ }
+-static int mos7840_calc_num_ports(struct usb_serial *serial)
++static int mos7840_probe(struct usb_serial *serial,
++                              const struct usb_device_id *id)
+ {
+-      __u16 data = 0x00;
++      u16 product = serial->dev->descriptor.idProduct;
+       u8 *buf;
+-      int mos7840_num_ports;
++      int device_type;
++
++      if (product == MOSCHIP_DEVICE_ID_7810 ||
++              product == MOSCHIP_DEVICE_ID_7820) {
++              device_type = product;
++              goto out;
++      }
+       buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+-      if (buf) {
+-              usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
++      if (!buf)
++              return -ENOMEM;
++
++      usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                       MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
+                       VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+-              data = *buf;
+-              kfree(buf);
+-      }
+-      if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
+-              serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
+-              device_type = serial->dev->descriptor.idProduct;
+-      } else {
+-              /* For a MCS7840 device GPIO0 must be set to 1 */
+-              if ((data & 0x01) == 1)
+-                      device_type = MOSCHIP_DEVICE_ID_7840;
+-              else if (mos7810_check(serial))
+-                      device_type = MOSCHIP_DEVICE_ID_7810;
+-              else
+-                      device_type = MOSCHIP_DEVICE_ID_7820;
+-      }
++      /* For a MCS7840 device GPIO0 must be set to 1 */
++      if (buf[0] & 0x01)
++              device_type = MOSCHIP_DEVICE_ID_7840;
++      else if (mos7810_check(serial))
++              device_type = MOSCHIP_DEVICE_ID_7810;
++      else
++              device_type = MOSCHIP_DEVICE_ID_7820;
++
++      kfree(buf);
++out:
++      usb_set_serial_data(serial, (void *)device_type);
++
++      return 0;
++}
++
++static int mos7840_calc_num_ports(struct usb_serial *serial)
++{
++      int device_type = (int)usb_get_serial_data(serial);
++      int mos7840_num_ports;
+       mos7840_num_ports = (device_type >> 4) & 0x000F;
+-      serial->num_bulk_in = mos7840_num_ports;
+-      serial->num_bulk_out = mos7840_num_ports;
+-      serial->num_ports = mos7840_num_ports;
+       return mos7840_num_ports;
+ }
+@@ -2255,6 +2251,7 @@ static int mos7840_calc_num_ports(struct
+ static int mos7840_port_probe(struct usb_serial_port *port)
+ {
+       struct usb_serial *serial = port->serial;
++      int device_type = (int)usb_get_serial_data(serial);
+       struct moschip_port *mos7840_port;
+       int status;
+       int pnum;
+@@ -2513,9 +2510,7 @@ static struct usb_serial_driver moschip7
+       .throttle = mos7840_throttle,
+       .unthrottle = mos7840_unthrottle,
+       .calc_num_ports = mos7840_calc_num_ports,
+-#ifdef MCSSerialProbe
+-      .probe = mos7840_serial_probe,
+-#endif
++      .probe = mos7840_probe,
+       .ioctl = mos7840_ioctl,
+       .set_termios = mos7840_set_termios,
+       .break_ctl = mos7840_break,
diff --git a/queue-3.10/usb-mos7840-fix-pointer-casts.patch b/queue-3.10/usb-mos7840-fix-pointer-casts.patch
new file mode 100644 (file)
index 0000000..8f0e084
--- /dev/null
@@ -0,0 +1,51 @@
+From 683a0e4d7971c3186dc4d429027debfe309129aa Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sat, 27 Jul 2013 13:34:42 +0200
+Subject: USB: mos7840: fix pointer casts
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 683a0e4d7971c3186dc4d429027debfe309129aa upstream.
+
+Silence compiler warnings on 64-bit systems introduced by commit
+05cf0dec ("USB: mos7840: fix race in led handling") which uses the
+usb-serial data pointer to temporarily store the device type during
+probe but failed to add the required casts.
+
+[gregkh - change uintptr_t to unsigned long]
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -2236,14 +2236,14 @@ static int mos7840_probe(struct usb_seri
+       kfree(buf);
+ out:
+-      usb_set_serial_data(serial, (void *)device_type);
++      usb_set_serial_data(serial, (void *)(unsigned long)device_type);
+       return 0;
+ }
+ static int mos7840_calc_num_ports(struct usb_serial *serial)
+ {
+-      int device_type = (int)usb_get_serial_data(serial);
++      int device_type = (unsigned long)usb_get_serial_data(serial);
+       int mos7840_num_ports;
+       mos7840_num_ports = (device_type >> 4) & 0x000F;
+@@ -2254,7 +2254,7 @@ static int mos7840_calc_num_ports(struct
+ static int mos7840_port_probe(struct usb_serial_port *port)
+ {
+       struct usb_serial *serial = port->serial;
+-      int device_type = (int)usb_get_serial_data(serial);
++      int device_type = (unsigned long)usb_get_serial_data(serial);
+       struct moschip_port *mos7840_port;
+       int status;
+       int pnum;
diff --git a/queue-3.10/usb-mos7840-fix-race-in-led-handling.patch b/queue-3.10/usb-mos7840-fix-race-in-led-handling.patch
new file mode 100644 (file)
index 0000000..bb0d4f4
--- /dev/null
@@ -0,0 +1,167 @@
+From 05cf0dec5ccc696a7636c84b265b477173498156 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Fri, 26 Jul 2013 11:55:19 +0200
+Subject: USB: mos7840: fix race in led handling
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 05cf0dec5ccc696a7636c84b265b477173498156 upstream.
+
+Fix race in LED handling introduced by commit 0eafe4de ("USB: serial:
+mos7840: add support for MCS7810 devices") which reused the port control
+urb for manipulating the LED without making sure that the urb is not
+already in use. This could lead to the control urb being manipulated
+while in flight.
+
+Fix by adding a dedicated LED urb and ctrlrequest along with a LED-busy
+flag to handle concurrency.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |   59 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 37 insertions(+), 22 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -185,6 +185,7 @@
+ enum mos7840_flag {
+       MOS7840_FLAG_CTRL_BUSY,
++      MOS7840_FLAG_LED_BUSY,
+ };
+ static const struct usb_device_id id_table[] = {
+@@ -240,9 +241,10 @@ struct moschip_port {
+       /* For device(s) with LED indicator */
+       bool has_led;
+-      bool led_flag;
+       struct timer_list led_timer1;   /* Timer for LED on */
+       struct timer_list led_timer2;   /* Timer for LED off */
++      struct urb *led_urb;
++      struct usb_ctrlrequest *led_dr;
+       unsigned long flags;
+ };
+@@ -542,7 +544,7 @@ static void mos7840_set_led_async(struct
+                               __u16 reg)
+ {
+       struct usb_device *dev = mcs->port->serial->dev;
+-      struct usb_ctrlrequest *dr = mcs->dr;
++      struct usb_ctrlrequest *dr = mcs->led_dr;
+       dr->bRequestType = MCS_WR_RTYPE;
+       dr->bRequest = MCS_WRREQ;
+@@ -550,10 +552,10 @@ static void mos7840_set_led_async(struct
+       dr->wIndex = cpu_to_le16(reg);
+       dr->wLength = cpu_to_le16(0);
+-      usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0),
++      usb_fill_control_urb(mcs->led_urb, dev, usb_sndctrlpipe(dev, 0),
+               (unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
+-      usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
++      usb_submit_urb(mcs->led_urb, GFP_ATOMIC);
+ }
+ static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
+@@ -579,7 +581,19 @@ static void mos7840_led_flag_off(unsigne
+ {
+       struct moschip_port *mcs = (struct moschip_port *) arg;
+-      mcs->led_flag = false;
++      clear_bit_unlock(MOS7840_FLAG_LED_BUSY, &mcs->flags);
++}
++
++static void mos7840_led_activity(struct usb_serial_port *port)
++{
++      struct moschip_port *mos7840_port = usb_get_serial_port_data(port);
++
++      if (test_and_set_bit_lock(MOS7840_FLAG_LED_BUSY, &mos7840_port->flags))
++              return;
++
++      mos7840_set_led_async(mos7840_port, 0x0301, MODEM_CONTROL_REGISTER);
++      mod_timer(&mos7840_port->led_timer1,
++                              jiffies + msecs_to_jiffies(LED_ON_MS));
+ }
+ /*****************************************************************************
+@@ -779,14 +793,8 @@ static void mos7840_bulk_in_callback(str
+               return;
+       }
+-      /* Turn on LED */
+-      if (mos7840_port->has_led && !mos7840_port->led_flag) {
+-              mos7840_port->led_flag = true;
+-              mos7840_set_led_async(mos7840_port, 0x0301,
+-                                      MODEM_CONTROL_REGISTER);
+-              mod_timer(&mos7840_port->led_timer1,
+-                              jiffies + msecs_to_jiffies(LED_ON_MS));
+-      }
++      if (mos7840_port->has_led)
++              mos7840_led_activity(port);
+       mos7840_port->read_urb_busy = true;
+       retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
+@@ -1467,13 +1475,8 @@ static int mos7840_write(struct tty_stru
+       data1 = urb->transfer_buffer;
+       dev_dbg(&port->dev, "bulkout endpoint is %d\n", port->bulk_out_endpointAddress);
+-      /* Turn on LED */
+-      if (mos7840_port->has_led && !mos7840_port->led_flag) {
+-              mos7840_port->led_flag = true;
+-              mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301);
+-              mod_timer(&mos7840_port->led_timer1,
+-                              jiffies + msecs_to_jiffies(LED_ON_MS));
+-      }
++      if (mos7840_port->has_led)
++              mos7840_led_activity(port);
+       /* send it down the pipe */
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+@@ -2429,6 +2432,14 @@ static int mos7840_port_probe(struct usb
+       if (device_type == MOSCHIP_DEVICE_ID_7810) {
+               mos7840_port->has_led = true;
++              mos7840_port->led_urb = usb_alloc_urb(0, GFP_KERNEL);
++              mos7840_port->led_dr = kmalloc(sizeof(*mos7840_port->led_dr),
++                                                              GFP_KERNEL);
++              if (!mos7840_port->led_urb || !mos7840_port->led_dr) {
++                      status = -ENOMEM;
++                      goto error;
++              }
++
+               init_timer(&mos7840_port->led_timer1);
+               mos7840_port->led_timer1.function = mos7840_led_off;
+               mos7840_port->led_timer1.expires =
+@@ -2441,8 +2452,6 @@ static int mos7840_port_probe(struct usb
+                       jiffies + msecs_to_jiffies(LED_OFF_MS);
+               mos7840_port->led_timer2.data = (unsigned long)mos7840_port;
+-              mos7840_port->led_flag = false;
+-
+               /* Turn off LED */
+               mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
+       }
+@@ -2464,6 +2473,8 @@ out:
+       }
+       return 0;
+ error:
++      kfree(mos7840_port->led_dr);
++      usb_free_urb(mos7840_port->led_urb);
+       kfree(mos7840_port->dr);
+       kfree(mos7840_port->ctrl_buf);
+       usb_free_urb(mos7840_port->control_urb);
+@@ -2484,6 +2495,10 @@ static int mos7840_port_remove(struct us
+               del_timer_sync(&mos7840_port->led_timer1);
+               del_timer_sync(&mos7840_port->led_timer2);
++
++              usb_kill_urb(mos7840_port->led_urb);
++              usb_free_urb(mos7840_port->led_urb);
++              kfree(mos7840_port->led_dr);
+       }
+       usb_kill_urb(mos7840_port->control_urb);
+       usb_free_urb(mos7840_port->control_urb);
diff --git a/queue-3.10/usb-mos7840-fix-race-in-register-handling.patch b/queue-3.10/usb-mos7840-fix-race-in-register-handling.patch
new file mode 100644 (file)
index 0000000..ed11b8e
--- /dev/null
@@ -0,0 +1,84 @@
+From d8a083cc746664916d9d36ed9e4d08a29525f245 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Fri, 26 Jul 2013 11:55:17 +0200
+Subject: USB: mos7840: fix race in register handling
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit d8a083cc746664916d9d36ed9e4d08a29525f245 upstream.
+
+Fix race in mos7840_get_reg which unconditionally manipulated the
+control urb (which may already be in use) by adding a control-urb busy
+flag.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |   18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -183,6 +183,10 @@
+ #define LED_ON_MS     500
+ #define LED_OFF_MS    500
++enum mos7840_flag {
++      MOS7840_FLAG_CTRL_BUSY,
++};
++
+ static int device_type;
+ static const struct usb_device_id id_table[] = {
+@@ -241,6 +245,8 @@ struct moschip_port {
+       bool led_flag;
+       struct timer_list led_timer1;   /* Timer for LED on */
+       struct timer_list led_timer2;   /* Timer for LED off */
++
++      unsigned long flags;
+ };
+ /*
+@@ -467,10 +473,10 @@ static void mos7840_control_callback(str
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status);
+-              return;
++              goto out;
+       default:
+               dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status);
+-              return;
++              goto out;
+       }
+       dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length);
+@@ -483,6 +489,8 @@ static void mos7840_control_callback(str
+               mos7840_handle_new_msr(mos7840_port, regval);
+       else if (mos7840_port->MsrLsr == 1)
+               mos7840_handle_new_lsr(mos7840_port, regval);
++out:
++      clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mos7840_port->flags);
+ }
+ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
+@@ -493,6 +501,9 @@ static int mos7840_get_reg(struct moschi
+       unsigned char *buffer = mcs->ctrl_buf;
+       int ret;
++      if (test_and_set_bit_lock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags))
++              return -EBUSY;
++
+       dr->bRequestType = MCS_RD_RTYPE;
+       dr->bRequest = MCS_RDREQ;
+       dr->wValue = cpu_to_le16(Wval); /* 0 */
+@@ -504,6 +515,9 @@ static int mos7840_get_reg(struct moschi
+                            mos7840_control_callback, mcs);
+       mcs->control_urb->transfer_buffer_length = 2;
+       ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
++      if (ret)
++              clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags);
++
+       return ret;
+ }