]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.35/genirq-respect-irqchip_skip_set_wake-in-irq_chip_set_wake_parent.patch
Linux 4.19.35
[thirdparty/kernel/stable-queue.git] / releases / 4.19.35 / genirq-respect-irqchip_skip_set_wake-in-irq_chip_set_wake_parent.patch
CommitLineData
1dabdb6f
GKH
1From 325aa19598e410672175ed50982f902d4e3f31c5 Mon Sep 17 00:00:00 2001
2From: Stephen Boyd <swboyd@chromium.org>
3Date: Mon, 25 Mar 2019 11:10:26 -0700
4Subject: genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent()
5
6From: Stephen Boyd <swboyd@chromium.org>
7
8commit 325aa19598e410672175ed50982f902d4e3f31c5 upstream.
9
10If a child irqchip calls irq_chip_set_wake_parent() but its parent irqchip
11has the IRQCHIP_SKIP_SET_WAKE flag set an error is returned.
12
13This is inconsistent behaviour vs. set_irq_wake_real() which returns 0 when
14the irqchip has the IRQCHIP_SKIP_SET_WAKE flag set. It doesn't attempt to
15walk the chain of parents and set irq wake on any chips that don't have the
16flag set either. If the intent is to call the .irq_set_wake() callback of
17the parent irqchip, then we expect irqchip implementations to omit the
18IRQCHIP_SKIP_SET_WAKE flag and implement an .irq_set_wake() function that
19calls irq_chip_set_wake_parent().
20
21The problem has been observed on a Qualcomm sdm845 device where set wake
22fails on any GPIO interrupts after applying work in progress wakeup irq
23patches to the GPIO driver. The chain of chips looks like this:
24
25 QCOM GPIO -> QCOM PDC (SKIP) -> ARM GIC (SKIP)
26
27The GPIO controllers parent is the QCOM PDC irqchip which in turn has ARM
28GIC as parent. The QCOM PDC irqchip has the IRQCHIP_SKIP_SET_WAKE flag
29set, and so does the grandparent ARM GIC.
30
31The GPIO driver doesn't know if the parent needs to set wake or not, so it
32unconditionally calls irq_chip_set_wake_parent() causing this function to
33return a failure because the parent irqchip (PDC) doesn't have the
34.irq_set_wake() callback set. Returning 0 instead makes everything work and
35irqs from the GPIO controller can be configured for wakeup.
36
37Make it consistent by returning 0 (success) from irq_chip_set_wake_parent()
38when a parent chip has IRQCHIP_SKIP_SET_WAKE set.
39
40[ tglx: Massaged changelog ]
41
42Fixes: 08b55e2a9208e ("genirq: Add irqchip_set_wake_parent")
43Signed-off-by: Stephen Boyd <swboyd@chromium.org>
44Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
45Acked-by: Marc Zyngier <marc.zyngier@arm.com>
46Cc: linux-arm-kernel@lists.infradead.org
47Cc: linux-gpio@vger.kernel.org
48Cc: Lina Iyer <ilina@codeaurora.org>
49Cc: stable@vger.kernel.org
50Link: https://lkml.kernel.org/r/20190325181026.247796-1-swboyd@chromium.org
51Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
52
53---
54 kernel/irq/chip.c | 4 ++++
55 1 file changed, 4 insertions(+)
56
57--- a/kernel/irq/chip.c
58+++ b/kernel/irq/chip.c
59@@ -1384,6 +1384,10 @@ int irq_chip_set_vcpu_affinity_parent(st
60 int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
61 {
62 data = data->parent_data;
63+
64+ if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE)
65+ return 0;
66+
67 if (data->chip->irq_set_wake)
68 return data->chip->irq_set_wake(data, on);
69