summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0056-genirq-Unmask-oneshot-irqs-when-thread-was-not-woken.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0056-genirq-Unmask-oneshot-irqs-when-thread-was-not-woken.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0056-genirq-Unmask-oneshot-irqs-when-thread-was-not-woken.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0056-genirq-Unmask-oneshot-irqs-when-thread-was-not-woken.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0056-genirq-Unmask-oneshot-irqs-when-thread-was-not-woken.patch
new file mode 100644
index 00000000..1dc0bbbf
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0056-genirq-Unmask-oneshot-irqs-when-thread-was-not-woken.patch
@@ -0,0 +1,81 @@
1From fb8f89c9c078476af3cda9f2373b5dc72cfc3ead Mon Sep 17 00:00:00 2001
2From: Thomas Gleixner <tglx@linutronix.de>
3Date: Tue, 7 Feb 2012 17:58:03 +0100
4Subject: [PATCH 56/72] genirq: Unmask oneshot irqs when thread was not woken
5
6commit ac5637611150281f398bb7a47e3fcb69a09e7803 upstream.
7
8When the primary handler of an interrupt which is marked IRQ_ONESHOT
9returns IRQ_HANDLED or IRQ_NONE, then the interrupt thread is not
10woken and the unmask logic of the interrupt line is never
11invoked. This keeps the interrupt masked forever.
12
13This was not noticed as most IRQ_ONESHOT users wake the thread
14unconditionally (usually because they cannot access the underlying
15device from hard interrupt context). Though this behaviour was nowhere
16documented and not necessarily intentional. Some drivers can avoid the
17thread wakeup in certain cases and run into the situation where the
18interrupt line s kept masked.
19
20Handle it gracefully.
21
22Reported-and-tested-by: Lothar Wassmann <lw@karo-electronics.de>
23Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
24Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25---
26 kernel/irq/chip.c | 25 +++++++++++++++++++++++--
27 1 file changed, 23 insertions(+), 2 deletions(-)
28
29diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
30index f7c543a..b742edc 100644
31--- a/kernel/irq/chip.c
32+++ b/kernel/irq/chip.c
33@@ -330,6 +330,24 @@ out_unlock:
34 }
35 EXPORT_SYMBOL_GPL(handle_simple_irq);
36
37+/*
38+ * Called unconditionally from handle_level_irq() and only for oneshot
39+ * interrupts from handle_fasteoi_irq()
40+ */
41+static void cond_unmask_irq(struct irq_desc *desc)
42+{
43+ /*
44+ * We need to unmask in the following cases:
45+ * - Standard level irq (IRQF_ONESHOT is not set)
46+ * - Oneshot irq which did not wake the thread (caused by a
47+ * spurious interrupt or a primary handler handling it
48+ * completely).
49+ */
50+ if (!irqd_irq_disabled(&desc->irq_data) &&
51+ irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot)
52+ unmask_irq(desc);
53+}
54+
55 /**
56 * handle_level_irq - Level type irq handler
57 * @irq: the interrupt number
58@@ -362,8 +380,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
59
60 handle_irq_event(desc);
61
62- if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
63- unmask_irq(desc);
64+ cond_unmask_irq(desc);
65+
66 out_unlock:
67 raw_spin_unlock(&desc->lock);
68 }
69@@ -417,6 +435,9 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
70 preflow_handler(desc);
71 handle_irq_event(desc);
72
73+ if (desc->istate & IRQS_ONESHOT)
74+ cond_unmask_irq(desc);
75+
76 out_eoi:
77 desc->irq_data.chip->irq_eoi(&desc->irq_data);
78 out_unlock:
79--
801.7.9.4
81