diff options
Diffstat (limited to 'kernel/irq/handle.c')
-rw-r--r-- | kernel/irq/handle.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index c20db0be9173..f6cdda68e5c6 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -39,6 +39,18 @@ void handle_bad_irq(unsigned int irq, struct irq_desc *desc) | |||
39 | ack_bad_irq(irq); | 39 | ack_bad_irq(irq); |
40 | } | 40 | } |
41 | 41 | ||
42 | #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) | ||
43 | static void __init init_irq_default_affinity(void) | ||
44 | { | ||
45 | alloc_bootmem_cpumask_var(&irq_default_affinity); | ||
46 | cpumask_setall(irq_default_affinity); | ||
47 | } | ||
48 | #else | ||
49 | static void __init init_irq_default_affinity(void) | ||
50 | { | ||
51 | } | ||
52 | #endif | ||
53 | |||
42 | /* | 54 | /* |
43 | * Linux has a controller-independent interrupt architecture. | 55 | * Linux has a controller-independent interrupt architecture. |
44 | * Every controller has a 'controller-template', that is used | 56 | * Every controller has a 'controller-template', that is used |
@@ -71,19 +83,21 @@ static struct irq_desc irq_desc_init = { | |||
71 | 83 | ||
72 | void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) | 84 | void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) |
73 | { | 85 | { |
74 | unsigned long bytes; | ||
75 | char *ptr; | ||
76 | int node; | 86 | int node; |
77 | 87 | void *ptr; | |
78 | /* Compute how many bytes we need per irq and allocate them */ | ||
79 | bytes = nr * sizeof(unsigned int); | ||
80 | 88 | ||
81 | node = cpu_to_node(cpu); | 89 | node = cpu_to_node(cpu); |
82 | ptr = kzalloc_node(bytes, GFP_ATOMIC, node); | 90 | ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node); |
83 | printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n", cpu, node); | ||
84 | 91 | ||
85 | if (ptr) | 92 | /* |
86 | desc->kstat_irqs = (unsigned int *)ptr; | 93 | * don't overwite if can not get new one |
94 | * init_copy_kstat_irqs() could still use old one | ||
95 | */ | ||
96 | if (ptr) { | ||
97 | printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n", | ||
98 | cpu, node); | ||
99 | desc->kstat_irqs = ptr; | ||
100 | } | ||
87 | } | 101 | } |
88 | 102 | ||
89 | static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) | 103 | static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) |
@@ -134,6 +148,8 @@ int __init early_irq_init(void) | |||
134 | int legacy_count; | 148 | int legacy_count; |
135 | int i; | 149 | int i; |
136 | 150 | ||
151 | init_irq_default_affinity(); | ||
152 | |||
137 | desc = irq_desc_legacy; | 153 | desc = irq_desc_legacy; |
138 | legacy_count = ARRAY_SIZE(irq_desc_legacy); | 154 | legacy_count = ARRAY_SIZE(irq_desc_legacy); |
139 | 155 | ||
@@ -213,17 +229,22 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | |||
213 | } | 229 | } |
214 | }; | 230 | }; |
215 | 231 | ||
232 | static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS]; | ||
216 | int __init early_irq_init(void) | 233 | int __init early_irq_init(void) |
217 | { | 234 | { |
218 | struct irq_desc *desc; | 235 | struct irq_desc *desc; |
219 | int count; | 236 | int count; |
220 | int i; | 237 | int i; |
221 | 238 | ||
239 | init_irq_default_affinity(); | ||
240 | |||
222 | desc = irq_desc; | 241 | desc = irq_desc; |
223 | count = ARRAY_SIZE(irq_desc); | 242 | count = ARRAY_SIZE(irq_desc); |
224 | 243 | ||
225 | for (i = 0; i < count; i++) | 244 | for (i = 0; i < count; i++) { |
226 | desc[i].irq = i; | 245 | desc[i].irq = i; |
246 | desc[i].kstat_irqs = kstat_irqs_all[i]; | ||
247 | } | ||
227 | 248 | ||
228 | return arch_early_irq_init(); | 249 | return arch_early_irq_init(); |
229 | } | 250 | } |
@@ -239,6 +260,11 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) | |||
239 | } | 260 | } |
240 | #endif /* !CONFIG_SPARSE_IRQ */ | 261 | #endif /* !CONFIG_SPARSE_IRQ */ |
241 | 262 | ||
263 | void clear_kstat_irqs(struct irq_desc *desc) | ||
264 | { | ||
265 | memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs))); | ||
266 | } | ||
267 | |||
242 | /* | 268 | /* |
243 | * What should we do if we get a hw irq event on an illegal vector? | 269 | * What should we do if we get a hw irq event on an illegal vector? |
244 | * Each architecture has to answer this themself. | 270 | * Each architecture has to answer this themself. |
@@ -312,6 +338,8 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) | |||
312 | irqreturn_t ret, retval = IRQ_NONE; | 338 | irqreturn_t ret, retval = IRQ_NONE; |
313 | unsigned int status = 0; | 339 | unsigned int status = 0; |
314 | 340 | ||
341 | WARN_ONCE(!in_irq(), "BUG: IRQ handler called from non-hardirq context!"); | ||
342 | |||
315 | if (!(action->flags & IRQF_DISABLED)) | 343 | if (!(action->flags & IRQF_DISABLED)) |
316 | local_irq_enable_in_hardirq(); | 344 | local_irq_enable_in_hardirq(); |
317 | 345 | ||
@@ -331,6 +359,11 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) | |||
331 | } | 359 | } |
332 | 360 | ||
333 | #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ | 361 | #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ |
362 | |||
363 | #ifdef CONFIG_ENABLE_WARN_DEPRECATED | ||
364 | # warning __do_IRQ is deprecated. Please convert to proper flow handlers | ||
365 | #endif | ||
366 | |||
334 | /** | 367 | /** |
335 | * __do_IRQ - original all in one highlevel IRQ handler | 368 | * __do_IRQ - original all in one highlevel IRQ handler |
336 | * @irq: the interrupt number | 369 | * @irq: the interrupt number |
@@ -451,12 +484,10 @@ void early_init_irq_lock_class(void) | |||
451 | } | 484 | } |
452 | } | 485 | } |
453 | 486 | ||
454 | #ifdef CONFIG_SPARSE_IRQ | ||
455 | unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) | 487 | unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) |
456 | { | 488 | { |
457 | struct irq_desc *desc = irq_to_desc(irq); | 489 | struct irq_desc *desc = irq_to_desc(irq); |
458 | return desc ? desc->kstat_irqs[cpu] : 0; | 490 | return desc ? desc->kstat_irqs[cpu] : 0; |
459 | } | 491 | } |
460 | #endif | ||
461 | EXPORT_SYMBOL(kstat_irqs_cpu); | 492 | EXPORT_SYMBOL(kstat_irqs_cpu); |
462 | 493 | ||