From patchwork Wed Jun 12 06:33:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 10988571 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0EC851395 for ; Wed, 12 Jun 2019 06:34:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EE89328913 for ; Wed, 12 Jun 2019 06:34:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E1F222896F; Wed, 12 Jun 2019 06:34:11 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7730428913 for ; Wed, 12 Jun 2019 06:34:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=nTYxeVpX6yZXEcSmkYRvxvH5NXJCThac1R7UfCHy2eY=; b=Mv6y2z5zraB4B+ DaKHfKh5/a43UhQuZwCQD+mQSTbUx7fd3JF3vxoUUW0geFeQvdAfAA3fglkNvK5v7ufvc7b2gy8nG TTcmEtk3MWVvWu4dhu5K/JclHQmx6ZinPxuBQHLb6GKLyYuVhDgGnuKWMD+fACb8nHYufc9wuUl98 Mmm/77r1hKHG3tdwxZ4ANJXklS652olS/mK0knWo75eortrKtn2+iFPHm2fnSPl5r6+xRhen+23A2 zs8B01ZlMKDfjuBxX8bY25eIGRHo8Tc+NhIdlFKBOBxSuuTrZub1nIdSUjBkGLbDTOf7HcnrCpOPV iXKt+lch0BYIi53A2UUQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hawpi-0002ja-Vv; Wed, 12 Jun 2019 06:34:06 +0000 Received: from muru.com ([72.249.23.125]) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hawpf-0002j1-H6 for linux-arm-kernel@lists.infradead.org; Wed, 12 Jun 2019 06:34:05 +0000 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 4568780E2; Wed, 12 Jun 2019 06:34:22 +0000 (UTC) From: Tony Lindgren To: Linus Walleij , Bartosz Golaszewski Subject: [PATCHv3] gpio: gpio-omap: Fix lost edge wake-up interrupts Date: Tue, 11 Jun 2019 23:33:52 -0700 Message-Id: <20190612063352.5760-1-tony@atomide.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190611_233403_612725_D3773A49 X-CRM114-Status: GOOD ( 12.01 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tero Kristo , Grygorii Strashko , Aaro Koskinen , Keerthy , Peter Ujfalusi , linux-gpio@vger.kernel.org, Russell King , Ladislav Michl , linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org 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 If an edge interrupt triggers while entering idle just before we save GPIO datain register to saved_datain, the triggered GPIO will not be noticed on wake-up. This is because the saved_datain and GPIO datain are the same on wake-up in omap_gpio_unidle(). Let's fix this by ignoring any pending edge interrupts for saved_datain. This issue affects only idle states where the GPIO module internal wake-up path is operational. For deeper idle states where the GPIO module gets powered off, Linux generic wakeirqs must be used for the padconf wake-up events with pinctrl-single driver. For examples, please see "interrupts-extended" dts usage in many drivers. This issue can be somewhat easily reproduced by pinging an idle system with smsc911x Ethernet interface configured IRQ_TYPE_EDGE_FALLING. At some point the smsc911x interrupts will just stop triggering. Also if WLCORE WLAN is used with EDGE interrupt like it's documentation specifies, we can see lost interrupts without this patch. Note that in the long run we may be able to cancel entering idle by returning an error in gpio_omap_cpu_notifier() on pending interrupts. But let's fix the bug first. Also note that because of the recent clean-up efforts this patch does not apply directly to older kernels. This does fix a long term issue though, and can be backported as needed. Cc: Aaro Koskinen Cc: Grygorii Strashko Cc: Keerthy Cc: Ladislav Michl Cc: Peter Ujfalusi Cc: Russell King Cc: Tero Kristo Signed-off-by: Tony Lindgren --- This patch is against v5.2-rc series. FYI, it does not conflict with the fixes (or the clean-up) in Russell's patch series. Changes since v2: - Add comments for what we're checking, drop comments for saved_datain Changes since v1: - Add handling to ignore EDGE_BOTH --- drivers/gpio/gpio-omap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1277,13 +1277,23 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) { struct device *dev = bank->chip.parent; void __iomem *base = bank->base; - u32 nowake; + u32 mask, nowake; bank->saved_datain = readl_relaxed(base + bank->regs->datain); if (!bank->enabled_non_wakeup_gpios) goto update_gpio_context_count; + /* Check for pending EDGE_FALLING, ignore EDGE_BOTH */ + mask = bank->enabled_non_wakeup_gpios & bank->context.fallingdetect; + mask &= ~bank->context.risingdetect; + bank->saved_datain |= mask; + + /* Check for pending EDGE_RISING, ignore EDGE_BOTH */ + mask = bank->enabled_non_wakeup_gpios & bank->context.risingdetect; + mask &= ~bank->context.fallingdetect; + bank->saved_datain &= ~mask; + if (!may_lose_context) goto update_gpio_context_count;