From patchwork Wed Nov 19 22:51:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 5344561 Return-Path: X-Original-To: patchwork-linux-rockchip@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 6039EC11AC for ; Wed, 19 Nov 2014 22:52:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 794C4201FA for ; Wed, 19 Nov 2014 22:52:39 +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 90BAB2017E for ; Wed, 19 Nov 2014 22:52:38 +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 1XrE73-0002yh-Mv; Wed, 19 Nov 2014 22:52:37 +0000 Received: from mail-ie0-x22a.google.com ([2607:f8b0:4001:c03::22a]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XrE6a-0002iu-2d for linux-rockchip@lists.infradead.org; Wed, 19 Nov 2014 22:52:08 +0000 Received: by mail-ie0-f170.google.com with SMTP id rd18so1631401iec.15 for ; Wed, 19 Nov 2014 14:51:46 -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=vsIbCCrbZX9S7PYeZ09ltwG4V3ynh27lj32jecyQCv4=; b=dNPO82V/P1ytsKFBvGV0mLZdgxuBcpREOxVJ5RpG0IaE32l1/TLZN7RIxysplIvbb4 K+SY+Rilk10FKEWzHx53MplyeSvzzYOyrJULUUSLjsA+ukbn+tTmNoW63DNkmHlsFhVz nA59QBPAAcMq9cVQIQXgDxuRAT9429QiDoQ8k= 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=vsIbCCrbZX9S7PYeZ09ltwG4V3ynh27lj32jecyQCv4=; b=eFkUP0mj3EtiCc3FZpMay1GG/sxOJo1N3G6S1bpb2N5qlbWD1IDM26lK0B5INivg0x xXH3WtmUKZrzSnGFEk3a0IsL5DUQqaAG/NyIVNrRFsco5KoCzdNhVIWxhuF6QvSdRxfp 7SvLFM9VIrwVaUJOBQW2rzkyBSmF55hYcD+L/AB7f1wc6sAGA4aAh22zPDAlc0UJKtfK dkT7qgd1yVOg5/bYRQ/a/E02i6xkQ9asvcSJpZ/usFiOxWHl/MpBbS9IGGh5OBd441p6 AFl81cJw6taWORKBVYFkN8RUEO7K7LzxG0g6rMgtIQ7aTpH4HNJA1R6xc+hh/ncLJ5ka SGZA== X-Gm-Message-State: ALoCoQmbvQi8aqT5Liay8VUTqyv63OJQ9pYPYsk6vP8E4RETb/CkUjqMYJCXYSUyGlZMXKZ5XSEn X-Received: by 10.50.128.163 with SMTP id np3mr12878849igb.28.1416437505946; Wed, 19 Nov 2014 14:51:45 -0800 (PST) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by mx.google.com with ESMTPSA id o2sm1557232igj.19.2014.11.19.14.51.45 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Nov 2014 14:51:45 -0800 (PST) From: Doug Anderson To: Heiko Stuebner , Linus Walleij Subject: [PATCH v2 2/2] pinctrl: rockchip: Fix enable/disable/mask/unmask Date: Wed, 19 Nov 2014 14:51:33 -0800 Message-Id: <1416437493-25588-3-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1416437493-25588-1-git-send-email-dianders@chromium.org> References: <1416437493-25588-1-git-send-email-dianders@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141119_145208_197859_70C8C7B8 X-CRM114-Status: GOOD ( 10.55 ) 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-rockchip@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=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 --- Changes in v2: - Spread out code (heiko) drivers/pinctrl/pinctrl-rockchip.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index e91e845..3c22dbe 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1562,6 +1562,34 @@ 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); + val &= ~d->mask; + irq_reg_writel(gc, val, 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); + val |= d->mask; + irq_reg_writel(gc, val, GPIO_INTEN); + + irq_gc_unlock(gc); +} + static int rockchip_interrupts_register(struct platform_device *pdev, struct rockchip_pinctrl *info) { @@ -1600,11 +1628,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;