diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index ff151ec084c402c75ce0d634dbd9be622cba19bd..43c1a4e06767d60a58f6f0c1df808c22ea5a8fdc 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt @@ -15,6 +15,7 @@ Optional properties: - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" + - resets : phandle + reset specifier pair Example (Sequoia 440EPx): ehci@e0000300 { diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index c7dd93aad20c59c4ace574a5e25a507bb267baa1..2f5b9ce3e042f7473b359740a73bf782090ba936 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ struct ehci_platform_priv { struct clk *clks[EHCI_MAX_CLKS]; + struct reset_control *rst; struct phy *phy; }; @@ -208,6 +210,18 @@ static int ehci_platform_probe(struct platform_device *dev) } } + priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); + if (IS_ERR(priv->rst)) { + err = PTR_ERR(priv->rst); + if (err == -EPROBE_DEFER) + goto err_put_clks; + priv->rst = NULL; + } else { + err = reset_control_deassert(priv->rst); + if (err) + goto err_put_clks; + } + if (pdata->big_endian_desc) ehci->big_endian_desc = 1; if (pdata->big_endian_mmio) @@ -218,7 +232,7 @@ static int ehci_platform_probe(struct platform_device *dev) dev_err(&dev->dev, "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n"); err = -EINVAL; - goto err_put_clks; + goto err_reset; } #endif #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC @@ -226,14 +240,14 @@ static int ehci_platform_probe(struct platform_device *dev) dev_err(&dev->dev, "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n"); err = -EINVAL; - goto err_put_clks; + goto err_reset; } #endif if (pdata->power_on) { err = pdata->power_on(dev); if (err < 0) - goto err_put_clks; + goto err_reset; } hcd->rsrc_start = res_mem->start; @@ -256,6 +270,9 @@ static int ehci_platform_probe(struct platform_device *dev) err_power: if (pdata->power_off) pdata->power_off(dev); +err_reset: + if (priv->rst) + reset_control_assert(priv->rst); err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); @@ -280,6 +297,9 @@ static int ehci_platform_remove(struct platform_device *dev) if (pdata->power_off) pdata->power_off(dev); + if (priv->rst) + reset_control_assert(priv->rst); + for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) clk_put(priv->clks[clk]);