aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/chip.c7
-rw-r--r--kernel/irq/handle.c32
-rw-r--r--kernel/irq/internals.h1
-rw-r--r--kernel/irq/manage.c2
-rw-r--r--kernel/irq/numa_migrate.c11
-rw-r--r--kernel/irq/spurious.c14
6 files changed, 43 insertions, 24 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 7de11bd64dfe..03d0bed2b8d9 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -78,6 +78,7 @@ void dynamic_irq_cleanup(unsigned int irq)
78 desc->handle_irq = handle_bad_irq; 78 desc->handle_irq = handle_bad_irq;
79 desc->chip = &no_irq_chip; 79 desc->chip = &no_irq_chip;
80 desc->name = NULL; 80 desc->name = NULL;
81 clear_kstat_irqs(desc);
81 spin_unlock_irqrestore(&desc->lock, flags); 82 spin_unlock_irqrestore(&desc->lock, flags);
82} 83}
83 84
@@ -290,7 +291,8 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
290 desc->chip->mask_ack(irq); 291 desc->chip->mask_ack(irq);
291 else { 292 else {
292 desc->chip->mask(irq); 293 desc->chip->mask(irq);
293 desc->chip->ack(irq); 294 if (desc->chip->ack)
295 desc->chip->ack(irq);
294 } 296 }
295} 297}
296 298
@@ -476,7 +478,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
476 kstat_incr_irqs_this_cpu(irq, desc); 478 kstat_incr_irqs_this_cpu(irq, desc);
477 479
478 /* Start handling the irq */ 480 /* Start handling the irq */
479 desc->chip->ack(irq); 481 if (desc->chip->ack)
482 desc->chip->ack(irq);
480 desc = irq_remap_to_desc(irq, desc); 483 desc = irq_remap_to_desc(irq, desc);
481 484
482 /* Mark the IRQ currently in progress.*/ 485 /* Mark the IRQ currently in progress.*/
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 3aba8d12f328..759b8b04d294 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -83,19 +83,21 @@ static struct irq_desc irq_desc_init = {
83 83
84void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) 84void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
85{ 85{
86 unsigned long bytes;
87 char *ptr;
88 int node; 86 int node;
89 87 void *ptr;
90 /* Compute how many bytes we need per irq and allocate them */
91 bytes = nr * sizeof(unsigned int);
92 88
93 node = cpu_to_node(cpu); 89 node = cpu_to_node(cpu);
94 ptr = kzalloc_node(bytes, GFP_ATOMIC, node); 90 ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
95 printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n", cpu, node);
96 91
97 if (ptr) 92 /*
98 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 }
99} 101}
100 102
101static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) 103static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
@@ -227,6 +229,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
227 } 229 }
228}; 230};
229 231
232static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
230int __init early_irq_init(void) 233int __init early_irq_init(void)
231{ 234{
232 struct irq_desc *desc; 235 struct irq_desc *desc;
@@ -238,8 +241,10 @@ int __init early_irq_init(void)
238 desc = irq_desc; 241 desc = irq_desc;
239 count = ARRAY_SIZE(irq_desc); 242 count = ARRAY_SIZE(irq_desc);
240 243
241 for (i = 0; i < count; i++) 244 for (i = 0; i < count; i++) {
242 desc[i].irq = i; 245 desc[i].irq = i;
246 desc[i].kstat_irqs = kstat_irqs_all[i];
247 }
243 248
244 return arch_early_irq_init(); 249 return arch_early_irq_init();
245} 250}
@@ -255,6 +260,11 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
255} 260}
256#endif /* !CONFIG_SPARSE_IRQ */ 261#endif /* !CONFIG_SPARSE_IRQ */
257 262
263void clear_kstat_irqs(struct irq_desc *desc)
264{
265 memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
266}
267
258/* 268/*
259 * 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?
260 * Each architecture has to answer this themself. 270 * Each architecture has to answer this themself.
@@ -467,12 +477,10 @@ void early_init_irq_lock_class(void)
467 } 477 }
468} 478}
469 479
470#ifdef CONFIG_SPARSE_IRQ
471unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) 480unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
472{ 481{
473 struct irq_desc *desc = irq_to_desc(irq); 482 struct irq_desc *desc = irq_to_desc(irq);
474 return desc ? desc->kstat_irqs[cpu] : 0; 483 return desc ? desc->kstat_irqs[cpu] : 0;
475} 484}
476#endif
477EXPORT_SYMBOL(kstat_irqs_cpu); 485EXPORT_SYMBOL(kstat_irqs_cpu);
478 486
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index e6d0a43cc125..b60950bf5a16 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -15,6 +15,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
15 15
16extern struct lock_class_key irq_desc_lock_class; 16extern struct lock_class_key irq_desc_lock_class;
17extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr); 17extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
18extern void clear_kstat_irqs(struct irq_desc *desc);
18extern spinlock_t sparse_irq_lock; 19extern spinlock_t sparse_irq_lock;
19extern struct irq_desc *irq_desc_ptrs[NR_IRQS]; 20extern struct irq_desc *irq_desc_ptrs[NR_IRQS];
20 21
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 38008b80bd59..cbc3828faf5f 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -709,7 +709,7 @@ int request_irq(unsigned int irq, irq_handler_t handler,
709 if (!handler) 709 if (!handler)
710 return -EINVAL; 710 return -EINVAL;
711 711
712 action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC); 712 action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
713 if (!action) 713 if (!action)
714 return -ENOMEM; 714 return -ENOMEM;
715 715
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index acd88356ac76..aef18ab6b75b 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -17,16 +17,11 @@ static void init_copy_kstat_irqs(struct irq_desc *old_desc,
17 struct irq_desc *desc, 17 struct irq_desc *desc,
18 int cpu, int nr) 18 int cpu, int nr)
19{ 19{
20 unsigned long bytes;
21
22 init_kstat_irqs(desc, cpu, nr); 20 init_kstat_irqs(desc, cpu, nr);
23 21
24 if (desc->kstat_irqs != old_desc->kstat_irqs) { 22 if (desc->kstat_irqs != old_desc->kstat_irqs)
25 /* Compute how many bytes we need per irq and allocate them */ 23 memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
26 bytes = nr * sizeof(unsigned int); 24 nr * sizeof(*desc->kstat_irqs));
27
28 memcpy(desc->kstat_irqs, old_desc->kstat_irqs, bytes);
29 }
30} 25}
31 26
32static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc) 27static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index dd364c11e56e..4d568294de3e 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -104,7 +104,7 @@ static int misrouted_irq(int irq)
104 return ok; 104 return ok;
105} 105}
106 106
107static void poll_spurious_irqs(unsigned long dummy) 107static void poll_all_shared_irqs(void)
108{ 108{
109 struct irq_desc *desc; 109 struct irq_desc *desc;
110 int i; 110 int i;
@@ -123,11 +123,23 @@ static void poll_spurious_irqs(unsigned long dummy)
123 123
124 try_one_irq(i, desc); 124 try_one_irq(i, desc);
125 } 125 }
126}
127
128static void poll_spurious_irqs(unsigned long dummy)
129{
130 poll_all_shared_irqs();
126 131
127 mod_timer(&poll_spurious_irq_timer, 132 mod_timer(&poll_spurious_irq_timer,
128 jiffies + POLL_SPURIOUS_IRQ_INTERVAL); 133 jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
129} 134}
130 135
136#ifdef CONFIG_DEBUG_SHIRQ
137void debug_poll_all_shared_irqs(void)
138{
139 poll_all_shared_irqs();
140}
141#endif
142
131/* 143/*
132 * If 99,900 of the previous 100,000 interrupts have not been handled 144 * If 99,900 of the previous 100,000 interrupts have not been handled
133 * then assume that the IRQ is stuck in some manner. Drop a diagnostic 145 * then assume that the IRQ is stuck in some manner. Drop a diagnostic