From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1419C4361B for ; Sat, 12 Dec 2020 10:53:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 682712184D for ; Sat, 12 Dec 2020 10:53:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2438793AbgLLKx2 (ORCPT ); Sat, 12 Dec 2020 05:53:28 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:40768 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726591AbgLLKx2 (ORCPT ); Sat, 12 Dec 2020 05:53:28 -0500 Date: Sat, 12 Dec 2020 10:52:44 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1607770365; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U0CX+i+lOGGHY/h0lZNjpIZorX3zxTtdgT4kQxFzL8s=; b=nL3l7ISvto62GQC9hfI5Ymh6nFTiSyVk6VjUVmmX8gqpOEVNgvEu3ySl6HAH9IWQhMPwde JQI8HgH6zNFTYB+JRwNmaennOru/BPQ7qzVciuin3RySPqPg6372wLvuOUwqyWF1dxciim IY/d7qfTsBF9i/i+Dtr/gkE2wvf+0IpCNlKboCYq/udVcswYZKZ8xjj9LuVDnNh/9fxSLw CImkvAtJ7Tgwecl1L0i73ZUUgkL3Sb1y3aH7g6sEz7tJVttcqFX0psDatEfc675aDriD5E QygkBNzlBhrUXPjIAZ2xFeHdIjLjUBhxKEd4DW7T6W2E0gQ8fGMVoKXWM9VHDQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1607770365; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U0CX+i+lOGGHY/h0lZNjpIZorX3zxTtdgT4kQxFzL8s=; b=WJkEk2T4B42AexAdmqtPmz3c/e2X6MbCeBVjwpSccAqXs2+oGpL/HyEwOVDZ7TIxrxmZiC 35rH4l/pIUWvKYDA== From: "irqchip-bot for Douglas Anderson" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-kernel@vger.kernel.org Subject: [irqchip: irq/irqchip-next] irqchip/qcom-pdc: Fix phantom irq when changing between rising/falling Cc: Douglas Anderson , Marc Zyngier , Maulik Shah , Stephen Boyd , tglx@linutronix.de In-Reply-To: <20201211141514.v4.1.I2702919afc253e2a451bebc3b701b462b2d22344@changeid> References: <20201211141514.v4.1.I2702919afc253e2a451bebc3b701b462b2d22344@changeid> MIME-Version: 1.0 Message-ID: <160777036408.3364.8611167035514304941.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam: Yes Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the irq/irqchip-next branch of irqchip: Commit-ID: 2f5fbc4305d07725bfebaedb09e57271315691ef Gitweb: https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms/2f5fbc4305d07725bfebaedb09e57271315691ef Author: Douglas Anderson AuthorDate: Fri, 11 Dec 2020 14:15:35 -08:00 Committer: Marc Zyngier CommitterDate: Sat, 12 Dec 2020 10:46:02 irqchip/qcom-pdc: Fix phantom irq when changing between rising/falling We have a problem if we use gpio-keys and configure wakeups such that we only want one edge to wake us up. AKA: wakeup-event-action = ; wakeup-source; Specifically we end up with a phantom interrupt that blocks suspend if the line was already high and we want wakeups on rising edges (AKA we want the GPIO to go low and then high again before we wake up). The opposite is also problematic. Specifically, here's what's happening today: 1. Normally, gpio-keys configures to look for both edges. Due to the current workaround introduced in commit c3c0c2e18d94 ("pinctrl: qcom: Handle broken/missing PDC dual edge IRQs on sc7180"), if the line was high we'd configure for falling edges. 2. At suspend time, we change to look for rising edges. 3. After qcom_pdc_gic_set_type() runs, we get a phantom interrupt. We can solve this by just clearing the phantom interrupt. NOTE: it is possible that this could cause problems for a client with very specific needs, but there's not much we can do with this hardware. As an example, let's say the interrupt signal is currently high and the client is looking for falling edges. The client now changes to look for rising edges. The client could possibly expect that if the line has a short pulse low (and back high) that it would always be detected. Specifically no matter when the pulse happened, it should either have tripped the (old) falling edge trigger or the (new) rising edge trigger. We will simply not trip it. We could narrow down the race a bit by polling our parent before changing types, but no matter what we do there will still be a period of time where we can't tell the difference between a real transition (or more than one transition) and the phantom. Fixes: f55c73aef890 ("irqchip/pdc: Add PDC interrupt controller for QCOM SoCs") Signed-off-by: Douglas Anderson Signed-off-by: Marc Zyngier Tested-by: Maulik Shah Reviewed-by: Maulik Shah Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20201211141514.v4.1.I2702919afc253e2a451bebc3b701b462b2d22344@changeid --- drivers/irqchip/qcom-pdc.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index bd39e9d..5dc63c2 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -159,6 +159,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) { int pin_out = d->hwirq; enum pdc_irq_config_bits pdc_type; + enum pdc_irq_config_bits old_pdc_type; + int ret; if (pin_out == GPIO_NO_WAKE_IRQ) return 0; @@ -187,9 +189,26 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } + old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out); pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type); - return irq_chip_set_type_parent(d, type); + ret = irq_chip_set_type_parent(d, type); + if (ret) + return ret; + + /* + * When we change types the PDC can give a phantom interrupt. + * Clear it. Specifically the phantom shows up when reconfiguring + * polarity of interrupt without changing the state of the signal + * but let's be consistent and clear it always. + * + * Doing this works because we have IRQCHIP_SET_TYPE_MASKED so the + * interrupt will be cleared before the rest of the system sees it. + */ + if (old_pdc_type != pdc_type) + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false); + + return 0; } static struct irq_chip qcom_pdc_gic_chip = {