diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-02-02 16:41:14 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-02-19 06:58:10 -0500 |
commit | 4699923861513671d3f6ade8efb4e56a9a7ecadf (patch) | |
tree | 862cda99b9af6fe96fda955107f24a7b5cc97a18 /kernel | |
parent | 3b56f0585fd4c02d047dc406668cb40159b2d340 (diff) |
genirq: Consolidate startup/shutdown of interrupts
Aside of duplicated code some of the startup/shutdown sites do not
handle the MASKED/DISABLED flags and the depth field at all. Move that
to a helper function and take care of it there.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110202212551.787481468@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/irq/autoprobe.c | 10 | ||||
-rw-r--r-- | kernel/irq/chip.c | 37 | ||||
-rw-r--r-- | kernel/irq/internals.h | 3 | ||||
-rw-r--r-- | kernel/irq/manage.c | 14 |
4 files changed, 33 insertions, 31 deletions
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 505798f86c36..08947cb61725 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
@@ -60,7 +60,7 @@ unsigned long probe_irq_on(void) | |||
60 | if (desc->irq_data.chip->irq_set_type) | 60 | if (desc->irq_data.chip->irq_set_type) |
61 | desc->irq_data.chip->irq_set_type(&desc->irq_data, | 61 | desc->irq_data.chip->irq_set_type(&desc->irq_data, |
62 | IRQ_TYPE_PROBE); | 62 | IRQ_TYPE_PROBE); |
63 | desc->irq_data.chip->irq_startup(&desc->irq_data); | 63 | irq_startup(desc); |
64 | } | 64 | } |
65 | raw_spin_unlock_irq(&desc->lock); | 65 | raw_spin_unlock_irq(&desc->lock); |
66 | } | 66 | } |
@@ -77,7 +77,7 @@ unsigned long probe_irq_on(void) | |||
77 | raw_spin_lock_irq(&desc->lock); | 77 | raw_spin_lock_irq(&desc->lock); |
78 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 78 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
79 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; | 79 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; |
80 | if (desc->irq_data.chip->irq_startup(&desc->irq_data)) | 80 | if (irq_startup(desc)) |
81 | desc->status |= IRQ_PENDING; | 81 | desc->status |= IRQ_PENDING; |
82 | } | 82 | } |
83 | raw_spin_unlock_irq(&desc->lock); | 83 | raw_spin_unlock_irq(&desc->lock); |
@@ -99,7 +99,7 @@ unsigned long probe_irq_on(void) | |||
99 | /* It triggered already - consider it spurious. */ | 99 | /* It triggered already - consider it spurious. */ |
100 | if (!(status & IRQ_WAITING)) { | 100 | if (!(status & IRQ_WAITING)) { |
101 | desc->status = status & ~IRQ_AUTODETECT; | 101 | desc->status = status & ~IRQ_AUTODETECT; |
102 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 102 | irq_shutdown(desc); |
103 | } else | 103 | } else |
104 | if (i < 32) | 104 | if (i < 32) |
105 | mask |= 1 << i; | 105 | mask |= 1 << i; |
@@ -138,7 +138,7 @@ unsigned int probe_irq_mask(unsigned long val) | |||
138 | mask |= 1 << i; | 138 | mask |= 1 << i; |
139 | 139 | ||
140 | desc->status = status & ~IRQ_AUTODETECT; | 140 | desc->status = status & ~IRQ_AUTODETECT; |
141 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 141 | irq_shutdown(desc); |
142 | } | 142 | } |
143 | raw_spin_unlock_irq(&desc->lock); | 143 | raw_spin_unlock_irq(&desc->lock); |
144 | } | 144 | } |
@@ -182,7 +182,7 @@ int probe_irq_off(unsigned long val) | |||
182 | nr_of_irqs++; | 182 | nr_of_irqs++; |
183 | } | 183 | } |
184 | desc->status = status & ~IRQ_AUTODETECT; | 184 | desc->status = status & ~IRQ_AUTODETECT; |
185 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 185 | irq_shutdown(desc); |
186 | } | 186 | } |
187 | raw_spin_unlock_irq(&desc->lock); | 187 | raw_spin_unlock_irq(&desc->lock); |
188 | } | 188 | } |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 31258782742c..988fe7a24282 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -192,6 +192,25 @@ void set_irq_nested_thread(unsigned int irq, int nest) | |||
192 | } | 192 | } |
193 | EXPORT_SYMBOL_GPL(set_irq_nested_thread); | 193 | EXPORT_SYMBOL_GPL(set_irq_nested_thread); |
194 | 194 | ||
195 | int irq_startup(struct irq_desc *desc) | ||
196 | { | ||
197 | desc->status &= ~(IRQ_MASKED | IRQ_DISABLED); | ||
198 | desc->depth = 0; | ||
199 | |||
200 | if (desc->irq_data.chip->irq_startup) | ||
201 | return desc->irq_data.chip->irq_startup(&desc->irq_data); | ||
202 | |||
203 | desc->irq_data.chip->irq_enable(&desc->irq_data); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | void irq_shutdown(struct irq_desc *desc) | ||
208 | { | ||
209 | desc->status |= IRQ_MASKED | IRQ_DISABLED; | ||
210 | desc->depth = 1; | ||
211 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | ||
212 | } | ||
213 | |||
195 | /* | 214 | /* |
196 | * default enable function | 215 | * default enable function |
197 | */ | 216 | */ |
@@ -211,17 +230,6 @@ static void default_disable(struct irq_data *data) | |||
211 | } | 230 | } |
212 | 231 | ||
213 | /* | 232 | /* |
214 | * default startup function | ||
215 | */ | ||
216 | static unsigned int default_startup(struct irq_data *data) | ||
217 | { | ||
218 | struct irq_desc *desc = irq_data_to_desc(data); | ||
219 | |||
220 | desc->irq_data.chip->irq_enable(data); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * default shutdown function | 233 | * default shutdown function |
226 | */ | 234 | */ |
227 | static void default_shutdown(struct irq_data *data) | 235 | static void default_shutdown(struct irq_data *data) |
@@ -229,7 +237,6 @@ static void default_shutdown(struct irq_data *data) | |||
229 | struct irq_desc *desc = irq_data_to_desc(data); | 237 | struct irq_desc *desc = irq_data_to_desc(data); |
230 | 238 | ||
231 | desc->irq_data.chip->irq_mask(&desc->irq_data); | 239 | desc->irq_data.chip->irq_mask(&desc->irq_data); |
232 | desc->status |= IRQ_MASKED; | ||
233 | } | 240 | } |
234 | 241 | ||
235 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED | 242 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED |
@@ -337,8 +344,6 @@ void irq_chip_set_defaults(struct irq_chip *chip) | |||
337 | chip->irq_enable = default_enable; | 344 | chip->irq_enable = default_enable; |
338 | if (!chip->irq_disable) | 345 | if (!chip->irq_disable) |
339 | chip->irq_disable = default_disable; | 346 | chip->irq_disable = default_disable; |
340 | if (!chip->irq_startup) | ||
341 | chip->irq_startup = default_startup; | ||
342 | /* | 347 | /* |
343 | * We use chip->irq_disable, when the user provided its own. When | 348 | * We use chip->irq_disable, when the user provided its own. When |
344 | * we have default_disable set for chip->irq_disable, then we need | 349 | * we have default_disable set for chip->irq_disable, then we need |
@@ -747,10 +752,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
747 | desc->name = name; | 752 | desc->name = name; |
748 | 753 | ||
749 | if (handle != handle_bad_irq && is_chained) { | 754 | if (handle != handle_bad_irq && is_chained) { |
750 | desc->status &= ~IRQ_DISABLED; | ||
751 | desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; | 755 | desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; |
752 | desc->depth = 0; | 756 | irq_startup(desc); |
753 | desc->irq_data.chip->irq_startup(&desc->irq_data); | ||
754 | } | 757 | } |
755 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 758 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
756 | chip_bus_sync_unlock(desc); | 759 | chip_bus_sync_unlock(desc); |
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index b17c98440400..5cbfc93ed7b1 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -38,6 +38,9 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
38 | extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp); | 38 | extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp); |
39 | extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume); | 39 | extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume); |
40 | 40 | ||
41 | extern int irq_startup(struct irq_desc *desc); | ||
42 | extern void irq_shutdown(struct irq_desc *desc); | ||
43 | |||
41 | extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); | 44 | extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); |
42 | 45 | ||
43 | /* Resending of interrupts :*/ | 46 | /* Resending of interrupts :*/ |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 30bc8de40905..9c562477e28b 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -906,11 +906,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
906 | if (new->flags & IRQF_ONESHOT) | 906 | if (new->flags & IRQF_ONESHOT) |
907 | desc->status |= IRQ_ONESHOT; | 907 | desc->status |= IRQ_ONESHOT; |
908 | 908 | ||
909 | if (!(desc->status & IRQ_NOAUTOEN)) { | 909 | if (!(desc->status & IRQ_NOAUTOEN)) |
910 | desc->depth = 0; | 910 | irq_startup(desc); |
911 | desc->status &= ~IRQ_DISABLED; | 911 | else |
912 | desc->irq_data.chip->irq_startup(&desc->irq_data); | ||
913 | } else | ||
914 | /* Undo nested disables: */ | 912 | /* Undo nested disables: */ |
915 | desc->depth = 1; | 913 | desc->depth = 1; |
916 | 914 | ||
@@ -1055,10 +1053,8 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
1055 | #endif | 1053 | #endif |
1056 | 1054 | ||
1057 | /* If this was the last handler, shut down the IRQ line: */ | 1055 | /* If this was the last handler, shut down the IRQ line: */ |
1058 | if (!desc->action) { | 1056 | if (!desc->action) |
1059 | desc->status |= IRQ_DISABLED; | 1057 | irq_shutdown(desc); |
1060 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | ||
1061 | } | ||
1062 | 1058 | ||
1063 | #ifdef CONFIG_SMP | 1059 | #ifdef CONFIG_SMP |
1064 | /* make sure affinity_hint is cleaned up */ | 1060 | /* make sure affinity_hint is cleaned up */ |