diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-09-15 04:53:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:53:10 -0400 |
commit | e00585bb7fc3d0b601181b765a254df7ff4ea59b (patch) | |
tree | 731d07071f04f54fbf4269912524455e54002858 /kernel/irq | |
parent | 56ffa1a028b9fce3860a247c6fe79fce7cbf425b (diff) |
irq: fix irqpoll && sparseirq
Steven Noonan reported a boot hang when using irqpoll and
CONFIG_HAVE_SPARSE_IRQ=y.
The irqpoll loop needs to be updated to not iterate from 1 to nr_irqs
but to iterate via for_each_irq_desc(). (in the former case desc can
be NULL which crashes the box)
Reported-by: Steven Noonan <steven@uplinklabs.net>
Tested-by: Steven Noonan <steven@uplinklabs.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/spurious.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index b5d906002e1d..ec5a4bef3054 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -90,14 +90,15 @@ static int misrouted_irq(int irq) | |||
90 | { | 90 | { |
91 | int i; | 91 | int i; |
92 | int ok = 0; | 92 | int ok = 0; |
93 | struct irq_desc *desc; | ||
93 | 94 | ||
94 | for (i = 1; i < nr_irqs; i++) { | 95 | for_each_irq_desc(i, desc) { |
95 | struct irq_desc *desc; | 96 | if (!i) |
97 | continue; | ||
96 | 98 | ||
97 | if (i == irq) /* Already tried */ | 99 | if (i == irq) /* Already tried */ |
98 | continue; | 100 | continue; |
99 | 101 | ||
100 | desc = irq_to_desc(i); | ||
101 | if (try_one_irq(i, desc)) | 102 | if (try_one_irq(i, desc)) |
102 | ok = 1; | 103 | ok = 1; |
103 | } | 104 | } |
@@ -108,10 +109,14 @@ static int misrouted_irq(int irq) | |||
108 | static void poll_spurious_irqs(unsigned long dummy) | 109 | static void poll_spurious_irqs(unsigned long dummy) |
109 | { | 110 | { |
110 | int i; | 111 | int i; |
111 | for (i = 1; i < nr_irqs; i++) { | 112 | struct irq_desc *desc; |
112 | struct irq_desc *desc = irq_to_desc(i); | 113 | |
114 | for_each_irq_desc(i, desc) { | ||
113 | unsigned int status; | 115 | unsigned int status; |
114 | 116 | ||
117 | if (!i) | ||
118 | continue; | ||
119 | |||
115 | /* Racy but it doesn't matter */ | 120 | /* Racy but it doesn't matter */ |
116 | status = desc->status; | 121 | status = desc->status; |
117 | barrier(); | 122 | barrier(); |
@@ -278,7 +283,7 @@ static int __init irqfixup_setup(char *str) | |||
278 | 283 | ||
279 | __setup("irqfixup", irqfixup_setup); | 284 | __setup("irqfixup", irqfixup_setup); |
280 | module_param(irqfixup, int, 0644); | 285 | module_param(irqfixup, int, 0644); |
281 | MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode 2: irqpoll mode"); | 286 | MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode, 2: irqpoll mode"); |
282 | 287 | ||
283 | static int __init irqpoll_setup(char *str) | 288 | static int __init irqpoll_setup(char *str) |
284 | { | 289 | { |