]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.34/gpio-gpio-omap-fix-level-interrupt-idling.patch
Linux 4.19.34
[thirdparty/kernel/stable-queue.git] / releases / 4.19.34 / gpio-gpio-omap-fix-level-interrupt-idling.patch
CommitLineData
ba172962
SL
1From c8c73d56576c41cb266bc83aa9283f361906252c Mon Sep 17 00:00:00 2001
2From: Russell King <rmk+kernel@armlinux.org.uk>
3Date: Fri, 1 Mar 2019 11:02:52 -0800
4Subject: gpio: gpio-omap: fix level interrupt idling
5
6[ Upstream commit d01849f7deba81f4959fd9e51bf20dbf46987d1c ]
7
8Tony notes that the GPIO module does not idle when level interrupts are
9in use, as the wakeup appears to get stuck.
10
11After extensive investigation, it appears that the wakeup will only be
12cleared if the interrupt status register is cleared while the interrupt
13is enabled. However, we are currently clearing it with the interrupt
14disabled for level-based interrupts.
15
16It is acknowledged that this observed behaviour conflicts with a
17statement in the TRM:
18
19CAUTION
20 After servicing the interrupt, the status bit in the interrupt status
21 register (GPIOi.GPIO_IRQSTATUS_0 or GPIOi.GPIO_IRQSTATUS_1) must be
22 reset and the interrupt line released (by setting the corresponding
23 bit of the interrupt status register to 1) before enabling an
24 interrupt for the GPIO channel in the interrupt-enable register
25 (GPIOi.GPIO_IRQSTATUS_SET_0 or GPIOi.GPIO_IRQSTATUS_SET_1) to prevent
26 the occurrence of unexpected interrupts when enabling an interrupt
27 for the GPIO channel.
28
29However, this does not appear to be a practical problem.
30
31Further, as reported by Grygorii Strashko <grygorii.strashko@ti.com>,
32the TI Android kernel tree has an earlier similar patch as "GPIO: OMAP:
33Fix the sequence to clear the IRQ status" saying:
34
35 if the status is cleared after disabling the IRQ then sWAKEUP will not
36 be cleared and gates the module transition
37
38When we unmask the level interrupt after the interrupt has been handled,
39enable the interrupt and only then clear the interrupt. If the interrupt
40is still pending, the hardware will re-assert the interrupt status.
41
42Should the caution note in the TRM prove to be a problem, we could
43use a clear-enable-clear sequence instead.
44
45Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
46Cc: Keerthy <j-keerthy@ti.com>
47Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
48Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
49[tony@atomide.com: updated comments based on an earlier TI patch]
50Signed-off-by: Tony Lindgren <tony@atomide.com>
51Acked-by: Grygorii Strashko <grygorii.strashko@ti.com>
52Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
53Signed-off-by: Sasha Levin <sashal@kernel.org>
54---
55 drivers/gpio/gpio-omap.c | 14 ++++++++------
56 1 file changed, 8 insertions(+), 6 deletions(-)
57
58diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
59index e81008678a38..6c1acf642c8e 100644
60--- a/drivers/gpio/gpio-omap.c
61+++ b/drivers/gpio/gpio-omap.c
62@@ -888,14 +888,16 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
63 if (trigger)
64 omap_set_gpio_triggering(bank, offset, trigger);
65
66- /* For level-triggered GPIOs, the clearing must be done after
67- * the HW source is cleared, thus after the handler has run */
68- if (bank->level_mask & BIT(offset)) {
69- omap_set_gpio_irqenable(bank, offset, 0);
70+ omap_set_gpio_irqenable(bank, offset, 1);
71+
72+ /*
73+ * For level-triggered GPIOs, clearing must be done after the source
74+ * is cleared, thus after the handler has run. OMAP4 needs this done
75+ * after enabing the interrupt to clear the wakeup status.
76+ */
77+ if (bank->level_mask & BIT(offset))
78 omap_clear_gpio_irqstatus(bank, offset);
79- }
80
81- omap_set_gpio_irqenable(bank, offset, 1);
82 raw_spin_unlock_irqrestore(&bank->lock, flags);
83 }
84
85--
862.19.1
87