aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r--arch/powerpc/kernel/irq.c137
1 files changed, 89 insertions, 48 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 02a334662cc0..f6dca4f4b295 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -87,7 +87,10 @@ extern int tau_interrupts(int);
87#endif /* CONFIG_PPC32 */ 87#endif /* CONFIG_PPC32 */
88 88
89#ifdef CONFIG_PPC64 89#ifdef CONFIG_PPC64
90
91#ifndef CONFIG_SPARSE_IRQ
90EXPORT_SYMBOL(irq_desc); 92EXPORT_SYMBOL(irq_desc);
93#endif
91 94
92int distribute_irqs = 1; 95int distribute_irqs = 1;
93 96
@@ -189,33 +192,7 @@ int show_interrupts(struct seq_file *p, void *v)
189 for_each_online_cpu(j) 192 for_each_online_cpu(j)
190 seq_printf(p, "CPU%d ", j); 193 seq_printf(p, "CPU%d ", j);
191 seq_putc(p, '\n'); 194 seq_putc(p, '\n');
192 } 195 } else if (i == nr_irqs) {
193
194 if (i < NR_IRQS) {
195 desc = get_irq_desc(i);
196 spin_lock_irqsave(&desc->lock, flags);
197 action = desc->action;
198 if (!action || !action->handler)
199 goto skip;
200 seq_printf(p, "%3d: ", i);
201#ifdef CONFIG_SMP
202 for_each_online_cpu(j)
203 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
204#else
205 seq_printf(p, "%10u ", kstat_irqs(i));
206#endif /* CONFIG_SMP */
207 if (desc->chip)
208 seq_printf(p, " %s ", desc->chip->typename);
209 else
210 seq_puts(p, " None ");
211 seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
212 seq_printf(p, " %s", action->name);
213 for (action = action->next; action; action = action->next)
214 seq_printf(p, ", %s", action->name);
215 seq_putc(p, '\n');
216skip:
217 spin_unlock_irqrestore(&desc->lock, flags);
218 } else if (i == NR_IRQS) {
219#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT) 196#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
220 if (tau_initialized){ 197 if (tau_initialized){
221 seq_puts(p, "TAU: "); 198 seq_puts(p, "TAU: ");
@@ -225,30 +202,68 @@ skip:
225 } 202 }
226#endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/ 203#endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/
227 seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); 204 seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
205
206 return 0;
228 } 207 }
208
209 desc = irq_to_desc(i);
210 if (!desc)
211 return 0;
212
213 spin_lock_irqsave(&desc->lock, flags);
214
215 action = desc->action;
216 if (!action || !action->handler)
217 goto skip;
218
219 seq_printf(p, "%3d: ", i);
220#ifdef CONFIG_SMP
221 for_each_online_cpu(j)
222 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
223#else
224 seq_printf(p, "%10u ", kstat_irqs(i));
225#endif /* CONFIG_SMP */
226
227 if (desc->chip)
228 seq_printf(p, " %s ", desc->chip->name);
229 else
230 seq_puts(p, " None ");
231
232 seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
233 seq_printf(p, " %s", action->name);
234
235 for (action = action->next; action; action = action->next)
236 seq_printf(p, ", %s", action->name);
237 seq_putc(p, '\n');
238
239skip:
240 spin_unlock_irqrestore(&desc->lock, flags);
241
229 return 0; 242 return 0;
230} 243}
231 244
232#ifdef CONFIG_HOTPLUG_CPU 245#ifdef CONFIG_HOTPLUG_CPU
233void fixup_irqs(cpumask_t map) 246void fixup_irqs(cpumask_t map)
234{ 247{
248 struct irq_desc *desc;
235 unsigned int irq; 249 unsigned int irq;
236 static int warned; 250 static int warned;
237 251
238 for_each_irq(irq) { 252 for_each_irq(irq) {
239 cpumask_t mask; 253 cpumask_t mask;
240 254
241 if (irq_desc[irq].status & IRQ_PER_CPU) 255 desc = irq_to_desc(irq);
256 if (desc && desc->status & IRQ_PER_CPU)
242 continue; 257 continue;
243 258
244 cpumask_and(&mask, irq_desc[irq].affinity, &map); 259 cpumask_and(&mask, desc->affinity, &map);
245 if (any_online_cpu(mask) == NR_CPUS) { 260 if (any_online_cpu(mask) == NR_CPUS) {
246 printk("Breaking affinity for irq %i\n", irq); 261 printk("Breaking affinity for irq %i\n", irq);
247 mask = map; 262 mask = map;
248 } 263 }
249 if (irq_desc[irq].chip->set_affinity) 264 if (desc->chip->set_affinity)
250 irq_desc[irq].chip->set_affinity(irq, &mask); 265 desc->chip->set_affinity(irq, &mask);
251 else if (irq_desc[irq].action && !(warned++)) 266 else if (desc->action && !(warned++))
252 printk("Cannot set affinity for irq %i\n", irq); 267 printk("Cannot set affinity for irq %i\n", irq);
253 } 268 }
254 269
@@ -275,7 +290,7 @@ static inline void handle_one_irq(unsigned int irq)
275 return; 290 return;
276 } 291 }
277 292
278 desc = irq_desc + irq; 293 desc = irq_to_desc(irq);
279 saved_sp_limit = current->thread.ksp_limit; 294 saved_sp_limit = current->thread.ksp_limit;
280 295
281 irqtp->task = curtp->task; 296 irqtp->task = curtp->task;
@@ -541,7 +556,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
541 smp_wmb(); 556 smp_wmb();
542 557
543 /* Clear norequest flags */ 558 /* Clear norequest flags */
544 get_irq_desc(i)->status &= ~IRQ_NOREQUEST; 559 irq_to_desc(i)->status &= ~IRQ_NOREQUEST;
545 560
546 /* Legacy flags are left to default at this point, 561 /* Legacy flags are left to default at this point,
547 * one can then use irq_create_mapping() to 562 * one can then use irq_create_mapping() to
@@ -607,8 +622,16 @@ void irq_set_virq_count(unsigned int count)
607static int irq_setup_virq(struct irq_host *host, unsigned int virq, 622static int irq_setup_virq(struct irq_host *host, unsigned int virq,
608 irq_hw_number_t hwirq) 623 irq_hw_number_t hwirq)
609{ 624{
625 struct irq_desc *desc;
626
627 desc = irq_to_desc_alloc_node(virq, 0);
628 if (!desc) {
629 pr_debug("irq: -> allocating desc failed\n");
630 goto error;
631 }
632
610 /* Clear IRQ_NOREQUEST flag */ 633 /* Clear IRQ_NOREQUEST flag */
611 get_irq_desc(virq)->status &= ~IRQ_NOREQUEST; 634 desc->status &= ~IRQ_NOREQUEST;
612 635
613 /* map it */ 636 /* map it */
614 smp_wmb(); 637 smp_wmb();
@@ -617,11 +640,14 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
617 640
618 if (host->ops->map(host, virq, hwirq)) { 641 if (host->ops->map(host, virq, hwirq)) {
619 pr_debug("irq: -> mapping failed, freeing\n"); 642 pr_debug("irq: -> mapping failed, freeing\n");
620 irq_free_virt(virq, 1); 643 goto error;
621 return -1;
622 } 644 }
623 645
624 return 0; 646 return 0;
647
648error:
649 irq_free_virt(virq, 1);
650 return -1;
625} 651}
626 652
627unsigned int irq_create_direct_mapping(struct irq_host *host) 653unsigned int irq_create_direct_mapping(struct irq_host *host)
@@ -705,7 +731,7 @@ unsigned int irq_create_mapping(struct irq_host *host,
705EXPORT_SYMBOL_GPL(irq_create_mapping); 731EXPORT_SYMBOL_GPL(irq_create_mapping);
706 732
707unsigned int irq_create_of_mapping(struct device_node *controller, 733unsigned int irq_create_of_mapping(struct device_node *controller,
708 u32 *intspec, unsigned int intsize) 734 const u32 *intspec, unsigned int intsize)
709{ 735{
710 struct irq_host *host; 736 struct irq_host *host;
711 irq_hw_number_t hwirq; 737 irq_hw_number_t hwirq;
@@ -738,7 +764,7 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
738 764
739 /* Set type if specified and different than the current one */ 765 /* Set type if specified and different than the current one */
740 if (type != IRQ_TYPE_NONE && 766 if (type != IRQ_TYPE_NONE &&
741 type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK)) 767 type != (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
742 set_irq_type(virq, type); 768 set_irq_type(virq, type);
743 return virq; 769 return virq;
744} 770}
@@ -810,7 +836,7 @@ void irq_dispose_mapping(unsigned int virq)
810 irq_map[virq].hwirq = host->inval_irq; 836 irq_map[virq].hwirq = host->inval_irq;
811 837
812 /* Set some flags */ 838 /* Set some flags */
813 get_irq_desc(virq)->status |= IRQ_NOREQUEST; 839 irq_to_desc(virq)->status |= IRQ_NOREQUEST;
814 840
815 /* Free it */ 841 /* Free it */
816 irq_free_virt(virq, 1); 842 irq_free_virt(virq, 1);
@@ -1002,12 +1028,24 @@ void irq_free_virt(unsigned int virq, unsigned int count)
1002 spin_unlock_irqrestore(&irq_big_lock, flags); 1028 spin_unlock_irqrestore(&irq_big_lock, flags);
1003} 1029}
1004 1030
1005void irq_early_init(void) 1031int arch_early_irq_init(void)
1006{ 1032{
1007 unsigned int i; 1033 struct irq_desc *desc;
1034 int i;
1035
1036 for (i = 0; i < NR_IRQS; i++) {
1037 desc = irq_to_desc(i);
1038 if (desc)
1039 desc->status |= IRQ_NOREQUEST;
1040 }
1008 1041
1009 for (i = 0; i < NR_IRQS; i++) 1042 return 0;
1010 get_irq_desc(i)->status |= IRQ_NOREQUEST; 1043}
1044
1045int arch_init_chip_data(struct irq_desc *desc, int node)
1046{
1047 desc->status |= IRQ_NOREQUEST;
1048 return 0;
1011} 1049}
1012 1050
1013/* We need to create the radix trees late */ 1051/* We need to create the radix trees late */
@@ -1069,16 +1107,19 @@ static int virq_debug_show(struct seq_file *m, void *private)
1069 seq_printf(m, "%-5s %-7s %-15s %s\n", "virq", "hwirq", 1107 seq_printf(m, "%-5s %-7s %-15s %s\n", "virq", "hwirq",
1070 "chip name", "host name"); 1108 "chip name", "host name");
1071 1109
1072 for (i = 1; i < NR_IRQS; i++) { 1110 for (i = 1; i < nr_irqs; i++) {
1073 desc = get_irq_desc(i); 1111 desc = irq_to_desc(i);
1112 if (!desc)
1113 continue;
1114
1074 spin_lock_irqsave(&desc->lock, flags); 1115 spin_lock_irqsave(&desc->lock, flags);
1075 1116
1076 if (desc->action && desc->action->handler) { 1117 if (desc->action && desc->action->handler) {
1077 seq_printf(m, "%5d ", i); 1118 seq_printf(m, "%5d ", i);
1078 seq_printf(m, "0x%05lx ", virq_to_hw(i)); 1119 seq_printf(m, "0x%05lx ", virq_to_hw(i));
1079 1120
1080 if (desc->chip && desc->chip->typename) 1121 if (desc->chip && desc->chip->name)
1081 p = desc->chip->typename; 1122 p = desc->chip->name;
1082 else 1123 else
1083 p = none; 1124 p = none;
1084 seq_printf(m, "%-15s ", p); 1125 seq_printf(m, "%-15s ", p);