From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 006A07E for ; Wed, 2 Nov 2022 02:48:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D0F3EC433D6; Wed, 2 Nov 2022 02:48:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1667357312; bh=IJjDxoyBGd+BxzJAYl7qcNNYEhvwB8p0wPEJBsFklBw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kiK2QefovJ2xS2q+Sdc5ELTJJdIApxL1L9NORtkVqLjlOuafBj3MxYRhisgYkntma l6awP1maLpVY/08h5menwpEukp6juDDG7hLfdvVHsW/qYvCYJmoOgRg0xOddXjZaO5 p8fNyl4HT+MZdhWH5YlvkEeLdja524QFnp0A8Fgc= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Horatiu Vultur , Michael Walle , Linus Walleij , Sasha Levin Subject: [PATCH 6.0 148/240] pinctrl: ocelot: Fix incorrect trigger of the interrupt. Date: Wed, 2 Nov 2022 03:32:03 +0100 Message-Id: <20221102022114.724196467@linuxfoundation.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221102022111.398283374@linuxfoundation.org> References: <20221102022111.398283374@linuxfoundation.org> User-Agent: quilt/0.67 Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Horatiu Vultur [ Upstream commit e9945b2633deccda74a769d94060df49c53ff181 ] The interrupt controller can detect only link changes. So in case an external device generated a level based interrupt, then the interrupt controller detected correctly the first edge. But the problem was that the interrupt controller was detecting also the edge when the interrupt was cleared. So it would generate another interrupt. The fix for this is to clear the second interrupt but still check the interrupt line status. Fixes: c297561bc98a ("pinctrl: ocelot: Fix interrupt controller") Signed-off-by: Horatiu Vultur Tested-by: Michael Walle Link: https://lore.kernel.org/r/20221018070959.1322606-1-horatiu.vultur@microchip.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-ocelot.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index c7df8c5fe585..105771ff82e6 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -1863,19 +1863,28 @@ static void ocelot_irq_unmask_level(struct irq_data *data) if (val & bit) ack = true; + /* Try to clear any rising edges */ + if (!active && ack) + regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio), + bit, bit); + /* Enable the interrupt now */ gpiochip_enable_irq(chip, gpio); regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), bit, bit); /* - * In case the interrupt line is still active and the interrupt - * controller has not seen any changes in the interrupt line, then it - * means that there happen another interrupt while the line was active. + * In case the interrupt line is still active then it means that + * there happen another interrupt while the line was active. * So we missed that one, so we need to kick the interrupt again * handler. */ - if (active && !ack) { + regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val); + if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) || + (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH)) + active = true; + + if (active) { struct ocelot_irq_work *work; work = kmalloc(sizeof(*work), GFP_ATOMIC); -- 2.35.1