From patchwork Tue Oct 4 15:08:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 9362017 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D18CF600C8 for ; Tue, 4 Oct 2016 15:15:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C114928450 for ; Tue, 4 Oct 2016 15:15:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B335428BF4; Tue, 4 Oct 2016 15:15:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 427F728450 for ; Tue, 4 Oct 2016 15:15:05 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1brRPJ-0007JG-BM; Tue, 04 Oct 2016 15:13:25 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1brRLR-0002Y3-EL for linux-arm-kernel@bombadil.infradead.org; Tue, 04 Oct 2016 15:09:25 +0000 Received: from mail-lf0-x233.google.com ([2a00:1450:4010:c07::233]) by casper.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1brRLL-000585-MD for linux-arm-kernel@lists.infradead.org; Tue, 04 Oct 2016 15:09:23 +0000 Received: by mail-lf0-x233.google.com with SMTP id b75so54401887lfg.3 for ; Tue, 04 Oct 2016 08:08:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aK00BcvbdDbnU/No+YflI0EVy8pBlzqntfrp3BV6XRc=; b=Pllbhz6toB7lh+SQBVvLgGhB185RLw1V5wcPL6KpA5u34/+7oqs4cCkoWZc6ewOJVW vbHkUTo2V4gA9lIDxuwR78M1PORWH/+FyGluVpfaN1VFFe3Wl61QmU63oF8rDJaAxmIO uIJrpViARiWPtt7cB8HLwY41Mfkm/7cNW4cXoyDzgbcXPMR0/j2ImF0o4PyJmJ+DTXgF FjoNBQnyrfcd9QMuQzM8V4RwZAIGDYH30E0jlMEa2fvHu+UnEtrRhTEYw8GxUT6ahBpt B4aOiju0KrPYFHtaM5o8z0YVkDvE01xasETD7JVPRpijbvxCpcan6lwwzp45nmzj/WEE aMkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aK00BcvbdDbnU/No+YflI0EVy8pBlzqntfrp3BV6XRc=; b=LJSKY+oNUjG+fIuChoWm19F+Ac6dQI3lXtDtx14SaHw1cITg7Hjwyh8HKrF/Ne6VyX IqoAyGMTDRWV79tyKtMm7NqtkUqGgEGVzrXdnzO/Ml12TeM1c4MCHvvhrdd00VNMgjhj dsqgss6jdT0QUfk8fCQIaQGpMnpveLfI0OpZ9WQPvQgeAlCGV7yFF5sLnuGLySmYxzIC iqiov5Fs3gM99WEm5mj89TilbCGjNM2mr+wHbIJkmnuYeCegUKSUbFIBhVkFpKJFjM0I KBw/fAccDHxtYxnthMLPC8zf2IXM2LeD1KcjmDOYn3mb3pSg8FxXsNgxN5oPVzChXecS hx8w== X-Gm-Message-State: AA6/9Rm6P0yWzODtr3t2Ut2f6tDX6/DUETCewzbLHHzw8fBcxuZcc/wKI01eMAewMYt2pij1 X-Received: by 10.194.206.68 with SMTP id lm4mr3406253wjc.106.1475593737648; Tue, 04 Oct 2016 08:08:57 -0700 (PDT) Received: from boomer.baylibre.com ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id j198sm4583539wmg.4.2016.10.04.08.08.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Oct 2016 08:08:57 -0700 (PDT) From: Jerome Brunet To: Kevin Hilman , Carlo Caione , Thomas Gleixner , Jason Cooper , Marc Zyngier Subject: [RFC 10/10] irqchip: meson: Add support for IRQ_TYPE_EDGE_BOTH Date: Tue, 4 Oct 2016 17:08:28 +0200 Message-Id: <1475593708-10526-11-git-send-email-jbrunet@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475593708-10526-1-git-send-email-jbrunet@baylibre.com> References: <1475593708-10526-1-git-send-email-jbrunet@baylibre.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161004_160919_804003_F42AA498 X-CRM114-Status: GOOD ( 24.38 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-amlogic@lists.infradead.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Jerome Brunet MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The IP cannot take IRQ_EDGE_BOTH because the polarity in the filtering block is just one bit. It can trigger on either edge, but not both with the same configuration. This prevents meson based SoC to use some simple generic driver, like gpio-keys. The proposition is to change edge polarity in the end of interrupt callback (just toggling the polarity register of the IP). This works nicely but has 2 limitations: 1) If the signal is initially high, the first falling edge will not be detected, because the chip is initially configured for a rising edge. 2) If the signal changes too quickly for all edges to be properly handled, an additional edge might get lost, for the same reason as point 1. There is no drawback for introducing this work around so, knowing the limitation, it would be nice to have it Signed-off-by: Jerome Brunet --- drivers/irqchip/irq-meson-gpio.c | 45 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c index 184025a9cdaf..5bcbefef3e94 100644 --- a/drivers/irqchip/irq-meson-gpio.c +++ b/drivers/irqchip/irq-meson-gpio.c @@ -58,6 +58,7 @@ struct meson_gpio_irq_domain { struct meson_gpio_irq_chip { void __iomem *base; int index; + unsigned int flow_type; }; static const struct meson_gpio_irq_params meson8_params = { @@ -91,6 +92,19 @@ static void meson_gpio_irq_update_bits(void __iomem *base, unsigned int reg, writel(tmp, base + reg); } +static void meson_gpio_irq_flip_bits(void __iomem *base, unsigned int reg, + u32 mask) +{ + u32 tmp, val; + + tmp = readl(base + reg); + val = tmp ^ mask; + tmp = (tmp & val) | val; + + writel(tmp, base + reg); +} + + static int meson_gpio_irq_get_index(struct meson_gpio_irq_domain *domain_data, int hwirq) { @@ -135,11 +149,15 @@ static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) pr_debug("set type of hwirq %lu to %u\n", data->hwirq, type); - if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) - return -EINVAL; + cd->flow_type = type; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) val |= REG_EDGE_POL_EDGE(cd->index); + /* + * Take care of the dual polarity issue here, starting positive + */ + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + type &= ~IRQ_TYPE_EDGE_FALLING; if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { val |= REG_EDGE_POL_LOW(cd->index); @@ -162,11 +180,31 @@ static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) return irq_chip_set_type_parent(data, type); } +static void meson_gpio_irq_eoi(struct irq_data *data) +{ + struct meson_gpio_irq_chip *cd = irq_data_get_irq_chip_data(data); + + /* + * To simulate IRQ_TYPE_EDGE_BOTH, change the polarity of the edge + * after each interrupt. + * Limitation: + * 1) If the signal is initially high, the first falling edge will not + * be detected + * 2) If the signal changes too quickly to detect all the edges, an + * additional edge might get lost. + */ + if ((cd->flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + meson_gpio_irq_flip_bits(cd->base, REG_EDGE_POL, + REG_EDGE_POL_LOW(cd->index)); + + irq_chip_eoi_parent(data); +} + static struct irq_chip meson_gpio_irq_chip = { .name = "meson-gpio-irqchip", .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, - .irq_eoi = irq_chip_eoi_parent, + .irq_eoi = meson_gpio_irq_eoi, .irq_set_type = meson_gpio_irq_set_type, .irq_retrigger = irq_chip_retrigger_hierarchy, #ifdef CONFIG_SMP @@ -221,6 +259,7 @@ static int meson_gpio_irq_domain_alloc(struct irq_domain *domain, cd->base = domain_data->base; cd->index = index; + cd->flow_type = type; fwspec_parent = &domain_data->parent_irqs[index]; irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,