summaryrefslogtreecommitdiff
path: root/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch')
-rw-r--r--target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch124
1 files changed, 124 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch b/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch
new file mode 100644
index 0000000..84fcbaf
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch
@@ -0,0 +1,124 @@
+From 5cb802766e9cdc9a56e8ce8e4686692ebbcfb5cc Mon Sep 17 00:00:00 2001
+From: Xenia Ragiadakou <burzalodowa@gmail.com>
+Date: Mon, 23 Dec 2013 16:59:02 +0100
+Subject: [PATCH 197/203] xhci: fix dma mask setup in xhci.c
+
+The function dma_set_mask() tests internally whether the dma_mask pointer
+for the device is initialized and fails if the dma_mask pointer is NULL.
+On pci platforms, the device dma_mask pointer is initialized, when pci
+devices are enumerated, to point to the pci_dev->dma_mask which is 0xffffffff.
+However, for non-pci platforms, the dma_mask pointer may not be initialized
+and in that case dma_set_mask() will fail.
+
+This patch initializes the dma_mask and the coherent_dma_mask to 32bits
+in xhci_plat_probe(), before the call to usb_create_hcd() that sets the
+"uses_dma" flag for the usb bus and the call to usb_add_hcd() that creates
+coherent dma pools for the usb hcd.
+
+Moreover, a call to dma_set_mask() does not set the device coherent_dma_mask.
+Since the xhci-hcd driver calls dma_alloc_coherent() and dma_pool_alloc()
+to allocate consistent DMA memory blocks, the coherent DMA address mask
+has to be set explicitly.
+
+This patch sets the coherent_dma_mask to 64bits in xhci_gen_setup() when
+the xHC is capable for 64-bit DMA addressing.
+
+If dma_set_mask() succeeds, for a given bitmask, it is guaranteed that
+the given bitmask is also supported for consistent DMA mappings.
+
+Other changes introduced in this patch are:
+
+- The return value of dma_set_mask() is checked to ensure that the required
+ dma bitmask conforms with the host system's addressing capabilities.
+
+- The dma_mask setup code for the non-primary hcd was removed since both
+ primary and non-primary hcd refer to the same generic device whose
+ dma_mask and coherent_dma_mask are already set during the setup of
+ the primary hcd.
+
+- The code for reading the HCCPARAMS register to find out the addressing
+ capabilities of xHC was removed since its value is already cached in
+ xhci->hccparams.
+
+- hcd->self.controller was replaced with the dev variable since it is
+ already available.
+
+Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+Conflicts:
+ drivers/usb/host/xhci-plat.c
+---
+ drivers/usb/host/xhci-plat.c | 10 ++++++++++
+ drivers/usb/host/xhci.c | 19 +++++--------------
+ 2 files changed, 15 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -15,6 +15,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/of.h>
++#include <linux/dma-mapping.h>
+
+ #include "xhci.h"
+
+@@ -105,6 +106,15 @@ static int xhci_plat_probe(struct platfo
+ if (!res)
+ return -ENODEV;
+
++ /* Initialize dma_mask and coherent_dma_mask to 32-bits */
++ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
++ if (ret)
++ return ret;
++ if (!pdev->dev.dma_mask)
++ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++ else
++ dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
++
+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4654,7 +4654,6 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ struct xhci_hcd *xhci;
+ struct device *dev = hcd->self.controller;
+ int retval;
+- u32 temp;
+
+ /* Accept arbitrarily long scatter-gather lists */
+ hcd->self.sg_tablesize = ~0;
+@@ -4682,14 +4681,6 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ /* xHCI private pointer was set in xhci_pci_probe for the second
+ * registered roothub.
+ */
+- xhci = hcd_to_xhci(hcd);
+- temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+- if (HCC_64BIT_ADDR(temp)) {
+- xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
+- dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
+- } else {
+- dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
+- }
+ return 0;
+ }
+
+@@ -4728,12 +4719,12 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ goto error;
+ xhci_dbg(xhci, "Reset complete\n");
+
+- temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+- if (HCC_64BIT_ADDR(temp)) {
++ /* Set dma_mask and coherent_dma_mask to 64-bits,
++ * if xHC supports 64-bit addressing */
++ if (HCC_64BIT_ADDR(xhci->hcc_params) &&
++ !dma_set_mask(dev, DMA_BIT_MASK(64))) {
+ xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
+- dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
+- } else {
+- dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
++ dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
+ }
+
+ xhci_dbg(xhci, "Calling HCD init\n");