diff options
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/autoprobe.c | 15 | ||||
-rw-r--r-- | kernel/irq/chip.c | 1 | ||||
-rw-r--r-- | kernel/irq/handle.c | 53 | ||||
-rw-r--r-- | kernel/irq/manage.c | 27 | ||||
-rw-r--r-- | kernel/irq/numa_migrate.c | 18 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 5 |
6 files changed, 59 insertions, 60 deletions
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 650ce4102a63..cc0f7321b8ce 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
@@ -40,9 +40,6 @@ unsigned long probe_irq_on(void) | |||
40 | * flush such a longstanding irq before considering it as spurious. | 40 | * flush such a longstanding irq before considering it as spurious. |
41 | */ | 41 | */ |
42 | for_each_irq_desc_reverse(i, desc) { | 42 | for_each_irq_desc_reverse(i, desc) { |
43 | if (!desc) | ||
44 | continue; | ||
45 | |||
46 | spin_lock_irq(&desc->lock); | 43 | spin_lock_irq(&desc->lock); |
47 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 44 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
48 | /* | 45 | /* |
@@ -71,9 +68,6 @@ unsigned long probe_irq_on(void) | |||
71 | * happened in the previous stage, it may have masked itself) | 68 | * happened in the previous stage, it may have masked itself) |
72 | */ | 69 | */ |
73 | for_each_irq_desc_reverse(i, desc) { | 70 | for_each_irq_desc_reverse(i, desc) { |
74 | if (!desc) | ||
75 | continue; | ||
76 | |||
77 | spin_lock_irq(&desc->lock); | 71 | spin_lock_irq(&desc->lock); |
78 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 72 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
79 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; | 73 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; |
@@ -92,9 +86,6 @@ unsigned long probe_irq_on(void) | |||
92 | * Now filter out any obviously spurious interrupts | 86 | * Now filter out any obviously spurious interrupts |
93 | */ | 87 | */ |
94 | for_each_irq_desc(i, desc) { | 88 | for_each_irq_desc(i, desc) { |
95 | if (!desc) | ||
96 | continue; | ||
97 | |||
98 | spin_lock_irq(&desc->lock); | 89 | spin_lock_irq(&desc->lock); |
99 | status = desc->status; | 90 | status = desc->status; |
100 | 91 | ||
@@ -133,9 +124,6 @@ unsigned int probe_irq_mask(unsigned long val) | |||
133 | int i; | 124 | int i; |
134 | 125 | ||
135 | for_each_irq_desc(i, desc) { | 126 | for_each_irq_desc(i, desc) { |
136 | if (!desc) | ||
137 | continue; | ||
138 | |||
139 | spin_lock_irq(&desc->lock); | 127 | spin_lock_irq(&desc->lock); |
140 | status = desc->status; | 128 | status = desc->status; |
141 | 129 | ||
@@ -178,9 +166,6 @@ int probe_irq_off(unsigned long val) | |||
178 | unsigned int status; | 166 | unsigned int status; |
179 | 167 | ||
180 | for_each_irq_desc(i, desc) { | 168 | for_each_irq_desc(i, desc) { |
181 | if (!desc) | ||
182 | continue; | ||
183 | |||
184 | spin_lock_irq(&desc->lock); | 169 | spin_lock_irq(&desc->lock); |
185 | status = desc->status; | 170 | status = desc->status; |
186 | 171 | ||
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index b343deedae91..f63c706d25e1 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -125,6 +125,7 @@ int set_irq_type(unsigned int irq, unsigned int type) | |||
125 | return -ENODEV; | 125 | return -ENODEV; |
126 | } | 126 | } |
127 | 127 | ||
128 | type &= IRQ_TYPE_SENSE_MASK; | ||
128 | if (type == IRQ_TYPE_NONE) | 129 | if (type == IRQ_TYPE_NONE) |
129 | return 0; | 130 | return 0; |
130 | 131 | ||
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index f1a23069c20a..c20db0be9173 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -56,10 +56,6 @@ void handle_bad_irq(unsigned int irq, struct irq_desc *desc) | |||
56 | int nr_irqs = NR_IRQS; | 56 | int nr_irqs = NR_IRQS; |
57 | EXPORT_SYMBOL_GPL(nr_irqs); | 57 | EXPORT_SYMBOL_GPL(nr_irqs); |
58 | 58 | ||
59 | void __init __attribute__((weak)) arch_early_irq_init(void) | ||
60 | { | ||
61 | } | ||
62 | |||
63 | #ifdef CONFIG_SPARSE_IRQ | 59 | #ifdef CONFIG_SPARSE_IRQ |
64 | static struct irq_desc irq_desc_init = { | 60 | static struct irq_desc irq_desc_init = { |
65 | .irq = -1, | 61 | .irq = -1, |
@@ -90,13 +86,11 @@ void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) | |||
90 | desc->kstat_irqs = (unsigned int *)ptr; | 86 | desc->kstat_irqs = (unsigned int *)ptr; |
91 | } | 87 | } |
92 | 88 | ||
93 | void __attribute__((weak)) arch_init_chip_data(struct irq_desc *desc, int cpu) | ||
94 | { | ||
95 | } | ||
96 | |||
97 | static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) | 89 | static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) |
98 | { | 90 | { |
99 | memcpy(desc, &irq_desc_init, sizeof(struct irq_desc)); | 91 | memcpy(desc, &irq_desc_init, sizeof(struct irq_desc)); |
92 | |||
93 | spin_lock_init(&desc->lock); | ||
100 | desc->irq = irq; | 94 | desc->irq = irq; |
101 | #ifdef CONFIG_SMP | 95 | #ifdef CONFIG_SMP |
102 | desc->cpu = cpu; | 96 | desc->cpu = cpu; |
@@ -134,7 +128,7 @@ static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_sm | |||
134 | /* FIXME: use bootmem alloc ...*/ | 128 | /* FIXME: use bootmem alloc ...*/ |
135 | static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS]; | 129 | static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS]; |
136 | 130 | ||
137 | void __init early_irq_init(void) | 131 | int __init early_irq_init(void) |
138 | { | 132 | { |
139 | struct irq_desc *desc; | 133 | struct irq_desc *desc; |
140 | int legacy_count; | 134 | int legacy_count; |
@@ -146,6 +140,7 @@ void __init early_irq_init(void) | |||
146 | for (i = 0; i < legacy_count; i++) { | 140 | for (i = 0; i < legacy_count; i++) { |
147 | desc[i].irq = i; | 141 | desc[i].irq = i; |
148 | desc[i].kstat_irqs = kstat_irqs_legacy[i]; | 142 | desc[i].kstat_irqs = kstat_irqs_legacy[i]; |
143 | lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); | ||
149 | 144 | ||
150 | irq_desc_ptrs[i] = desc + i; | 145 | irq_desc_ptrs[i] = desc + i; |
151 | } | 146 | } |
@@ -153,7 +148,7 @@ void __init early_irq_init(void) | |||
153 | for (i = legacy_count; i < NR_IRQS; i++) | 148 | for (i = legacy_count; i < NR_IRQS; i++) |
154 | irq_desc_ptrs[i] = NULL; | 149 | irq_desc_ptrs[i] = NULL; |
155 | 150 | ||
156 | arch_early_irq_init(); | 151 | return arch_early_irq_init(); |
157 | } | 152 | } |
158 | 153 | ||
159 | struct irq_desc *irq_to_desc(unsigned int irq) | 154 | struct irq_desc *irq_to_desc(unsigned int irq) |
@@ -203,7 +198,7 @@ out_unlock: | |||
203 | return desc; | 198 | return desc; |
204 | } | 199 | } |
205 | 200 | ||
206 | #else | 201 | #else /* !CONFIG_SPARSE_IRQ */ |
207 | 202 | ||
208 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | 203 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { |
209 | [0 ... NR_IRQS-1] = { | 204 | [0 ... NR_IRQS-1] = { |
@@ -218,7 +213,31 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | |||
218 | } | 213 | } |
219 | }; | 214 | }; |
220 | 215 | ||
221 | #endif | 216 | int __init early_irq_init(void) |
217 | { | ||
218 | struct irq_desc *desc; | ||
219 | int count; | ||
220 | int i; | ||
221 | |||
222 | desc = irq_desc; | ||
223 | count = ARRAY_SIZE(irq_desc); | ||
224 | |||
225 | for (i = 0; i < count; i++) | ||
226 | desc[i].irq = i; | ||
227 | |||
228 | return arch_early_irq_init(); | ||
229 | } | ||
230 | |||
231 | struct irq_desc *irq_to_desc(unsigned int irq) | ||
232 | { | ||
233 | return (irq < NR_IRQS) ? irq_desc + irq : NULL; | ||
234 | } | ||
235 | |||
236 | struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) | ||
237 | { | ||
238 | return irq_to_desc(irq); | ||
239 | } | ||
240 | #endif /* !CONFIG_SPARSE_IRQ */ | ||
222 | 241 | ||
223 | /* | 242 | /* |
224 | * What should we do if we get a hw irq event on an illegal vector? | 243 | * What should we do if we get a hw irq event on an illegal vector? |
@@ -422,29 +441,21 @@ out: | |||
422 | } | 441 | } |
423 | #endif | 442 | #endif |
424 | 443 | ||
425 | |||
426 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
427 | void early_init_irq_lock_class(void) | 444 | void early_init_irq_lock_class(void) |
428 | { | 445 | { |
429 | #ifndef CONFIG_SPARSE_IRQ | ||
430 | struct irq_desc *desc; | 446 | struct irq_desc *desc; |
431 | int i; | 447 | int i; |
432 | 448 | ||
433 | for_each_irq_desc(i, desc) { | 449 | for_each_irq_desc(i, desc) { |
434 | if (!desc) | ||
435 | continue; | ||
436 | |||
437 | lockdep_set_class(&desc->lock, &irq_desc_lock_class); | 450 | lockdep_set_class(&desc->lock, &irq_desc_lock_class); |
438 | } | 451 | } |
439 | #endif | ||
440 | } | 452 | } |
441 | #endif | ||
442 | 453 | ||
443 | #ifdef CONFIG_SPARSE_IRQ | 454 | #ifdef CONFIG_SPARSE_IRQ |
444 | unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) | 455 | unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) |
445 | { | 456 | { |
446 | struct irq_desc *desc = irq_to_desc(irq); | 457 | struct irq_desc *desc = irq_to_desc(irq); |
447 | return desc->kstat_irqs[cpu]; | 458 | return desc ? desc->kstat_irqs[cpu] : 0; |
448 | } | 459 | } |
449 | #endif | 460 | #endif |
450 | EXPORT_SYMBOL(kstat_irqs_cpu); | 461 | EXPORT_SYMBOL(kstat_irqs_cpu); |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 10ad2f87ed9a..61c4a9b62165 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -368,16 +368,18 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
368 | return 0; | 368 | return 0; |
369 | } | 369 | } |
370 | 370 | ||
371 | ret = chip->set_type(irq, flags & IRQF_TRIGGER_MASK); | 371 | /* caller masked out all except trigger mode flags */ |
372 | ret = chip->set_type(irq, flags); | ||
372 | 373 | ||
373 | if (ret) | 374 | if (ret) |
374 | pr_err("setting trigger mode %d for irq %u failed (%pF)\n", | 375 | pr_err("setting trigger mode %d for irq %u failed (%pF)\n", |
375 | (int)(flags & IRQF_TRIGGER_MASK), | 376 | (int)flags, irq, chip->set_type); |
376 | irq, chip->set_type); | ||
377 | else { | 377 | else { |
378 | if (flags & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
379 | flags |= IRQ_LEVEL; | ||
378 | /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ | 380 | /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ |
379 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | 381 | desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK); |
380 | desc->status |= flags & IRQ_TYPE_SENSE_MASK; | 382 | desc->status |= flags; |
381 | } | 383 | } |
382 | 384 | ||
383 | return ret; | 385 | return ret; |
@@ -457,7 +459,8 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new) | |||
457 | 459 | ||
458 | /* Setup the type (level, edge polarity) if configured: */ | 460 | /* Setup the type (level, edge polarity) if configured: */ |
459 | if (new->flags & IRQF_TRIGGER_MASK) { | 461 | if (new->flags & IRQF_TRIGGER_MASK) { |
460 | ret = __irq_set_trigger(desc, irq, new->flags); | 462 | ret = __irq_set_trigger(desc, irq, |
463 | new->flags & IRQF_TRIGGER_MASK); | ||
461 | 464 | ||
462 | if (ret) { | 465 | if (ret) { |
463 | spin_unlock_irqrestore(&desc->lock, flags); | 466 | spin_unlock_irqrestore(&desc->lock, flags); |
@@ -671,6 +674,18 @@ int request_irq(unsigned int irq, irq_handler_t handler, | |||
671 | struct irq_desc *desc; | 674 | struct irq_desc *desc; |
672 | int retval; | 675 | int retval; |
673 | 676 | ||
677 | /* | ||
678 | * handle_IRQ_event() always ignores IRQF_DISABLED except for | ||
679 | * the _first_ irqaction (sigh). That can cause oopsing, but | ||
680 | * the behavior is classified as "will not fix" so we need to | ||
681 | * start nudging drivers away from using that idiom. | ||
682 | */ | ||
683 | if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) | ||
684 | == (IRQF_SHARED|IRQF_DISABLED)) | ||
685 | pr_warning("IRQ %d/%s: IRQF_DISABLED is not " | ||
686 | "guaranteed on shared IRQs\n", | ||
687 | irq, devname); | ||
688 | |||
674 | #ifdef CONFIG_LOCKDEP | 689 | #ifdef CONFIG_LOCKDEP |
675 | /* | 690 | /* |
676 | * Lockdep wants atomic interrupt handlers: | 691 | * Lockdep wants atomic interrupt handlers: |
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c index 0178e2296990..ecf765c6a77a 100644 --- a/kernel/irq/numa_migrate.c +++ b/kernel/irq/numa_migrate.c | |||
@@ -1,13 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * linux/kernel/irq/handle.c | 2 | * NUMA irq-desc migration code |
3 | * | ||
4 | * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar | ||
5 | * Copyright (C) 2005-2006, Thomas Gleixner, Russell King | ||
6 | * | ||
7 | * This file contains the core interrupt handling code. | ||
8 | * | ||
9 | * Detailed information is available in Documentation/DocBook/genericirq | ||
10 | * | 3 | * |
4 | * Migrate IRQ data structures (irq_desc, chip_data, etc.) over to | ||
5 | * the new "home node" of the IRQ. | ||
11 | */ | 6 | */ |
12 | 7 | ||
13 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
@@ -47,6 +42,7 @@ static void init_copy_one_irq_desc(int irq, struct irq_desc *old_desc, | |||
47 | struct irq_desc *desc, int cpu) | 42 | struct irq_desc *desc, int cpu) |
48 | { | 43 | { |
49 | memcpy(desc, old_desc, sizeof(struct irq_desc)); | 44 | memcpy(desc, old_desc, sizeof(struct irq_desc)); |
45 | spin_lock_init(&desc->lock); | ||
50 | desc->cpu = cpu; | 46 | desc->cpu = cpu; |
51 | lockdep_set_class(&desc->lock, &irq_desc_lock_class); | 47 | lockdep_set_class(&desc->lock, &irq_desc_lock_class); |
52 | init_copy_kstat_irqs(old_desc, desc, cpu, nr_cpu_ids); | 48 | init_copy_kstat_irqs(old_desc, desc, cpu, nr_cpu_ids); |
@@ -79,10 +75,8 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
79 | 75 | ||
80 | node = cpu_to_node(cpu); | 76 | node = cpu_to_node(cpu); |
81 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); | 77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); |
82 | printk(KERN_DEBUG " move irq_desc for %d to cpu %d node %d\n", | ||
83 | irq, cpu, node); | ||
84 | if (!desc) { | 78 | if (!desc) { |
85 | printk(KERN_ERR "can not get new irq_desc for moving\n"); | 79 | printk(KERN_ERR "irq %d: can not get new irq_desc for migration.\n", irq); |
86 | /* still use old one */ | 80 | /* still use old one */ |
87 | desc = old_desc; | 81 | desc = old_desc; |
88 | goto out_unlock; | 82 | goto out_unlock; |
@@ -111,8 +105,6 @@ struct irq_desc *move_irq_desc(struct irq_desc *desc, int cpu) | |||
111 | return desc; | 105 | return desc; |
112 | 106 | ||
113 | old_cpu = desc->cpu; | 107 | old_cpu = desc->cpu; |
114 | printk(KERN_DEBUG | ||
115 | "try to move irq_desc from cpu %d to %d\n", old_cpu, cpu); | ||
116 | if (old_cpu != cpu) { | 108 | if (old_cpu != cpu) { |
117 | node = cpu_to_node(cpu); | 109 | node = cpu_to_node(cpu); |
118 | old_node = cpu_to_node(old_cpu); | 110 | old_node = cpu_to_node(old_cpu); |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index 3738107531fd..dd364c11e56e 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -91,9 +91,6 @@ static int misrouted_irq(int irq) | |||
91 | int i, ok = 0; | 91 | int i, ok = 0; |
92 | 92 | ||
93 | for_each_irq_desc(i, desc) { | 93 | for_each_irq_desc(i, desc) { |
94 | if (!desc) | ||
95 | continue; | ||
96 | |||
97 | if (!i) | 94 | if (!i) |
98 | continue; | 95 | continue; |
99 | 96 | ||
@@ -115,8 +112,6 @@ static void poll_spurious_irqs(unsigned long dummy) | |||
115 | for_each_irq_desc(i, desc) { | 112 | for_each_irq_desc(i, desc) { |
116 | unsigned int status; | 113 | unsigned int status; |
117 | 114 | ||
118 | if (!desc) | ||
119 | continue; | ||
120 | if (!i) | 115 | if (!i) |
121 | continue; | 116 | continue; |
122 | 117 | ||