From patchwork Tue Nov 18 23:49:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 5333841 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1407EC11AC for ; Tue, 18 Nov 2014 23:53:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2B284201E4 for ; Tue, 18 Nov 2014 23:53:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4AF6D201CE for ; Tue, 18 Nov 2014 23:53:19 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XqsXw-0006NT-RI; Tue, 18 Nov 2014 23:50:56 +0000 Received: from mail-ig0-x234.google.com ([2607:f8b0:4001:c05::234]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XqsXZ-0006Ed-2r for linux-arm-kernel@lists.infradead.org; Tue, 18 Nov 2014 23:50:34 +0000 Received: by mail-ig0-f180.google.com with SMTP id h15so42404igd.7 for ; Tue, 18 Nov 2014 15:50:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pZuQJOlz/UaJj/eH5MJBaYUcCCJiNKa7Rnx+c03Y/Ks=; b=nAO0HHOOZtqZsWdRLQ/Es6DP4W1i8xMTZmRDVnZMTUju8AjsRM0OWGs5997T2/G81E aaIx+24BvnLxJgsJ8TdIs8ynE2GHuzckaO2bT6tXZxZj7b7KpSaJ5sd0IIYLzkic/8Fg wswKKuBYR2/5dGmD558gfZf4S0M07Xf40TTpo= 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=pZuQJOlz/UaJj/eH5MJBaYUcCCJiNKa7Rnx+c03Y/Ks=; b=joiVSRMe6w8aA9EUYxmZ93V0fbD4mok8X87RqgDGti9kVEvgKxb049w9kzdjX5bhHW 52Vx9VuqDF6qwXc2f30KyeTbRXCG65tQJeXOPyu/9qb8YEyJwesH67lnrgjWRCQ9iXUa IUlpCZlt8KJxYTIzHrY28v5qiCFYyLNRGidIzOxv0ecciOgQi5vx8Bk21505rlm+dcQX j9qa9rV5Qb/QAC4dxXvH19zXuH+3Oe/J5nnWzSTLe6dUhKxX4i9sDm4uNwSW28u7qHoF yTisJ/396HlHwpjOy0SJ7WFjaIHwzgYQTTGf9hSA+MXTQIuanQ/pdt7F5atDoBYIqpHE 4P3w== X-Gm-Message-State: ALoCoQml1yC96eg7pS6EkThUKArYkwatxI7641LjmVc3rDxRJNmz7gkUOn7ymaN/H/JXkV1XbNDL X-Received: by 10.50.30.200 with SMTP id u8mr6929637igh.35.1416354611259; Tue, 18 Nov 2014 15:50:11 -0800 (PST) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by mx.google.com with ESMTPSA id c62sm7592185ioe.22.2014.11.18.15.50.10 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Nov 2014 15:50:10 -0800 (PST) From: Doug Anderson To: Heiko Stuebner , Linus Walleij Subject: [PATCH 2/2] pinctrl: rockchip: Fix enable/disable/mask/unmask Date: Tue, 18 Nov 2014 15:49:56 -0800 Message-Id: <1416354596-15013-3-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1416354596-15013-1-git-send-email-dianders@chromium.org> References: <1416354596-15013-1-git-send-email-dianders@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141118_155033_193057_29720B99 X-CRM114-Status: GOOD ( 11.93 ) X-Spam-Score: -0.8 (/) Cc: linux-gpio@vger.kernel.org, Dmitry Torokhov , Doug Anderson , linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Chris Zhong , Sonny Rao , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_LOW, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The Rockchip pinctrl driver was only implementing the "mask" and "unmask" operations though the hardware actually has two distinct things: enable/disable and mask/unmask. It was implementing the "mask" operations as a hardware enable/disable and always leaving all interrupts unmasked. I believe that the old system had some downsides, specifically: - (Untested) if an interrupt went off while interrupts were "masked" it would be lost. Now it will be kept track of. - If someone wanted to change an interrupt back into a GPIO (is such a thing sensible?) by calling irq_disable() it wouldn't actually take effect. That's because Linux does some extra optimizations when there's no true "disable" function: it does a lazy mask. Let's actually implement enable/disable/mask/unmask properly. Signed-off-by: Doug Anderson Reviewed-by: Dmitry Torokhov Reviewed-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index e91e845..60d1a49 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1562,6 +1562,28 @@ static void rockchip_irq_resume(struct irq_data *d) irq_reg_writel(gc, bank->saved_enables, GPIO_INTEN); } +static void rockchip_irq_disable(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 val; + + irq_gc_lock(gc); + val = irq_reg_readl(gc, GPIO_INTEN); + irq_reg_writel(gc, val & ~d->mask, GPIO_INTEN); + irq_gc_unlock(gc); +} + +static void rockchip_irq_enable(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 val; + + irq_gc_lock(gc); + val = irq_reg_readl(gc, GPIO_INTEN); + irq_reg_writel(gc, val | d->mask, GPIO_INTEN); + irq_gc_unlock(gc); +} + static int rockchip_interrupts_register(struct platform_device *pdev, struct rockchip_pinctrl *info) { @@ -1600,11 +1622,13 @@ static int rockchip_interrupts_register(struct platform_device *pdev, gc = irq_get_domain_generic_chip(bank->domain, 0); gc->reg_base = bank->reg_base; gc->private = bank; - gc->chip_types[0].regs.mask = GPIO_INTEN; + gc->chip_types[0].regs.mask = GPIO_INTMASK; gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; - gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; + gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; + gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;