There are cases when the bootloader configures a pin to work
as a function rather than GPIO, and other cases when the pin
is configured as a function at POR.
This commit makes sure the pin is configured as a GPIO the
moment we need it to work as an interrupt.

Signed-off-by: Fabrizio Castro <fabrizio.cas...@bp.renesas.com>

---
v1->v2:
* Moved gpio_rcar_request call from gpio_rcar_irq_set_type to
  rcar_gpio_irq_request_resources
* Added rcar_gpio_irq_release_resources for calling gpio_rcar_free

Comments very welcome!

 drivers/gpio/gpio-rcar.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index 3c82bb3..c16598b 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -344,6 +344,29 @@ static int gpio_rcar_direction_output(struct gpio_chip 
*chip, unsigned offset,
        return 0;
 }
 
+static int rcar_gpio_irq_request_resources(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct gpio_rcar_priv *p = gpiochip_get_data(gc);
+       unsigned int hwirq = irqd_to_hwirq(d);
+       int err;
+
+       gpio_rcar_direction_input(gc, hwirq);
+       err = gpio_rcar_request(gc, hwirq);
+       if (err)
+               dev_err(&p->pdev->dev, "Can't request GPIO %u from %s\n", hwirq,
+                       gc->label);
+       return err;
+}
+
+static void rcar_gpio_irq_release_resources(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       unsigned int hwirq = irqd_to_hwirq(d);
+
+       gpio_rcar_free(gc, hwirq);
+}
+
 struct gpio_rcar_info {
        bool has_both_edge_trigger;
 };
@@ -491,6 +514,8 @@ static int gpio_rcar_probe(struct platform_device *pdev)
        irq_chip->irq_set_type = gpio_rcar_irq_set_type;
        irq_chip->irq_set_wake = gpio_rcar_irq_set_wake;
        irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;
+       irq_chip->irq_request_resources = rcar_gpio_irq_request_resources;
+       irq_chip->irq_release_resources = rcar_gpio_irq_release_resources;
 
        ret = gpiochip_add_data(gpio_chip, p);
        if (ret) {
-- 
2.7.4

Reply via email to