diff options
Diffstat (limited to 'drivers/usb/host/xhci-plat.c')
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 649ffd861b44..044855818cb1 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -180,7 +180,7 @@ static int xhci_plat_probe(struct platform_device *pdev) struct device *sysdev, *tmpdev; struct xhci_hcd *xhci; struct resource *res; - struct usb_hcd *hcd; + struct usb_hcd *hcd, *usb3_hcd; int ret; int irq; struct xhci_plat_priv *priv = NULL; @@ -245,6 +245,8 @@ static int xhci_plat_probe(struct platform_device *pdev) xhci = hcd_to_xhci(hcd); + xhci->allow_single_roothub = 1; + /* * Not all platforms have clks so it is not an error if the * clock do not exist. @@ -283,12 +285,6 @@ static int xhci_plat_probe(struct platform_device *pdev) device_set_wakeup_capable(&pdev->dev, true); xhci->main_hcd = hcd; - xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, - dev_name(&pdev->dev), hcd); - if (!xhci->shared_hcd) { - ret = -ENOMEM; - goto disable_clk; - } /* imod_interval is the interrupt moderation value in nanoseconds. */ xhci->imod_interval = 40000; @@ -313,16 +309,16 @@ static int xhci_plat_probe(struct platform_device *pdev) if (IS_ERR(hcd->usb_phy)) { ret = PTR_ERR(hcd->usb_phy); if (ret == -EPROBE_DEFER) - goto put_usb3_hcd; + goto disable_clk; hcd->usb_phy = NULL; } else { ret = usb_phy_init(hcd->usb_phy); if (ret) - goto put_usb3_hcd; + goto disable_clk; } hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); - xhci->shared_hcd->tpl_support = hcd->tpl_support; + if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)) hcd->skip_phy_initialization = 1; @@ -333,12 +329,26 @@ static int xhci_plat_probe(struct platform_device *pdev) if (ret) goto disable_usb_phy; - if (HCC_MAX_PSA(xhci->hcc_params) >= 4) - xhci->shared_hcd->can_do_streams = 1; + if (!xhci_has_one_roothub(xhci)) { + xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, + dev_name(&pdev->dev), hcd); + if (!xhci->shared_hcd) { + ret = -ENOMEM; + goto dealloc_usb2_hcd; + } - ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); - if (ret) - goto dealloc_usb2_hcd; + xhci->shared_hcd->tpl_support = hcd->tpl_support; + } + + usb3_hcd = xhci_get_usb3_hcd(xhci); + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4) + usb3_hcd->can_do_streams = 1; + + if (xhci->shared_hcd) { + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); + if (ret) + goto put_usb3_hcd; + } device_enable_async_suspend(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); @@ -352,15 +362,15 @@ static int xhci_plat_probe(struct platform_device *pdev) return 0; +put_usb3_hcd: + usb_put_hcd(xhci->shared_hcd); + dealloc_usb2_hcd: usb_remove_hcd(hcd); disable_usb_phy: usb_phy_shutdown(hcd->usb_phy); -put_usb3_hcd: - usb_put_hcd(xhci->shared_hcd); - disable_clk: clk_disable_unprepare(xhci->clk); |