diff options
author | Arnd Bergmann <arnd@arndb.de> | 2017-03-13 10:18:44 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-23 08:20:21 +0100 |
commit | 4c39d4b949d36faffbc726525b469886cf311d1c (patch) | |
tree | 282a26b4ab609647b94eb9080e88e74ef52dd59c /drivers/usb/host/xhci-plat.c | |
parent | 8123e4953fe6c1d3303d23eefe5e41d2934e2a06 (diff) | |
download | linux-4c39d4b949d36faffbc726525b469886cf311d1c.tar.bz2 |
usb: xhci: use bus->sysdev for DMA configuration
For xhci-hcd platform device, all the DMA parameters are not
configured properly, notably dma ops for dwc3 devices. So, set
the dma for xhci from sysdev. sysdev is pointing to device that
is known to the system firmware or hardware.
Cc: Baolin Wang <baolin.wang@linaro.org>
Tested-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Tested-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-plat.c')
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index bd02a6cd8e2c..fa97826d0058 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -14,6 +14,7 @@ #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/module.h> +#include <linux/pci.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/usb/phy.h> @@ -148,6 +149,7 @@ static int xhci_plat_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct hc_driver *driver; + struct device *sysdev; struct xhci_hcd *xhci; struct resource *res; struct usb_hcd *hcd; @@ -164,22 +166,39 @@ static int xhci_plat_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; + /* + * sysdev must point to a device that is known to the system firmware + * or PCI hardware. We handle these three cases here: + * 1. xhci_plat comes from firmware + * 2. xhci_plat is child of a device from firmware (dwc3-plat) + * 3. xhci_plat is grandchild of a pci device (dwc3-pci) + */ + sysdev = &pdev->dev; + if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) + sysdev = sysdev->parent; +#ifdef CONFIG_PCI + else if (sysdev->parent && sysdev->parent->parent && + sysdev->parent->parent->bus == &pci_bus_type) + sysdev = sysdev->parent->parent; +#endif + /* Try to set 64-bit DMA first */ - if (!pdev->dev.dma_mask) + if (WARN_ON(!sysdev->dma_mask)) /* Platform did not initialize dma_mask */ - ret = dma_coerce_mask_and_coherent(&pdev->dev, + ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64)); else - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64)); /* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */ if (ret) { - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32)); if (ret) return ret; } - hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); + hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, + dev_name(&pdev->dev), NULL); if (!hcd) return -ENOMEM; @@ -222,20 +241,20 @@ static int xhci_plat_probe(struct platform_device *pdev) xhci->clk = clk; xhci->main_hcd = hcd; - xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, + xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, dev_name(&pdev->dev), hcd); if (!xhci->shared_hcd) { ret = -ENOMEM; goto disable_clk; } - if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) + if (device_property_read_bool(sysdev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) xhci->quirks |= XHCI_BROKEN_PORT_PED; - hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); + hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); if (IS_ERR(hcd->usb_phy)) { ret = PTR_ERR(hcd->usb_phy); if (ret == -EPROBE_DEFER) |