aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpio/dwapb_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/dwapb_gpio.c')
-rw-r--r--drivers/gpio/dwapb_gpio.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index e5e3518194..37916e7771 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -40,7 +40,7 @@ struct gpio_dwapb_platdata {
const char *name;
int bank;
int pins;
- fdt_addr_t base;
+ void __iomem *base;
};
static int dwapb_gpio_direction_input(struct udevice *dev, unsigned pin)
@@ -66,13 +66,6 @@ static int dwapb_gpio_direction_output(struct udevice *dev, unsigned pin,
return 0;
}
-static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
-{
- struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
- return !!(readl(plat->base + GPIO_EXT_PORT(plat->bank)) & (1 << pin));
-}
-
-
static int dwapb_gpio_set_value(struct udevice *dev, unsigned pin, int val)
{
struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
@@ -98,6 +91,18 @@ static int dwapb_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
+static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
+{
+ struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
+ u32 value;
+
+ if (dwapb_gpio_get_function(dev, pin) == GPIOF_OUTPUT)
+ value = readl(plat->base + GPIO_SWPORT_DR(plat->bank));
+ else
+ value = readl(plat->base + GPIO_EXT_PORT(plat->bank));
+ return !!(value & BIT(pin));
+}
+
static const struct dm_gpio_ops gpio_dwapb_ops = {
.direction_input = dwapb_gpio_direction_input,
.direction_output = dwapb_gpio_direction_output,
@@ -176,7 +181,7 @@ static int gpio_dwapb_bind(struct udevice *dev)
if (!plat)
return -ENOMEM;
- plat->base = base;
+ plat->base = (void *)base;
plat->bank = bank;
plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0);
@@ -186,7 +191,15 @@ static int gpio_dwapb_bind(struct udevice *dev)
* Fall back to node name. This means accessing pins
* via bank name won't work.
*/
- plat->name = ofnode_get_name(node);
+ char name[32];
+
+ snprintf(name, sizeof(name), "%s_",
+ ofnode_get_name(node));
+ plat->name = strdup(name);
+ if (!plat->name) {
+ kfree(plat);
+ return -ENOMEM;
+ }
}
ret = device_bind_ofnode(dev, dev->driver, plat->name,