From patchwork Fri Nov 7 09:22:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshihiro Kaneko X-Patchwork-Id: 408008 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 6D1DE14012A for ; Fri, 7 Nov 2014 20:23:27 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751173AbaKGJX0 (ORCPT ); Fri, 7 Nov 2014 04:23:26 -0500 Received: from mail-pa0-f49.google.com ([209.85.220.49]:49561 "EHLO mail-pa0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750919AbaKGJXX (ORCPT ); Fri, 7 Nov 2014 04:23:23 -0500 Received: by mail-pa0-f49.google.com with SMTP id lj1so3156466pab.36 for ; Fri, 07 Nov 2014 01:23:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=PZr2VhqUGhNfLRtCyfHb3H5TXOY+ByqtAFbpKWI7vOM=; b=vQWQEBurOxZ1KQZpQTvaNOrLchnyFpO6ImGErS03AHQZMd4Ndn606n/VQWz8bAdMVz 5CY1qNdEKktd6Zzi7O/p9QY15uldHIJoV6QfD9V/iPHx5VTINiW+kRoCl3+O8U2XC8sI pFxYq2Yv3O3xILQA0+hQKpbnyNl1TZyjYRk1z05A+awdSQK4nBDdDJC78Nt0VeWuqNHv SVm5DLxGqIjOmSyd4LuzcGsOjW3FAiqSJRidhUJhaE9VtxCNKqEoVRg1P80PcGWKoqaF YX6F5ufBfL4kft/0AkHePPDMQkLnyR/NtiCBpzZhX7bXHpoyLvBsdBLkQ1cewPBrMZgQ TSsw== X-Received: by 10.66.145.234 with SMTP id sx10mr10772391pab.130.1415352203302; Fri, 07 Nov 2014 01:23:23 -0800 (PST) Received: from localhost.localdomain (p5095-ipngn6701marunouchi.tokyo.ocn.ne.jp. [153.174.4.95]) by mx.google.com with ESMTPSA id fm15sm8135977pdb.58.2014.11.07.01.23.21 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Nov 2014 01:23:22 -0800 (PST) From: Yoshihiro Kaneko To: linux-gpio@vger.kernel.org Cc: Linus Walleij , Alexandre Courbot , Simon Horman , Magnus Damm , linux-sh@vger.kernel.org Subject: [PATCH] gpio-rcar: .irq_set_wake() support to work with suspend_device_irqs() Date: Fri, 7 Nov 2014 18:22:45 +0900 Message-Id: <1415352165-26597-1-git-send-email-ykaneko0929@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Shinya Kuribayashi All IRQs in the kernel get disabled by PM core prior to .suspend_noirq() step through kernel/irq/pm.c::suspend_device_irqs(). The SYSC hardware block in the R-Car SoCs, on the other hand, uses any interrupt as wake-up source(es) and requires them to be unmasked during the system is suspended. This patch implements .irq_set_wake() which makes __disable_irq() call a NOP when a GPIO port is claimed as a wake-up source. Signed-off-by: Shinya Kuribayashi Signed-off-by: Koji Matsuoka Signed-off-by: Yoshihiro Kaneko --- This patch is based on for-next branch of Linus Walleij's gpio tree. 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 bf6c094..ef71ca8 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -38,6 +38,7 @@ struct gpio_rcar_priv { struct gpio_chip gpio_chip; struct irq_chip irq_chip; struct irq_domain *irq_domain; + u32 no_suspend; /* do not disable this GPIO port during suspend */ }; #define IOINTSEL 0x00 @@ -83,6 +84,15 @@ static void gpio_rcar_irq_disable(struct irq_data *d) { struct gpio_rcar_priv *p = irq_data_get_irq_chip_data(d); + if (p->no_suspend & BIT(irqd_to_hwirq(d))) { + /* + * This GPIO port is claimed as a wake-up source and + * currently in a no-suspend-requested state. Don't + * disable this IRQ during suspend. + */ + return; + } + gpio_rcar_write(p, INTMSK, ~BIT(irqd_to_hwirq(d))); } @@ -164,6 +174,20 @@ static int gpio_rcar_irq_set_type(struct irq_data *d, unsigned int type) return 0; } +static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct gpio_rcar_priv *p = irq_data_get_irq_chip_data(d); + unsigned int hwirq = irqd_to_hwirq(d); + + dev_dbg(&p->pdev->dev, "wake irq = %u %s\n", hwirq, on ? "on" : "off"); + + if (on) + p->no_suspend |= BIT(hwirq); + else + p->no_suspend &= ~BIT(hwirq); + return 0; +} + static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) { struct gpio_rcar_priv *p = dev_id; @@ -416,6 +440,7 @@ 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_set_wake = gpio_rcar_irq_set_wake; irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;