Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759222AbcCVK6V (ORCPT ); Tue, 22 Mar 2016 06:58:21 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:56908 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932607AbcCVKm5 (ORCPT ); Tue, 22 Mar 2016 06:42:57 -0400 From: Luis Henriques To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, kernel-team@lists.ubuntu.com Cc: Geert Uytterhoeven , Linus Walleij , Luis Henriques Subject: [PATCH 3.16.y-ckt 109/142] gpio: rcar: Add Runtime PM handling for interrupts Date: Tue, 22 Mar 2016 10:40:38 +0000 Message-Id: <1458643271-4227-110-git-send-email-luis.henriques@canonical.com> In-Reply-To: <1458643271-4227-1-git-send-email-luis.henriques@canonical.com> References: <1458643271-4227-1-git-send-email-luis.henriques@canonical.com> X-Extended-Stable: 3.16 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3201 Lines: 91 3.16.7-ckt26 -stable review patch. If anyone has any objections, please let me know. ---8<------------------------------------------------------------ From: Geert Uytterhoeven commit b26a719bdba9aa926ceaadecc66e07623d2b8a53 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: d5c3d84657db57bd "net: phy: Avoid polling PHY with PHY_IGNORE_INTERRUPTS" Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Walleij [ luis: backported to 3.16: - use gpio_to_priv() instead of gpiochip_get_data() - adjusted context ] Signed-off-by: Luis Henriques --- drivers/gpio/gpio-rcar.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index c3ea3e9e3d14..b97094ce448f 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -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); } +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) @@ -414,6 +452,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;