diff options
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.patch | 117 |
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 @@ | |||
1 | From cde7a1b79f95c783def648bff541ee319148e611 Mon Sep 17 00:00:00 2001 | ||
2 | From: Thomas Gleixner <tglx@linutronix.de> | ||
3 | Date: Wed, 8 Feb 2012 11:57:52 +0100 | ||
4 | Subject: [PATCH 57/72] genirq: Handle pending irqs in irq_startup() | ||
5 | |||
6 | commit b4bc724e82e80478cba5fe9825b62e71ddf78757 upstream. | ||
7 | |||
8 | An interrupt might be pending when irq_startup() is called, but the | ||
9 | startup code does not invoke the resend logic. In some cases this | ||
10 | prevents the device from issuing another interrupt which renders the | ||
11 | device non functional. | ||
12 | |||
13 | Call the resend function in irq_startup() to keep things going. | ||
14 | |||
15 | Reported-and-tested-by: Russell King <rmk+kernel@arm.linux.org.uk> | ||
16 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | ||
17 | Signed-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 | |||
25 | diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c | ||
26 | index 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); | ||
47 | diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c | ||
48 | index 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); | ||
89 | diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h | ||
90 | index 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); | ||
102 | diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c | ||
103 | index 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 | -- | ||
116 | 1.7.9.4 | ||
117 | |||