Commit 9d313c12 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Luis Henriques

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>
parent c3ad1774
...@@ -186,6 +186,44 @@ static inline struct gpio_rcar_priv *gpio_to_priv(struct gpio_chip *chip) ...@@ -186,6 +186,44 @@ static inline struct gpio_rcar_priv *gpio_to_priv(struct gpio_chip *chip)
return container_of(chip, struct gpio_rcar_priv, gpio_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, static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,
unsigned int gpio, unsigned int gpio,
bool output) bool output)
...@@ -414,6 +452,10 @@ static int gpio_rcar_probe(struct platform_device *pdev) ...@@ -414,6 +452,10 @@ static int gpio_rcar_probe(struct platform_device *pdev)
irq_chip->irq_mask = gpio_rcar_irq_disable; irq_chip->irq_mask = gpio_rcar_irq_disable;
irq_chip->irq_unmask = gpio_rcar_irq_enable; irq_chip->irq_unmask = gpio_rcar_irq_enable;
irq_chip->irq_set_type = gpio_rcar_irq_set_type; 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 irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED
| IRQCHIP_MASK_ON_SUSPEND; | 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