diff options
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.patch | 124 |
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 0000000000..84fcbafb5b --- /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"); |