Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9089843pxu; Mon, 28 Dec 2020 06:23:15 -0800 (PST) X-Google-Smtp-Source: ABdhPJyjHMjgJNDZpv/ZXbjBDh5nU1NituWjUTX3I7sQf5p42tMD0E1nhik2HdJPJ5nvmdc9YKBO X-Received: by 2002:a17:906:fb0e:: with SMTP id lz14mr42885802ejb.232.1609165395397; Mon, 28 Dec 2020 06:23:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609165395; cv=none; d=google.com; s=arc-20160816; b=nzxPoTQaaGW8qf23xAbSik32Uf11D+MkRvCEPC4XZI4addbyBartPvZCeuohZ0Hki2 MPX+Yu+cAEtmYRdB8b6IVMaYodqV6tS9T/btRWdDEOoQIYQD39X2G3CuuaTQ4H6CNypR HqZvzqea8m8qx68VIdtcWRRvl7fdVVdQdGx8DSnU5QRHuIqeWEl8g+qu2M0tuJmopgtV WyQBB0RxZ1Z+gTks2x2BPgXlFPLpHeV4h4m+sO3VHFnSpJ1YonI/ZpaxATrzBu44O3Z+ KkSx6HUaC3+RIwuAG/Cg4xy1Gic0ETaAFYNwZSdqObgTNPT1m/+SBiNbT/NvzXGihKbQ PRkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=TzWZo2ZaOWVGF/1Ay0gi7CPNozpzyGL889VG8NtP6kw=; b=YQv97p9TRg+gg8KjUsQwrqViymzAuv1wLe5XXo3TRrYxhKQwBcW4LOkV4hCBG0/ohY E43PYKi936q3S9LOJLKnlwjaR6s1Xq0LRkQXobiXhCezMlTPINX6DSY4oFGhBZN8IETp uY28mHdvrRkHIM4gICJeySMIIbqDexF7VMN78ycq2FMBK5IX1KpB25bd6E8xdcU1o0Xe j1jbEKOJZLbK9IaXI1cfG2XMgqcedBn2SdskL05V6H2gc5RU1pOLPN7GDuKzFnQONWKf GR3iY4Rz7N9409Btvq7W7UMtHbGTTqAOypB3npAFwSwyjUvzgcpfr4qHZRPtYGnV/HXz apZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=tDNyy7AU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f11si18840960eje.349.2020.12.28.06.22.50; Mon, 28 Dec 2020 06:23:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=tDNyy7AU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2440801AbgL1OTw (ORCPT + 99 others); Mon, 28 Dec 2020 09:19:52 -0500 Received: from mail.kernel.org ([198.145.29.99]:54958 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392032AbgL1OTs (ORCPT ); Mon, 28 Dec 2020 09:19:48 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2EF78208B6; Mon, 28 Dec 2020 14:19:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609165141; bh=FmXvl1EVS9KHZmAGIQJFM7YJDBG6ot7telItY//m53U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tDNyy7AUShj5P1qvI+UDaiY9OSmDyzTGW5gnzG6aTRRWS/l5MASHkAdaZtnJz6htf sCTBavAuu8HWC3zqYJw76tRgkOOqipYfufPP2wLQK36Dgcy4VYu0IJ6f/XfLgZcyyJ WrLZcQfSNeI+P73+sa/M5TOw3CYL8hD44WHFaApU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Douglas Anderson , Marc Zyngier , Maulik Shah , Stephen Boyd , Sasha Levin Subject: [PATCH 5.10 427/717] irqchip/qcom-pdc: Fix phantom irq when changing between rising/falling Date: Mon, 28 Dec 2020 13:47:05 +0100 Message-Id: <20201228125041.423506901@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228125020.963311703@linuxfoundation.org> References: <20201228125020.963311703@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Douglas Anderson [ Upstream commit 2f5fbc4305d07725bfebaedb09e57271315691ef ] 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 Signed-off-by: Sasha Levin --- 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 bd39e9de6ecf7..5dc63c20b67ea 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 = { -- 2.27.0