[PATCH 2/2] gpio/mxc: implement reading output gpio value

From: Eduardo Valentin
Date: Wed Aug 05 2015 - 13:23:43 EST


In current implementation, reading the value of an output gpio
always return 0. The reason is because when a gpio is configured
as output, its output status can be read from the GPIO_DR register,
and when it is configure as input, its value can be read from
GPIO_PSR. With current implementation of basic mmio gpio driver,
we can only read the value from one single register.

Therefore, to workaround the basic mmio gpio driver limitation,
this patch changes the gpio-mxc driver to provide its own .get
callback. In the callback, we check the current status of the
gpio direction, and read the correct register based on its
current gpio direction status.

Cc: Linus Walleij <linus.walleij@xxxxxxxxxx>
Cc: Alexandre Courbot <gnurou@xxxxxxxxx>
Cc: linux-gpio@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Signed-off-by: Ulises Brindis <ubrindis56@xxxxxxxxx>
Signed-off-by: Eduardo Valentin <edubezval@xxxxxxxxx>
---
drivers/gpio/gpio-mxc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 9e5bdbd..8822823 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -401,6 +401,18 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return irq_find_mapping(port->domain, offset);
}

+static int mxc_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+
+ if (!!(bgc->read_reg(bgc->reg_dir) & bgc->pin2mask(bgc, gpio)))
+ return !!(bgc->read_reg(bgc->reg_set) &
+ bgc->pin2mask(bgc, gpio));
+ else
+ return !!(bgc->read_reg(bgc->reg_dat) &
+ bgc->pin2mask(bgc, gpio));
+}
+
static int mxc_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -455,6 +467,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (err)
goto out_bgio;

+ port->bgc.gc.get = mxc_gpio_get;
port->bgc.gc.to_irq = mxc_gpio_to_irq;
port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
pdev->id * 32;
--
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/