Commit 3e8e505a authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Kamal Mostafa

gpio: rcar: Add Runtime PM handling for interrupts

commit b26a719b upstream.

The R-Car GPIO driver handles Runtime PM for requested GPIOs only.

When using a GPIO purely as an interrupt source, no Runtime PM handling
is done, and the GPIO module's clock may not be enabled.

To fix this:
  - Add .irq_request_resources() and .irq_release_resources() callbacks
    to handle Runtime PM when an interrupt is requested,
  - Add irq_bus_lock() and sync_unlock() callbacks to handle Runtime PM
    when e.g. disabling/enabling an interrupt, or configuring the
    interrupt type.

Fixes: d5c3d846 "net: phy: Avoid polling PHY with PHY_IGNORE_INTERRUPTS"
Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
[ luis: backported to 3.16:
  - use gpio_to_priv() instead of gpiochip_get_data()
  - adjusted context ]
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent ed15c603
......@@ -187,6 +187,44 @@ static inline struct gpio_rcar_priv *gpio_to_priv(struct gpio_chip *chip)
return container_of(chip, struct gpio_rcar_priv, gpio_chip);
}
static void gpio_rcar_irq_bus_lock(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpio_to_priv(gc);
pm_runtime_get_sync(&p->pdev->dev);
}
static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpio_to_priv(gc);
pm_runtime_put(&p->pdev->dev);
}
static int gpio_rcar_irq_request_resources(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpio_to_priv(gc);
int error;
error = pm_runtime_get_sync(&p->pdev->dev);
if (error < 0)
return error;
return 0;
}
static void gpio_rcar_irq_release_resources(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpio_to_priv(gc);
pm_runtime_put(&p->pdev->dev);
}
static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,
unsigned int gpio,
bool output)
......@@ -425,6 +463,10 @@ static int gpio_rcar_probe(struct platform_device *pdev)
irq_chip->irq_mask = gpio_rcar_irq_disable;
irq_chip->irq_unmask = gpio_rcar_irq_enable;
irq_chip->irq_set_type = gpio_rcar_irq_set_type;
irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock;
irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock;
irq_chip->irq_request_resources = gpio_rcar_irq_request_resources;
irq_chip->irq_release_resources = gpio_rcar_irq_release_resources;
irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED
| IRQCHIP_MASK_ON_SUSPEND;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment