--- /dev/null
+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):
--- /dev/null
+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),
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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__ */
--- /dev/null
+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");
--- /dev/null
+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;
+ }
--- /dev/null
+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;
+ }
--- /dev/null
+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 */
--- /dev/null
+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,
--- /dev/null
+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;
+
--- /dev/null
+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;
+
--- /dev/null
+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;
--- /dev/null
+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))
--- /dev/null
+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;
+ }
+
--- /dev/null
+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
--- /dev/null
+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) {
--- /dev/null
+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);
--- /dev/null
+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)
--- /dev/null
+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");
--- /dev/null
+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;
+ }
+
--- /dev/null
+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);
+ }
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
--- /dev/null
+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,
--- /dev/null
+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;
--- /dev/null
+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);
--- /dev/null
+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;
+ }
+