aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-02-07 15:48:49 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-19 06:58:16 -0500
commit009b4c3b8ad584b3462734127a5bec680d5d6af4 (patch)
treef7cb860dde86ba96afcc085ec7a75ca2a41e49b6
parent6954b75b488dd740950573f244ddd66fd28620aa (diff)
genirq: Add IRQ_INPROGRESS to core
We need to maintain the flag for now in both fields status and istate. Add a CONFIG_GENERIC_HARDIRQS_NO_COMPAT switch to allow testing w/o the status one. Wrap the access to status IRQ_INPROGRESS in a inline which can be turned of with CONFIG_GENERIC_HARDIRQS_NO_COMPAT along with the define. There is no reason that anything outside of core looks at this. That needs some modifications, but we'll get there. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/irq.h6
-rw-r--r--kernel/irq/Kconfig3
-rw-r--r--kernel/irq/chip.c16
-rw-r--r--kernel/irq/compat.h17
-rw-r--r--kernel/irq/handle.c6
-rw-r--r--kernel/irq/internals.h5
-rw-r--r--kernel/irq/manage.c17
-rw-r--r--kernel/irq/settings.h3
-rw-r--r--kernel/irq/spurious.c6
9 files changed, 57 insertions, 22 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 047a695511df..274590fc55a3 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -50,7 +50,11 @@ typedef void (*irq_flow_handler_t)(unsigned int irq,
50#define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */ 50#define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */
51 51
52/* Internal flags */ 52/* Internal flags */
53#define IRQ_INPROGRESS 0x00000100 /* IRQ handler active - do not enter! */ 53
54#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
55#define IRQ_INPROGRESS 0x00000100 /* DEPRECATED */
56#endif
57
54#define IRQ_DISABLED 0x00000200 /* IRQ disabled - do not enter! */ 58#define IRQ_DISABLED 0x00000200 /* IRQ disabled - do not enter! */
55#define IRQ_PENDING 0x00000400 /* IRQ pending - replay on enable */ 59#define IRQ_PENDING 0x00000400 /* IRQ pending - replay on enable */
56#define IRQ_REPLAY 0x00000800 /* IRQ has been replayed but not acked yet */ 60#define IRQ_REPLAY 0x00000800 /* IRQ has been replayed but not acked yet */
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 4cd5d7135e0f..9e2256de1d1a 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -13,6 +13,9 @@ config GENERIC_HARDIRQS
13config GENERIC_HARDIRQS_NO_DEPRECATED 13config GENERIC_HARDIRQS_NO_DEPRECATED
14 def_bool n 14 def_bool n
15 15
16config GENERIC_HARDIRQS_NO_COMPAT
17 def_bool n
18
16# Options selectable by the architecture code 19# Options selectable by the architecture code
17config HAVE_SPARSE_IRQ 20config HAVE_SPARSE_IRQ
18 def_bool n 21 def_bool n
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 34245e7d1213..075385549dcd 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -383,7 +383,8 @@ void handle_nested_irq(unsigned int irq)
383 if (unlikely(!action || (desc->status & IRQ_DISABLED))) 383 if (unlikely(!action || (desc->status & IRQ_DISABLED)))
384 goto out_unlock; 384 goto out_unlock;
385 385
386 desc->status |= IRQ_INPROGRESS; 386 irq_compat_set_progress(desc);
387 desc->istate |= IRQS_INPROGRESS;
387 raw_spin_unlock_irq(&desc->lock); 388 raw_spin_unlock_irq(&desc->lock);
388 389
389 action_ret = action->thread_fn(action->irq, action->dev_id); 390 action_ret = action->thread_fn(action->irq, action->dev_id);
@@ -391,7 +392,8 @@ void handle_nested_irq(unsigned int irq)
391 note_interrupt(irq, desc, action_ret); 392 note_interrupt(irq, desc, action_ret);
392 393
393 raw_spin_lock_irq(&desc->lock); 394 raw_spin_lock_irq(&desc->lock);
394 desc->status &= ~IRQ_INPROGRESS; 395 desc->istate &= ~IRQS_INPROGRESS;
396 irq_compat_clr_progress(desc);
395 397
396out_unlock: 398out_unlock:
397 raw_spin_unlock_irq(&desc->lock); 399 raw_spin_unlock_irq(&desc->lock);
@@ -422,7 +424,7 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
422{ 424{
423 raw_spin_lock(&desc->lock); 425 raw_spin_lock(&desc->lock);
424 426
425 if (unlikely(desc->status & IRQ_INPROGRESS)) 427 if (unlikely(desc->istate & IRQS_INPROGRESS))
426 if (!irq_check_poll(desc)) 428 if (!irq_check_poll(desc))
427 goto out_unlock; 429 goto out_unlock;
428 430
@@ -454,7 +456,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
454 raw_spin_lock(&desc->lock); 456 raw_spin_lock(&desc->lock);
455 mask_ack_irq(desc); 457 mask_ack_irq(desc);
456 458
457 if (unlikely(desc->status & IRQ_INPROGRESS)) 459 if (unlikely(desc->istate & IRQS_INPROGRESS))
458 if (!irq_check_poll(desc)) 460 if (!irq_check_poll(desc))
459 goto out_unlock; 461 goto out_unlock;
460 462
@@ -492,7 +494,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
492{ 494{
493 raw_spin_lock(&desc->lock); 495 raw_spin_lock(&desc->lock);
494 496
495 if (unlikely(desc->status & IRQ_INPROGRESS)) 497 if (unlikely(desc->istate & IRQS_INPROGRESS))
496 if (!irq_check_poll(desc)) 498 if (!irq_check_poll(desc))
497 goto out; 499 goto out;
498 500
@@ -542,8 +544,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
542 * we shouldn't process the IRQ. Mark it pending, handle 544 * we shouldn't process the IRQ. Mark it pending, handle
543 * the necessary masking and go out 545 * the necessary masking and go out
544 */ 546 */
545 if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || 547 if (unlikely((desc->istate & (IRQS_INPROGRESS) ||
546 !desc->action)) { 548 (desc->status & IRQ_DISABLED) || !desc->action))) {
547 if (!irq_check_poll(desc)) { 549 if (!irq_check_poll(desc)) {
548 desc->status |= IRQ_PENDING; 550 desc->status |= IRQ_PENDING;
549 mask_ack_irq(desc); 551 mask_ack_irq(desc);
diff --git a/kernel/irq/compat.h b/kernel/irq/compat.h
new file mode 100644
index 000000000000..aac6e400e608
--- /dev/null
+++ b/kernel/irq/compat.h
@@ -0,0 +1,17 @@
1/*
2 * Compat layer for transition period
3 */
4#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
5static inline void irq_compat_set_progress(struct irq_desc *desc)
6{
7 desc->status |= IRQ_INPROGRESS;
8}
9
10static inline void irq_compat_clr_progress(struct irq_desc *desc)
11{
12 desc->status &= ~IRQ_INPROGRESS;
13}
14#else
15static inline void irq_compat_set_progress(struct irq_desc *desc) { }
16static inline void irq_compat_clr_progress(struct irq_desc *desc) { }
17#endif
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index ff40e0f5e2e2..d4ae0b1ccc00 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -123,13 +123,15 @@ irqreturn_t handle_irq_event(struct irq_desc *desc)
123 irqreturn_t ret; 123 irqreturn_t ret;
124 124
125 desc->status &= ~IRQ_PENDING; 125 desc->status &= ~IRQ_PENDING;
126 desc->status |= IRQ_INPROGRESS; 126 irq_compat_set_progress(desc);
127 desc->istate |= IRQS_INPROGRESS;
127 raw_spin_unlock(&desc->lock); 128 raw_spin_unlock(&desc->lock);
128 129
129 ret = handle_irq_event_percpu(desc, action); 130 ret = handle_irq_event_percpu(desc, action);
130 131
131 raw_spin_lock(&desc->lock); 132 raw_spin_lock(&desc->lock);
132 desc->status &= ~IRQ_INPROGRESS; 133 desc->istate &= ~IRQS_INPROGRESS;
134 irq_compat_clr_progress(desc);
133 return ret; 135 return ret;
134} 136}
135 137
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index f5d28e1e1eda..d1cb1f8df6fe 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -13,6 +13,7 @@
13# define IRQ_BITMAP_BITS NR_IRQS 13# define IRQ_BITMAP_BITS NR_IRQS
14#endif 14#endif
15 15
16#include "compat.h"
16#include "settings.h" 17#include "settings.h"
17 18
18#define istate core_internal_state__do_not_mess_with_it 19#define istate core_internal_state__do_not_mess_with_it
@@ -40,11 +41,13 @@ enum {
40 * IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt 41 * IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt
41 * detection 42 * detection
42 * IRQS_POLL_INPROGRESS - polling in progress 43 * IRQS_POLL_INPROGRESS - polling in progress
44 * IRQS_INPROGRESS - Interrupt in progress
43 */ 45 */
44enum { 46enum {
45 IRQS_AUTODETECT = 0x00000001, 47 IRQS_AUTODETECT = 0x00000001,
46 IRQS_SPURIOUS_DISABLED = 0x00000002, 48 IRQS_SPURIOUS_DISABLED = 0x00000002,
47 IRQS_POLL_INPROGRESS = 0x00000008, 49 IRQS_POLL_INPROGRESS = 0x00000008,
50 IRQS_INPROGRESS = 0x00000010,
48}; 51};
49 52
50#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) 53#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
@@ -128,7 +131,6 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
128 print_symbol("%s\n", (unsigned long)desc->action->handler); 131 print_symbol("%s\n", (unsigned long)desc->action->handler);
129 } 132 }
130 133
131 P(IRQ_INPROGRESS);
132 P(IRQ_DISABLED); 134 P(IRQ_DISABLED);
133 P(IRQ_PENDING); 135 P(IRQ_PENDING);
134 P(IRQ_REPLAY); 136 P(IRQ_REPLAY);
@@ -143,6 +145,7 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
143 P(IRQ_NOAUTOEN); 145 P(IRQ_NOAUTOEN);
144 146
145 PS(IRQS_AUTODETECT); 147 PS(IRQS_AUTODETECT);
148 PS(IRQS_INPROGRESS);
146} 149}
147 150
148#undef P 151#undef P
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 5b918ffa46af..7e5a50825088 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -30,7 +30,7 @@
30void synchronize_irq(unsigned int irq) 30void synchronize_irq(unsigned int irq)
31{ 31{
32 struct irq_desc *desc = irq_to_desc(irq); 32 struct irq_desc *desc = irq_to_desc(irq);
33 unsigned int status; 33 unsigned int state;
34 34
35 if (!desc) 35 if (!desc)
36 return; 36 return;
@@ -42,16 +42,16 @@ void synchronize_irq(unsigned int irq)
42 * Wait until we're out of the critical section. This might 42 * Wait until we're out of the critical section. This might
43 * give the wrong answer due to the lack of memory barriers. 43 * give the wrong answer due to the lack of memory barriers.
44 */ 44 */
45 while (desc->status & IRQ_INPROGRESS) 45 while (desc->istate & IRQS_INPROGRESS)
46 cpu_relax(); 46 cpu_relax();
47 47
48 /* Ok, that indicated we're done: double-check carefully. */ 48 /* Ok, that indicated we're done: double-check carefully. */
49 raw_spin_lock_irqsave(&desc->lock, flags); 49 raw_spin_lock_irqsave(&desc->lock, flags);
50 status = desc->status; 50 state = desc->istate;
51 raw_spin_unlock_irqrestore(&desc->lock, flags); 51 raw_spin_unlock_irqrestore(&desc->lock, flags);
52 52
53 /* Oops, that failed? */ 53 /* Oops, that failed? */
54 } while (status & IRQ_INPROGRESS); 54 } while (state & IRQS_INPROGRESS);
55 55
56 /* 56 /*
57 * We made sure that no hardirq handler is running. Now verify 57 * We made sure that no hardirq handler is running. Now verify
@@ -637,9 +637,9 @@ again:
637 * The thread is faster done than the hard interrupt handler 637 * The thread is faster done than the hard interrupt handler
638 * on the other CPU. If we unmask the irq line then the 638 * on the other CPU. If we unmask the irq line then the
639 * interrupt can come in again and masks the line, leaves due 639 * interrupt can come in again and masks the line, leaves due
640 * to IRQ_INPROGRESS and the irq line is masked forever. 640 * to IRQS_INPROGRESS and the irq line is masked forever.
641 */ 641 */
642 if (unlikely(desc->status & IRQ_INPROGRESS)) { 642 if (unlikely(desc->istate & IRQS_INPROGRESS)) {
643 raw_spin_unlock_irq(&desc->lock); 643 raw_spin_unlock_irq(&desc->lock);
644 chip_bus_sync_unlock(desc); 644 chip_bus_sync_unlock(desc);
645 cpu_relax(); 645 cpu_relax();
@@ -897,8 +897,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
897 desc->status |= IRQ_PER_CPU; 897 desc->status |= IRQ_PER_CPU;
898#endif 898#endif
899 899
900 desc->status &= ~(IRQ_WAITING | IRQ_ONESHOT | IRQ_INPROGRESS); 900 desc->status &= ~(IRQ_WAITING | IRQ_ONESHOT);
901 desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED); 901 desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \
902 IRQS_INPROGRESS);
902 903
903 if (new->flags & IRQF_ONESHOT) 904 if (new->flags & IRQF_ONESHOT)
904 desc->status |= IRQ_ONESHOT; 905 desc->status |= IRQ_ONESHOT;
diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
index 610f55597ce7..a96140eea409 100644
--- a/kernel/irq/settings.h
+++ b/kernel/irq/settings.h
@@ -5,3 +5,6 @@
5enum { 5enum {
6 _IRQ_DEFAULT_INIT_FLAGS = IRQ_DEFAULT_INIT_FLAGS, 6 _IRQ_DEFAULT_INIT_FLAGS = IRQ_DEFAULT_INIT_FLAGS,
7}; 7};
8
9#undef IRQ_INPROGRESS
10#define IRQ_INPROGRESS GOT_YOU_MORON
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 21c46178b1a6..51504837d8cc 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -45,10 +45,10 @@ bool irq_wait_for_poll(struct irq_desc *desc)
45#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
46 do { 46 do {
47 raw_spin_unlock(&desc->lock); 47 raw_spin_unlock(&desc->lock);
48 while (desc->status & IRQ_INPROGRESS) 48 while (desc->istate & IRQS_INPROGRESS)
49 cpu_relax(); 49 cpu_relax();
50 raw_spin_lock(&desc->lock); 50 raw_spin_lock(&desc->lock);
51 } while (desc->status & IRQ_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->status & IRQ_DISABLED) && desc->action;
54#else 54#else
@@ -88,7 +88,7 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force)
88 goto out; 88 goto out;
89 89
90 /* Already running on another processor */ 90 /* Already running on another processor */
91 if (desc->status & IRQ_INPROGRESS) { 91 if (desc->istate & IRQS_INPROGRESS) {
92 /* 92 /*
93 * Already running: If it is shared get the other 93 * Already running: If it is shared get the other
94 * CPU to go looking for our mystery interrupt too 94 * CPU to go looking for our mystery interrupt too