aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/autoprobe.c15
-rw-r--r--kernel/irq/chip.c1
-rw-r--r--kernel/irq/handle.c53
-rw-r--r--kernel/irq/manage.c27
-rw-r--r--kernel/irq/numa_migrate.c18
-rw-r--r--kernel/irq/spurious.c5
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)
56int nr_irqs = NR_IRQS; 56int nr_irqs = NR_IRQS;
57EXPORT_SYMBOL_GPL(nr_irqs); 57EXPORT_SYMBOL_GPL(nr_irqs);
58 58
59void __init __attribute__((weak)) arch_early_irq_init(void)
60{
61}
62
63#ifdef CONFIG_SPARSE_IRQ 59#ifdef CONFIG_SPARSE_IRQ
64static struct irq_desc irq_desc_init = { 60static 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
93void __attribute__((weak)) arch_init_chip_data(struct irq_desc *desc, int cpu)
94{
95}
96
97static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) 89static 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 ...*/
135static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS]; 129static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS];
136 130
137void __init early_irq_init(void) 131int __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
159struct irq_desc *irq_to_desc(unsigned int irq) 154struct 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
208struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { 203struct 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 216int __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
231struct irq_desc *irq_to_desc(unsigned int irq)
232{
233 return (irq < NR_IRQS) ? irq_desc + irq : NULL;
234}
235
236struct 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
427void early_init_irq_lock_class(void) 444void 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
444unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) 455unsigned 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
450EXPORT_SYMBOL(kstat_irqs_cpu); 461EXPORT_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