aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/irq_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
-rw-r--r--arch/sparc/kernel/irq_64.c123
1 files changed, 33 insertions, 90 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index eb16e3b8a2dd..b1d275ce3435 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -162,47 +162,14 @@ void irq_free(unsigned int irq)
162/* 162/*
163 * /proc/interrupts printing: 163 * /proc/interrupts printing:
164 */ 164 */
165 165int arch_show_interrupts(struct seq_file *p, int prec)
166int show_interrupts(struct seq_file *p, void *v)
167{ 166{
168 int i = *(loff_t *) v, j; 167 int j;
169 struct irqaction * action;
170 unsigned long flags;
171 168
172 if (i == 0) { 169 seq_printf(p, "NMI: ");
173 seq_printf(p, " "); 170 for_each_online_cpu(j)
174 for_each_online_cpu(j) 171 seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
175 seq_printf(p, "CPU%d ",j); 172 seq_printf(p, " Non-maskable interrupts\n");
176 seq_putc(p, '\n');
177 }
178
179 if (i < NR_IRQS) {
180 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
181 action = irq_desc[i].action;
182 if (!action)
183 goto skip;
184 seq_printf(p, "%3d: ",i);
185#ifndef CONFIG_SMP
186 seq_printf(p, "%10u ", kstat_irqs(i));
187#else
188 for_each_online_cpu(j)
189 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
190#endif
191 seq_printf(p, " %9s", irq_desc[i].irq_data.chip->name);
192 seq_printf(p, " %s", action->name);
193
194 for (action=action->next; action; action = action->next)
195 seq_printf(p, ", %s", action->name);
196
197 seq_putc(p, '\n');
198skip:
199 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
200 } else if (i == NR_IRQS) {
201 seq_printf(p, "NMI: ");
202 for_each_online_cpu(j)
203 seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
204 seq_printf(p, " Non-maskable interrupts\n");
205 }
206 return 0; 173 return 0;
207} 174}
208 175
@@ -344,10 +311,6 @@ static void sun4u_irq_disable(struct irq_data *data)
344static void sun4u_irq_eoi(struct irq_data *data) 311static void sun4u_irq_eoi(struct irq_data *data)
345{ 312{
346 struct irq_handler_data *handler_data = data->handler_data; 313 struct irq_handler_data *handler_data = data->handler_data;
347 struct irq_desc *desc = irq_desc + data->irq;
348
349 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
350 return;
351 314
352 if (likely(handler_data)) 315 if (likely(handler_data))
353 upa_writeq(ICLR_IDLE, handler_data->iclr); 316 upa_writeq(ICLR_IDLE, handler_data->iclr);
@@ -402,12 +365,8 @@ static void sun4v_irq_disable(struct irq_data *data)
402static void sun4v_irq_eoi(struct irq_data *data) 365static void sun4v_irq_eoi(struct irq_data *data)
403{ 366{
404 unsigned int ino = irq_table[data->irq].dev_ino; 367 unsigned int ino = irq_table[data->irq].dev_ino;
405 struct irq_desc *desc = irq_desc + data->irq;
406 int err; 368 int err;
407 369
408 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
409 return;
410
411 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 370 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
412 if (err != HV_EOK) 371 if (err != HV_EOK)
413 printk(KERN_ERR "sun4v_intr_setstate(%x): " 372 printk(KERN_ERR "sun4v_intr_setstate(%x): "
@@ -481,13 +440,9 @@ static void sun4v_virq_disable(struct irq_data *data)
481 440
482static void sun4v_virq_eoi(struct irq_data *data) 441static void sun4v_virq_eoi(struct irq_data *data)
483{ 442{
484 struct irq_desc *desc = irq_desc + data->irq;
485 unsigned long dev_handle, dev_ino; 443 unsigned long dev_handle, dev_ino;
486 int err; 444 int err;
487 445
488 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
489 return;
490
491 dev_handle = irq_table[data->irq].dev_handle; 446 dev_handle = irq_table[data->irq].dev_handle;
492 dev_ino = irq_table[data->irq].dev_ino; 447 dev_ino = irq_table[data->irq].dev_ino;
493 448
@@ -505,6 +460,7 @@ static struct irq_chip sun4u_irq = {
505 .irq_disable = sun4u_irq_disable, 460 .irq_disable = sun4u_irq_disable,
506 .irq_eoi = sun4u_irq_eoi, 461 .irq_eoi = sun4u_irq_eoi,
507 .irq_set_affinity = sun4u_set_affinity, 462 .irq_set_affinity = sun4u_set_affinity,
463 .flags = IRQCHIP_EOI_IF_HANDLED,
508}; 464};
509 465
510static struct irq_chip sun4v_irq = { 466static struct irq_chip sun4v_irq = {
@@ -513,6 +469,7 @@ static struct irq_chip sun4v_irq = {
513 .irq_disable = sun4v_irq_disable, 469 .irq_disable = sun4v_irq_disable,
514 .irq_eoi = sun4v_irq_eoi, 470 .irq_eoi = sun4v_irq_eoi,
515 .irq_set_affinity = sun4v_set_affinity, 471 .irq_set_affinity = sun4v_set_affinity,
472 .flags = IRQCHIP_EOI_IF_HANDLED,
516}; 473};
517 474
518static struct irq_chip sun4v_virq = { 475static struct irq_chip sun4v_virq = {
@@ -521,30 +478,28 @@ static struct irq_chip sun4v_virq = {
521 .irq_disable = sun4v_virq_disable, 478 .irq_disable = sun4v_virq_disable,
522 .irq_eoi = sun4v_virq_eoi, 479 .irq_eoi = sun4v_virq_eoi,
523 .irq_set_affinity = sun4v_virt_set_affinity, 480 .irq_set_affinity = sun4v_virt_set_affinity,
481 .flags = IRQCHIP_EOI_IF_HANDLED,
524}; 482};
525 483
526static void pre_flow_handler(unsigned int irq, struct irq_desc *desc) 484static void pre_flow_handler(struct irq_data *d)
527{ 485{
528 struct irq_handler_data *handler_data = get_irq_data(irq); 486 struct irq_handler_data *handler_data = irq_data_get_irq_handler_data(d);
529 unsigned int ino = irq_table[irq].dev_ino; 487 unsigned int ino = irq_table[d->irq].dev_ino;
530 488
531 handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2); 489 handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2);
532
533 handle_fasteoi_irq(irq, desc);
534} 490}
535 491
536void irq_install_pre_handler(int irq, 492void irq_install_pre_handler(int irq,
537 void (*func)(unsigned int, void *, void *), 493 void (*func)(unsigned int, void *, void *),
538 void *arg1, void *arg2) 494 void *arg1, void *arg2)
539{ 495{
540 struct irq_handler_data *handler_data = get_irq_data(irq); 496 struct irq_handler_data *handler_data = irq_get_handler_data(irq);
541 struct irq_desc *desc = irq_desc + irq;
542 497
543 handler_data->pre_handler = func; 498 handler_data->pre_handler = func;
544 handler_data->arg1 = arg1; 499 handler_data->arg1 = arg1;
545 handler_data->arg2 = arg2; 500 handler_data->arg2 = arg2;
546 501
547 desc->handle_irq = pre_flow_handler; 502 __irq_set_preflow_handler(irq, pre_flow_handler);
548} 503}
549 504
550unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) 505unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
@@ -562,13 +517,11 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
562 if (!irq) { 517 if (!irq) {
563 irq = irq_alloc(0, ino); 518 irq = irq_alloc(0, ino);
564 bucket_set_irq(__pa(bucket), irq); 519 bucket_set_irq(__pa(bucket), irq);
565 set_irq_chip_and_handler_name(irq, 520 irq_set_chip_and_handler_name(irq, &sun4u_irq,
566 &sun4u_irq, 521 handle_fasteoi_irq, "IVEC");
567 handle_fasteoi_irq,
568 "IVEC");
569 } 522 }
570 523
571 handler_data = get_irq_data(irq); 524 handler_data = irq_get_handler_data(irq);
572 if (unlikely(handler_data)) 525 if (unlikely(handler_data))
573 goto out; 526 goto out;
574 527
@@ -577,7 +530,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
577 prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); 530 prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n");
578 prom_halt(); 531 prom_halt();
579 } 532 }
580 set_irq_data(irq, handler_data); 533 irq_set_handler_data(irq, handler_data);
581 534
582 handler_data->imap = imap; 535 handler_data->imap = imap;
583 handler_data->iclr = iclr; 536 handler_data->iclr = iclr;
@@ -600,12 +553,11 @@ static unsigned int sun4v_build_common(unsigned long sysino,
600 if (!irq) { 553 if (!irq) {
601 irq = irq_alloc(0, sysino); 554 irq = irq_alloc(0, sysino);
602 bucket_set_irq(__pa(bucket), irq); 555 bucket_set_irq(__pa(bucket), irq);
603 set_irq_chip_and_handler_name(irq, chip, 556 irq_set_chip_and_handler_name(irq, chip, handle_fasteoi_irq,
604 handle_fasteoi_irq,
605 "IVEC"); 557 "IVEC");
606 } 558 }
607 559
608 handler_data = get_irq_data(irq); 560 handler_data = irq_get_handler_data(irq);
609 if (unlikely(handler_data)) 561 if (unlikely(handler_data))
610 goto out; 562 goto out;
611 563
@@ -614,7 +566,7 @@ static unsigned int sun4v_build_common(unsigned long sysino,
614 prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); 566 prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n");
615 prom_halt(); 567 prom_halt();
616 } 568 }
617 set_irq_data(irq, handler_data); 569 irq_set_handler_data(irq, handler_data);
618 570
619 /* Catch accidental accesses to these things. IMAP/ICLR handling 571 /* Catch accidental accesses to these things. IMAP/ICLR handling
620 * is done by hypervisor calls on sun4v platforms, not by direct 572 * is done by hypervisor calls on sun4v platforms, not by direct
@@ -639,7 +591,6 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
639 struct irq_handler_data *handler_data; 591 struct irq_handler_data *handler_data;
640 unsigned long hv_err, cookie; 592 unsigned long hv_err, cookie;
641 struct ino_bucket *bucket; 593 struct ino_bucket *bucket;
642 struct irq_desc *desc;
643 unsigned int irq; 594 unsigned int irq;
644 595
645 bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); 596 bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
@@ -660,8 +611,7 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
660 irq = irq_alloc(devhandle, devino); 611 irq = irq_alloc(devhandle, devino);
661 bucket_set_irq(__pa(bucket), irq); 612 bucket_set_irq(__pa(bucket), irq);
662 613
663 set_irq_chip_and_handler_name(irq, &sun4v_virq, 614 irq_set_chip_and_handler_name(irq, &sun4v_virq, handle_fasteoi_irq,
664 handle_fasteoi_irq,
665 "IVEC"); 615 "IVEC");
666 616
667 handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); 617 handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
@@ -672,10 +622,8 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
672 * especially wrt. locking, we do not let request_irq() enable 622 * especially wrt. locking, we do not let request_irq() enable
673 * the interrupt. 623 * the interrupt.
674 */ 624 */
675 desc = irq_desc + irq; 625 irq_set_status_flags(irq, IRQ_NOAUTOEN);
676 desc->status |= IRQ_NOAUTOEN; 626 irq_set_handler_data(irq, handler_data);
677
678 set_irq_data(irq, handler_data);
679 627
680 /* Catch accidental accesses to these things. IMAP/ICLR handling 628 /* Catch accidental accesses to these things. IMAP/ICLR handling
681 * is done by hypervisor calls on sun4v platforms, not by direct 629 * is done by hypervisor calls on sun4v platforms, not by direct
@@ -734,7 +682,6 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs)
734 orig_sp = set_hardirq_stack(); 682 orig_sp = set_hardirq_stack();
735 683
736 while (bucket_pa) { 684 while (bucket_pa) {
737 struct irq_desc *desc;
738 unsigned long next_pa; 685 unsigned long next_pa;
739 unsigned int irq; 686 unsigned int irq;
740 687
@@ -742,10 +689,7 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs)
742 irq = bucket_get_irq(bucket_pa); 689 irq = bucket_get_irq(bucket_pa);
743 bucket_clear_chain_pa(bucket_pa); 690 bucket_clear_chain_pa(bucket_pa);
744 691
745 desc = irq_desc + irq; 692 generic_handle_irq(irq);
746
747 if (!(desc->status & IRQ_DISABLED))
748 desc->handle_irq(irq, desc);
749 693
750 bucket_pa = next_pa; 694 bucket_pa = next_pa;
751 } 695 }
@@ -788,19 +732,18 @@ void fixup_irqs(void)
788 unsigned int irq; 732 unsigned int irq;
789 733
790 for (irq = 0; irq < NR_IRQS; irq++) { 734 for (irq = 0; irq < NR_IRQS; irq++) {
735 struct irq_desc *desc = irq_to_desc(irq);
736 struct irq_data *data = irq_desc_get_irq_data(desc);
791 unsigned long flags; 737 unsigned long flags;
792 738
793 raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); 739 raw_spin_lock_irqsave(&desc->lock, flags);
794 if (irq_desc[irq].action && 740 if (desc->action && !irqd_is_per_cpu(data)) {
795 !(irq_desc[irq].status & IRQ_PER_CPU)) {
796 struct irq_data *data = irq_get_irq_data(irq);
797
798 if (data->chip->irq_set_affinity) 741 if (data->chip->irq_set_affinity)
799 data->chip->irq_set_affinity(data, 742 data->chip->irq_set_affinity(data,
800 data->affinity, 743 data->affinity,
801 false); 744 false);
802 } 745 }
803 raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); 746 raw_spin_unlock_irqrestore(&desc->lock, flags);
804 } 747 }
805 748
806 tick_ops->disable_irq(); 749 tick_ops->disable_irq();
@@ -1038,5 +981,5 @@ void __init init_IRQ(void)
1038 : "i" (PSTATE_IE) 981 : "i" (PSTATE_IE)
1039 : "g1"); 982 : "g1");
1040 983
1041 irq_desc[0].action = &timer_irq_action; 984 irq_to_desc(0)->action = &timer_irq_action;
1042} 985}