summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0057-genirq-Handle-pending-irqs-in-irq_startup.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0057-genirq-Handle-pending-irqs-in-irq_startup.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0057-genirq-Handle-pending-irqs-in-irq_startup.patch117
1 files changed, 117 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0057-genirq-Handle-pending-irqs-in-irq_startup.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0057-genirq-Handle-pending-irqs-in-irq_startup.patch
new file mode 100644
index 00000000..b52cb6a3
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0057-genirq-Handle-pending-irqs-in-irq_startup.patch
@@ -0,0 +1,117 @@
1From cde7a1b79f95c783def648bff541ee319148e611 Mon Sep 17 00:00:00 2001
2From: Thomas Gleixner <tglx@linutronix.de>
3Date: Wed, 8 Feb 2012 11:57:52 +0100
4Subject: [PATCH 57/72] genirq: Handle pending irqs in irq_startup()
5
6commit b4bc724e82e80478cba5fe9825b62e71ddf78757 upstream.
7
8An interrupt might be pending when irq_startup() is called, but the
9startup code does not invoke the resend logic. In some cases this
10prevents the device from issuing another interrupt which renders the
11device non functional.
12
13Call the resend function in irq_startup() to keep things going.
14
15Reported-and-tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
16Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
17Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
18---
19 kernel/irq/autoprobe.c | 4 ++--
20 kernel/irq/chip.c | 17 ++++++++++-------
21 kernel/irq/internals.h | 2 +-
22 kernel/irq/manage.c | 2 +-
23 4 files changed, 14 insertions(+), 11 deletions(-)
24
25diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
26index 342d8f4..0119b9d 100644
27--- a/kernel/irq/autoprobe.c
28+++ b/kernel/irq/autoprobe.c
29@@ -53,7 +53,7 @@ unsigned long probe_irq_on(void)
30 if (desc->irq_data.chip->irq_set_type)
31 desc->irq_data.chip->irq_set_type(&desc->irq_data,
32 IRQ_TYPE_PROBE);
33- irq_startup(desc);
34+ irq_startup(desc, false);
35 }
36 raw_spin_unlock_irq(&desc->lock);
37 }
38@@ -70,7 +70,7 @@ unsigned long probe_irq_on(void)
39 raw_spin_lock_irq(&desc->lock);
40 if (!desc->action && irq_settings_can_probe(desc)) {
41 desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
42- if (irq_startup(desc))
43+ if (irq_startup(desc, false))
44 desc->istate |= IRQS_PENDING;
45 }
46 raw_spin_unlock_irq(&desc->lock);
47diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
48index b742edc..fb7db75 100644
49--- a/kernel/irq/chip.c
50+++ b/kernel/irq/chip.c
51@@ -157,19 +157,22 @@ static void irq_state_set_masked(struct irq_desc *desc)
52 irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
53 }
54
55-int irq_startup(struct irq_desc *desc)
56+int irq_startup(struct irq_desc *desc, bool resend)
57 {
58+ int ret = 0;
59+
60 irq_state_clr_disabled(desc);
61 desc->depth = 0;
62
63 if (desc->irq_data.chip->irq_startup) {
64- int ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
65+ ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
66 irq_state_clr_masked(desc);
67- return ret;
68+ } else {
69+ irq_enable(desc);
70 }
71-
72- irq_enable(desc);
73- return 0;
74+ if (resend)
75+ check_irq_resend(desc, desc->irq_data.irq);
76+ return ret;
77 }
78
79 void irq_shutdown(struct irq_desc *desc)
80@@ -646,7 +649,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
81 irq_settings_set_noprobe(desc);
82 irq_settings_set_norequest(desc);
83 irq_settings_set_nothread(desc);
84- irq_startup(desc);
85+ irq_startup(desc, true);
86 }
87 out:
88 irq_put_desc_busunlock(desc, flags);
89diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
90index a73dd6c..e1a8b64 100644
91--- a/kernel/irq/internals.h
92+++ b/kernel/irq/internals.h
93@@ -67,7 +67,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
94 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
95 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
96
97-extern int irq_startup(struct irq_desc *desc);
98+extern int irq_startup(struct irq_desc *desc, bool resend);
99 extern void irq_shutdown(struct irq_desc *desc);
100 extern void irq_enable(struct irq_desc *desc);
101 extern void irq_disable(struct irq_desc *desc);
102diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
103index 1da999f..cf2d7ae 100644
104--- a/kernel/irq/manage.c
105+++ b/kernel/irq/manage.c
106@@ -1027,7 +1027,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
107 desc->istate |= IRQS_ONESHOT;
108
109 if (irq_settings_can_autoenable(desc))
110- irq_startup(desc);
111+ irq_startup(desc, true);
112 else
113 /* Undo nested disables: */
114 desc->depth = 1;
115--
1161.7.9.4
117