[U-Boot] [PATCH v2] 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 ley.foon.tan@intel.com
--- v2: - Move reset to probe() function. --- drivers/gpio/dwapb_gpio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..dfe1e6d 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include <dm/lists.h> #include <dm/root.h> #include <errno.h> +#include <reset.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,13 +100,30 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, };
+static void gpio_dwapb_reset(struct udevice *dev) +{ + struct reset_ctl_bulk reset_bulk; + int ret; + + ret = reset_get_bulk(dev, &reset_bulk); + if (ret) { + dev_warn(dev, "Can't get reset: %d\n", ret); + return; + } + + reset_deassert_bulk(&reset_bulk); +} + 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) + if (!plat) { + /* Reset on parent device only */ + gpio_dwapb_reset(dev); return 0; + }
priv->gpio_count = plat->pins; priv->bank_name = plat->name;

Enabled get_function support for dwapb where the function will return the state of GPIO port.
Signed-off-by: Chin Liang See chin.liang.see@intel.com Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com
--- v2: Change to use "if (gpio & BIT(offset))" bit masking. --- drivers/gpio/dwapb_gpio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 680b11a..7cf2d47 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -78,11 +78,25 @@ static int dwapb_gpio_set_value(struct udevice *dev, unsigned pin, int val) return 0; }
+static int dwapb_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct gpio_dwapb_platdata *plat = dev_get_platdata(dev); + u32 gpio; + + gpio = readl(plat->base + GPIO_SWPORT_DDR(plat->bank)); + + if (gpio & BIT(offset)) + return GPIOF_OUTPUT; + else + return GPIOF_INPUT; +} + static const struct dm_gpio_ops gpio_dwapb_ops = { .direction_input = dwapb_gpio_direction_input, .direction_output = dwapb_gpio_direction_output, .get_value = dwapb_gpio_get_value, .set_value = dwapb_gpio_set_value, + .get_function = dwapb_gpio_get_function, };
static int gpio_dwapb_probe(struct udevice *dev)

On 08/16/2018 07:46 AM, 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 ley.foon.tan@intel.com
v2:
- Move reset to probe() function.
drivers/gpio/dwapb_gpio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..dfe1e6d 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include <dm/lists.h> #include <dm/root.h> #include <errno.h> +#include <reset.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,13 +100,30 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, };
+static void gpio_dwapb_reset(struct udevice *dev) +{
- struct reset_ctl_bulk reset_bulk;
- int ret;
- ret = reset_get_bulk(dev, &reset_bulk);
- if (ret) {
dev_warn(dev, "Can't get reset: %d\n", ret);
return;
- }
- reset_deassert_bulk(&reset_bulk);
+}
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)
if (!plat) {
/* Reset on parent device only */
gpio_dwapb_reset(dev);
return 0;
}
priv->gpio_count = plat->pins; priv->bank_name = plat->name;
What about .remove() and reset_release ?

On Thu, Aug 16, 2018 at 4:28 PM, Marek Vasut marex@denx.de wrote:
On 08/16/2018 07:46 AM, 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 ley.foon.tan@intel.com
v2:
- Move reset to probe() function.
drivers/gpio/dwapb_gpio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..dfe1e6d 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include <dm/lists.h> #include <dm/root.h> #include <errno.h> +#include <reset.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,13 +100,30 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, };
+static void gpio_dwapb_reset(struct udevice *dev) +{
struct reset_ctl_bulk reset_bulk;
int ret;
ret = reset_get_bulk(dev, &reset_bulk);
if (ret) {
dev_warn(dev, "Can't get reset: %d\n", ret);
return;
}
reset_deassert_bulk(&reset_bulk);
+}
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)
if (!plat) {
/* Reset on parent device only */
gpio_dwapb_reset(dev); return 0;
} priv->gpio_count = plat->pins; priv->bank_name = plat->name;
What about .remove() and reset_release ?
This driver doesn't implement .remove, should we add this to assert reset?
Regards Ley Foon

On 08/16/2018 10:39 AM, Ley Foon Tan wrote:
On Thu, Aug 16, 2018 at 4:28 PM, Marek Vasut marex@denx.de wrote:
On 08/16/2018 07:46 AM, 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 ley.foon.tan@intel.com
v2:
- Move reset to probe() function.
drivers/gpio/dwapb_gpio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..dfe1e6d 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include <dm/lists.h> #include <dm/root.h> #include <errno.h> +#include <reset.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,13 +100,30 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, };
+static void gpio_dwapb_reset(struct udevice *dev) +{
struct reset_ctl_bulk reset_bulk;
int ret;
ret = reset_get_bulk(dev, &reset_bulk);
if (ret) {
dev_warn(dev, "Can't get reset: %d\n", ret);
return;
}
reset_deassert_bulk(&reset_bulk);
+}
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)
if (!plat) {
/* Reset on parent device only */
gpio_dwapb_reset(dev); return 0;
} priv->gpio_count = plat->pins; priv->bank_name = plat->name;
What about .remove() and reset_release ?
This driver doesn't implement .remove, should we add this to assert reset?
Yes

On Thu, Aug 16, 2018 at 4:46 PM, Marek Vasut marex@denx.de wrote:
On 08/16/2018 10:39 AM, Ley Foon Tan wrote:
On Thu, Aug 16, 2018 at 4:28 PM, Marek Vasut marex@denx.de wrote:
On 08/16/2018 07:46 AM, 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 ley.foon.tan@intel.com
v2:
- Move reset to probe() function.
drivers/gpio/dwapb_gpio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..dfe1e6d 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include <dm/lists.h> #include <dm/root.h> #include <errno.h> +#include <reset.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,13 +100,30 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, };
+static void gpio_dwapb_reset(struct udevice *dev) +{
struct reset_ctl_bulk reset_bulk;
int ret;
ret = reset_get_bulk(dev, &reset_bulk);
if (ret) {
dev_warn(dev, "Can't get reset: %d\n", ret);
return;
}
reset_deassert_bulk(&reset_bulk);
+}
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)
if (!plat) {
/* Reset on parent device only */
gpio_dwapb_reset(dev); return 0;
} priv->gpio_count = plat->pins; priv->bank_name = plat->name;
What about .remove() and reset_release ?
This driver doesn't implement .remove, should we add this to assert reset?
Yes
Okay, will try to add it.
BTW, when .remove will be call in Uboot?
Regards Ley Foon

On 08/16/2018 11:39 AM, Ley Foon Tan wrote:
On Thu, Aug 16, 2018 at 4:46 PM, Marek Vasut marex@denx.de wrote:
On 08/16/2018 10:39 AM, Ley Foon Tan wrote:
On Thu, Aug 16, 2018 at 4:28 PM, Marek Vasut marex@denx.de wrote:
On 08/16/2018 07:46 AM, 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 ley.foon.tan@intel.com
v2:
- Move reset to probe() function.
drivers/gpio/dwapb_gpio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c index 7cf2d47..dfe1e6d 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -15,6 +15,7 @@ #include <dm/lists.h> #include <dm/root.h> #include <errno.h> +#include <reset.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,13 +100,30 @@ static const struct dm_gpio_ops gpio_dwapb_ops = { .get_function = dwapb_gpio_get_function, };
+static void gpio_dwapb_reset(struct udevice *dev) +{
struct reset_ctl_bulk reset_bulk;
int ret;
ret = reset_get_bulk(dev, &reset_bulk);
if (ret) {
dev_warn(dev, "Can't get reset: %d\n", ret);
return;
}
reset_deassert_bulk(&reset_bulk);
+}
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)
if (!plat) {
/* Reset on parent device only */
gpio_dwapb_reset(dev); return 0;
} priv->gpio_count = plat->pins; priv->bank_name = plat->name;
What about .remove() and reset_release ?
This driver doesn't implement .remove, should we add this to assert reset?
Yes
Okay, will try to add it.
BTW, when .remove will be call in Uboot?
When removing the driver and possibly before booting Linux.
participants (3)
-
Ley Foon Tan
-
Ley Foon Tan
-
Marek Vasut