diff options
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.patch | 81 |
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 @@ | |||
1 | From fb8f89c9c078476af3cda9f2373b5dc72cfc3ead Mon Sep 17 00:00:00 2001 | ||
2 | From: Thomas Gleixner <tglx@linutronix.de> | ||
3 | Date: Tue, 7 Feb 2012 17:58:03 +0100 | ||
4 | Subject: [PATCH 56/72] genirq: Unmask oneshot irqs when thread was not woken | ||
5 | |||
6 | commit ac5637611150281f398bb7a47e3fcb69a09e7803 upstream. | ||
7 | |||
8 | When the primary handler of an interrupt which is marked IRQ_ONESHOT | ||
9 | returns IRQ_HANDLED or IRQ_NONE, then the interrupt thread is not | ||
10 | woken and the unmask logic of the interrupt line is never | ||
11 | invoked. This keeps the interrupt masked forever. | ||
12 | |||
13 | This was not noticed as most IRQ_ONESHOT users wake the thread | ||
14 | unconditionally (usually because they cannot access the underlying | ||
15 | device from hard interrupt context). Though this behaviour was nowhere | ||
16 | documented and not necessarily intentional. Some drivers can avoid the | ||
17 | thread wakeup in certain cases and run into the situation where the | ||
18 | interrupt line s kept masked. | ||
19 | |||
20 | Handle it gracefully. | ||
21 | |||
22 | Reported-and-tested-by: Lothar Wassmann <lw@karo-electronics.de> | ||
23 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | ||
24 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
25 | --- | ||
26 | kernel/irq/chip.c | 25 +++++++++++++++++++++++-- | ||
27 | 1 file changed, 23 insertions(+), 2 deletions(-) | ||
28 | |||
29 | diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c | ||
30 | index 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 | -- | ||
80 | 1.7.9.4 | ||
81 | |||