|
|
|
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
|
|
|
|
@@ -4657,7 +4657,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;
|
|
|
|
@@ -4685,14 +4684,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;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -4731,12 +4722,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");
|