stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Patch "xhci: Reset Renesas uPD72020x USB controller for 32-bit DMA issue" has been added to the 4.12-stable tree
@ 2017-08-13 22:26 gregkh
  0 siblings, 0 replies; only message in thread
From: gregkh @ 2017-08-13 22:26 UTC (permalink / raw)
  To: marc.zyngier, ard.biesheuvel, bhelgaas, gregkh, mathias.nyman
  Cc: stable, stable-commits


This is a note to let you know that I've just added the patch titled

    xhci: Reset Renesas uPD72020x USB controller for 32-bit DMA issue

to the 4.12-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     xhci-reset-renesas-upd72020x-usb-controller-for-32-bit-dma-issue.patch
and it can be found in the queue-4.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.


>From 8466489ef5ba48272ba4fa4ea9f8f403306de4c7 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <marc.zyngier@arm.com>
Date: Tue, 1 Aug 2017 20:11:08 -0500
Subject: xhci: Reset Renesas uPD72020x USB controller for 32-bit DMA issue

From: Marc Zyngier <marc.zyngier@arm.com>

commit 8466489ef5ba48272ba4fa4ea9f8f403306de4c7 upstream.

The Renesas uPD72020x XHCI controller seems to suffer from a really
annoying bug, where it may retain some of its DMA programming across a XHCI
reset, and despite the driver correctly programming new DMA addresses.
This is visible if the device has been using 64-bit DMA addresses, and is
then switched to using 32-bit DMA addresses.  The top 32 bits of the
address (now zero) are ignored are replaced by the 32 bits from the
*previous* programming.  Sticking with 64-bit DMA always works, but doesn't
seem very appropriate.

A PCI reset of the device restores the normal functionality, which is done
at probe time.  Unfortunately, this has to be done before any quirk has
been discovered, hence the intrusive nature of the fix.

Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/usb/host/pci-quirks.c |   20 ++++++++++++++++++++
 drivers/usb/host/pci-quirks.h |    1 +
 drivers/usb/host/xhci-pci.c   |    7 +++++++
 3 files changed, 28 insertions(+)

--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -1157,3 +1157,23 @@ static void quirk_usb_early_handoff(stru
 }
 DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
 			PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
+
+bool usb_xhci_needs_pci_reset(struct pci_dev *pdev)
+{
+	/*
+	 * Our dear uPD72020{1,2} friend only partially resets when
+	 * asked to via the XHCI interface, and may end up doing DMA
+	 * at the wrong addresses, as it keeps the top 32bit of some
+	 * addresses from its previous programming under obscure
+	 * circumstances.
+	 * Give it a good wack at probe time. Unfortunately, this
+	 * needs to happen before we've had a chance to discover any
+	 * quirk, or the system will be in a rather bad state.
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
+	    (pdev->device == 0x0014 || pdev->device == 0x0015))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(usb_xhci_needs_pci_reset);
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -15,6 +15,7 @@ void usb_asmedia_modifyflowcontrol(struc
 void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
 void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
 void sb800_prefetch(struct device *dev, int on);
+bool usb_xhci_needs_pci_reset(struct pci_dev *pdev);
 #else
 struct pci_dev;
 static inline void usb_amd_quirk_pll_disable(void) {}
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -285,6 +285,13 @@ static int xhci_pci_probe(struct pci_dev
 
 	driver = (struct hc_driver *)id->driver_data;
 
+	/* For some HW implementation, a XHCI reset is just not enough... */
+	if (usb_xhci_needs_pci_reset(dev)) {
+		dev_info(&dev->dev, "Resetting\n");
+		if (pci_reset_function_locked(dev))
+			dev_warn(&dev->dev, "Reset failed");
+	}
+
 	/* Prevent runtime suspending between USB-2 and USB-3 initialization */
 	pm_runtime_get_noresume(&dev->dev);
 


Patches currently in stable-queue which might be from marc.zyngier@arm.com are

queue-4.12/pci-add-pci_reset_function_locked.patch
queue-4.12/xhci-reset-renesas-upd72020x-usb-controller-for-32-bit-dma-issue.patch

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-08-14  0:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-13 22:26 Patch "xhci: Reset Renesas uPD72020x USB controller for 32-bit DMA issue" has been added to the 4.12-stable tree gregkh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).