|
@@ -157,6 +157,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
|
|
struct resource *res;
|
|
|
struct usb_hcd *hcd;
|
|
|
struct clk *clk;
|
|
|
+ struct clk *reg_clk;
|
|
|
int ret;
|
|
|
int irq;
|
|
|
|
|
@@ -226,17 +227,27 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
|
|
hcd->rsrc_len = resource_size(res);
|
|
|
|
|
|
/*
|
|
|
- * Not all platforms have a clk so it is not an error if the
|
|
|
- * clock does not exists.
|
|
|
+ * Not all platforms have clks so it is not an error if the
|
|
|
+ * clock do not exist.
|
|
|
*/
|
|
|
+ reg_clk = devm_clk_get(&pdev->dev, "reg");
|
|
|
+ if (!IS_ERR(reg_clk)) {
|
|
|
+ ret = clk_prepare_enable(reg_clk);
|
|
|
+ if (ret)
|
|
|
+ goto put_hcd;
|
|
|
+ } else if (PTR_ERR(reg_clk) == -EPROBE_DEFER) {
|
|
|
+ ret = -EPROBE_DEFER;
|
|
|
+ goto put_hcd;
|
|
|
+ }
|
|
|
+
|
|
|
clk = devm_clk_get(&pdev->dev, NULL);
|
|
|
if (!IS_ERR(clk)) {
|
|
|
ret = clk_prepare_enable(clk);
|
|
|
if (ret)
|
|
|
- goto put_hcd;
|
|
|
+ goto disable_reg_clk;
|
|
|
} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
|
|
|
ret = -EPROBE_DEFER;
|
|
|
- goto put_hcd;
|
|
|
+ goto disable_reg_clk;
|
|
|
}
|
|
|
|
|
|
xhci = hcd_to_xhci(hcd);
|
|
@@ -252,6 +263,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
|
|
device_wakeup_enable(hcd->self.controller);
|
|
|
|
|
|
xhci->clk = clk;
|
|
|
+ xhci->reg_clk = reg_clk;
|
|
|
xhci->main_hcd = hcd;
|
|
|
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
|
|
|
dev_name(&pdev->dev), hcd);
|
|
@@ -322,6 +334,9 @@ put_usb3_hcd:
|
|
|
disable_clk:
|
|
|
clk_disable_unprepare(clk);
|
|
|
|
|
|
+disable_reg_clk:
|
|
|
+ clk_disable_unprepare(reg_clk);
|
|
|
+
|
|
|
put_hcd:
|
|
|
usb_put_hcd(hcd);
|
|
|
|
|
@@ -337,6 +352,7 @@ static int xhci_plat_remove(struct platform_device *dev)
|
|
|
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
|
|
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
|
|
struct clk *clk = xhci->clk;
|
|
|
+ struct clk *reg_clk = xhci->reg_clk;
|
|
|
|
|
|
xhci->xhc_state |= XHCI_STATE_REMOVING;
|
|
|
|
|
@@ -347,6 +363,7 @@ static int xhci_plat_remove(struct platform_device *dev)
|
|
|
usb_put_hcd(xhci->shared_hcd);
|
|
|
|
|
|
clk_disable_unprepare(clk);
|
|
|
+ clk_disable_unprepare(reg_clk);
|
|
|
usb_put_hcd(hcd);
|
|
|
|
|
|
pm_runtime_set_suspended(&dev->dev);
|