diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-02-07 16:11:30 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-02-19 06:58:17 -0500 |
commit | c1594b77e46124bb462f961e536120e471c67446 (patch) | |
tree | 3f52ad5809125ab5be6db1fd4b1212fe6127df66 | |
parent | 163ef3091195f514a06f064b12914597d2644c55 (diff) |
genirq: Move IRQ_DISABLED to core
Keep status in sync until all abusers are fixed.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | include/linux/irq.h | 4 | ||||
-rw-r--r-- | kernel/irq/chip.c | 48 | ||||
-rw-r--r-- | kernel/irq/compat.h | 12 | ||||
-rw-r--r-- | kernel/irq/internals.h | 4 | ||||
-rw-r--r-- | kernel/irq/irqdesc.c | 2 | ||||
-rw-r--r-- | kernel/irq/manage.c | 4 | ||||
-rw-r--r-- | kernel/irq/migration.c | 2 | ||||
-rw-r--r-- | kernel/irq/settings.h | 2 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 4 |
9 files changed, 57 insertions, 25 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index c38dbd506656..32efca71ce88 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -55,9 +55,9 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, | |||
55 | #define IRQ_INPROGRESS 0x00000100 /* DEPRECATED */ | 55 | #define IRQ_INPROGRESS 0x00000100 /* DEPRECATED */ |
56 | #define IRQ_REPLAY 0x00000200 /* DEPRECATED */ | 56 | #define IRQ_REPLAY 0x00000200 /* DEPRECATED */ |
57 | #define IRQ_WAITING 0x00000400 /* DEPRECATED */ | 57 | #define IRQ_WAITING 0x00000400 /* DEPRECATED */ |
58 | #define IRQ_DISABLED 0x00000800 /* DEPRECATED */ | ||
58 | #endif | 59 | #endif |
59 | 60 | ||
60 | #define IRQ_DISABLED 0x00000800 /* IRQ disabled - do not enter! */ | ||
61 | #define IRQ_PENDING 0x00001000 /* IRQ pending - replay on enable */ | 61 | #define IRQ_PENDING 0x00001000 /* IRQ pending - replay on enable */ |
62 | 62 | ||
63 | #define IRQ_LEVEL 0x00004000 /* IRQ level triggered */ | 63 | #define IRQ_LEVEL 0x00004000 /* IRQ level triggered */ |
@@ -231,7 +231,7 @@ struct irq_chip { | |||
231 | # define ARCH_IRQ_INIT_FLAGS 0 | 231 | # define ARCH_IRQ_INIT_FLAGS 0 |
232 | #endif | 232 | #endif |
233 | 233 | ||
234 | #define IRQ_DEFAULT_INIT_FLAGS (IRQ_DISABLED | ARCH_IRQ_INIT_FLAGS) | 234 | #define IRQ_DEFAULT_INIT_FLAGS ARCH_IRQ_INIT_FLAGS |
235 | 235 | ||
236 | struct irqaction; | 236 | struct irqaction; |
237 | extern int setup_irq(unsigned int irq, struct irqaction *new); | 237 | extern int setup_irq(unsigned int irq, struct irqaction *new); |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 59ae14527ecd..527df7ab1b05 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -164,9 +164,21 @@ struct irq_data *irq_get_irq_data(unsigned int irq) | |||
164 | } | 164 | } |
165 | EXPORT_SYMBOL_GPL(irq_get_irq_data); | 165 | EXPORT_SYMBOL_GPL(irq_get_irq_data); |
166 | 166 | ||
167 | static void irq_state_clr_disabled(struct irq_desc *desc) | ||
168 | { | ||
169 | desc->istate &= ~IRQS_DISABLED; | ||
170 | irq_compat_clr_disabled(desc); | ||
171 | } | ||
172 | |||
173 | static void irq_state_set_disabled(struct irq_desc *desc) | ||
174 | { | ||
175 | desc->istate |= IRQS_DISABLED; | ||
176 | irq_compat_set_disabled(desc); | ||
177 | } | ||
178 | |||
167 | int irq_startup(struct irq_desc *desc) | 179 | int irq_startup(struct irq_desc *desc) |
168 | { | 180 | { |
169 | desc->status &= ~IRQ_DISABLED; | 181 | irq_state_clr_disabled(desc); |
170 | desc->depth = 0; | 182 | desc->depth = 0; |
171 | 183 | ||
172 | if (desc->irq_data.chip->irq_startup) { | 184 | if (desc->irq_data.chip->irq_startup) { |
@@ -181,7 +193,7 @@ int irq_startup(struct irq_desc *desc) | |||
181 | 193 | ||
182 | void irq_shutdown(struct irq_desc *desc) | 194 | void irq_shutdown(struct irq_desc *desc) |
183 | { | 195 | { |
184 | desc->status |= IRQ_DISABLED; | 196 | irq_state_set_disabled(desc); |
185 | desc->depth = 1; | 197 | desc->depth = 1; |
186 | if (desc->irq_data.chip->irq_shutdown) | 198 | if (desc->irq_data.chip->irq_shutdown) |
187 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 199 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); |
@@ -194,7 +206,7 @@ void irq_shutdown(struct irq_desc *desc) | |||
194 | 206 | ||
195 | void irq_enable(struct irq_desc *desc) | 207 | void irq_enable(struct irq_desc *desc) |
196 | { | 208 | { |
197 | desc->status &= ~IRQ_DISABLED; | 209 | irq_state_clr_disabled(desc); |
198 | if (desc->irq_data.chip->irq_enable) | 210 | if (desc->irq_data.chip->irq_enable) |
199 | desc->irq_data.chip->irq_enable(&desc->irq_data); | 211 | desc->irq_data.chip->irq_enable(&desc->irq_data); |
200 | else | 212 | else |
@@ -204,7 +216,7 @@ void irq_enable(struct irq_desc *desc) | |||
204 | 216 | ||
205 | void irq_disable(struct irq_desc *desc) | 217 | void irq_disable(struct irq_desc *desc) |
206 | { | 218 | { |
207 | desc->status |= IRQ_DISABLED; | 219 | irq_state_set_disabled(desc); |
208 | if (desc->irq_data.chip->irq_disable) { | 220 | if (desc->irq_data.chip->irq_disable) { |
209 | desc->irq_data.chip->irq_disable(&desc->irq_data); | 221 | desc->irq_data.chip->irq_disable(&desc->irq_data); |
210 | desc->status |= IRQ_MASKED; | 222 | desc->status |= IRQ_MASKED; |
@@ -380,7 +392,7 @@ void handle_nested_irq(unsigned int irq) | |||
380 | kstat_incr_irqs_this_cpu(irq, desc); | 392 | kstat_incr_irqs_this_cpu(irq, desc); |
381 | 393 | ||
382 | action = desc->action; | 394 | action = desc->action; |
383 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) | 395 | if (unlikely(!action || (desc->istate & IRQS_DISABLED))) |
384 | goto out_unlock; | 396 | goto out_unlock; |
385 | 397 | ||
386 | irq_compat_set_progress(desc); | 398 | irq_compat_set_progress(desc); |
@@ -431,7 +443,7 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) | |||
431 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); | 443 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); |
432 | kstat_incr_irqs_this_cpu(irq, desc); | 444 | kstat_incr_irqs_this_cpu(irq, desc); |
433 | 445 | ||
434 | if (unlikely(!desc->action || (desc->status & IRQ_DISABLED))) | 446 | if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) |
435 | goto out_unlock; | 447 | goto out_unlock; |
436 | 448 | ||
437 | handle_irq_event(desc); | 449 | handle_irq_event(desc); |
@@ -467,12 +479,12 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) | |||
467 | * If its disabled or no action available | 479 | * If its disabled or no action available |
468 | * keep it masked and get out of here | 480 | * keep it masked and get out of here |
469 | */ | 481 | */ |
470 | if (unlikely(!desc->action || (desc->status & IRQ_DISABLED))) | 482 | if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) |
471 | goto out_unlock; | 483 | goto out_unlock; |
472 | 484 | ||
473 | handle_irq_event(desc); | 485 | handle_irq_event(desc); |
474 | 486 | ||
475 | if (!(desc->status & IRQ_DISABLED) && !(desc->istate & IRQS_ONESHOT)) | 487 | if (!(desc->istate & (IRQS_DISABLED | IRQS_ONESHOT))) |
476 | unmask_irq(desc); | 488 | unmask_irq(desc); |
477 | out_unlock: | 489 | out_unlock: |
478 | raw_spin_unlock(&desc->lock); | 490 | raw_spin_unlock(&desc->lock); |
@@ -505,7 +517,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) | |||
505 | * If its disabled or no action available | 517 | * If its disabled or no action available |
506 | * then mask it and get out of here: | 518 | * then mask it and get out of here: |
507 | */ | 519 | */ |
508 | if (unlikely(!desc->action || (desc->status & IRQ_DISABLED))) { | 520 | if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) { |
509 | desc->status |= IRQ_PENDING; | 521 | desc->status |= IRQ_PENDING; |
510 | mask_irq(desc); | 522 | mask_irq(desc); |
511 | goto out; | 523 | goto out; |
@@ -543,8 +555,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) | |||
543 | * we shouldn't process the IRQ. Mark it pending, handle | 555 | * we shouldn't process the IRQ. Mark it pending, handle |
544 | * the necessary masking and go out | 556 | * the necessary masking and go out |
545 | */ | 557 | */ |
546 | if (unlikely((desc->istate & (IRQS_INPROGRESS) || | 558 | if (unlikely((desc->istate & (IRQS_DISABLED | IRQS_INPROGRESS) || |
547 | (desc->status & IRQ_DISABLED) || !desc->action))) { | 559 | !desc->action))) { |
548 | if (!irq_check_poll(desc)) { | 560 | if (!irq_check_poll(desc)) { |
549 | desc->status |= IRQ_PENDING; | 561 | desc->status |= IRQ_PENDING; |
550 | mask_ack_irq(desc); | 562 | mask_ack_irq(desc); |
@@ -567,15 +579,16 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) | |||
567 | * one, we could have masked the irq. | 579 | * one, we could have masked the irq. |
568 | * Renable it, if it was not disabled in meantime. | 580 | * Renable it, if it was not disabled in meantime. |
569 | */ | 581 | */ |
570 | if (unlikely((desc->status & | 582 | if (unlikely(desc->status & IRQ_PENDING)) { |
571 | (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) == | 583 | if (!(desc->istate & IRQS_DISABLED) && |
572 | (IRQ_PENDING | IRQ_MASKED))) { | 584 | (desc->status & IRQ_MASKED)) |
573 | unmask_irq(desc); | 585 | unmask_irq(desc); |
574 | } | 586 | } |
575 | 587 | ||
576 | handle_irq_event(desc); | 588 | handle_irq_event(desc); |
577 | 589 | ||
578 | } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); | 590 | } while ((desc->status & IRQ_PENDING) && |
591 | !(desc->istate & IRQS_DISABLED)); | ||
579 | 592 | ||
580 | out_unlock: | 593 | out_unlock: |
581 | raw_spin_unlock(&desc->lock); | 594 | raw_spin_unlock(&desc->lock); |
@@ -639,7 +652,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
639 | if (handle == handle_bad_irq) { | 652 | if (handle == handle_bad_irq) { |
640 | if (desc->irq_data.chip != &no_irq_chip) | 653 | if (desc->irq_data.chip != &no_irq_chip) |
641 | mask_ack_irq(desc); | 654 | mask_ack_irq(desc); |
642 | desc->status |= IRQ_DISABLED; | 655 | irq_compat_set_disabled(desc); |
656 | desc->istate |= IRQS_DISABLED; | ||
643 | desc->depth = 1; | 657 | desc->depth = 1; |
644 | } | 658 | } |
645 | desc->handle_irq = handle; | 659 | desc->handle_irq = handle; |
diff --git a/kernel/irq/compat.h b/kernel/irq/compat.h index aac6e400e608..bc0c2a501e82 100644 --- a/kernel/irq/compat.h +++ b/kernel/irq/compat.h | |||
@@ -11,7 +11,19 @@ static inline void irq_compat_clr_progress(struct irq_desc *desc) | |||
11 | { | 11 | { |
12 | desc->status &= ~IRQ_INPROGRESS; | 12 | desc->status &= ~IRQ_INPROGRESS; |
13 | } | 13 | } |
14 | static inline void irq_compat_set_disabled(struct irq_desc *desc) | ||
15 | { | ||
16 | desc->status |= IRQ_DISABLED; | ||
17 | } | ||
18 | |||
19 | static inline void irq_compat_clr_disabled(struct irq_desc *desc) | ||
20 | { | ||
21 | desc->status &= ~IRQ_DISABLED; | ||
22 | } | ||
14 | #else | 23 | #else |
15 | static inline void irq_compat_set_progress(struct irq_desc *desc) { } | 24 | static inline void irq_compat_set_progress(struct irq_desc *desc) { } |
16 | static inline void irq_compat_clr_progress(struct irq_desc *desc) { } | 25 | static inline void irq_compat_clr_progress(struct irq_desc *desc) { } |
26 | static inline void irq_compat_set_disabled(struct irq_desc *desc) { } | ||
27 | static inline void irq_compat_clr_disabled(struct irq_desc *desc) { } | ||
17 | #endif | 28 | #endif |
29 | |||
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 54037533af7a..919d2dd0bb33 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -45,6 +45,7 @@ enum { | |||
45 | * IRQS_ONESHOT - irq is not unmasked in primary handler | 45 | * IRQS_ONESHOT - irq is not unmasked in primary handler |
46 | * IRQS_REPLAY - irq is replayed | 46 | * IRQS_REPLAY - irq is replayed |
47 | * IRQS_WAITING - irq is waiting | 47 | * IRQS_WAITING - irq is waiting |
48 | * IRQS_DISABLED - irq is disabled | ||
48 | */ | 49 | */ |
49 | enum { | 50 | enum { |
50 | IRQS_AUTODETECT = 0x00000001, | 51 | IRQS_AUTODETECT = 0x00000001, |
@@ -54,6 +55,7 @@ enum { | |||
54 | IRQS_ONESHOT = 0x00000020, | 55 | IRQS_ONESHOT = 0x00000020, |
55 | IRQS_REPLAY = 0x00000040, | 56 | IRQS_REPLAY = 0x00000040, |
56 | IRQS_WAITING = 0x00000080, | 57 | IRQS_WAITING = 0x00000080, |
58 | IRQS_DISABLED = 0x00000100, | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | #define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) | 61 | #define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) |
@@ -137,7 +139,6 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) | |||
137 | print_symbol("%s\n", (unsigned long)desc->action->handler); | 139 | print_symbol("%s\n", (unsigned long)desc->action->handler); |
138 | } | 140 | } |
139 | 141 | ||
140 | P(IRQ_DISABLED); | ||
141 | P(IRQ_PENDING); | 142 | P(IRQ_PENDING); |
142 | P(IRQ_LEVEL); | 143 | P(IRQ_LEVEL); |
143 | P(IRQ_MASKED); | 144 | P(IRQ_MASKED); |
@@ -152,6 +153,7 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) | |||
152 | PS(IRQS_INPROGRESS); | 153 | PS(IRQS_INPROGRESS); |
153 | PS(IRQS_REPLAY); | 154 | PS(IRQS_REPLAY); |
154 | PS(IRQS_WAITING); | 155 | PS(IRQS_WAITING); |
156 | PS(IRQS_DISABLED); | ||
155 | } | 157 | } |
156 | 158 | ||
157 | #undef P | 159 | #undef P |
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 8b87f2ce0203..78866d050bc9 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
@@ -80,6 +80,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node) | |||
80 | desc->irq_data.handler_data = NULL; | 80 | desc->irq_data.handler_data = NULL; |
81 | desc->irq_data.msi_desc = NULL; | 81 | desc->irq_data.msi_desc = NULL; |
82 | desc->status = _IRQ_DEFAULT_INIT_FLAGS; | 82 | desc->status = _IRQ_DEFAULT_INIT_FLAGS; |
83 | desc->istate = IRQS_DISABLED; | ||
83 | desc->handle_irq = handle_bad_irq; | 84 | desc->handle_irq = handle_bad_irq; |
84 | desc->depth = 1; | 85 | desc->depth = 1; |
85 | desc->irq_count = 0; | 86 | desc->irq_count = 0; |
@@ -247,6 +248,7 @@ int __init early_irq_init(void) | |||
247 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | 248 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { |
248 | [0 ... NR_IRQS-1] = { | 249 | [0 ... NR_IRQS-1] = { |
249 | .status = _IRQ_DEFAULT_INIT_FLAGS, | 250 | .status = _IRQ_DEFAULT_INIT_FLAGS, |
251 | .istate = IRQS_DISABLED, | ||
250 | .handle_irq = handle_bad_irq, | 252 | .handle_irq = handle_bad_irq, |
251 | .depth = 1, | 253 | .depth = 1, |
252 | .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock), | 254 | .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock), |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 7971df53d6a9..77ff275b54cf 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -646,7 +646,7 @@ again: | |||
646 | goto again; | 646 | goto again; |
647 | } | 647 | } |
648 | 648 | ||
649 | if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) { | 649 | if (!(desc->istate & IRQS_DISABLED) && (desc->status & IRQ_MASKED)) { |
650 | desc->status &= ~IRQ_MASKED; | 650 | desc->status &= ~IRQ_MASKED; |
651 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 651 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
652 | } | 652 | } |
@@ -709,7 +709,7 @@ static int irq_thread(void *data) | |||
709 | atomic_inc(&desc->threads_active); | 709 | atomic_inc(&desc->threads_active); |
710 | 710 | ||
711 | raw_spin_lock_irq(&desc->lock); | 711 | raw_spin_lock_irq(&desc->lock); |
712 | if (unlikely(desc->status & IRQ_DISABLED)) { | 712 | if (unlikely(desc->istate & IRQS_DISABLED)) { |
713 | /* | 713 | /* |
714 | * CHECKME: We might need a dedicated | 714 | * CHECKME: We might need a dedicated |
715 | * IRQ_THREAD_PENDING flag here, which | 715 | * IRQ_THREAD_PENDING flag here, which |
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index 441fd629ff04..8c68cb8555a7 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c | |||
@@ -61,7 +61,7 @@ void move_native_irq(int irq) | |||
61 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) | 61 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) |
62 | return; | 62 | return; |
63 | 63 | ||
64 | if (unlikely(desc->status & IRQ_DISABLED)) | 64 | if (unlikely(desc->istate & IRQS_DISABLED)) |
65 | return; | 65 | return; |
66 | 66 | ||
67 | /* | 67 | /* |
diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h index 2e7d08fff0ce..5e3411c7c62b 100644 --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h | |||
@@ -12,3 +12,5 @@ enum { | |||
12 | #define IRQ_REPLAY GOT_YOU_MORON | 12 | #define IRQ_REPLAY GOT_YOU_MORON |
13 | #undef IRQ_WAITING | 13 | #undef IRQ_WAITING |
14 | #define IRQ_WAITING GOT_YOU_MORON | 14 | #define IRQ_WAITING GOT_YOU_MORON |
15 | #undef IRQ_DISABLED | ||
16 | #define IRQ_DISABLED GOT_YOU_MORON | ||
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index 51504837d8cc..367614f858ff 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -50,7 +50,7 @@ bool irq_wait_for_poll(struct irq_desc *desc) | |||
50 | raw_spin_lock(&desc->lock); | 50 | raw_spin_lock(&desc->lock); |
51 | } while (desc->istate & IRQS_INPROGRESS); | 51 | } while (desc->istate & IRQS_INPROGRESS); |
52 | /* Might have been disabled in meantime */ | 52 | /* Might have been disabled in meantime */ |
53 | return !(desc->status & IRQ_DISABLED) && desc->action; | 53 | return !(desc->istate & IRQS_DISABLED) && desc->action; |
54 | #else | 54 | #else |
55 | return false; | 55 | return false; |
56 | #endif | 56 | #endif |
@@ -75,7 +75,7 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force) | |||
75 | * Do not poll disabled interrupts unless the spurious | 75 | * Do not poll disabled interrupts unless the spurious |
76 | * disabled poller asks explicitely. | 76 | * disabled poller asks explicitely. |
77 | */ | 77 | */ |
78 | if ((desc->status & IRQ_DISABLED) && !force) | 78 | if ((desc->istate & IRQS_DISABLED) && !force) |
79 | goto out; | 79 | goto out; |
80 | 80 | ||
81 | /* | 81 | /* |