From a762345c7c331cf0c80819ab2fc368f3cec0a4e9 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Sat, 3 Jun 2017 20:11:54 -0700 Subject: usb-nop-xceiv: Add support for 'reset-gpios' binding Cc: cphealy@gmail.com Cc: Nikita Yushchenko Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/phy/usb-nop-xceiv.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'drivers/phy') diff --git a/drivers/phy/usb-nop-xceiv.c b/drivers/phy/usb-nop-xceiv.c index d403fe4d66..b124e6c0c4 100644 --- a/drivers/phy/usb-nop-xceiv.c +++ b/drivers/phy/usb-nop-xceiv.c @@ -22,12 +22,15 @@ #include #include #include +#include +#include struct nop_usbphy { struct usb_phy usb_phy; struct phy *phy; struct phy_provider *provider; struct clk *clk; + int reset; }; static struct phy *nop_usbphy_xlate(struct device_d *dev, @@ -40,9 +43,22 @@ static struct phy *nop_usbphy_xlate(struct device_d *dev, static int nop_usbphy_init(struct phy *phy) { + int ret; struct nop_usbphy *nopphy = phy_get_drvdata(phy); - return clk_enable(nopphy->clk); + ret = clk_enable(nopphy->clk); + if (ret < 0) + return ret; + + if (gpio_is_valid(nopphy->reset)) { + /* + * Let's wait for 100 ms before deasserting reset line + */ + mdelay(100); + gpio_set_active(nopphy->reset, false); + } + + return 0; } static struct usb_phy *nop_usbphy_to_usbphy(struct phy *phy) @@ -61,6 +77,9 @@ static int nop_usbphy_probe(struct device_d *dev) { int ret; struct nop_usbphy *nopphy; + enum of_gpio_flags of_flags; + char *name = NULL; + unsigned long flags = GPIOF_OUT_INIT_ACTIVE; nopphy = xzalloc(sizeof(*nopphy)); @@ -70,6 +89,20 @@ static int nop_usbphy_probe(struct device_d *dev) if (IS_ERR(nopphy->clk)) nopphy->clk = NULL; + nopphy->reset = of_get_named_gpio_flags(dev->device_node, + "reset-gpios", 0, &of_flags); + if (gpio_is_valid(nopphy->reset)) { + /* assert reset */ + + if (of_flags & OF_GPIO_ACTIVE_LOW) + flags |= GPIOF_ACTIVE_LOW; + + name = basprintf("%s reset", dev_name(dev)); + ret = gpio_request_one(nopphy->reset, flags, name); + if (ret < 0) + goto err_free; + } + /* FIXME: Add vbus regulator support */ /* FIXME: Add vbus-detect-gpio support */ @@ -77,7 +110,7 @@ static int nop_usbphy_probe(struct device_d *dev) nopphy->phy = phy_create(dev, NULL, &nop_phy_ops, NULL); if (IS_ERR(nopphy->phy)) { ret = PTR_ERR(nopphy->phy); - goto err_free; + goto release_gpio; } phy_set_drvdata(nopphy->phy, nopphy); @@ -85,13 +118,17 @@ static int nop_usbphy_probe(struct device_d *dev) nopphy->provider = of_phy_provider_register(dev, nop_usbphy_xlate); if (IS_ERR(nopphy->provider)) { ret = PTR_ERR(nopphy->provider); - goto err_free; + goto release_gpio; } return 0; + +release_gpio: + if (gpio_is_valid(nopphy->reset)) + gpio_free(nopphy->reset); err_free: free(nopphy); - + free(name); return ret; }; -- cgit v1.2.3