static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
{
+ struct usb_xhci_pdata *pdata = dev_get_platdata(dev);
+
/*
* As of now platform drivers don't provide MSI support so we ensure
* here that the generic code does not try to make a pci_dev from our
* dev struct in order to setup MSI
*/
xhci->quirks |= XHCI_PLAT;
+
+ /*
+ * On some xHCI controllers (e.g. Rockchip SoCs), it need an
+ * extraordinary delay to wait for xHCI enter the Halted state
+ * after the Run/Stop (R/S) bit is cleared to '0'.
+ */
+ if (pdata && pdata->xhci_slow_suspend)
+ xhci->quirks |= XHCI_SLOW_SUSPEND;
}
/* called during probe() after chip reset completes */
ret = clk_prepare_enable(clk);
if (ret)
goto put_hcd;
+ } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto put_hcd;
}
if (of_device_is_compatible(pdev->dev.of_node,
(pdata && pdata->usb3_lpm_capable))
xhci->quirks |= XHCI_LPM_SUPPORT;
- if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
- xhci->shared_hcd->can_do_streams = 1;
+ if (pdata && pdata->usb3_disable_autosuspend)
+ xhci->quirks |= XHCI_DIS_AUTOSUSPEND;
+
+ xhci->shared_hcd->usb_phy = devm_usb_get_phy(&pdev->dev,
+ USB_PHY_TYPE_USB3);
+ if (IS_ERR(xhci->shared_hcd->usb_phy)) {
+ ret = PTR_ERR(xhci->shared_hcd->usb_phy);
+ if (ret == -EPROBE_DEFER)
+ goto put_usb3_hcd;
+ xhci->shared_hcd->usb_phy = NULL;
+ }
hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
if (IS_ERR(hcd->usb_phy)) {
if (ret)
goto dealloc_usb2_hcd;
+ if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+ xhci->shared_hcd->can_do_streams = 1;
+
return 0;
static struct platform_driver usb_xhci_driver = {
.probe = xhci_plat_probe,
.remove = xhci_plat_remove,
+ .shutdown = usb_hcd_platform_shutdown,
.driver = {
.name = "xhci-hcd",
.pm = DEV_PM_OPS,