Re: [U-Boot] [PATCH v3 2/2] gpio: dwapb_gpio: Add reset ctrl to driver
On Tue, Aug 28, 2018 at 5:53 PM Marek Vasut wrote: > > On 08/28/2018 06:07 PM, Ley Foon Tan wrote: > > Add code to reset all reset signals as in gpio DT node. A reset property > > is an optional feature, so only print out a warning and do not fail if a > > reset property is not present. > > > > If a reset property is discovered, then use it to deassert, thus > > bringing the IP out of reset. > > > > Signed-off-by: Ley Foon Tan > > > > --- > > v3: > > - Add .remove function. > > - Add error handling when return non-zero from reset_get_bulk(). > > > > v2: > > - Move reset to probe() function. > > --- > > drivers/gpio/dwapb_gpio.c | 42 -- > > 1 files changed, 40 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c > > index 7cf2d47..6394fa9 100644 > > --- a/drivers/gpio/dwapb_gpio.c > > +++ b/drivers/gpio/dwapb_gpio.c > > @@ -15,6 +15,7 @@ > > #include > > #include > > #include > > +#include > > > > DECLARE_GLOBAL_DATA_PTR; > > > > @@ -99,13 +100,42 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { > > .get_function = dwapb_gpio_get_function, > > }; > > > > +static int gpio_dwapb_reset(struct udevice *dev) > > +{ > > + int ret; > > + struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); > > + > > + ret = reset_get_bulk(dev, >resets); > > + if (ret) { > > + dev_warn(dev, "Can't get reset: %d\n", ret); > > + /* Return 0 if error due to !CONFIG_DM_RESET and reset > > + * DT property is not present. > > + */ > > + if (ret == -ENOENT || ret == -ENOTSUPP) > > + return 0; > > + else > > + return ret; > > + } > > + > > + ret = reset_deassert_bulk(>resets); > > + if (ret) { > > + reset_release_bulk(>resets); > > + dev_err(dev, "Failed to reset: %d\n", ret); > > + return ret; > > + } > > + > > + return 0; > > +} > > + > > static int gpio_dwapb_probe(struct udevice *dev) > > { > > struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); > > struct gpio_dwapb_platdata *plat = dev->platdata; > > > > - if (!plat) > > - return 0; > > + if (!plat) { > > + /* Reset on parent device only */ > > + return gpio_dwapb_reset(dev); > > + } > > > > priv->gpio_count = plat->pins; > > priv->bank_name = plat->name; > > @@ -166,6 +196,13 @@ err: > > return ret; > > } > > > > +static int gpio_dwapb_remove(struct udevice *dev) > > +{ > > + struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); > > You might want to assert the reset too. reset_release_bulk() function will assert the reset and free reset struct. > > > + return reset_release_bulk(>resets); > > +} > > + > > static const struct udevice_id gpio_dwapb_ids[] = { > > { .compatible = "snps,dw-apb-gpio" }, > > { } > > @@ -178,4 +215,5 @@ U_BOOT_DRIVER(gpio_dwapb) = { > > .ops= _dwapb_ops, > > .bind = gpio_dwapb_bind, > > .probe = gpio_dwapb_probe, > > + .remove = gpio_dwapb_remove, > > }; > > > > Regards Ley Foon ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH v3 2/2] gpio: dwapb_gpio: Add reset ctrl to driver
On 08/28/2018 06:07 PM, Ley Foon Tan wrote: > Add code to reset all reset signals as in gpio DT node. A reset property > is an optional feature, so only print out a warning and do not fail if a > reset property is not present. > > If a reset property is discovered, then use it to deassert, thus > bringing the IP out of reset. > > Signed-off-by: Ley Foon Tan > > --- > v3: > - Add .remove function. > - Add error handling when return non-zero from reset_get_bulk(). > > v2: > - Move reset to probe() function. > --- > drivers/gpio/dwapb_gpio.c | 42 -- > 1 files changed, 40 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c > index 7cf2d47..6394fa9 100644 > --- a/drivers/gpio/dwapb_gpio.c > +++ b/drivers/gpio/dwapb_gpio.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > > DECLARE_GLOBAL_DATA_PTR; > > @@ -99,13 +100,42 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { > .get_function = dwapb_gpio_get_function, > }; > > +static int gpio_dwapb_reset(struct udevice *dev) > +{ > + int ret; > + struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); > + > + ret = reset_get_bulk(dev, >resets); > + if (ret) { > + dev_warn(dev, "Can't get reset: %d\n", ret); > + /* Return 0 if error due to !CONFIG_DM_RESET and reset > + * DT property is not present. > + */ > + if (ret == -ENOENT || ret == -ENOTSUPP) > + return 0; > + else > + return ret; > + } > + > + ret = reset_deassert_bulk(>resets); > + if (ret) { > + reset_release_bulk(>resets); > + dev_err(dev, "Failed to reset: %d\n", ret); > + return ret; > + } > + > + return 0; > +} > + > static int gpio_dwapb_probe(struct udevice *dev) > { > struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); > struct gpio_dwapb_platdata *plat = dev->platdata; > > - if (!plat) > - return 0; > + if (!plat) { > + /* Reset on parent device only */ > + return gpio_dwapb_reset(dev); > + } > > priv->gpio_count = plat->pins; > priv->bank_name = plat->name; > @@ -166,6 +196,13 @@ err: > return ret; > } > > +static int gpio_dwapb_remove(struct udevice *dev) > +{ > + struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); You might want to assert the reset too. > + return reset_release_bulk(>resets); > +} > + > static const struct udevice_id gpio_dwapb_ids[] = { > { .compatible = "snps,dw-apb-gpio" }, > { } > @@ -178,4 +215,5 @@ U_BOOT_DRIVER(gpio_dwapb) = { > .ops= _dwapb_ops, > .bind = gpio_dwapb_bind, > .probe = gpio_dwapb_probe, > + .remove = gpio_dwapb_remove, > }; > -- Best regards, Marek Vasut ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v3 2/2] gpio: dwapb_gpio: Add reset ctrl to driver
Add code to reset all reset signals as in gpio DT node. A reset property is an optional feature, so only print out a warning and do not fail if a reset property is not present. If a reset property is discovered, then use it to deassert, thus bringing the IP out of reset. Signed-off-by: Ley Foon Tan --- v3: - Add .remove function. - Add error handling when return non-zero from reset_get_bulk(). v2: - Move reset to probe() function. --- drivers/gpio/dwapb_gpio.c | 42 -- 1 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..6394fa9 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -99,13 +100,42 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, }; +static int gpio_dwapb_reset(struct udevice *dev) +{ + int ret; + struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); + + ret = reset_get_bulk(dev, >resets); + if (ret) { + dev_warn(dev, "Can't get reset: %d\n", ret); + /* Return 0 if error due to !CONFIG_DM_RESET and reset +* DT property is not present. +*/ + if (ret == -ENOENT || ret == -ENOTSUPP) + return 0; + else + return ret; + } + + ret = reset_deassert_bulk(>resets); + if (ret) { + reset_release_bulk(>resets); + dev_err(dev, "Failed to reset: %d\n", ret); + return ret; + } + + return 0; +} + static int gpio_dwapb_probe(struct udevice *dev) { struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); struct gpio_dwapb_platdata *plat = dev->platdata; - if (!plat) - return 0; + if (!plat) { + /* Reset on parent device only */ + return gpio_dwapb_reset(dev); + } priv->gpio_count = plat->pins; priv->bank_name = plat->name; @@ -166,6 +196,13 @@ err: return ret; } +static int gpio_dwapb_remove(struct udevice *dev) +{ + struct gpio_dev_priv *priv = dev_get_uclass_priv(dev); + + return reset_release_bulk(>resets); +} + static const struct udevice_id gpio_dwapb_ids[] = { { .compatible = "snps,dw-apb-gpio" }, { } @@ -178,4 +215,5 @@ U_BOOT_DRIVER(gpio_dwapb) = { .ops= _dwapb_ops, .bind = gpio_dwapb_bind, .probe = gpio_dwapb_probe, + .remove = gpio_dwapb_remove, }; -- 1.7.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot