diff options
Diffstat (limited to 'drivers/usb/phy/phy-generic.c')
-rw-r--r-- | drivers/usb/phy/phy-generic.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 89d6e7a5fdb7..08b8875ac520 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -57,28 +57,35 @@ void usb_phy_generic_unregister(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(usb_phy_generic_unregister); -static int nop_set_suspend(struct usb_phy *x, int suspend) +static void nop_reset(struct usb_phy_generic *nop) { - struct usb_phy_generic *nop = dev_get_drvdata(x->dev); + if (!nop->gpiod_reset) + return; - if (!IS_ERR(nop->clk)) { - if (suspend) - clk_disable_unprepare(nop->clk); - else - clk_prepare_enable(nop->clk); - } + dev_dbg(nop->dev, "reset\n"); - return 0; + gpiod_set_value_cansleep(nop->gpiod_reset, 1); + usleep_range(10000, 20000); + gpiod_set_value_cansleep(nop->gpiod_reset, 0); } -static void nop_reset(struct usb_phy_generic *nop) +static int nop_set_suspend(struct usb_phy *x, int suspend) { - if (!nop->gpiod_reset) - return; + struct usb_phy_generic *nop = dev_get_drvdata(x->dev); - gpiod_set_value(nop->gpiod_reset, 1); - usleep_range(10000, 20000); - gpiod_set_value(nop->gpiod_reset, 0); + dev_dbg(x->dev, "%s\n", suspend ? "suspend" : "resume"); + + if (suspend) { + if (!IS_ERR(nop->clk)) + clk_disable_unprepare(nop->clk); + } else { + if (!IS_ERR(nop->clk)) + clk_prepare_enable(nop->clk); + + if (nop->reset_on_resume) + nop_reset(nop); + } + return 0; } /* interface to regulator framework */ @@ -172,7 +179,7 @@ void usb_gen_phy_shutdown(struct usb_phy *phy) { struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); - gpiod_set_value(nop->gpiod_reset, 1); + gpiod_set_value_cansleep(nop->gpiod_reset, 1); if (!IS_ERR(nop->clk)) clk_disable_unprepare(nop->clk); @@ -232,6 +239,9 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; + nop->reset_on_resume = + of_property_read_bool(node, "reset-on-resume"); + needs_vcc = of_property_read_bool(node, "vcc-supply"); nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); @@ -241,6 +251,8 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, "vbus-detect", GPIOD_ASIS); err = PTR_ERR_OR_ZERO(nop->gpiod_vbus); + } else { + nop->gpiod_reset = NULL; } } else if (pdata) { type = pdata->type; |