]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Aug 2015 21:35:12 +0000 (14:35 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Aug 2015 21:35:12 +0000 (14:35 -0700)
added patches:
bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch
dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch
dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch
drivers-usb-delete-xhci-command-timer-if-necessary.patch
drm-dp-mst-remove-debug-warn_on.patch
drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch
drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch
drm-radeon-combios-add-some-validation-of-lvds-values.patch
drm-radeon-rework-audio-detect-v4.patch
fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch
ipr-fix-incorrect-trace-indexing.patch
ipr-fix-invalid-array-indexing-for-hrrq.patch
ipr-fix-locking-for-unit-attention-handling.patch
mips-do_mcheck-fix-kernel-code-dump-with-eva.patch
mips-export-get_c0_perfcount_int.patch
mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch
mips-flush-rps-on-kernel-entry-with-eva.patch
mips-make-set_pte-smp-safe.patch
mips-malta-don-t-reinitialise-rtc.patch
mips-show_stack-fix-stack-trace-with-eva.patch
phy-twl4030-usb-make-runtime-pm-more-reliable.patch
revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch
usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch
usb-sierra-add-1199-68ab-device-id.patch
usb-udc-core-add-device_del-call-to-error-pathway.patch
xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch

27 files changed:
queue-4.1/bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch [new file with mode: 0644]
queue-4.1/dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch [new file with mode: 0644]
queue-4.1/dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch [new file with mode: 0644]
queue-4.1/drivers-usb-delete-xhci-command-timer-if-necessary.patch [new file with mode: 0644]
queue-4.1/drm-dp-mst-remove-debug-warn_on.patch [new file with mode: 0644]
queue-4.1/drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch [new file with mode: 0644]
queue-4.1/drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch [new file with mode: 0644]
queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch [new file with mode: 0644]
queue-4.1/drm-radeon-rework-audio-detect-v4.patch [new file with mode: 0644]
queue-4.1/fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch [new file with mode: 0644]
queue-4.1/ipr-fix-incorrect-trace-indexing.patch [new file with mode: 0644]
queue-4.1/ipr-fix-invalid-array-indexing-for-hrrq.patch [new file with mode: 0644]
queue-4.1/ipr-fix-locking-for-unit-attention-handling.patch [new file with mode: 0644]
queue-4.1/mips-do_mcheck-fix-kernel-code-dump-with-eva.patch [new file with mode: 0644]
queue-4.1/mips-export-get_c0_perfcount_int.patch [new file with mode: 0644]
queue-4.1/mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch [new file with mode: 0644]
queue-4.1/mips-flush-rps-on-kernel-entry-with-eva.patch [new file with mode: 0644]
queue-4.1/mips-make-set_pte-smp-safe.patch [new file with mode: 0644]
queue-4.1/mips-malta-don-t-reinitialise-rtc.patch [new file with mode: 0644]
queue-4.1/mips-show_stack-fix-stack-trace-with-eva.patch [new file with mode: 0644]
queue-4.1/phy-twl4030-usb-make-runtime-pm-more-reliable.patch [new file with mode: 0644]
queue-4.1/revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch [new file with mode: 0644]
queue-4.1/series
queue-4.1/usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch [new file with mode: 0644]
queue-4.1/usb-sierra-add-1199-68ab-device-id.patch [new file with mode: 0644]
queue-4.1/usb-udc-core-add-device_del-call-to-error-pathway.patch [new file with mode: 0644]
queue-4.1/xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch [new file with mode: 0644]

diff --git a/queue-4.1/bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch b/queue-4.1/bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch
new file mode 100644 (file)
index 0000000..bd4f7f2
--- /dev/null
@@ -0,0 +1,36 @@
+From 25ba265390c09b0a2b2f3fd9ba82e37248b7a371 Mon Sep 17 00:00:00 2001
+From: Johan Hedberg <johan.hedberg@intel.com>
+Date: Mon, 20 Jul 2015 20:31:25 +0300
+Subject: Bluetooth: Fix NULL pointer dereference in smp_conn_security
+
+From: Johan Hedberg <johan.hedberg@intel.com>
+
+commit 25ba265390c09b0a2b2f3fd9ba82e37248b7a371 upstream.
+
+The l2cap_conn->smp pointer may be NULL for various valid reasons where SMP has
+failed to initialize properly. One such scenario is when crypto support is
+missing, another when the adapter has been powered on through a legacy method.
+The smp_conn_security() function should have the appropriate check for this
+situation to avoid NULL pointer dereferences.
+
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bluetooth/smp.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2295,6 +2295,10 @@ int smp_conn_security(struct hci_conn *h
+               return 1;
+       chan = conn->smp;
++      if (!chan) {
++              BT_ERR("SMP security requested but not available");
++              return 1;
++      }
+       if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
+               return 1;
diff --git a/queue-4.1/dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch b/queue-4.1/dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch
new file mode 100644 (file)
index 0000000..ee521cb
--- /dev/null
@@ -0,0 +1,36 @@
+From ae128293d97404f491dc76f1843c7adacfec3441 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Date: Mon, 15 Jun 2015 17:25:16 +0900
+Subject: dmaengine: pl330: Fix overflow when reporting residue in memcpy
+
+From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+
+commit ae128293d97404f491dc76f1843c7adacfec3441 upstream.
+
+During memcpy operations the residue was always set to an u32 overflowed
+value.
+
+In pl330_tx_status() function number of currently transferred bytes was
+subtracted from internal "bytes_requested" field. However this
+"bytes_requested" was not initialized at start to length of memcpy
+buffer so transferred bytes were subtracted from 0 causing overflow.
+
+Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Fixes: aee4d1fac887 ("dmaengine: pl330: improve pl330_tx_status() function")
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/pl330.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2621,6 +2621,7 @@ pl330_prep_dma_memcpy(struct dma_chan *c
+               desc->rqcfg.brst_len = 1;
+       desc->rqcfg.brst_len = get_burst_len(desc, len);
++      desc->bytes_requested = len;
+       desc->txd.flags = flags;
diff --git a/queue-4.1/dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch b/queue-4.1/dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch
new file mode 100644 (file)
index 0000000..6cd98b3
--- /dev/null
@@ -0,0 +1,52 @@
+From 5dd90e5b91e0f5c925b12b132c7cd27538870256 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <k.kozlowski.k@gmail.com>
+Date: Mon, 15 Jun 2015 23:00:09 +0900
+Subject: dmaengine: pl330: Really fix choppy sound because of wrong residue calculation
+
+From: Krzysztof Kozlowski <k.kozlowski.k@gmail.com>
+
+commit 5dd90e5b91e0f5c925b12b132c7cd27538870256 upstream.
+
+When pl330 driver was used during sound playback, after some time or
+after a number of plays the sound became choppy or totally noisy. For
+example on Odroid XU3 board the first four executions of aplay with
+small WAVE worked fine, but fifth was unrecognizable with errors:
+       $ aplay /usr/share/sounds/alsa/Front_Right.wava
+       underrun!!! (at least 0.095 ms long)
+
+Issue was caused by wrong residue reported by pl330 driver to
+pcm_dmaengine for its cyclic dma transfers.
+
+The pl330_tx_status(), residue reporting function, used a "last" flag in
+a descriptor to indicate that there is no more data to send.
+
+The pl330_tx_submit() iterated over descriptors trying to remove this
+flag from them and then mark last descriptor as "last".  However when
+iterating it actually removed the flag not from descriptors but always
+from last of it (and then reset it). Thus effectively once some
+descriptor was marked as last, then it stayed like this forever causing
+residue to be reported too low.
+
+Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k@gmail.com>
+Fixes: aee4d1fac887 ("dmaengine: pl330: improve pl330_tx_status() function")
+Reported-by: gabriel@unseen.is
+Suggested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-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 |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2328,7 +2328,7 @@ static dma_cookie_t pl330_tx_submit(stru
+                       desc->txd.callback = last->txd.callback;
+                       desc->txd.callback_param = last->txd.callback_param;
+               }
+-              last->last = false;
++              desc->last = false;
+               dma_cookie_assign(&desc->txd);
diff --git a/queue-4.1/drivers-usb-delete-xhci-command-timer-if-necessary.patch b/queue-4.1/drivers-usb-delete-xhci-command-timer-if-necessary.patch
new file mode 100644 (file)
index 0000000..893b451
--- /dev/null
@@ -0,0 +1,60 @@
+From ffe5adcb7661d94e952d6b5ed7f493cb4ef0c7bc Mon Sep 17 00:00:00 2001
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Date: Mon, 3 Aug 2015 16:07:49 +0300
+Subject: drivers/usb: Delete XHCI command timer if necessary
+
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+
+commit ffe5adcb7661d94e952d6b5ed7f493cb4ef0c7bc upstream.
+
+When xhci_mem_cleanup() is called, it's possible that the command
+timer isn't initialized and scheduled. For those cases, to delete
+the command timer causes soft-lockup as below stack dump shows.
+
+The patch avoids deleting the command timer if it's not scheduled
+with the help of timer_pending().
+
+NMI watchdog: BUG: soft lockup - CPU#40 stuck for 23s! [kworker/40:1:8140]
+      :
+NIP [c000000000150b30] lock_timer_base.isra.34+0x90/0xa0
+LR [c000000000150c24] try_to_del_timer_sync+0x34/0xa0
+Call Trace:
+[c000000f67c975e0] [c0000000015b84f8] mon_ops+0x0/0x8 (unreliable)
+[c000000f67c97620] [c000000000150c24] try_to_del_timer_sync+0x34/0xa0
+[c000000f67c97660] [c000000000150cf0] del_timer_sync+0x60/0x80
+[c000000f67c97690] [c00000000070ac0c] xhci_mem_cleanup+0x5c/0x5e0
+[c000000f67c97740] [c00000000070c2e8] xhci_mem_init+0x1158/0x13b0
+[c000000f67c97860] [c000000000700978] xhci_init+0x88/0x110
+[c000000f67c978e0] [c000000000701644] xhci_gen_setup+0x2b4/0x590
+[c000000f67c97970] [c0000000006d4410] xhci_pci_setup+0x40/0x190
+[c000000f67c979f0] [c0000000006b1af8] usb_add_hcd+0x418/0xba0
+[c000000f67c97ab0] [c0000000006cb15c] usb_hcd_pci_probe+0x1dc/0x5c0
+[c000000f67c97b50] [c0000000006d3ba4] xhci_pci_probe+0x64/0x1f0
+[c000000f67c97ba0] [c0000000004fe9ac] local_pci_probe+0x6c/0x130
+[c000000f67c97c30] [c0000000000e5ce8] work_for_cpu_fn+0x38/0x60
+[c000000f67c97c60] [c0000000000eacb8] process_one_work+0x198/0x470
+[c000000f67c97cf0] [c0000000000eb6ac] worker_thread+0x37c/0x5a0
+[c000000f67c97d80] [c0000000000f2730] kthread+0x110/0x130
+[c000000f67c97e30] [c000000000009660] ret_from_kernel_thread+0x5c/0x7c
+
+Reported-by: Priya M. A <priyama2@in.ibm.com>
+Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1792,7 +1792,8 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+       int size;
+       int i, j, num_ports;
+-      del_timer_sync(&xhci->cmd_timer);
++      if (timer_pending(&xhci->cmd_timer))
++              del_timer_sync(&xhci->cmd_timer);
+       /* Free the Event Ring Segment Table and the actual Event Ring */
+       size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
diff --git a/queue-4.1/drm-dp-mst-remove-debug-warn_on.patch b/queue-4.1/drm-dp-mst-remove-debug-warn_on.patch
new file mode 100644 (file)
index 0000000..30a1510
--- /dev/null
@@ -0,0 +1,34 @@
+From 42639ba554655c280ae6cb72df0522b1201f2961 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Mon, 3 Aug 2015 17:24:10 +0200
+Subject: drm/dp-mst: Remove debug WARN_ON
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 42639ba554655c280ae6cb72df0522b1201f2961 upstream.
+
+Apparently been in there since forever and fairly easy to hit when
+hotplugging really fast. I can do that since my mst hub has a manual
+button to flick the hpd line for reprobing. The resulting WARNING spam
+isn't pretty.
+
+Cc: Dave Airlie <airlied@gmail.com>
+Reviewed-by: Thierry Reding <treding@nvidia.com>
+Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_dp_mst_topology.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/drm_dp_mst_topology.c
+@@ -1294,7 +1294,6 @@ retry:
+                               goto retry;
+                       }
+                       DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret);
+-                      WARN(1, "fail\n");
+                       return -EIO;
+               }
diff --git a/queue-4.1/drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch b/queue-4.1/drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch
new file mode 100644 (file)
index 0000000..812134c
--- /dev/null
@@ -0,0 +1,56 @@
+From 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Sun, 28 Jun 2015 09:19:26 +0100
+Subject: drm/i915: Declare the swizzling unknown for L-shaped configurations
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940 upstream.
+
+The old style of memory interleaving swizzled upto the end of the
+first even bank of memory, and then used the remainder as unswizzled on
+the unpaired bank - i.e. swizzling is not constant for all memory. This
+causes problems when we try to migrate memory and so the kernel prevents
+migration at all when we detect L-shaped inconsistent swizzling.
+However, this issue also extends to userspace who try to manually detile
+into memory as the swizzling for an individual page is unknown (it
+depends on its physical address only known to the kernel), userspace
+cannot correctly swizzle.
+
+Note that this is a new attempt for the previously merged one,
+reverted in
+
+commit d82c0ba6e306f079407f07003e53c262d683397b
+Author: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date:   Tue Jul 14 12:29:27 2015 +0200
+
+    Revert "drm/i915: Declare the swizzling unknown for L-shaped configurations"
+
+This is cc: stable since we need it to fix up troubles with wc cpu
+mmaps that userspace recently started to use widely.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91105
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+[danvet: Add note about previous (failed attempt).]
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_gem_tiling.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
+@@ -464,7 +464,10 @@ i915_gem_get_tiling(struct drm_device *d
+       }
+       /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
+-      args->phys_swizzle_mode = args->swizzle_mode;
++      if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
++              args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN;
++      else
++              args->phys_swizzle_mode = args->swizzle_mode;
+       if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+               args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+       if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
diff --git a/queue-4.1/drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch b/queue-4.1/drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch
new file mode 100644 (file)
index 0000000..f63fa4a
--- /dev/null
@@ -0,0 +1,51 @@
+From ee0a227b7ac6e75f28e10269f81c7ec6eb600952 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Wed, 15 Jul 2015 09:50:42 +0100
+Subject: drm/i915: Replace WARN inside I915_READ64_2x32 with retry loop
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit ee0a227b7ac6e75f28e10269f81c7ec6eb600952 upstream.
+
+Since we may conceivably encounter situations where the upper part of the
+64bit register changes between reads, for example when a timestamp
+counter overflows, change the WARN into a retry loop.
+
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: MichaƂ Winiarski <michal.winiarski@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_drv.h |   17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -3190,15 +3190,14 @@ int intel_freq_opcode(struct drm_i915_pr
+ #define I915_READ64(reg)      dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true)
+ #define I915_READ64_2x32(lower_reg, upper_reg) ({                     \
+-              u32 upper = I915_READ(upper_reg);                       \
+-              u32 lower = I915_READ(lower_reg);                       \
+-              u32 tmp = I915_READ(upper_reg);                         \
+-              if (upper != tmp) {                                     \
+-                      upper = tmp;                                    \
+-                      lower = I915_READ(lower_reg);                   \
+-                      WARN_ON(I915_READ(upper_reg) != upper);         \
+-              }                                                       \
+-              (u64)upper << 32 | lower; })
++      u32 upper, lower, tmp;                                          \
++      tmp = I915_READ(upper_reg);                                     \
++      do {                                                            \
++              upper = tmp;                                            \
++              lower = I915_READ(lower_reg);                           \
++              tmp = I915_READ(upper_reg);                             \
++      } while (upper != tmp);                                         \
++      (u64)upper << 32 | lower; })
+ #define POSTING_READ(reg)     (void)I915_READ_NOTRACE(reg)
+ #define POSTING_READ16(reg)   (void)I915_READ16_NOTRACE(reg)
diff --git a/queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch b/queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch
new file mode 100644 (file)
index 0000000..e527752
--- /dev/null
@@ -0,0 +1,45 @@
+From 0a90a0cff9f429f886f423967ae053150dce9259 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 27 Jul 2015 19:24:31 -0400
+Subject: drm/radeon/combios: add some validation of lvds values
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 0a90a0cff9f429f886f423967ae053150dce9259 upstream.
+
+Fixes a broken hsync start value uncovered by:
+abc0b1447d4974963548777a5ba4a4457c82c426
+(drm: Perform basic sanity checks on probed modes)
+
+The driver handled the bad hsync start elsewhere, but
+the above commit prevented it from getting added.
+
+bug:
+https://bugs.freedesktop.org/show_bug.cgi?id=91401
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_combios.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_combios.c
++++ b/drivers/gpu/drm/radeon/radeon_combios.c
+@@ -1255,10 +1255,15 @@ struct radeon_encoder_lvds *radeon_combi
+                       if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
+                           (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) {
++                              u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8;
++
++                              if (hss > lvds->native_mode.hdisplay)
++                                      hss = (10 - 1) * 8;
++
+                               lvds->native_mode.htotal = lvds->native_mode.hdisplay +
+                                       (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
+                               lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
+-                                      (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8;
++                                      hss;
+                               lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
+                                       (RBIOS8(tmp + 23) * 8);
diff --git a/queue-4.1/drm-radeon-rework-audio-detect-v4.patch b/queue-4.1/drm-radeon-rework-audio-detect-v4.patch
new file mode 100644 (file)
index 0000000..b428309
--- /dev/null
@@ -0,0 +1,528 @@
+From d0ea397e22f9ad0113c1dbdaab14eded050472eb Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 23 Jul 2015 10:01:09 -0400
+Subject: drm/radeon: rework audio detect (v4)
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit d0ea397e22f9ad0113c1dbdaab14eded050472eb upstream.
+
+1. Always assign audio function pointers even if the display does
+not support audio.  We need to properly disable the audio stream
+when when using a non-audio capable monitor.  Fixes purple line
+on some hdmi monitors.
+
+2. Check if a pin is in use by another encoder before disabling
+it.
+
+v2: make sure we've fetched the edid before checking audio and
+    look up the encoder before calling audio_detect since
+    connector->encoder may not be assigned yet.  Separate
+    pin and afmt.  They are allocated at different times and
+    have no dependency on eachother.
+v3: fix connector fetching in encoder functions
+v4: fix missed dig->pin check in dce6_afmt_write_latency_fields
+
+bugs:
+https://bugzilla.kernel.org/show_bug.cgi?id=93701
+https://bugzilla.redhat.com/show_bug.cgi?id=1236337
+https://bugs.freedesktop.org/show_bug.cgi?id=91041
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/dce6_afmt.c         |   62 +++++-------
+ drivers/gpu/drm/radeon/radeon_audio.c      |  143 ++++++++++++-----------------
+ drivers/gpu/drm/radeon/radeon_audio.h      |    3 
+ drivers/gpu/drm/radeon/radeon_connectors.c |   18 ++-
+ drivers/gpu/drm/radeon/radeon_mode.h       |    2 
+ 5 files changed, 105 insertions(+), 123 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/dce6_afmt.c
++++ b/drivers/gpu/drm/radeon/dce6_afmt.c
+@@ -93,30 +93,26 @@ void dce6_afmt_select_pin(struct drm_enc
+       struct radeon_device *rdev = encoder->dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+-      u32 offset;
+-      if (!dig || !dig->afmt || !dig->afmt->pin)
++      if (!dig || !dig->afmt || !dig->pin)
+               return;
+-      offset = dig->afmt->offset;
+-
+-      WREG32(AFMT_AUDIO_SRC_CONTROL + offset,
+-             AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id));
++      WREG32(AFMT_AUDIO_SRC_CONTROL +  dig->afmt->offset,
++             AFMT_AUDIO_SRC_SELECT(dig->pin->id));
+ }
+ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
+-              struct drm_connector *connector, struct drm_display_mode *mode)
++                                  struct drm_connector *connector,
++                                  struct drm_display_mode *mode)
+ {
+       struct radeon_device *rdev = encoder->dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+-      u32 tmp = 0, offset;
++      u32 tmp = 0;
+-      if (!dig || !dig->afmt || !dig->afmt->pin)
++      if (!dig || !dig->afmt || !dig->pin)
+               return;
+-      offset = dig->afmt->pin->offset;
+-
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+               if (connector->latency_present[1])
+                       tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
+@@ -130,24 +126,24 @@ void dce6_afmt_write_latency_fields(stru
+               else
+                       tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
+       }
+-      WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
++      WREG32_ENDPOINT(dig->pin->offset,
++                      AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
+ }
+ void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+-      u8 *sadb, int sad_count)
++                                           u8 *sadb, int sad_count)
+ {
+       struct radeon_device *rdev = encoder->dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+-      u32 offset, tmp;
++      u32 tmp;
+-      if (!dig || !dig->afmt || !dig->afmt->pin)
++      if (!dig || !dig->afmt || !dig->pin)
+               return;
+-      offset = dig->afmt->pin->offset;
+-
+       /* program the speaker allocation */
+-      tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
++      tmp = RREG32_ENDPOINT(dig->pin->offset,
++                            AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
+       tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
+       /* set HDMI mode */
+       tmp |= HDMI_CONNECTION;
+@@ -155,24 +151,24 @@ void dce6_afmt_hdmi_write_speaker_alloca
+               tmp |= SPEAKER_ALLOCATION(sadb[0]);
+       else
+               tmp |= SPEAKER_ALLOCATION(5); /* stereo */
+-      WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
++      WREG32_ENDPOINT(dig->pin->offset,
++                      AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
+ }
+ void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+-      u8 *sadb, int sad_count)
++                                         u8 *sadb, int sad_count)
+ {
+       struct radeon_device *rdev = encoder->dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+-      u32 offset, tmp;
++      u32 tmp;
+-      if (!dig || !dig->afmt || !dig->afmt->pin)
++      if (!dig || !dig->afmt || !dig->pin)
+               return;
+-      offset = dig->afmt->pin->offset;
+-
+       /* program the speaker allocation */
+-      tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
++      tmp = RREG32_ENDPOINT(dig->pin->offset,
++                            AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
+       tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK);
+       /* set DP mode */
+       tmp |= DP_CONNECTION;
+@@ -180,13 +176,13 @@ void dce6_afmt_dp_write_speaker_allocati
+               tmp |= SPEAKER_ALLOCATION(sadb[0]);
+       else
+               tmp |= SPEAKER_ALLOCATION(5); /* stereo */
+-      WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
++      WREG32_ENDPOINT(dig->pin->offset,
++                      AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
+ }
+ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder,
+-      struct cea_sad *sads, int sad_count)
++                            struct cea_sad *sads, int sad_count)
+ {
+-      u32 offset;
+       int i;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+@@ -206,11 +202,9 @@ void dce6_afmt_write_sad_regs(struct drm
+               { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
+       };
+-      if (!dig || !dig->afmt || !dig->afmt->pin)
++      if (!dig || !dig->afmt || !dig->pin)
+               return;
+-      offset = dig->afmt->pin->offset;
+-
+       for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
+               u32 value = 0;
+               u8 stereo_freqs = 0;
+@@ -237,7 +231,7 @@ void dce6_afmt_write_sad_regs(struct drm
+               value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
+-              WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value);
++              WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value);
+       }
+ }
+@@ -253,7 +247,7 @@ void dce6_audio_enable(struct radeon_dev
+ }
+ void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
+-      struct radeon_crtc *crtc, unsigned int clock)
++                           struct radeon_crtc *crtc, unsigned int clock)
+ {
+       /* Two dtos; generally use dto0 for HDMI */
+       u32 value = 0;
+@@ -272,7 +266,7 @@ void dce6_hdmi_audio_set_dto(struct rade
+ }
+ void dce6_dp_audio_set_dto(struct radeon_device *rdev,
+-      struct radeon_crtc *crtc, unsigned int clock)
++                         struct radeon_crtc *crtc, unsigned int clock)
+ {
+       /* Two dtos; generally use dto1 for DP */
+       u32 value = 0;
+--- a/drivers/gpu/drm/radeon/radeon_audio.c
++++ b/drivers/gpu/drm/radeon/radeon_audio.c
+@@ -245,6 +245,28 @@ static struct radeon_audio_funcs dce6_dp
+ static void radeon_audio_enable(struct radeon_device *rdev,
+                               struct r600_audio_pin *pin, u8 enable_mask)
+ {
++      struct drm_encoder *encoder;
++      struct radeon_encoder *radeon_encoder;
++      struct radeon_encoder_atom_dig *dig;
++      int pin_count = 0;
++
++      if (!pin)
++              return;
++
++      if (rdev->mode_info.mode_config_initialized) {
++              list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
++                      if (radeon_encoder_is_digital(encoder)) {
++                              radeon_encoder = to_radeon_encoder(encoder);
++                              dig = radeon_encoder->enc_priv;
++                              if (dig->pin == pin)
++                                      pin_count++;
++                      }
++              }
++
++              if ((pin_count > 1) && (enable_mask == 0))
++                      return;
++      }
++
+       if (rdev->audio.funcs->enable)
+               rdev->audio.funcs->enable(rdev, pin, enable_mask);
+ }
+@@ -336,24 +358,13 @@ void radeon_audio_endpoint_wreg(struct r
+ static void radeon_audio_write_sad_regs(struct drm_encoder *encoder)
+ {
+-      struct radeon_encoder *radeon_encoder;
+-      struct drm_connector *connector;
+-      struct radeon_connector *radeon_connector = NULL;
++      struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
++      struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct cea_sad *sads;
+       int sad_count;
+-      list_for_each_entry(connector,
+-              &encoder->dev->mode_config.connector_list, head) {
+-              if (connector->encoder == encoder) {
+-                      radeon_connector = to_radeon_connector(connector);
+-                      break;
+-              }
+-      }
+-
+-      if (!radeon_connector) {
+-              DRM_ERROR("Couldn't find encoder's connector\n");
++      if (!connector)
+               return;
+-      }
+       sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
+       if (sad_count <= 0) {
+@@ -362,8 +373,6 @@ static void radeon_audio_write_sad_regs(
+       }
+       BUG_ON(!sads);
+-      radeon_encoder = to_radeon_encoder(encoder);
+-
+       if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs)
+               radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count);
+@@ -372,27 +381,16 @@ static void radeon_audio_write_sad_regs(
+ static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder)
+ {
++      struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+-      struct drm_connector *connector;
+-      struct radeon_connector *radeon_connector = NULL;
+       u8 *sadb = NULL;
+       int sad_count;
+-      list_for_each_entry(connector,
+-                          &encoder->dev->mode_config.connector_list, head) {
+-              if (connector->encoder == encoder) {
+-                      radeon_connector = to_radeon_connector(connector);
+-                      break;
+-              }
+-      }
+-
+-      if (!radeon_connector) {
+-              DRM_ERROR("Couldn't find encoder's connector\n");
++      if (!connector)
+               return;
+-      }
+-      sad_count = drm_edid_to_speaker_allocation(
+-              radeon_connector_edid(connector), &sadb);
++      sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector),
++                                                 &sadb);
+       if (sad_count < 0) {
+               DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n",
+                         sad_count);
+@@ -406,26 +404,13 @@ static void radeon_audio_write_speaker_a
+ }
+ static void radeon_audio_write_latency_fields(struct drm_encoder *encoder,
+-      struct drm_display_mode *mode)
++                                            struct drm_display_mode *mode)
+ {
+-      struct radeon_encoder *radeon_encoder;
+-      struct drm_connector *connector;
+-      struct radeon_connector *radeon_connector = 0;
+-
+-      list_for_each_entry(connector,
+-              &encoder->dev->mode_config.connector_list, head) {
+-              if (connector->encoder == encoder) {
+-                      radeon_connector = to_radeon_connector(connector);
+-                      break;
+-              }
+-      }
++      struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
++      struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+-      if (!radeon_connector) {
+-              DRM_ERROR("Couldn't find encoder's connector\n");
++      if (!connector)
+               return;
+-      }
+-
+-      radeon_encoder = to_radeon_encoder(encoder);
+       if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields)
+               radeon_encoder->audio->write_latency_fields(encoder, connector, mode);
+@@ -451,29 +436,23 @@ static void radeon_audio_select_pin(stru
+ }
+ void radeon_audio_detect(struct drm_connector *connector,
++                       struct drm_encoder *encoder,
+                        enum drm_connector_status status)
+ {
+-      struct radeon_device *rdev;
+-      struct radeon_encoder *radeon_encoder;
++      struct drm_device *dev = connector->dev;
++      struct radeon_device *rdev = dev->dev_private;
++      struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig;
+-      if (!connector || !connector->encoder)
++      if (!radeon_audio_chipset_supported(rdev))
+               return;
+-      rdev = connector->encoder->dev->dev_private;
+-
+-      if (!radeon_audio_chipset_supported(rdev))
++      if (!radeon_encoder_is_digital(encoder))
+               return;
+-      radeon_encoder = to_radeon_encoder(connector->encoder);
+       dig = radeon_encoder->enc_priv;
+       if (status == connector_status_connected) {
+-              if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+-                      radeon_encoder->audio = NULL;
+-                      return;
+-              }
+-
+               if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+@@ -486,11 +465,17 @@ void radeon_audio_detect(struct drm_conn
+                       radeon_encoder->audio = rdev->audio.hdmi_funcs;
+               }
+-              dig->afmt->pin = radeon_audio_get_pin(connector->encoder);
+-              radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
++              if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
++                      if (!dig->pin)
++                              dig->pin = radeon_audio_get_pin(encoder);
++                      radeon_audio_enable(rdev, dig->pin, 0xf);
++              } else {
++                      radeon_audio_enable(rdev, dig->pin, 0);
++                      dig->pin = NULL;
++              }
+       } else {
+-              radeon_audio_enable(rdev, dig->afmt->pin, 0);
+-              dig->afmt->pin = NULL;
++              radeon_audio_enable(rdev, dig->pin, 0);
++              dig->pin = NULL;
+       }
+ }
+@@ -518,29 +503,18 @@ static void radeon_audio_set_dto(struct
+ }
+ static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
+-      struct drm_display_mode *mode)
++                                     struct drm_display_mode *mode)
+ {
+       struct radeon_device *rdev = encoder->dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+-      struct drm_connector *connector;
+-      struct radeon_connector *radeon_connector = NULL;
++      struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
+       struct hdmi_avi_infoframe frame;
+       int err;
+-      list_for_each_entry(connector,
+-              &encoder->dev->mode_config.connector_list, head) {
+-              if (connector->encoder == encoder) {
+-                      radeon_connector = to_radeon_connector(connector);
+-                      break;
+-              }
+-      }
+-
+-      if (!radeon_connector) {
+-              DRM_ERROR("Couldn't find encoder's connector\n");
+-              return -ENOENT;
+-      }
++      if (!connector)
++              return -EINVAL;
+       err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+       if (err < 0) {
+@@ -563,8 +537,8 @@ static int radeon_audio_set_avi_packet(s
+               return err;
+       }
+-      if (dig && dig->afmt &&
+-              radeon_encoder->audio && radeon_encoder->audio->set_avi_packet)
++      if (dig && dig->afmt && radeon_encoder->audio &&
++          radeon_encoder->audio->set_avi_packet)
+               radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset,
+                       buffer, sizeof(buffer));
+@@ -745,7 +719,7 @@ static void radeon_audio_hdmi_mode_set(s
+ }
+ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
+-      struct drm_display_mode *mode)
++                                   struct drm_display_mode *mode)
+ {
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+@@ -756,6 +730,9 @@ static void radeon_audio_dp_mode_set(str
+       struct radeon_connector_atom_dig *dig_connector =
+               radeon_connector->con_priv;
++      if (!connector)
++              return;
++
+       if (!dig || !dig->afmt)
+               return;
+@@ -774,7 +751,7 @@ static void radeon_audio_dp_mode_set(str
+ }
+ void radeon_audio_mode_set(struct drm_encoder *encoder,
+-      struct drm_display_mode *mode)
++                         struct drm_display_mode *mode)
+ {
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+--- a/drivers/gpu/drm/radeon/radeon_audio.h
++++ b/drivers/gpu/drm/radeon/radeon_audio.h
+@@ -68,7 +68,8 @@ struct radeon_audio_funcs
+ int radeon_audio_init(struct radeon_device *rdev);
+ void radeon_audio_detect(struct drm_connector *connector,
+-      enum drm_connector_status status);
++                       struct drm_encoder *encoder,
++                       enum drm_connector_status status);
+ u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev,
+       u32 offset, u32 reg);
+ void radeon_audio_endpoint_wreg(struct radeon_device *rdev,
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -1379,8 +1379,16 @@ out:
+       /* updated in get modes as well since we need to know if it's analog or digital */
+       radeon_connector_update_scratch_regs(connector, ret);
+-      if (radeon_audio != 0)
+-              radeon_audio_detect(connector, ret);
++      if ((radeon_audio != 0) && radeon_connector->use_digital) {
++              const struct drm_connector_helper_funcs *connector_funcs =
++                      connector->helper_private;
++
++              encoder = connector_funcs->best_encoder(connector);
++              if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) {
++                      radeon_connector_get_edid(connector);
++                      radeon_audio_detect(connector, encoder, ret);
++              }
++      }
+ exit:
+       pm_runtime_mark_last_busy(connector->dev->dev);
+@@ -1717,8 +1725,10 @@ radeon_dp_detect(struct drm_connector *c
+       radeon_connector_update_scratch_regs(connector, ret);
+-      if (radeon_audio != 0)
+-              radeon_audio_detect(connector, ret);
++      if ((radeon_audio != 0) && encoder) {
++              radeon_connector_get_edid(connector);
++              radeon_audio_detect(connector, encoder, ret);
++      }
+ out:
+       pm_runtime_mark_last_busy(connector->dev->dev);
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -237,7 +237,6 @@ struct radeon_afmt {
+       int offset;
+       bool last_buffer_filled_status;
+       int id;
+-      struct r600_audio_pin *pin;
+ };
+ struct radeon_mode_info {
+@@ -439,6 +438,7 @@ struct radeon_encoder_atom_dig {
+       uint8_t backlight_level;
+       int panel_mode;
+       struct radeon_afmt *afmt;
++      struct r600_audio_pin *pin;
+       int active_mst_links;
+ };
diff --git a/queue-4.1/fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch b/queue-4.1/fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch
new file mode 100644 (file)
index 0000000..b978185
--- /dev/null
@@ -0,0 +1,77 @@
+From 8f2f3eb59dff4ec538de55f2e0592fec85966aab Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.com>
+Date: Thu, 6 Aug 2015 15:46:42 -0700
+Subject: fsnotify: fix oops in fsnotify_clear_marks_by_group_flags()
+
+From: Jan Kara <jack@suse.com>
+
+commit 8f2f3eb59dff4ec538de55f2e0592fec85966aab upstream.
+
+fsnotify_clear_marks_by_group_flags() can race with
+fsnotify_destroy_marks() so that when fsnotify_destroy_mark_locked()
+drops mark_mutex, a mark from the list iterated by
+fsnotify_clear_marks_by_group_flags() can be freed and thus the next
+entry pointer we have cached may become stale and we dereference free
+memory.
+
+Fix the problem by first moving marks to free to a special private list
+and then always free the first entry in the special list.  This method
+is safe even when entries from the list can disappear once we drop the
+lock.
+
+Signed-off-by: Jan Kara <jack@suse.com>
+Reported-by: Ashish Sangwan <a.sangwan@samsung.com>
+Reviewed-by: Ashish Sangwan <a.sangwan@samsung.com>
+Cc: Lino Sanfilippo <LinoSanfilippo@gmx.de>
+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>
+
+---
+ fs/notify/mark.c |   30 +++++++++++++++++++++++++-----
+ 1 file changed, 25 insertions(+), 5 deletions(-)
+
+--- a/fs/notify/mark.c
++++ b/fs/notify/mark.c
+@@ -412,16 +412,36 @@ void fsnotify_clear_marks_by_group_flags
+                                        unsigned int flags)
+ {
+       struct fsnotify_mark *lmark, *mark;
++      LIST_HEAD(to_free);
++      /*
++       * We have to be really careful here. Anytime we drop mark_mutex, e.g.
++       * fsnotify_clear_marks_by_inode() can come and free marks. Even in our
++       * to_free list so we have to use mark_mutex even when accessing that
++       * list. And freeing mark requires us to drop mark_mutex. So we can
++       * reliably free only the first mark in the list. That's why we first
++       * move marks to free to to_free list in one go and then free marks in
++       * to_free list one by one.
++       */
+       mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
+       list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
+-              if (mark->flags & flags) {
+-                      fsnotify_get_mark(mark);
+-                      fsnotify_destroy_mark_locked(mark, group);
+-                      fsnotify_put_mark(mark);
+-              }
++              if (mark->flags & flags)
++                      list_move(&mark->g_list, &to_free);
+       }
+       mutex_unlock(&group->mark_mutex);
++
++      while (1) {
++              mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
++              if (list_empty(&to_free)) {
++                      mutex_unlock(&group->mark_mutex);
++                      break;
++              }
++              mark = list_first_entry(&to_free, struct fsnotify_mark, g_list);
++              fsnotify_get_mark(mark);
++              fsnotify_destroy_mark_locked(mark, group);
++              mutex_unlock(&group->mark_mutex);
++              fsnotify_put_mark(mark);
++      }
+ }
+ /*
diff --git a/queue-4.1/ipr-fix-incorrect-trace-indexing.patch b/queue-4.1/ipr-fix-incorrect-trace-indexing.patch
new file mode 100644 (file)
index 0000000..ad57477
--- /dev/null
@@ -0,0 +1,52 @@
+From bb7c54339e6a10ecce5c4961adf5e75b3cf0af30 Mon Sep 17 00:00:00 2001
+From: Brian King <brking@linux.vnet.ibm.com>
+Date: Tue, 14 Jul 2015 11:41:31 -0500
+Subject: ipr: Fix incorrect trace indexing
+
+From: Brian King <brking@linux.vnet.ibm.com>
+
+commit bb7c54339e6a10ecce5c4961adf5e75b3cf0af30 upstream.
+
+When ipr's internal driver trace was changed to an atomic, a signed/unsigned
+bug slipped in which results in us indexing backwards in our memory buffer
+writing on memory that does not belong to us. This patch fixes this by removing
+the modulo and instead just mask off the low bits.
+
+Tested-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
+Reviewed-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
+Reviewed-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
+Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/ipr.c |    5 +++--
+ drivers/scsi/ipr.h |    1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -599,9 +599,10 @@ static void ipr_trc_hook(struct ipr_cmnd
+ {
+       struct ipr_trace_entry *trace_entry;
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
++      unsigned int trace_index;
+-      trace_entry = &ioa_cfg->trace[atomic_add_return
+-                      (1, &ioa_cfg->trace_index)%IPR_NUM_TRACE_ENTRIES];
++      trace_index = atomic_add_return(1, &ioa_cfg->trace_index) & IPR_TRACE_INDEX_MASK;
++      trace_entry = &ioa_cfg->trace[trace_index];
+       trace_entry->time = jiffies;
+       trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
+       trace_entry->type = type;
+--- a/drivers/scsi/ipr.h
++++ b/drivers/scsi/ipr.h
+@@ -1486,6 +1486,7 @@ struct ipr_ioa_cfg {
+ #define IPR_NUM_TRACE_INDEX_BITS      8
+ #define IPR_NUM_TRACE_ENTRIES         (1 << IPR_NUM_TRACE_INDEX_BITS)
++#define IPR_TRACE_INDEX_MASK          (IPR_NUM_TRACE_ENTRIES - 1)
+ #define IPR_TRACE_SIZE        (sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES)
+       char trace_start[8];
+ #define IPR_TRACE_START_LABEL                 "trace"
diff --git a/queue-4.1/ipr-fix-invalid-array-indexing-for-hrrq.patch b/queue-4.1/ipr-fix-invalid-array-indexing-for-hrrq.patch
new file mode 100644 (file)
index 0000000..5343f94
--- /dev/null
@@ -0,0 +1,67 @@
+From 3f1c0581310d5d94bd72740231507e763a6252a4 Mon Sep 17 00:00:00 2001
+From: Brian King <brking@linux.vnet.ibm.com>
+Date: Tue, 14 Jul 2015 11:41:33 -0500
+Subject: ipr: Fix invalid array indexing for HRRQ
+
+From: Brian King <brking@linux.vnet.ibm.com>
+
+commit 3f1c0581310d5d94bd72740231507e763a6252a4 upstream.
+
+Fixes another signed / unsigned array indexing bug in the ipr driver.
+Currently, when hrrq_index wraps, it becomes a negative number. We
+do the modulo, but still have a negative number, so we end up indexing
+backwards in the array. Given where the hrrq array is located in memory,
+we probably won't actually reference memory we don't own, but nonetheless
+ipr is still looking at data within struct ipr_ioa_cfg and interpreting it as
+struct ipr_hrr_queue data, so bad things could certainly happen.
+
+Each ipr adapter has anywhere from 1 to 16 HRRQs. By default, we use 2 on new
+adapters.  Let's take an example:
+
+Assume ioa_cfg->hrrq_index=0x7fffffffe and ioa_cfg->hrrq_num=4:
+
+The atomic_add_return will then return -1. We mod this with 3 and get -2, add
+one and get -1 for an array index.
+
+On adapters which support more than a single HRRQ, we dedicate HRRQ to adapter
+initialization and error interrupts so that we can optimize the other queues
+for fast path I/O. So all normal I/O uses HRRQ 1-15. So we want to spread the
+I/O requests across those HRRQs.
+
+With the default module parameter settings, this bug won't hit, only when
+someone sets the ipr.number_of_msix parameter to a value larger than 3 is when
+bad things start to happen.
+
+Tested-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
+Reviewed-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
+Reviewed-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
+Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/ipr.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -1052,10 +1052,15 @@ static void ipr_send_blocking_cmd(struct
+ static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg)
+ {
++      unsigned int hrrq;
++
+       if (ioa_cfg->hrrq_num == 1)
+-              return 0;
+-      else
+-              return (atomic_add_return(1, &ioa_cfg->hrrq_index) % (ioa_cfg->hrrq_num - 1)) + 1;
++              hrrq = 0;
++      else {
++              hrrq = atomic_add_return(1, &ioa_cfg->hrrq_index);
++              hrrq = (hrrq % (ioa_cfg->hrrq_num - 1)) + 1;
++      }
++      return hrrq;
+ }
+ /**
diff --git a/queue-4.1/ipr-fix-locking-for-unit-attention-handling.patch b/queue-4.1/ipr-fix-locking-for-unit-attention-handling.patch
new file mode 100644 (file)
index 0000000..4b592a3
--- /dev/null
@@ -0,0 +1,55 @@
+From 36b8e180e1e929e00b351c3b72aab3147fc14116 Mon Sep 17 00:00:00 2001
+From: Brian King <brking@linux.vnet.ibm.com>
+Date: Tue, 14 Jul 2015 11:41:29 -0500
+Subject: ipr: Fix locking for unit attention handling
+
+From: Brian King <brking@linux.vnet.ibm.com>
+
+commit 36b8e180e1e929e00b351c3b72aab3147fc14116 upstream.
+
+Make sure we have the host lock held when calling scsi_report_bus_reset. Fixes
+a crash seen as the __devices list in the scsi host was changing as we were
+iterating through it.
+
+Reviewed-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
+Reviewed-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
+Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/ipr.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -6263,21 +6263,23 @@ static void ipr_scsi_done(struct ipr_cmn
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
+       u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
+-      unsigned long hrrq_flags;
++      unsigned long lock_flags;
+       scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len));
+       if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) {
+               scsi_dma_unmap(scsi_cmd);
+-              spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags);
++              spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags);
+               list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
+               scsi_cmd->scsi_done(scsi_cmd);
+-              spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags);
++              spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags);
+       } else {
+-              spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags);
++              spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
++              spin_lock(&ipr_cmd->hrrq->_lock);
+               ipr_erp_start(ioa_cfg, ipr_cmd);
+-              spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags);
++              spin_unlock(&ipr_cmd->hrrq->_lock);
++              spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+       }
+ }
diff --git a/queue-4.1/mips-do_mcheck-fix-kernel-code-dump-with-eva.patch b/queue-4.1/mips-do_mcheck-fix-kernel-code-dump-with-eva.patch
new file mode 100644 (file)
index 0000000..27e4372
--- /dev/null
@@ -0,0 +1,58 @@
+From 55c723e181ccec30fb5c672397fe69ec35967d97 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Mon, 27 Jul 2015 13:50:21 +0100
+Subject: MIPS: do_mcheck: Fix kernel code dump with EVA
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 55c723e181ccec30fb5c672397fe69ec35967d97 upstream.
+
+If a machine check exception is raised in kernel mode, user context,
+with EVA enabled, then the do_mcheck handler will attempt to read the
+code around the EPC using EVA load instructions, i.e. as if the reads
+were from user mode. This will either read random user data if the
+process has anything mapped at the same address, or it will cause an
+exception which is handled by __get_user, resulting in this output:
+
+ Code: (Bad address in epc)
+
+Fix by setting the current user access mode to kernel if the saved
+register context indicates the exception was taken in kernel mode. This
+causes __get_user to use normal loads to read the kernel code.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Markos Chandras <markos.chandras@imgtec.com>
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/10777/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/traps.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -1518,6 +1518,7 @@ asmlinkage void do_mcheck(struct pt_regs
+       const int field = 2 * sizeof(unsigned long);
+       int multi_match = regs->cp0_status & ST0_TS;
+       enum ctx_state prev_state;
++      mm_segment_t old_fs = get_fs();
+       prev_state = exception_enter();
+       show_regs(regs);
+@@ -1539,8 +1540,13 @@ asmlinkage void do_mcheck(struct pt_regs
+               dump_tlb_all();
+       }
++      if (!user_mode(regs))
++              set_fs(KERNEL_DS);
++
+       show_code((unsigned int __user *) regs->cp0_epc);
++      set_fs(old_fs);
++
+       /*
+        * Some chips may have other causes of machine check (e.g. SB1
+        * graduation timer)
diff --git a/queue-4.1/mips-export-get_c0_perfcount_int.patch b/queue-4.1/mips-export-get_c0_perfcount_int.patch
new file mode 100644 (file)
index 0000000..1db3cd4
--- /dev/null
@@ -0,0 +1,90 @@
+From 0cb0985f57783c2f3c6c8ffe7e7665e80c56bd92 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Thu, 23 Jul 2015 18:59:52 +0200
+Subject: MIPS: Export get_c0_perfcount_int()
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 0cb0985f57783c2f3c6c8ffe7e7665e80c56bd92 upstream.
+
+get_c0_perfcount_int is tested from oprofile code. If oprofile is
+compiled as module, get_c0_perfcount_int needs to be exported, otherwise
+it cannot be resolved.
+
+Fixes: a669efc4a3b4 ("MIPS: Add hook to get C0 performance counter interrupt")
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Cc: linux-mips@linux-mips.org
+Cc: abrestic@chromium.org
+Patchwork: https://patchwork.linux-mips.org/patch/10763/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/ath79/setup.c          |    1 +
+ arch/mips/lantiq/irq.c           |    1 +
+ arch/mips/mti-malta/malta-time.c |    1 +
+ arch/mips/mti-sead3/sead3-time.c |    1 +
+ arch/mips/pistachio/time.c       |    1 +
+ arch/mips/ralink/irq.c           |    1 +
+ 6 files changed, 6 insertions(+)
+
+--- a/arch/mips/ath79/setup.c
++++ b/arch/mips/ath79/setup.c
+@@ -186,6 +186,7 @@ int get_c0_perfcount_int(void)
+ {
+       return ATH79_MISC_IRQ(5);
+ }
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+ unsigned int get_c0_compare_int(void)
+ {
+--- a/arch/mips/lantiq/irq.c
++++ b/arch/mips/lantiq/irq.c
+@@ -466,6 +466,7 @@ int get_c0_perfcount_int(void)
+ {
+       return ltq_perfcount_irq;
+ }
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+ unsigned int get_c0_compare_int(void)
+ {
+--- a/arch/mips/mti-malta/malta-time.c
++++ b/arch/mips/mti-malta/malta-time.c
+@@ -148,6 +148,7 @@ int get_c0_perfcount_int(void)
+       return mips_cpu_perf_irq;
+ }
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+ unsigned int get_c0_compare_int(void)
+ {
+--- a/arch/mips/mti-sead3/sead3-time.c
++++ b/arch/mips/mti-sead3/sead3-time.c
+@@ -77,6 +77,7 @@ int get_c0_perfcount_int(void)
+               return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+       return -1;
+ }
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+ unsigned int get_c0_compare_int(void)
+ {
+--- a/arch/mips/pistachio/time.c
++++ b/arch/mips/pistachio/time.c
+@@ -26,6 +26,7 @@ int get_c0_perfcount_int(void)
+ {
+       return gic_get_c0_perfcount_int();
+ }
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+ void __init plat_time_init(void)
+ {
+--- a/arch/mips/ralink/irq.c
++++ b/arch/mips/ralink/irq.c
+@@ -89,6 +89,7 @@ int get_c0_perfcount_int(void)
+ {
+       return rt_perfcount_irq;
+ }
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+ unsigned int get_c0_compare_int(void)
+ {
diff --git a/queue-4.1/mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch b/queue-4.1/mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch
new file mode 100644 (file)
index 0000000..6611ef1
--- /dev/null
@@ -0,0 +1,46 @@
+From 1d62d737555e1378eb62a8bba26644f7d97139d2 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 19 Jul 2015 00:38:41 +0200
+Subject: MIPS: Fix sched_getaffinity with MT FPAFF enabled
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 1d62d737555e1378eb62a8bba26644f7d97139d2 upstream.
+
+p->thread.user_cpus_allowed is zero-initialized and is only filled on
+the first sched_setaffinity call.
+
+To avoid adding overhead in the task initialization codepath, simply OR
+the returned mask in sched_getaffinity with p->cpus_allowed.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/10740/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/mips-mt-fpaff.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/kernel/mips-mt-fpaff.c
++++ b/arch/mips/kernel/mips-mt-fpaff.c
+@@ -154,7 +154,7 @@ asmlinkage long mipsmt_sys_sched_getaffi
+                                     unsigned long __user *user_mask_ptr)
+ {
+       unsigned int real_len;
+-      cpumask_t mask;
++      cpumask_t allowed, mask;
+       int retval;
+       struct task_struct *p;
+@@ -173,7 +173,8 @@ asmlinkage long mipsmt_sys_sched_getaffi
+       if (retval)
+               goto out_unlock;
+-      cpumask_and(&mask, &p->thread.user_cpus_allowed, cpu_possible_mask);
++      cpumask_or(&allowed, &p->thread.user_cpus_allowed, &p->cpus_allowed);
++      cpumask_and(&mask, &allowed, cpu_active_mask);
+ out_unlock:
+       read_unlock(&tasklist_lock);
diff --git a/queue-4.1/mips-flush-rps-on-kernel-entry-with-eva.patch b/queue-4.1/mips-flush-rps-on-kernel-entry-with-eva.patch
new file mode 100644 (file)
index 0000000..8754f60
--- /dev/null
@@ -0,0 +1,64 @@
+From 3aff47c062b944a5e1f9af56a37a23f5295628fc Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 31 Jul 2015 16:29:38 +0100
+Subject: MIPS: Flush RPS on kernel entry with EVA
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 3aff47c062b944a5e1f9af56a37a23f5295628fc upstream.
+
+When EVA is enabled, flush the Return Prediction Stack (RPS) present on
+some MIPS cores on entry to the kernel from user mode.
+
+This is important specifically for interAptiv with EVA enabled,
+otherwise kernel mode RPS mispredicts may trigger speculative fetches of
+user return addresses, which may be sensitive in the kernel address
+space due to EVA's overlapping user/kernel address spaces.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Markos Chandras <markos.chandras@imgtec.com>
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/10812/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/stackframe.h |   25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/arch/mips/include/asm/stackframe.h
++++ b/arch/mips/include/asm/stackframe.h
+@@ -152,6 +152,31 @@
+               .set    noreorder
+               bltz    k0, 8f
+                move   k1, sp
++#ifdef CONFIG_EVA
++              /*
++               * Flush interAptiv's Return Prediction Stack (RPS) by writing
++               * EntryHi. Toggling Config7.RPS is slower and less portable.
++               *
++               * The RPS isn't automatically flushed when exceptions are
++               * taken, which can result in kernel mode speculative accesses
++               * to user addresses if the RPS mispredicts. That's harmless
++               * when user and kernel share the same address space, but with
++               * EVA the same user segments may be unmapped to kernel mode,
++               * even containing sensitive MMIO regions or invalid memory.
++               *
++               * This can happen when the kernel sets the return address to
++               * ret_from_* and jr's to the exception handler, which looks
++               * more like a tail call than a function call. If nested calls
++               * don't evict the last user address in the RPS, it will
++               * mispredict the return and fetch from a user controlled
++               * address into the icache.
++               *
++               * More recent EVA-capable cores with MAAR to restrict
++               * speculative accesses aren't affected.
++               */
++              MFC0    k0, CP0_ENTRYHI
++              MTC0    k0, CP0_ENTRYHI
++#endif
+               .set    reorder
+               /* Called from user mode, new stack. */
+               get_saved_sp
diff --git a/queue-4.1/mips-make-set_pte-smp-safe.patch b/queue-4.1/mips-make-set_pte-smp-safe.patch
new file mode 100644 (file)
index 0000000..895a175
--- /dev/null
@@ -0,0 +1,77 @@
+From 46011e6ea39235e4aca656673c500eac81a07a17 Mon Sep 17 00:00:00 2001
+From: David Daney <david.daney@cavium.com>
+Date: Mon, 3 Aug 2015 17:48:43 -0700
+Subject: MIPS: Make set_pte() SMP safe.
+
+From: David Daney <david.daney@cavium.com>
+
+commit 46011e6ea39235e4aca656673c500eac81a07a17 upstream.
+
+On MIPS the GLOBAL bit of the PTE must have the same value in any
+aligned pair of PTEs.  These pairs of PTEs are referred to as
+"buddies".  In a SMP system is is possible for two CPUs to be calling
+set_pte() on adjacent PTEs at the same time.  There is a race between
+setting the PTE and a different CPU setting the GLOBAL bit in its
+buddy PTE.
+
+This race can be observed when multiple CPUs are executing
+vmap()/vfree() at the same time.
+
+Make setting the buddy PTE's GLOBAL bit an atomic operation to close
+the race condition.
+
+The case of CONFIG_64BIT_PHYS_ADDR && CONFIG_CPU_MIPS32 is *not*
+handled.
+
+Signed-off-by: David Daney <david.daney@cavium.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/10835/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/pgtable.h |   31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -182,8 +182,39 @@ static inline void set_pte(pte_t *ptep,
+                * Make sure the buddy is global too (if it's !none,
+                * it better already be global)
+                */
++#ifdef CONFIG_SMP
++              /*
++               * For SMP, multiple CPUs can race, so we need to do
++               * this atomically.
++               */
++#ifdef CONFIG_64BIT
++#define LL_INSN "lld"
++#define SC_INSN "scd"
++#else /* CONFIG_32BIT */
++#define LL_INSN "ll"
++#define SC_INSN "sc"
++#endif
++              unsigned long page_global = _PAGE_GLOBAL;
++              unsigned long tmp;
++
++              __asm__ __volatile__ (
++                      "       .set    push\n"
++                      "       .set    noreorder\n"
++                      "1:     " LL_INSN "     %[tmp], %[buddy]\n"
++                      "       bnez    %[tmp], 2f\n"
++                      "        or     %[tmp], %[tmp], %[global]\n"
++                      "       " SC_INSN "     %[tmp], %[buddy]\n"
++                      "       beqz    %[tmp], 1b\n"
++                      "        nop\n"
++                      "2:\n"
++                      "       .set pop"
++                      : [buddy] "+m" (buddy->pte),
++                        [tmp] "=&r" (tmp)
++                      : [global] "r" (page_global));
++#else /* !CONFIG_SMP */
+               if (pte_none(*buddy))
+                       pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
++#endif /* CONFIG_SMP */
+       }
+ #endif
+ }
diff --git a/queue-4.1/mips-malta-don-t-reinitialise-rtc.patch b/queue-4.1/mips-malta-don-t-reinitialise-rtc.patch
new file mode 100644 (file)
index 0000000..e96e3fb
--- /dev/null
@@ -0,0 +1,69 @@
+From 106eccb4d20f35ebc58ff2286c170d9e79c5ff68 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 17 Jul 2015 15:54:41 +0100
+Subject: MIPS: Malta: Don't reinitialise RTC
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 106eccb4d20f35ebc58ff2286c170d9e79c5ff68 upstream.
+
+On Malta, since commit a87ea88d8f6c ("MIPS: Malta: initialise the RTC at
+boot"), the RTC is reinitialised and forced into binary coded decimal
+(BCD) mode during init, even if the bootloader has already initialised
+it, and may even have already put it into binary mode (as YAMON does).
+This corrupts the current time, can result in the RTC seconds being an
+invalid BCD (e.g. 0x1a..0x1f) for up to 6 seconds, as well as confusing
+YAMON for a while after reset, enough for it to report timeouts when
+attempting to load from TFTP (it actually uses the RTC in that code).
+
+Therefore only initialise the RTC to the extent that is necessary so
+that Linux avoids interfering with the bootloader setup, while also
+allowing it to estimate the CPU frequency without hanging, without a
+bootloader necessarily having done anything with the RTC (for example
+when the kernel is loaded via EJTAG).
+
+The divider control is configured for a 32KHZ reference clock if
+necessary, and the SET bit of the RTC_CONTROL register is cleared if
+necessary without changing any other bits (this bit will be set when
+coming out of reset if the battery has been disconnected).
+
+Fixes: a87ea88d8f6c ("MIPS: Malta: initialise the RTC at boot")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Reviewed-by: Paul Burton <paul.burton@imgtec.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Maciej W. Rozycki <macro@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/10739/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/mti-malta/malta-time.c |   15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/arch/mips/mti-malta/malta-time.c
++++ b/arch/mips/mti-malta/malta-time.c
+@@ -165,14 +165,17 @@ unsigned int get_c0_compare_int(void)
+ static void __init init_rtc(void)
+ {
+-      /* stop the clock whilst setting it up */
+-      CMOS_WRITE(RTC_SET | RTC_24H, RTC_CONTROL);
++      unsigned char freq, ctrl;
+-      /* 32KHz time base */
+-      CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_FREQ_SELECT);
++      /* Set 32KHz time base if not already set */
++      freq = CMOS_READ(RTC_FREQ_SELECT);
++      if ((freq & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ)
++              CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_FREQ_SELECT);
+-      /* start the clock */
+-      CMOS_WRITE(RTC_24H, RTC_CONTROL);
++      /* Ensure SET bit is clear so RTC can run */
++      ctrl = CMOS_READ(RTC_CONTROL);
++      if (ctrl & RTC_SET)
++              CMOS_WRITE(ctrl & ~RTC_SET, RTC_CONTROL);
+ }
+ void __init plat_time_init(void)
diff --git a/queue-4.1/mips-show_stack-fix-stack-trace-with-eva.patch b/queue-4.1/mips-show_stack-fix-stack-trace-with-eva.patch
new file mode 100644 (file)
index 0000000..9fe0f76
--- /dev/null
@@ -0,0 +1,69 @@
+From 1e77863a51698c4319587df34171bd823691a66a Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Mon, 27 Jul 2015 13:50:22 +0100
+Subject: MIPS: show_stack: Fix stack trace with EVA
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 1e77863a51698c4319587df34171bd823691a66a upstream.
+
+The show_stack() function deals exclusively with kernel contexts, but if
+it gets called in user context with EVA enabled, show_stacktrace() will
+attempt to access the stack using EVA accesses, which will either read
+other user mapped data, or more likely cause an exception which will be
+handled by __get_user().
+
+This is easily reproduced using SysRq t to show all task states, which
+results in the following stack dump output:
+
+ Stack : (Bad stack address)
+
+Fix by setting the current user access mode to kernel around the call to
+show_stacktrace(). This causes __get_user() to use normal loads to read
+the kernel stack.
+
+Now we get the correct output, like this:
+
+ Stack : 00000000 80168960 00000000 004a0000 00000000 00000000 8060016c 1f3abd0c
+           1f172cd8 8056f09c 7ff1e450 8014fc3c 00000001 806dd0b0 0000001d 00000002
+           1f17c6a0 1f17c804 1f17c6a0 8066f6e0 00000000 0000000a 00000000 00000000
+           00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+           00000000 00000000 00000000 00000000 00000000 0110e800 1f3abd6c 1f17c6a0
+           ...
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Markos Chandras <markos.chandras@imgtec.com>
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/10778/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/traps.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -192,6 +192,7 @@ static void show_stacktrace(struct task_
+ void show_stack(struct task_struct *task, unsigned long *sp)
+ {
+       struct pt_regs regs;
++      mm_segment_t old_fs = get_fs();
+       if (sp) {
+               regs.regs[29] = (unsigned long)sp;
+               regs.regs[31] = 0;
+@@ -210,7 +211,13 @@ void show_stack(struct task_struct *task
+                       prepare_frametrace(&regs);
+               }
+       }
++      /*
++       * show_stack() deals exclusively with kernel mode, so be sure to access
++       * the stack in the kernel (not user) address space.
++       */
++      set_fs(KERNEL_DS);
+       show_stacktrace(task, &regs);
++      set_fs(old_fs);
+ }
+ static void show_code(unsigned int __user *pc)
diff --git a/queue-4.1/phy-twl4030-usb-make-runtime-pm-more-reliable.patch b/queue-4.1/phy-twl4030-usb-make-runtime-pm-more-reliable.patch
new file mode 100644 (file)
index 0000000..164fe7e
--- /dev/null
@@ -0,0 +1,102 @@
+From 56301df6bcaaed31e77b8c500ca1b437f46a3158 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 16 Apr 2015 18:03:04 +1000
+Subject: phy: twl4030-usb: make runtime pm more reliable.
+
+From: NeilBrown <neilb@suse.de>
+
+commit 56301df6bcaaed31e77b8c500ca1b437f46a3158 upstream.
+
+A construct like:
+
+        if (pm_runtime_suspended(twl->dev))
+               pm_runtime_get_sync(twl->dev);
+
+is against the spirit of the runtime_pm interface as it
+makes the internal refcounting useless.
+
+In this case it is also racy, particularly as 'put_autosuspend'
+is used to drop a reference.
+When that happens a timer is started and the device is
+runtime-suspended after the timeout.
+If the above code runs in this window, the device will not be
+found to be suspended so no pm_runtime reference is taken.
+When the timer expires the device will be suspended, which is
+against the intention of the code.
+
+So be more direct is taking and dropping references.
+If twl->linkstat is VBUS_VALID or ID_GROUND, then hold a
+pm_runtime reference, otherwise don't.
+Define "cable_present()" to test for this condition.
+
+Tested-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: Alexander Holler <holler@ahsoftware.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/phy/phy-twl4030-usb.c |   29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+--- a/drivers/phy/phy-twl4030-usb.c
++++ b/drivers/phy/phy-twl4030-usb.c
+@@ -144,6 +144,16 @@
+ #define PMBR1                         0x0D
+ #define GPIO_USB_4PIN_ULPI_2430C      (3 << 0)
++/*
++ * If VBUS is valid or ID is ground, then we know a
++ * cable is present and we need to be runtime-enabled
++ */
++static inline bool cable_present(enum omap_musb_vbus_id_status stat)
++{
++      return stat == OMAP_MUSB_VBUS_VALID ||
++              stat == OMAP_MUSB_ID_GROUND;
++}
++
+ struct twl4030_usb {
+       struct usb_phy          phy;
+       struct device           *dev;
+@@ -536,8 +546,10 @@ static irqreturn_t twl4030_usb_irq(int i
+       mutex_lock(&twl->lock);
+       if (status >= 0 && status != twl->linkstat) {
++              status_changed =
++                      cable_present(twl->linkstat) !=
++                      cable_present(status);
+               twl->linkstat = status;
+-              status_changed = true;
+       }
+       mutex_unlock(&twl->lock);
+@@ -553,15 +565,11 @@ static irqreturn_t twl4030_usb_irq(int i
+                * USB_LINK_VBUS state.  musb_hdrc won't care until it
+                * starts to handle softconnect right.
+                */
+-              if ((status == OMAP_MUSB_VBUS_VALID) ||
+-                  (status == OMAP_MUSB_ID_GROUND)) {
+-                      if (pm_runtime_suspended(twl->dev))
+-                              pm_runtime_get_sync(twl->dev);
++              if (cable_present(status)) {
++                      pm_runtime_get_sync(twl->dev);
+               } else {
+-                      if (pm_runtime_active(twl->dev)) {
+-                              pm_runtime_mark_last_busy(twl->dev);
+-                              pm_runtime_put_autosuspend(twl->dev);
+-                      }
++                      pm_runtime_mark_last_busy(twl->dev);
++                      pm_runtime_put_autosuspend(twl->dev);
+               }
+               omap_musb_mailbox(status);
+       }
+@@ -766,6 +774,9 @@ static int twl4030_usb_remove(struct pla
+       /* disable complete OTG block */
+       twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
++
++      if (cable_present(twl->linkstat))
++              pm_runtime_put_noidle(twl->dev);
+       pm_runtime_mark_last_busy(twl->dev);
+       pm_runtime_put(twl->dev);
diff --git a/queue-4.1/revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch b/queue-4.1/revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch
new file mode 100644 (file)
index 0000000..9e839d6
--- /dev/null
@@ -0,0 +1,54 @@
+From 247bfb65d731350093f5d1a0a8b3d65e49c17baa Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 28 Jul 2015 19:24:24 -0700
+Subject: Revert "MIPS: BCM63xx: Provide a plat_post_dma_flush hook"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit 247bfb65d731350093f5d1a0a8b3d65e49c17baa upstream.
+
+This reverts commit 3cf29543413207d3ab1c3f62a88c09bb46f2264e ("MIPS:
+BCM63xx: Provide a plat_post_dma_flush hook") since this commit was
+found to prevent BCM6358 (early BMIPS4350 cores) and some BCM6368
+(BMIPS4380 cores) from booting reliably.
+
+Alvaro was able to track this down to an issue specifically located to
+devices that use the second thread (TP1) when booting. Since BCM63xx did
+not have a need for plat_post_dma_flush() hook before, let's just keep
+things the way they were.
+
+Reported-by: Ălvaro FernĂĄndez Rojas <noltari@gmail.com>
+Reported-by: Jonas Gorski <jogo@openwrt.org>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Cc: Kevin Cernekee <cernekee@gmail.com>
+Cc: Nicolas Schichan <nschichan@freebox.fr>
+Cc: linux-mips@linux-mips.org
+Cc: blogic@openwrt.org
+Cc: noltari@gmail.com
+Cc: jogo@openwrt.org
+Cc: Florian Fainelli <f.fainelli@gmail.com>
+Cc: stable@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/10804/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/mach-bcm63xx/dma-coherence.h |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h
++++ /dev/null
+@@ -1,10 +0,0 @@
+-#ifndef __ASM_MACH_BCM63XX_DMA_COHERENCE_H
+-#define __ASM_MACH_BCM63XX_DMA_COHERENCE_H
+-
+-#include <asm/bmips.h>
+-
+-#define plat_post_dma_flush   bmips_post_dma_flush
+-
+-#include <asm/mach-generic/dma-coherence.h>
+-
+-#endif /* __ASM_MACH_BCM63XX_DMA_COHERENCE_H */
index 947288b5a96945e85931386e204a40fc63cfc2c3..26042d2847e96c22904c9a8a738388d21ec07081 100644 (file)
@@ -1,2 +1,28 @@
 mips-unaligned-fix-build-error-on-big-endian-r6-kernels.patch
 mips-replace-add-and-sub-instructions-in-relocate_kernel.s-with-addiu.patch
+mips-malta-don-t-reinitialise-rtc.patch
+mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch
+mips-export-get_c0_perfcount_int.patch
+mips-do_mcheck-fix-kernel-code-dump-with-eva.patch
+mips-show_stack-fix-stack-trace-with-eva.patch
+revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch
+mips-flush-rps-on-kernel-entry-with-eva.patch
+mips-make-set_pte-smp-safe.patch
+fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch
+drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch
+drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch
+drm-radeon-rework-audio-detect-v4.patch
+drm-radeon-combios-add-some-validation-of-lvds-values.patch
+drm-dp-mst-remove-debug-warn_on.patch
+ipr-fix-locking-for-unit-attention-handling.patch
+ipr-fix-incorrect-trace-indexing.patch
+ipr-fix-invalid-array-indexing-for-hrrq.patch
+bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch
+dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch
+dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch
+xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch
+drivers-usb-delete-xhci-command-timer-if-necessary.patch
+usb-sierra-add-1199-68ab-device-id.patch
+usb-udc-core-add-device_del-call-to-error-pathway.patch
+usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch
+phy-twl4030-usb-make-runtime-pm-more-reliable.patch
diff --git a/queue-4.1/usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch b/queue-4.1/usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch
new file mode 100644 (file)
index 0000000..260ac54
--- /dev/null
@@ -0,0 +1,199 @@
+From 2f01a33bd26545c16fea7592697f7f15c416402b Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@freescale.com>
+Date: Tue, 21 Jul 2015 09:51:29 +0800
+Subject: usb: chipidea: ehci_init_driver is intended to call one time
+
+From: Peter Chen <peter.chen@freescale.com>
+
+commit 2f01a33bd26545c16fea7592697f7f15c416402b upstream.
+
+The ehci_init_driver is used to initialize hcd APIs for each
+ehci controller driver, it is designed to be called only one time
+and before driver register is called. The current design will
+cause ehci_init_driver is called multiple times at probe process,
+it will cause hc_driver's initialization affect current running hcd.
+
+We run out NULL pointer dereference problem when one hcd is started
+by module_init, and the other is started by otg thread at SMP platform.
+The reason for this problem is ehci_init_driver will do memory copy
+for current uniform hc_driver, and this memory copy will do memset (as 0)
+first, so when the first hcd is running usb_add_hcd, and the second
+hcd may clear the uniform hc_driver's space (at ehci_init_driver),
+then the first hcd will meet NULL pointer at the same time.
+
+See below two logs:
+
+LOG_1:
+ci_hdrc ci_hdrc.0: EHCI Host Controller
+ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
+ci_hdrc ci_hdrc.1: doesn't support gadget
+Unable to handle kernel NULL pointer dereference at virtual address 00000014
+pgd = 80004000
+[00000014] *pgd=00000000
+Internal error: Oops: 805 [#1] PREEMPT SMP ARM
+Modules linked in:
+CPU: 0 PID: 108 Comm: kworker/u8:2 Not tainted 3.14.38-222193-g24b2734-dirty #25
+Workqueue: ci_otg ci_otg_work
+task: d839ec00 ti: d8400000 task.ti: d8400000
+PC is at ehci_run+0x4c/0x284
+LR is at _raw_spin_unlock_irqrestore+0x28/0x54
+pc : [<8041f9a0>]    lr : [<8070ea84>]    psr: 60000113
+sp : d8401e30  ip : 00000000  fp : d8004400
+r10: 00000001  r9 : 00000001  r8 : 00000000
+r7 : 00000000  r6 : d8419940  r5 : 80dd24c0  r4 : d8419800
+r3 : 8001d060  r2 : 00000000  r1 : 00000001  r0 : 00000000
+Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
+Control: 10c53c7d  Table: 1000404a  DAC: 00000015
+Process kworker/u8:2 (pid: 108, stack limit = 0xd8400238)
+Stack: (0xd8401e30 to 0xd8402000)
+1e20:                                     d87523c0 d8401e48 66667562 d8419800
+1e40: 00000000 00000000 d8419800 00000000 00000000 00000000 d84198b0 8040fcdc
+1e60: 00000000 80dd320c d8477610 d8419c00 d803d010 d8419800 00000000 00000000
+1e80: d8004400 00000000 d8400008 80431494 80431374 d803d100 d803d010 d803d1ac
+1ea0: 00000000 80432428 804323d4 d803d100 00000001 80435eb8 80e0d0bc d803d100
+1ec0: 00000006 80436458 00000000 d803d100 80e92ec8 80436f44 d803d010 d803d100
+1ee0: d83fde00 8043292c d8752710 d803d1f4 d803d010 8042ddfc 8042ddb8 d83f3b00
+1f00: d803d1f4 80042b60 00000000 00000003 00000001 00000001 80054598 d83f3b00
+1f20: d8004400 d83f3b18 d8004414 d8400000 80e3957b 00000089 d8004400 80043814
+1f40: d839ec00 00000000 d83fcd80 d83f3b00 800436e4 00000000 00000000 00000000
+1f60: 00000000 80048f34 00000000 00000000 00000000 d83f3b00 00000000 00000000
+1f80: d8401f80 d8401f80 00000000 00000000 d8401f90 d8401f90 d8401fac d83fcd80
+1fa0: 80048e68 00000000 00000000 8000e538 00000000 00000000 00000000 00000000
+1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
+[<8041f9a0>] (ehci_run) from [<8040fcdc>] (usb_add_hcd+0x248/0x6e8)
+[<8040fcdc>] (usb_add_hcd) from [<80431494>] (host_start+0x120/0x2e4)
+[<80431494>] (host_start) from [<80432428>] (ci_otg_start_host+0x54/0xbc)
+[<80432428>] (ci_otg_start_host) from [<80435eb8>] (otg_set_protocol+0xa4/0xd0)
+[<80435eb8>] (otg_set_protocol) from [<80436458>] (otg_set_state+0x574/0xc58)
+[<80436458>] (otg_set_state) from [<80436f44>] (otg_statemachine+0x408/0x46c)
+[<80436f44>] (otg_statemachine) from [<8043292c>] (ci_otg_fsm_work+0x3c/0x190)
+[<8043292c>] (ci_otg_fsm_work) from [<8042ddfc>] (ci_otg_work+0x44/0x1c4)
+[<8042ddfc>] (ci_otg_work) from [<80042b60>] (process_one_work+0xf4/0x35c)
+[<80042b60>] (process_one_work) from [<80043814>] (worker_thread+0x130/0x3bc)
+[<80043814>] (worker_thread) from [<80048f34>] (kthread+0xcc/0xe4)
+[<80048f34>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c)
+Code: e5953018 e3530000 0a000000 e12fff33 (e5878014)
+
+LOG_2:
+ci_hdrc ci_hdrc.0: EHCI Host Controller
+ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
+ci_hdrc ci_hdrc.1: doesn't support gadget
+Unable to handle kernel NULL pointer dereference at virtual address 00000000
+pgd = 80004000
+[00000000] *pgd=00000000
+In Online 00:00ternal e      Offline rror: Oops: 80000005 [#1] PREEMPT SMP ARM
+Modules linked in:
+CPU: 0 PID: 108 Comm: kworker/u8:2 Not tainted 3.14.38-02007-g24b2734-dirty #127
+Workque Online 00:00ue: ci_o      Offline tg ci_otg_work
+Online 00:00task: d8      Offline 39ec00 ti: d83ea000 task.ti: d83ea000
+PC is at 0x0
+LR is at usb_add_hcd+0x248/0x6e8
+pc : [<00000000>]    lr : [<8040f644>]    psr: 60000113
+sp : d83ebe60  ip : 00000000  fp : d8004400
+r10: 00000001  r9 : 00000001  r8 : d85fd4b0
+r7 : 00000000  r6 : 00000000  r5 : 00000000  r4 : d85fd400
+r3 : 00000000  r2 : d85fd4f4  r1 : 80410178  r0 : d85fd400
+Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
+Control: 10c53c7d  Table: 1000404a  DAC: 00000015
+Process kworker/u8:2 (pid: 108, stack limit = 0xd83ea238)
+Stack: (0xd83ebe60 to 0xd83ec000)
+be60: 00000000 80dd920c d8654e10 d85fd800 d803e010 d85fd400 00000000 00000000
+be80: d8004400 00000000 d83ea008 80430e34 80430d14 d803e100 d803e010 d803e1ac
+bea0: 00000000 80431dc8 80431d74 d803e100 00000001 80435858 80e130bc d803e100
+bec0: 00000006 80435df8 00000000 d803e100 80e98ec8 804368e4 d803e010 d803e100
+bee0: d86e8100 804322cc d86cf050 d803e1f4 d803e010 8042d79c 8042d758 d83cf900
+bf00: d803e1f4 80042b78 00000000 00000003 00000001 00000001 800545e8 d83cf900
+bf20: d8004400 d83cf918 d8004414 d83ea000 80e3f57b 00000089 d8004400 8004382c
+bf40: d839ec00 00000000 d8393780 d83cf900 800436fc 00000000 00000000 00000000
+bf60: 00000000 80048f50 80e019f4 00000000 0000264c d83cf900 00000000 00000000
+bf80: d83ebf80 d83ebf80 00000000 00000000 d83ebf90 d83ebf90 d83ebfac d8393780
+bfa0: 80048e84 00000000 00000000 8000e538 00000000 00000000 00000000 00000000
+bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ee66e85d 133ebd03
+[<804 Online 00:000f644>]       Offline (usb_add_hcd) from [<80430e34>] (host_start+0x120/0x2e4)
+[<80430e34>] (host_start) from [<80431dc8>] (ci_otg_start_host+0x54/0xbc)
+[<80431dc8>] (ci_otg_start_host) from [<80435858>] (otg_set_protocol+0xa4/0xd0)
+[<80435858>] (otg_set_protocol) from [<80435df8>] (otg_set_state+0x574/0xc58)
+[<80435df8>] (otg_set_state) from [<804368e4>] (otg_statemachine+0x408/0x46c)
+[<804368e4>] (otg_statemachine) from [<804322cc>] (ci_otg_fsm_work+0x3c/0x190)
+[<804322cc>] (ci_otg_fsm_work) from [<8042d79c>] (ci_otg_work+0x44/0x1c4)
+[<8042d79c>] (ci_otg_work) from [<80042b78>] (process_one_work+0xf4/0x35c)
+[<80042b78>] (process_one_work) from [<8004382c>] (worker_thread+0x130/0x3bc)
+[<8004382c>] (worker_thread) from [<80048f50>] (kthread+0xcc/0xe4)
+[<80048f50>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c)
+Code: bad PC value
+
+Cc: Jun Li <jun.li@freescale.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Peter Chen <peter.chen@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/core.c |   13 ++++++++++++-
+ drivers/usb/chipidea/host.c |    7 +++++--
+ drivers/usb/chipidea/host.h |    6 ++++++
+ 3 files changed, 23 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -1024,7 +1024,18 @@ static struct platform_driver ci_hdrc_dr
+       },
+ };
+-module_platform_driver(ci_hdrc_driver);
++static int __init ci_hdrc_platform_register(void)
++{
++      ci_hdrc_host_driver_init();
++      return platform_driver_register(&ci_hdrc_driver);
++}
++module_init(ci_hdrc_platform_register);
++
++static void __exit ci_hdrc_platform_unregister(void)
++{
++      platform_driver_unregister(&ci_hdrc_driver);
++}
++module_exit(ci_hdrc_platform_unregister);
+ MODULE_ALIAS("platform:ci_hdrc");
+ MODULE_LICENSE("GPL v2");
+--- a/drivers/usb/chipidea/host.c
++++ b/drivers/usb/chipidea/host.c
+@@ -237,9 +237,12 @@ int ci_hdrc_host_init(struct ci_hdrc *ci
+       rdrv->name      = "host";
+       ci->roles[CI_ROLE_HOST] = rdrv;
++      return 0;
++}
++
++void ci_hdrc_host_driver_init(void)
++{
+       ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
+       orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
+       ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
+-
+-      return 0;
+ }
+--- a/drivers/usb/chipidea/host.h
++++ b/drivers/usb/chipidea/host.h
+@@ -5,6 +5,7 @@
+ int ci_hdrc_host_init(struct ci_hdrc *ci);
+ void ci_hdrc_host_destroy(struct ci_hdrc *ci);
++void ci_hdrc_host_driver_init(void);
+ #else
+@@ -17,6 +18,11 @@ static inline void ci_hdrc_host_destroy(
+ {
+ }
++
++static void ci_hdrc_host_driver_init(void)
++{
++
++}
+ #endif
diff --git a/queue-4.1/usb-sierra-add-1199-68ab-device-id.patch b/queue-4.1/usb-sierra-add-1199-68ab-device-id.patch
new file mode 100644 (file)
index 0000000..e266b5f
--- /dev/null
@@ -0,0 +1,330 @@
+From 74472233233f577eaa0ca6d6e17d9017b6e53150 Mon Sep 17 00:00:00 2001
+From: Dirk Behme <dirk.behme@de.bosch.com>
+Date: Mon, 27 Jul 2015 08:56:05 +0200
+Subject: USB: sierra: add 1199:68AB device ID
+
+From: Dirk Behme <dirk.behme@de.bosch.com>
+
+commit 74472233233f577eaa0ca6d6e17d9017b6e53150 upstream.
+
+Add support for the Sierra Wireless AR8550 device with
+USB descriptor 0x1199, 0x68AB.
+
+It is common with MC879x modules 1199:683c/683d which
+also are composite devices with 7 interfaces (0..6)
+and also MDM62xx based as the AR8550.
+
+The major difference are only the interface attributes
+02/02/01 on interfaces 3 and 4 on the AR8550. They are
+vendor specific ff/ff/ff on MC879x modules.
+
+lsusb reports:
+
+Bus 001 Device 004: ID 1199:68ab Sierra Wireless, Inc.
+Device Descriptor:
+  bLength                18
+  bDescriptorType         1
+  bcdUSB               2.00
+  bDeviceClass            0 (Defined at Interface level)
+  bDeviceSubClass         0
+  bDeviceProtocol         0
+  bMaxPacketSize0        64
+  idVendor           0x1199 Sierra Wireless, Inc.
+  idProduct          0x68ab
+  bcdDevice            0.06
+  iManufacturer           3 Sierra Wireless, Incorporated
+  iProduct                2 AR8550
+  iSerial                 0
+  bNumConfigurations      1
+  Configuration Descriptor:
+    bLength                 9
+    bDescriptorType         2
+    wTotalLength          198
+    bNumInterfaces          7
+    bConfigurationValue     1
+    iConfiguration          1 Sierra Configuration
+    bmAttributes         0xe0
+      Self Powered
+      Remote Wakeup
+    MaxPower                0mA
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        0
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol    255 Vendor Specific Protocol
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x81  EP 1 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x01  EP 1 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        1
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol    255 Vendor Specific Protocol
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x82  EP 2 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x02  EP 2 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        2
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol    255 Vendor Specific Protocol
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x83  EP 3 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x03  EP 3 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        3
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass         2 Communications
+      bInterfaceSubClass      2 Abstract (modem)
+      bInterfaceProtocol      1 AT-commands (v.25ter)
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x84  EP 4 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               5
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x85  EP 5 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x04  EP 4 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        4
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass         2 Communications
+      bInterfaceSubClass      2 Abstract (modem)
+      bInterfaceProtocol      1 AT-commands (v.25ter)
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x86  EP 6 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               5
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x87  EP 7 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x05  EP 5 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        5
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol    255 Vendor Specific Protocol
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x88  EP 8 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               5
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x89  EP 9 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x06  EP 6 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        6
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol    255 Vendor Specific Protocol
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x8a  EP 10 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               5
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x8b  EP 11 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x07  EP 7 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval              32
+Device Qualifier (for other device speed):
+  bLength                10
+  bDescriptorType         6
+  bcdUSB               2.00
+  bDeviceClass            0 (Defined at Interface level)
+  bDeviceSubClass         0
+  bDeviceProtocol         0
+  bMaxPacketSize0        64
+  bNumConfigurations      1
+Device Status:     0x0001
+  Self Powered
+
+Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
+Cc: Lars Melin <larsm17@gmail.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -289,6 +289,7 @@ static const struct usb_device_id id_tab
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF),
+         .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+       },
++      { USB_DEVICE(0x1199, 0x68AB) }, /* Sierra Wireless AR8550 */
+       /* AT&T Direct IP LTE modems */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF),
+         .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
diff --git a/queue-4.1/usb-udc-core-add-device_del-call-to-error-pathway.patch b/queue-4.1/usb-udc-core-add-device_del-call-to-error-pathway.patch
new file mode 100644 (file)
index 0000000..0ef6492
--- /dev/null
@@ -0,0 +1,33 @@
+From c93e64e91248becd0edb8f01723dff9da890e2ab Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 16 Jan 2015 11:32:51 -0500
+Subject: usb: udc: core: add device_del() call to error pathway
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit c93e64e91248becd0edb8f01723dff9da890e2ab upstream.
+
+This patch fixes a bug in the error pathway of
+usb_add_gadget_udc_release() in udc-core.c.  If the udc registration
+fails, the gadget registration is not fully undone; there's a
+put_device(&gadget->dev) call but no device_del().
+
+Acked-by: Peter Chen <peter.chen@freescale.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/udc-core.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/udc/udc-core.c
++++ b/drivers/usb/gadget/udc/udc-core.c
+@@ -321,6 +321,7 @@ err4:
+ err3:
+       put_device(&udc->dev);
++      device_del(&gadget->dev);
+ err2:
+       put_device(&gadget->dev);
diff --git a/queue-4.1/xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch b/queue-4.1/xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch
new file mode 100644 (file)
index 0000000..12ca9a3
--- /dev/null
@@ -0,0 +1,50 @@
+From 7895086afde2a05fa24a0e410d8e6b75ca7c8fdd Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 3 Aug 2015 16:07:48 +0300
+Subject: xhci: fix off by one error in TRB DMA address boundary check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 7895086afde2a05fa24a0e410d8e6b75ca7c8fdd upstream.
+
+We need to check that a TRB is part of the current segment
+before calculating its DMA address.
+
+Previously a ring segment didn't use a full memory page, and every
+new ring segment got a new memory page, so the off by one
+error in checking the upper bound was never seen.
+
+Now that we use a full memory page, 256 TRBs (4096 bytes), the off by one
+didn't catch the case when a TRB was the first element of the next segment.
+
+This is triggered if the virtual memory pages for a ring segment are
+next to each in increasing order where the ring buffer wraps around and
+causes errors like:
+
+[  106.398223] xhci_hcd 0000:00:14.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 0 comp_code 1
+[  106.398230] xhci_hcd 0000:00:14.0: Looking for event-dma fffd3000 trb-start fffd4fd0 trb-end fffd5000 seg-start fffd4000 seg-end fffd4ff0
+
+The trb-end address is one outside the end-seg address.
+
+Tested-by: Arkadiusz Miƛkiewicz <arekm@maven.pl>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -82,7 +82,7 @@ dma_addr_t xhci_trb_virt_to_dma(struct x
+               return 0;
+       /* offset in TRBs */
+       segment_offset = trb - seg->trbs;
+-      if (segment_offset > TRBS_PER_SEGMENT)
++      if (segment_offset >= TRBS_PER_SEGMENT)
+               return 0;
+       return seg->dma + (segment_offset * sizeof(*trb));
+ }