]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Feb 2016 22:46:42 +0000 (14:46 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Feb 2016 22:46:42 +0000 (14:46 -0800)
added patches:
media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch
mtd-nand-assign-reasonable-default-name-for-nand-drivers.patch
parisc-fix-__arch_si_preamble_size.patch
parisc-protect-huge-page-pte-changes-with-spinlocks.patch
pci-fix-minimum-allocation-address-overwrite.patch
pci-host-mark-pcie-pci-msi-irq-cascade-handlers-as-irqf_no_thread.patch
printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch
tracing-fix-stacktrace-skip-depth-in-trace_buffer_unlock_commit_regs.patch
tracing-stacktrace-show-entire-trace-if-passed-in-function-not-found.patch
wlcore-wl12xx-spi-fix-null-pointer-dereference-oops.patch
wlcore-wl12xx-spi-fix-oops-on-firmware-load.patch

12 files changed:
queue-4.4/media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch [new file with mode: 0644]
queue-4.4/mtd-nand-assign-reasonable-default-name-for-nand-drivers.patch [new file with mode: 0644]
queue-4.4/parisc-fix-__arch_si_preamble_size.patch [new file with mode: 0644]
queue-4.4/parisc-protect-huge-page-pte-changes-with-spinlocks.patch [new file with mode: 0644]
queue-4.4/pci-fix-minimum-allocation-address-overwrite.patch [new file with mode: 0644]
queue-4.4/pci-host-mark-pcie-pci-msi-irq-cascade-handlers-as-irqf_no_thread.patch [new file with mode: 0644]
queue-4.4/printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/tracing-fix-stacktrace-skip-depth-in-trace_buffer_unlock_commit_regs.patch [new file with mode: 0644]
queue-4.4/tracing-stacktrace-show-entire-trace-if-passed-in-function-not-found.patch [new file with mode: 0644]
queue-4.4/wlcore-wl12xx-spi-fix-null-pointer-dereference-oops.patch [new file with mode: 0644]
queue-4.4/wlcore-wl12xx-spi-fix-oops-on-firmware-load.patch [new file with mode: 0644]

diff --git a/queue-4.4/media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch b/queue-4.4/media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch
new file mode 100644 (file)
index 0000000..9586912
--- /dev/null
@@ -0,0 +1,45 @@
+From 329d88da4df9a96da43018aceabd3a06e6a7e7ae Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javier@osg.samsung.com>
+Date: Wed, 27 Jan 2016 12:03:23 -0200
+Subject: [media] media: i2c: Don't export ir-kbd-i2c module alias
+
+From: Javier Martinez Canillas <javier@osg.samsung.com>
+
+commit 329d88da4df9a96da43018aceabd3a06e6a7e7ae upstream.
+
+This is a partial revert of commit ed8d1cf07cb16d ("[media] Export I2C
+module alias information in missing drivers") that exported the module
+aliases for the I2C drivers that were missing to make autoload to work.
+
+But there is a bug report [0] that auto load of the ir-kbd-i2c driver
+cause the Hauppauge HD-PVR driver to not behave correctly.
+
+This is a hdpvr latent bug that was just exposed by ir-kbd-i2c module
+autoloading working and will also happen if the I2C driver is built-in
+or a user calls modprobe to load the module and register the driver.
+
+But there is a regression experimented by users so until the real bug
+is fixed, let's not export the module alias for the ir-kbd-i2c driver
+even when this just masks the actual issue.
+
+[0]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=810726
+
+Fixes: ed8d1cf07cb1 ("[media] Export I2C module alias information in missing drivers")
+
+Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/i2c/ir-kbd-i2c.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/media/i2c/ir-kbd-i2c.c
++++ b/drivers/media/i2c/ir-kbd-i2c.c
+@@ -478,7 +478,6 @@ static const struct i2c_device_id ir_kbd
+       { "ir_rx_z8f0811_hdpvr", 0 },
+       { }
+ };
+-MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
+ static struct i2c_driver ir_kbd_driver = {
+       .driver = {
diff --git a/queue-4.4/mtd-nand-assign-reasonable-default-name-for-nand-drivers.patch b/queue-4.4/mtd-nand-assign-reasonable-default-name-for-nand-drivers.patch
new file mode 100644 (file)
index 0000000..4d4462e
--- /dev/null
@@ -0,0 +1,52 @@
+From f7a8e38f07a17be90758559fe66fe7337096053f Mon Sep 17 00:00:00 2001
+From: Brian Norris <computersforpeace@gmail.com>
+Date: Tue, 5 Jan 2016 10:39:45 -0800
+Subject: mtd: nand: assign reasonable default name for NAND drivers
+
+From: Brian Norris <computersforpeace@gmail.com>
+
+commit f7a8e38f07a17be90758559fe66fe7337096053f upstream.
+
+Commits such as commit 853f1c58c4b2 ("mtd: nand: omap2: show parent
+device structure in sysfs") attempt to rely on the core MTD code to set
+the MTD name based on the parent device. However, nand_base tries to set
+a different default name according to the flash name (e.g., extracted
+from the ONFI parameter page), which means NAND drivers will never make
+use of the MTD defaults. This is not the intention of commit
+853f1c58c4b2.
+
+This results in problems when trying to use the cmdline partition
+parser, since the MTD name is different than expected. Let's fix this by
+providing a default NAND name, where possible.
+
+Note that this is not really a great default name in the long run, since
+this means that if there are multiple MTDs attached to the same
+controller device, they will have the same name. But that is an existing
+issue and requires future work on a better controller vs. flash chip
+abstraction to fix properly.
+
+Fixes: 853f1c58c4b2 ("mtd: nand: omap2: show parent device structure in sysfs")
+Reported-by: Heiko Schocher <hs@denx.de>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Tested-by: Heiko Schocher <hs@denx.de>
+Cc: Heiko Schocher <hs@denx.de>
+Cc: Frans Klaver <fransklaver@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/nand_base.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -3995,6 +3995,9 @@ int nand_scan_ident(struct mtd_info *mtd
+                       return ret;
+       }
++      if (!mtd->name && mtd->dev.parent)
++              mtd->name = dev_name(mtd->dev.parent);
++
+       /* Set the default functions */
+       nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
diff --git a/queue-4.4/parisc-fix-__arch_si_preamble_size.patch b/queue-4.4/parisc-fix-__arch_si_preamble_size.patch
new file mode 100644 (file)
index 0000000..7b2b873
--- /dev/null
@@ -0,0 +1,38 @@
+From e60fc5aa608eb38b47ba4ee058f306f739eb70a0 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Sun, 10 Jan 2016 09:30:42 +0100
+Subject: parisc: Fix __ARCH_SI_PREAMBLE_SIZE
+
+From: Helge Deller <deller@gmx.de>
+
+commit e60fc5aa608eb38b47ba4ee058f306f739eb70a0 upstream.
+
+On a 64bit kernel build the compiler aligns the _sifields union in the
+struct siginfo_t on a 64bit address. The __ARCH_SI_PREAMBLE_SIZE define
+compensates for this alignment and thus fixes the wait testcase of the
+strace package.
+
+The symptoms of a wrong __ARCH_SI_PREAMBLE_SIZE value is that
+_sigchld.si_stime variable is missed to be copied and thus after a
+copy_siginfo() will have uninitialized values.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/include/uapi/asm/siginfo.h |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/parisc/include/uapi/asm/siginfo.h
++++ b/arch/parisc/include/uapi/asm/siginfo.h
+@@ -1,6 +1,10 @@
+ #ifndef _PARISC_SIGINFO_H
+ #define _PARISC_SIGINFO_H
++#if defined(__LP64__)
++#define __ARCH_SI_PREAMBLE_SIZE   (4 * sizeof(int))
++#endif
++
+ #include <asm-generic/siginfo.h>
+ #undef NSIGTRAP
diff --git a/queue-4.4/parisc-protect-huge-page-pte-changes-with-spinlocks.patch b/queue-4.4/parisc-protect-huge-page-pte-changes-with-spinlocks.patch
new file mode 100644 (file)
index 0000000..d5b1ea4
--- /dev/null
@@ -0,0 +1,155 @@
+From b0e551313ebde17764f3a5ed273df524d1e7e690 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Thu, 26 Nov 2015 21:14:02 +0100
+Subject: parisc: Protect huge page pte changes with spinlocks
+
+From: Helge Deller <deller@gmx.de>
+
+commit b0e551313ebde17764f3a5ed273df524d1e7e690 upstream.
+
+PA-RISC doesn't have atomic instructions to modify page table entries, so it
+takes spinlock in the TLB handler and modifies the page table entry
+non-atomically. If you modify the page table entry without the spinlock, you
+may race with TLB handler on another CPU and your modification may be lost.
+Protect against that with usage of purge_tlb_start() and purge_tlb_end() which
+handles the TLB spinlock.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/include/asm/hugetlb.h |   20 ++----------
+ arch/parisc/mm/hugetlbpage.c      |   60 ++++++++++++++++++++++++++++++--------
+ 2 files changed, 52 insertions(+), 28 deletions(-)
+
+--- a/arch/parisc/include/asm/hugetlb.h
++++ b/arch/parisc/include/asm/hugetlb.h
+@@ -54,24 +54,12 @@ static inline pte_t huge_pte_wrprotect(p
+       return pte_wrprotect(pte);
+ }
+-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+-                                         unsigned long addr, pte_t *ptep)
+-{
+-      pte_t old_pte = *ptep;
+-      set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+-}
++void huge_ptep_set_wrprotect(struct mm_struct *mm,
++                                         unsigned long addr, pte_t *ptep);
+-static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
++int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+                                            unsigned long addr, pte_t *ptep,
+-                                           pte_t pte, int dirty)
+-{
+-      int changed = !pte_same(*ptep, pte);
+-      if (changed) {
+-              set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+-              flush_tlb_page(vma, addr);
+-      }
+-      return changed;
+-}
++                                           pte_t pte, int dirty);
+ static inline pte_t huge_ptep_get(pte_t *ptep)
+ {
+--- a/arch/parisc/mm/hugetlbpage.c
++++ b/arch/parisc/mm/hugetlbpage.c
+@@ -105,15 +105,13 @@ static inline void purge_tlb_entries_hug
+       addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT;
+       for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) {
+-              mtsp(mm->context, 1);
+-              pdtlb(addr);
+-              if (unlikely(split_tlb))
+-                      pitlb(addr);
++              purge_tlb_entries(mm, addr);
+               addr += (1UL << REAL_HPAGE_SHIFT);
+       }
+ }
+-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
++/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */
++static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+                    pte_t *ptep, pte_t entry)
+ {
+       unsigned long addr_start;
+@@ -123,14 +121,9 @@ void set_huge_pte_at(struct mm_struct *m
+       addr_start = addr;
+       for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-              /* Directly write pte entry.  We could call set_pte_at(mm, addr, ptep, entry)
+-               * instead, but then we get double locking on pa_tlb_lock. */
+-              *ptep = entry;
++              set_pte(ptep, entry);
+               ptep++;
+-              /* Drop the PAGE_SIZE/non-huge tlb entry */
+-              purge_tlb_entries(mm, addr);
+-
+               addr += PAGE_SIZE;
+               pte_val(entry) += PAGE_SIZE;
+       }
+@@ -138,18 +131,61 @@ void set_huge_pte_at(struct mm_struct *m
+       purge_tlb_entries_huge(mm, addr_start);
+ }
++void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
++                   pte_t *ptep, pte_t entry)
++{
++      unsigned long flags;
++
++      purge_tlb_start(flags);
++      __set_huge_pte_at(mm, addr, ptep, entry);
++      purge_tlb_end(flags);
++}
++
+ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep)
+ {
++      unsigned long flags;
+       pte_t entry;
++      purge_tlb_start(flags);
+       entry = *ptep;
+-      set_huge_pte_at(mm, addr, ptep, __pte(0));
++      __set_huge_pte_at(mm, addr, ptep, __pte(0));
++      purge_tlb_end(flags);
+       return entry;
+ }
++
++void huge_ptep_set_wrprotect(struct mm_struct *mm,
++                              unsigned long addr, pte_t *ptep)
++{
++      unsigned long flags;
++      pte_t old_pte;
++
++      purge_tlb_start(flags);
++      old_pte = *ptep;
++      __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
++      purge_tlb_end(flags);
++}
++
++int huge_ptep_set_access_flags(struct vm_area_struct *vma,
++                              unsigned long addr, pte_t *ptep,
++                              pte_t pte, int dirty)
++{
++      unsigned long flags;
++      int changed;
++
++      purge_tlb_start(flags);
++      changed = !pte_same(*ptep, pte);
++      if (changed) {
++              __set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
++      }
++      purge_tlb_end(flags);
++      return changed;
++}
++
++
+ int pmd_huge(pmd_t pmd)
+ {
+       return 0;
diff --git a/queue-4.4/pci-fix-minimum-allocation-address-overwrite.patch b/queue-4.4/pci-fix-minimum-allocation-address-overwrite.patch
new file mode 100644 (file)
index 0000000..7bbd9d9
--- /dev/null
@@ -0,0 +1,52 @@
+From 3460baa620685c20f5ee19afb6d99d26150c382c Mon Sep 17 00:00:00 2001
+From: Christoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
+Date: Wed, 23 Dec 2015 16:51:57 +0100
+Subject: PCI: Fix minimum allocation address overwrite
+
+From: Christoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
+
+commit 3460baa620685c20f5ee19afb6d99d26150c382c upstream.
+
+Commit 36e097a8a297 ("PCI: Split out bridge window override of minimum
+allocation address") claimed to do no functional changes but unfortunately
+did: The "min" variable is altered.  At least the AVM A1 PCMCIA adapter was
+no longer detected, breaking ISDN operation.
+
+Use a local copy of "min" to restore the previous behaviour.
+
+[bhelgaas: avoid gcc "?:" extension for portability and readability]
+Fixes: 36e097a8a297 ("PCI: Split out bridge window override of minimum allocation address")
+Signed-off-by: Christoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/bus.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/bus.c
++++ b/drivers/pci/bus.c
+@@ -140,6 +140,8 @@ static int pci_bus_alloc_from_region(str
+       type_mask |= IORESOURCE_TYPE_BITS;
+       pci_bus_for_each_resource(bus, r, i) {
++              resource_size_t min_used = min;
++
+               if (!r)
+                       continue;
+@@ -163,12 +165,12 @@ static int pci_bus_alloc_from_region(str
+                * overrides "min".
+                */
+               if (avail.start)
+-                      min = avail.start;
++                      min_used = avail.start;
+               max = avail.end;
+               /* Ok, try it out.. */
+-              ret = allocate_resource(r, res, size, min, max,
++              ret = allocate_resource(r, res, size, min_used, max,
+                                       align, alignf, alignf_data);
+               if (ret == 0)
+                       return 0;
diff --git a/queue-4.4/pci-host-mark-pcie-pci-msi-irq-cascade-handlers-as-irqf_no_thread.patch b/queue-4.4/pci-host-mark-pcie-pci-msi-irq-cascade-handlers-as-irqf_no_thread.patch
new file mode 100644 (file)
index 0000000..be967ff
--- /dev/null
@@ -0,0 +1,160 @@
+From 8ff0ef996ca00028519c70e8d51d32bd37eb51dc Mon Sep 17 00:00:00 2001
+From: Grygorii Strashko <grygorii.strashko@ti.com>
+Date: Thu, 10 Dec 2015 21:18:20 +0200
+Subject: PCI: host: Mark PCIe/PCI (MSI) IRQ cascade handlers as IRQF_NO_THREAD
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Grygorii Strashko <grygorii.strashko@ti.com>
+
+commit 8ff0ef996ca00028519c70e8d51d32bd37eb51dc upstream.
+
+On -RT and if kernel is booting with "threadirqs" cmd line parameter,
+PCIe/PCI (MSI) IRQ cascade handlers (like dra7xx_pcie_msi_irq_handler())
+will be forced threaded and, as result, will generate warnings like this:
+
+  WARNING: CPU: 1 PID: 82 at kernel/irq/handle.c:150 handle_irq_event_percpu+0x14c/0x174()
+  irq 460 handler irq_default_primary_handler+0x0/0x14 enabled interrupts
+  Backtrace:
+   (warn_slowpath_common) from (warn_slowpath_fmt+0x38/0x40)
+   (warn_slowpath_fmt) from (handle_irq_event_percpu+0x14c/0x174)
+   (handle_irq_event_percpu) from (handle_irq_event+0x84/0xb8)
+   (handle_irq_event) from (handle_simple_irq+0x90/0x118)
+   (handle_simple_irq) from (generic_handle_irq+0x30/0x44)
+   (generic_handle_irq) from (dra7xx_pcie_msi_irq_handler+0x7c/0x8c)
+   (dra7xx_pcie_msi_irq_handler) from (irq_forced_thread_fn+0x28/0x5c)
+   (irq_forced_thread_fn) from (irq_thread+0x128/0x204)
+
+This happens because all of them invoke generic_handle_irq() from the
+requested handler.  generic_handle_irq() grabs raw_locks and thus needs to
+run in raw-IRQ context.
+
+This issue was originally reproduced on TI dra7-evem, but, as was
+identified during discussion [1], other hosts can also suffer from this
+issue.  Fix all them at once by marking PCIe/PCI (MSI) IRQ cascade handlers
+IRQF_NO_THREAD explicitly.
+
+[1] http://lkml.kernel.org/r/1448027966-21610-1-git-send-email-grygorii.strashko@ti.com
+
+[bhelgaas: add stable tag, fix typos]
+Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Lucas Stach <l.stach@pengutronix.de> (for imx6)
+CC: Kishon Vijay Abraham I <kishon@ti.com>
+CC: Jingoo Han <jingoohan1@gmail.com>
+CC: Kukjin Kim <kgene@kernel.org>
+CC: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+CC: Richard Zhu <Richard.Zhu@freescale.com>
+CC: Thierry Reding <thierry.reding@gmail.com>
+CC: Stephen Warren <swarren@wwwdotorg.org>
+CC: Alexandre Courbot <gnurou@gmail.com>
+CC: Simon Horman <horms@verge.net.au>
+CC: Pratyush Anand <pratyush.anand@gmail.com>
+CC: Michal Simek <michal.simek@xilinx.com>
+CC: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
+CC: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pci-dra7xx.c     |    3 ++-
+ drivers/pci/host/pci-exynos.c     |    3 ++-
+ drivers/pci/host/pci-imx6.c       |    3 ++-
+ drivers/pci/host/pci-tegra.c      |    2 +-
+ drivers/pci/host/pcie-rcar.c      |    6 ++++--
+ drivers/pci/host/pcie-spear13xx.c |    3 ++-
+ drivers/pci/host/pcie-xilinx.c    |    3 ++-
+ 7 files changed, 15 insertions(+), 8 deletions(-)
+
+--- a/drivers/pci/host/pci-dra7xx.c
++++ b/drivers/pci/host/pci-dra7xx.c
+@@ -302,7 +302,8 @@ static int __init dra7xx_add_pcie_port(s
+       }
+       ret = devm_request_irq(&pdev->dev, pp->irq,
+-                             dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
++                             dra7xx_pcie_msi_irq_handler,
++                             IRQF_SHARED | IRQF_NO_THREAD,
+                              "dra7-pcie-msi", pp);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request irq\n");
+--- a/drivers/pci/host/pci-exynos.c
++++ b/drivers/pci/host/pci-exynos.c
+@@ -522,7 +522,8 @@ static int __init exynos_add_pcie_port(s
+               ret = devm_request_irq(&pdev->dev, pp->msi_irq,
+                                       exynos_pcie_msi_irq_handler,
+-                                      IRQF_SHARED, "exynos-pcie", pp);
++                                      IRQF_SHARED | IRQF_NO_THREAD,
++                                      "exynos-pcie", pp);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request msi irq\n");
+                       return ret;
+--- a/drivers/pci/host/pci-imx6.c
++++ b/drivers/pci/host/pci-imx6.c
+@@ -537,7 +537,8 @@ static int __init imx6_add_pcie_port(str
+               ret = devm_request_irq(&pdev->dev, pp->msi_irq,
+                                      imx6_pcie_msi_handler,
+-                                     IRQF_SHARED, "mx6-pcie-msi", pp);
++                                     IRQF_SHARED | IRQF_NO_THREAD,
++                                     "mx6-pcie-msi", pp);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request MSI irq\n");
+                       return ret;
+--- a/drivers/pci/host/pci-tegra.c
++++ b/drivers/pci/host/pci-tegra.c
+@@ -1288,7 +1288,7 @@ static int tegra_pcie_enable_msi(struct
+       msi->irq = err;
+-      err = request_irq(msi->irq, tegra_pcie_msi_irq, 0,
++      err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
+                         tegra_msi_irq_chip.name, pcie);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -720,14 +720,16 @@ static int rcar_pcie_enable_msi(struct r
+       /* Two irqs are for MSI, but they are also used for non-MSI irqs */
+       err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
+-                             IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
++                             IRQF_SHARED | IRQF_NO_THREAD,
++                             rcar_msi_irq_chip.name, pcie);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
+               goto err;
+       }
+       err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
+-                             IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
++                             IRQF_SHARED | IRQF_NO_THREAD,
++                             rcar_msi_irq_chip.name, pcie);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
+               goto err;
+--- a/drivers/pci/host/pcie-spear13xx.c
++++ b/drivers/pci/host/pcie-spear13xx.c
+@@ -279,7 +279,8 @@ static int spear13xx_add_pcie_port(struc
+               return -ENODEV;
+       }
+       ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
+-                             IRQF_SHARED, "spear1340-pcie", pp);
++                             IRQF_SHARED | IRQF_NO_THREAD,
++                             "spear1340-pcie", pp);
+       if (ret) {
+               dev_err(dev, "failed to request irq %d\n", pp->irq);
+               return ret;
+--- a/drivers/pci/host/pcie-xilinx.c
++++ b/drivers/pci/host/pcie-xilinx.c
+@@ -781,7 +781,8 @@ static int xilinx_pcie_parse_dt(struct x
+       port->irq = irq_of_parse_and_map(node, 0);
+       err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler,
+-                             IRQF_SHARED, "xilinx-pcie", port);
++                             IRQF_SHARED | IRQF_NO_THREAD,
++                             "xilinx-pcie", port);
+       if (err) {
+               dev_err(dev, "unable to request irq %d\n", port->irq);
+               return err;
diff --git a/queue-4.4/printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch b/queue-4.4/printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch
new file mode 100644 (file)
index 0000000..be503d4
--- /dev/null
@@ -0,0 +1,133 @@
+From 8d91f8b15361dfb438ab6eb3b319e2ded43458ff Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Fri, 15 Jan 2016 16:58:24 -0800
+Subject: printk: do cond_resched() between lines while outputting to consoles
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 8d91f8b15361dfb438ab6eb3b319e2ded43458ff upstream.
+
+@console_may_schedule tracks whether console_sem was acquired through
+lock or trylock.  If the former, we're inside a sleepable context and
+console_conditional_schedule() performs cond_resched().  This allows
+console drivers which use console_lock for synchronization to yield
+while performing time-consuming operations such as scrolling.
+
+However, the actual console outputting is performed while holding
+irq-safe logbuf_lock, so console_unlock() clears @console_may_schedule
+before starting outputting lines.  Also, only a few drivers call
+console_conditional_schedule() to begin with.  This means that when a
+lot of lines need to be output by console_unlock(), for example on a
+console registration, the task doing console_unlock() may not yield for
+a long time on a non-preemptible kernel.
+
+If this happens with a slow console devices, for example a serial
+console, the outputting task may occupy the cpu for a very long time.
+Long enough to trigger softlockup and/or RCU stall warnings, which in
+turn pile more messages, sometimes enough to trigger the next cycle of
+warnings incapacitating the system.
+
+Fix it by making console_unlock() insert cond_resched() between lines if
+@console_may_schedule.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Calvin Owens <calvinowens@fb.com>
+Acked-by: Jan Kara <jack@suse.com>
+Cc: Dave Jones <davej@codemonkey.org.uk>
+Cc: Kyle McMartin <kyle@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/console.h |    1 +
+ kernel/panic.c          |    3 +--
+ kernel/printk/printk.c  |   35 ++++++++++++++++++++++++++++++++++-
+ 3 files changed, 36 insertions(+), 3 deletions(-)
+
+--- a/include/linux/console.h
++++ b/include/linux/console.h
+@@ -150,6 +150,7 @@ extern int console_trylock(void);
+ extern void console_unlock(void);
+ extern void console_conditional_schedule(void);
+ extern void console_unblank(void);
++extern void console_flush_on_panic(void);
+ extern struct tty_driver *console_device(int *);
+ extern void console_stop(struct console *);
+ extern void console_start(struct console *);
+--- a/kernel/panic.c
++++ b/kernel/panic.c
+@@ -157,8 +157,7 @@ void panic(const char *fmt, ...)
+        * panic() is not being callled from OOPS.
+        */
+       debug_locks_off();
+-      console_trylock();
+-      console_unlock();
++      console_flush_on_panic();
+       if (!panic_blink)
+               panic_blink = no_blink;
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -2233,13 +2233,24 @@ void console_unlock(void)
+       static u64 seen_seq;
+       unsigned long flags;
+       bool wake_klogd = false;
+-      bool retry;
++      bool do_cond_resched, retry;
+       if (console_suspended) {
+               up_console_sem();
+               return;
+       }
++      /*
++       * Console drivers are called under logbuf_lock, so
++       * @console_may_schedule should be cleared before; however, we may
++       * end up dumping a lot of lines, for example, if called from
++       * console registration path, and should invoke cond_resched()
++       * between lines if allowable.  Not doing so can cause a very long
++       * scheduling stall on a slow console leading to RCU stall and
++       * softlockup warnings which exacerbate the issue with more
++       * messages practically incapacitating the system.
++       */
++      do_cond_resched = console_may_schedule;
+       console_may_schedule = 0;
+       /* flush buffered message fragment immediately to console */
+@@ -2311,6 +2322,9 @@ skip:
+               call_console_drivers(level, ext_text, ext_len, text, len);
+               start_critical_timings();
+               local_irq_restore(flags);
++
++              if (do_cond_resched)
++                      cond_resched();
+       }
+       console_locked = 0;
+@@ -2378,6 +2392,25 @@ void console_unblank(void)
+       console_unlock();
+ }
++/**
++ * console_flush_on_panic - flush console content on panic
++ *
++ * Immediately output all pending messages no matter what.
++ */
++void console_flush_on_panic(void)
++{
++      /*
++       * If someone else is holding the console lock, trylock will fail
++       * and may_schedule may be set.  Ignore and proceed to unlock so
++       * that messages are flushed out.  As this can be called from any
++       * context and we don't want to get preempted while flushing,
++       * ensure may_schedule is cleared.
++       */
++      console_trylock();
++      console_may_schedule = 0;
++      console_unlock();
++}
++
+ /*
+  * Return the console tty driver structure and its associated index
+  */
index 9748f6455515b3ce742f9cc0f6e46036676f4e64..e5fed62a338e542f3053cff61aead9c27724f656 100644 (file)
@@ -8,3 +8,14 @@ block-fix-bio-splitting-on-max-sectors.patch
 alsa-hda-implement-loopback-control-switch-for-realtek-and-other-codecs.patch
 ocfs2-dlm-ignore-cleaning-the-migration-mle-that-is-inuse.patch
 ocfs2-dlm-clear-refmap-bit-of-recovery-lock-while-doing-local-recovery-cleanup.patch
+wlcore-wl12xx-spi-fix-oops-on-firmware-load.patch
+wlcore-wl12xx-spi-fix-null-pointer-dereference-oops.patch
+mtd-nand-assign-reasonable-default-name-for-nand-drivers.patch
+pci-host-mark-pcie-pci-msi-irq-cascade-handlers-as-irqf_no_thread.patch
+pci-fix-minimum-allocation-address-overwrite.patch
+tracing-fix-stacktrace-skip-depth-in-trace_buffer_unlock_commit_regs.patch
+tracing-stacktrace-show-entire-trace-if-passed-in-function-not-found.patch
+printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch
+parisc-protect-huge-page-pte-changes-with-spinlocks.patch
+parisc-fix-__arch_si_preamble_size.patch
+media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch
diff --git a/queue-4.4/tracing-fix-stacktrace-skip-depth-in-trace_buffer_unlock_commit_regs.patch b/queue-4.4/tracing-fix-stacktrace-skip-depth-in-trace_buffer_unlock_commit_regs.patch
new file mode 100644 (file)
index 0000000..01b8df8
--- /dev/null
@@ -0,0 +1,63 @@
+From 7717c6be699975f6733d278b13b7c4295d73caf6 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
+Date: Wed, 13 Jan 2016 15:48:54 -0500
+Subject: tracing: Fix stacktrace skip depth in trace_buffer_unlock_commit_regs()
+
+From: Steven Rostedt (Red Hat) <rostedt@goodmis.org>
+
+commit 7717c6be699975f6733d278b13b7c4295d73caf6 upstream.
+
+While cleaning the stacktrace code I unintentially changed the skip depth of
+trace_buffer_unlock_commit_regs() from 0 to 6. kprobes uses this function,
+and with skipping 6 call backs, it can easily produce no stack.
+
+Here's how I tested it:
+
+ # echo 'p:ext4_sync_fs ext4_sync_fs ' > /sys/kernel/debug/tracing/kprobe_events
+ # echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable
+ # cat /sys/kernel/debug/trace
+            sync-2394  [005]   502.457060: ext4_sync_fs: (ffffffff81317650)
+            sync-2394  [005]   502.457063: kernel_stack:         <stack trace>
+            sync-2394  [005]   502.457086: ext4_sync_fs: (ffffffff81317650)
+            sync-2394  [005]   502.457087: kernel_stack:         <stack trace>
+            sync-2394  [005]   502.457091: ext4_sync_fs: (ffffffff81317650)
+
+After putting back the skip stack to zero, we have:
+
+            sync-2270  [000]   748.052693: ext4_sync_fs: (ffffffff81317650)
+            sync-2270  [000]   748.052695: kernel_stack:         <stack trace>
+ => iterate_supers (ffffffff8126412e)
+ => sys_sync (ffffffff8129c4b6)
+ => entry_SYSCALL_64_fastpath (ffffffff8181f0b2)
+            sync-2270  [000]   748.053017: ext4_sync_fs: (ffffffff81317650)
+            sync-2270  [000]   748.053019: kernel_stack:         <stack trace>
+ => iterate_supers (ffffffff8126412e)
+ => sys_sync (ffffffff8129c4b6)
+ => entry_SYSCALL_64_fastpath (ffffffff8181f0b2)
+            sync-2270  [000]   748.053381: ext4_sync_fs: (ffffffff81317650)
+            sync-2270  [000]   748.053383: kernel_stack:         <stack trace>
+ => iterate_supers (ffffffff8126412e)
+ => sys_sync (ffffffff8129c4b6)
+ => entry_SYSCALL_64_fastpath (ffffffff8181f0b2)
+
+Fixes: 73dddbb57bb0 "tracing: Only create stacktrace option when STACKTRACE is configured"
+Reported-by: Brendan Gregg <brendan.d.gregg@gmail.com>
+Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1751,7 +1751,7 @@ void trace_buffer_unlock_commit_regs(str
+ {
+       __buffer_unlock_commit(buffer, event);
+-      ftrace_trace_stack(tr, buffer, flags, 6, pc, regs);
++      ftrace_trace_stack(tr, buffer, flags, 0, pc, regs);
+       ftrace_trace_userstack(buffer, flags, pc);
+ }
+ EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs);
diff --git a/queue-4.4/tracing-stacktrace-show-entire-trace-if-passed-in-function-not-found.patch b/queue-4.4/tracing-stacktrace-show-entire-trace-if-passed-in-function-not-found.patch
new file mode 100644 (file)
index 0000000..4b8fc46
--- /dev/null
@@ -0,0 +1,46 @@
+From 6ccd83714a009ee301b50c15f6c3a5dc1f30164c Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Fri, 29 Jan 2016 10:22:41 -0500
+Subject: tracing/stacktrace: Show entire trace if passed in function not found
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit 6ccd83714a009ee301b50c15f6c3a5dc1f30164c upstream.
+
+When a max stack trace is discovered, the stack dump is saved. In order to
+not record the overhead of the stack tracer, the ip of the traced function
+is looked for within the dump. The trace is started from the location of
+that function. But if for some reason the ip is not found, the entire stack
+trace is then truncated. That's not very useful. Instead, print everything
+if the ip of the traced function is not found within the trace.
+
+This issue showed up on s390.
+
+Link: http://lkml.kernel.org/r/20160129102241.1b3c9c04@gandalf.local.home
+
+Fixes: 72ac426a5bb0 ("tracing: Clean up stack tracing and fix fentry updates")
+Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Tested-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace_stack.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/kernel/trace/trace_stack.c
++++ b/kernel/trace/trace_stack.c
+@@ -126,6 +126,13 @@ check_stack(unsigned long ip, unsigned l
+       }
+       /*
++       * Some archs may not have the passed in ip in the dump.
++       * If that happens, we need to show everything.
++       */
++      if (i == stack_trace_max.nr_entries)
++              i = 0;
++
++      /*
+        * Now find where in the stack these are.
+        */
+       x = 0;
diff --git a/queue-4.4/wlcore-wl12xx-spi-fix-null-pointer-dereference-oops.patch b/queue-4.4/wlcore-wl12xx-spi-fix-null-pointer-dereference-oops.patch
new file mode 100644 (file)
index 0000000..aca6a7f
--- /dev/null
@@ -0,0 +1,101 @@
+From e47301b06d5a65678690f04c2248fd181db1e59a Mon Sep 17 00:00:00 2001
+From: Uri Mashiach <uri.mashiach@compulab.co.il>
+Date: Thu, 24 Dec 2015 16:05:00 +0200
+Subject: wlcore/wl12xx: spi: fix NULL pointer dereference (Oops)
+
+From: Uri Mashiach <uri.mashiach@compulab.co.il>
+
+commit e47301b06d5a65678690f04c2248fd181db1e59a upstream.
+
+Fix the below Oops when trying to modprobe wlcore_spi.
+The oops occurs because the wl1271_power_{off,on}()
+function doesn't check the power() function pointer.
+
+[   23.401447] Unable to handle kernel NULL pointer dereference at
+virtual address 00000000
+[   23.409954] pgd = c0004000
+[   23.412922] [00000000] *pgd=00000000
+[   23.416693] Internal error: Oops: 80000007 [#1] SMP ARM
+[   23.422168] Modules linked in: wl12xx wlcore mac80211 cfg80211
+musb_dsps musb_hdrc usbcore usb_common snd_soc_simple_card evdev joydev
+omap_rng wlcore_spi snd_soc_tlv320aic23_i2c rng_core snd_soc_tlv320aic23
+c_can_platform c_can can_dev snd_soc_davinci_mcasp snd_soc_edma
+snd_soc_omap omap_wdt musb_am335x cpufreq_dt thermal_sys hwmon
+[   23.453253] CPU: 0 PID: 36 Comm: kworker/0:2 Not tainted
+4.2.0-00002-g951efee-dirty #233
+[   23.461720] Hardware name: Generic AM33XX (Flattened Device Tree)
+[   23.468123] Workqueue: events request_firmware_work_func
+[   23.473690] task: de32efc0 ti: de4ee000 task.ti: de4ee000
+[   23.479341] PC is at 0x0
+[   23.482112] LR is at wl12xx_set_power_on+0x28/0x124 [wlcore]
+[   23.488074] pc : [<00000000>]    lr : [<bf2581f0>]    psr: 60000013
+[   23.488074] sp : de4efe50  ip : 00000002  fp : 00000000
+[   23.500162] r10: de7cdd00  r9 : dc848800  r8 : bf27af00
+[   23.505663] r7 : bf27a1a8  r6 : dcbd8a80  r5 : dce0e2e0  r4 :
+dce0d2e0
+[   23.512536] r3 : 00000000  r2 : 00000000  r1 : 00000001  r0 :
+dc848810
+[   23.519412] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
+Segment kernel
+[   23.527109] Control: 10c5387d  Table: 9cb78019  DAC: 00000015
+[   23.533160] Process kworker/0:2 (pid: 36, stack limit = 0xde4ee218)
+[   23.539760] Stack: (0xde4efe50 to 0xde4f0000)
+
+[...]
+
+[   23.665030] [<bf2581f0>] (wl12xx_set_power_on [wlcore]) from
+[<bf25f7ac>] (wlcore_nvs_cb+0x118/0xa4c [wlcore])
+[   23.675604] [<bf25f7ac>] (wlcore_nvs_cb [wlcore]) from [<c04387ec>]
+(request_firmware_work_func+0x30/0x58)
+[   23.685784] [<c04387ec>] (request_firmware_work_func) from
+[<c0058e2c>] (process_one_work+0x1b4/0x4b4)
+[   23.695591] [<c0058e2c>] (process_one_work) from [<c0059168>]
+(worker_thread+0x3c/0x4a4)
+[   23.704124] [<c0059168>] (worker_thread) from [<c005ee68>]
+(kthread+0xd4/0xf0)
+[   23.711747] [<c005ee68>] (kthread) from [<c000f598>]
+(ret_from_fork+0x14/0x3c)
+[   23.719357] Code: bad PC value
+[   23.722760] ---[ end trace 981be8510db9b3a9 ]---
+
+Prevent oops by validationg power() pointer value before
+calling the function.
+
+Signed-off-by: Uri Mashiach <uri.mashiach@compulab.co.il>
+Acked-by: Igor Grinberg <grinberg@compulab.co.il>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ti/wlcore/io.h |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ti/wlcore/io.h
++++ b/drivers/net/wireless/ti/wlcore/io.h
+@@ -207,19 +207,23 @@ static inline int __must_check wlcore_wr
+ static inline void wl1271_power_off(struct wl1271 *wl)
+ {
+-      int ret;
++      int ret = 0;
+       if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags))
+               return;
+-      ret = wl->if_ops->power(wl->dev, false);
++      if (wl->if_ops->power)
++              ret = wl->if_ops->power(wl->dev, false);
+       if (!ret)
+               clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+ }
+ static inline int wl1271_power_on(struct wl1271 *wl)
+ {
+-      int ret = wl->if_ops->power(wl->dev, true);
++      int ret = 0;
++
++      if (wl->if_ops->power)
++              ret = wl->if_ops->power(wl->dev, true);
+       if (ret == 0)
+               set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
diff --git a/queue-4.4/wlcore-wl12xx-spi-fix-oops-on-firmware-load.patch b/queue-4.4/wlcore-wl12xx-spi-fix-oops-on-firmware-load.patch
new file mode 100644 (file)
index 0000000..2e0ab77
--- /dev/null
@@ -0,0 +1,117 @@
+From 9b2761cb72dc41e1948c8a5512b4efd384eda130 Mon Sep 17 00:00:00 2001
+From: Uri Mashiach <uri.mashiach@compulab.co.il>
+Date: Thu, 10 Dec 2015 15:12:56 +0200
+Subject: wlcore/wl12xx: spi: fix oops on firmware load
+
+From: Uri Mashiach <uri.mashiach@compulab.co.il>
+
+commit 9b2761cb72dc41e1948c8a5512b4efd384eda130 upstream.
+
+The maximum chunks used by the function is
+(SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE + 1).
+The original commands array had space for
+(SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) commands.
+When the last chunk is used (len > 4 * WSPI_MAX_CHUNK_SIZE), the last
+command is stored outside the bounds of the commands array.
+
+Oops 5 (page fault) is generated during current wl1271 firmware load
+attempt:
+
+root@debian-armhf:~# ifconfig wlan0 up
+[  294.312399] Unable to handle kernel paging request at virtual address
+00203fc4
+[  294.320173] pgd = de528000
+[  294.323028] [00203fc4] *pgd=00000000
+[  294.326916] Internal error: Oops: 5 [#1] SMP ARM
+[  294.331789] Modules linked in: bnep rfcomm bluetooth ipv6 arc4 wl12xx
+wlcore mac80211 musb_dsps cfg80211 musb_hdrc usbcore usb_common
+wlcore_spi omap_rng rng_core musb_am335x omap_wdt cpufreq_dt thermal_sys
+hwmon
+[  294.351838] CPU: 0 PID: 1827 Comm: ifconfig Not tainted
+4.2.0-00002-g3e9ad27-dirty #78
+[  294.360154] Hardware name: Generic AM33XX (Flattened Device Tree)
+[  294.366557] task: dc9d6d40 ti: de550000 task.ti: de550000
+[  294.372236] PC is at __spi_validate+0xa8/0x2ac
+[  294.376902] LR is at __spi_sync+0x78/0x210
+[  294.381200] pc : [<c049c760>]    lr : [<c049ebe0>]    psr: 60000013
+[  294.381200] sp : de551998  ip : de5519d8  fp : 00200000
+[  294.393242] r10: de551c8c  r9 : de5519d8  r8 : de3a9000
+[  294.398730] r7 : de3a9258  r6 : de3a9400  r5 : de551a48  r4 :
+00203fbc
+[  294.405577] r3 : 00000000  r2 : 00000000  r1 : 00000000  r0 :
+de3a9000
+[  294.412420] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
+Segment user
+[  294.419918] Control: 10c5387d  Table: 9e528019  DAC: 00000015
+[  294.425954] Process ifconfig (pid: 1827, stack limit = 0xde550218)
+[  294.432437] Stack: (0xde551998 to 0xde552000)
+
+...
+
+[  294.883613] [<c049c760>] (__spi_validate) from [<c049ebe0>]
+(__spi_sync+0x78/0x210)
+[  294.891670] [<c049ebe0>] (__spi_sync) from [<bf036598>]
+(wl12xx_spi_raw_write+0xfc/0x148 [wlcore_spi])
+[  294.901661] [<bf036598>] (wl12xx_spi_raw_write [wlcore_spi]) from
+[<bf21c694>] (wlcore_boot_upload_firmware+0x1ec/0x458 [wlcore])
+[  294.914038] [<bf21c694>] (wlcore_boot_upload_firmware [wlcore]) from
+[<bf24532c>] (wl12xx_boot+0xc10/0xfac [wl12xx])
+[  294.925161] [<bf24532c>] (wl12xx_boot [wl12xx]) from [<bf20d5cc>]
+(wl1271_op_add_interface+0x5b0/0x910 [wlcore])
+[  294.936364] [<bf20d5cc>] (wl1271_op_add_interface [wlcore]) from
+[<bf15c4ac>] (ieee80211_do_open+0x44c/0xf7c [mac80211])
+[  294.947963] [<bf15c4ac>] (ieee80211_do_open [mac80211]) from
+[<c0537978>] (__dev_open+0xa8/0x110)
+[  294.957307] [<c0537978>] (__dev_open) from [<c0537bf8>]
+(__dev_change_flags+0x88/0x148)
+[  294.965713] [<c0537bf8>] (__dev_change_flags) from [<c0537cd0>]
+(dev_change_flags+0x18/0x48)
+[  294.974576] [<c0537cd0>] (dev_change_flags) from [<c05a55a0>]
+(devinet_ioctl+0x6b4/0x7d0)
+[  294.983191] [<c05a55a0>] (devinet_ioctl) from [<c0517040>]
+(sock_ioctl+0x1e4/0x2bc)
+[  294.991244] [<c0517040>] (sock_ioctl) from [<c017d378>]
+(do_vfs_ioctl+0x420/0x6b0)
+[  294.999208] [<c017d378>] (do_vfs_ioctl) from [<c017d674>]
+(SyS_ioctl+0x6c/0x7c)
+[  295.006880] [<c017d674>] (SyS_ioctl) from [<c000f4c0>]
+(ret_fast_syscall+0x0/0x54)
+[  295.014835] Code: e1550004 e2444034 0a00007d e5953018 (e5942008)
+[  295.021544] ---[ end trace 66ed188198f4e24e ]---
+
+Signed-off-by: Uri Mashiach <uri.mashiach@compulab.co.il>
+Acked-by: Igor Grinberg <grinberg@compulab.co.il>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ti/wlcore/spi.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ti/wlcore/spi.c
++++ b/drivers/net/wireless/ti/wlcore/spi.c
+@@ -73,7 +73,10 @@
+  */
+ #define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
+-#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
++/* Maximum number of SPI write chunks */
++#define WSPI_MAX_NUM_OF_CHUNKS \
++      ((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
++
+ struct wl12xx_spi_glue {
+       struct device *dev;
+@@ -268,9 +271,10 @@ static int __must_check wl12xx_spi_raw_w
+                                            void *buf, size_t len, bool fixed)
+ {
+       struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+-      struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
++      /* SPI write buffers - 2 for each chunk */
++      struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
+       struct spi_message m;
+-      u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
++      u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
+       u32 *cmd;
+       u32 chunk_len;
+       int i;