aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/pci
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-24 04:30:41 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 15:10:28 -0400
commitf4eae94f71372ea5ec1ba17a85f3aebedc516ca8 (patch)
treeec3d6a527bf276a92e8befd559d9a0f0866ab7bd /arch/s390/pci
parent386aa051fb4b6298c23996e68b7c92f186e484b6 (diff)
s390/airq: simplify adapter interrupt code
There are three users of adapter interrupts: AP, QDIO and PCI. Each registers a single adapter interrupt with independent ISCs. Define a "struct airq" with the interrupt handler, a pointer and a mask for the local summary indicator and the ISC for the adapter interrupt source. Convert the indicator array with its fixed number of adapter interrupt sources per ISE to an array of hlists. This removes the limitation to 32 adapter interrupts per ISC and allows for arbitrary memory locations for the local summary indicator. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/pci')
-rw-r--r--arch/s390/pci/pci.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 51c3ca86bd05..e2956ad39a4f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -82,8 +82,13 @@ struct intr_bucket {
82 82
83static struct intr_bucket *bucket; 83static struct intr_bucket *bucket;
84 84
85/* Adapter local summary indicator */ 85/* Adapter interrupt definitions */
86static u8 *zpci_irq_si; 86static void zpci_irq_handler(struct airq_struct *airq);
87
88static struct airq_struct zpci_airq = {
89 .handler = zpci_irq_handler,
90 .isc = PCI_ISC,
91};
87 92
88/* I/O Map */ 93/* I/O Map */
89static DEFINE_SPINLOCK(zpci_iomap_lock); 94static DEFINE_SPINLOCK(zpci_iomap_lock);
@@ -402,7 +407,7 @@ static struct pci_ops pci_root_ops = {
402/* store the last handled bit to implement fair scheduling of devices */ 407/* store the last handled bit to implement fair scheduling of devices */
403static DEFINE_PER_CPU(unsigned long, next_sbit); 408static DEFINE_PER_CPU(unsigned long, next_sbit);
404 409
405static void zpci_irq_handler(void *dont, void *need) 410static void zpci_irq_handler(struct airq_struct *airq)
406{ 411{
407 unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit); 412 unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit);
408 int rescan = 0, max = aisb_max; 413 int rescan = 0, max = aisb_max;
@@ -712,25 +717,20 @@ static int __init zpci_irq_init(void)
712 goto out_alloc; 717 goto out_alloc;
713 } 718 }
714 719
715 isc_register(PCI_ISC); 720 rc = register_adapter_interrupt(&zpci_airq);
716 zpci_irq_si = s390_register_adapter_interrupt(&zpci_irq_handler, NULL, PCI_ISC); 721 if (rc)
717 if (IS_ERR(zpci_irq_si)) {
718 rc = PTR_ERR(zpci_irq_si);
719 zpci_irq_si = NULL;
720 goto out_ai; 722 goto out_ai;
721 } 723 /* Set summary to 1 to be called every time for the ISC. */
724 *zpci_airq.lsi_ptr = 1;
722 725
723 for_each_online_cpu(cpu) 726 for_each_online_cpu(cpu)
724 per_cpu(next_sbit, cpu) = 0; 727 per_cpu(next_sbit, cpu) = 0;
725 728
726 spin_lock_init(&bucket->lock); 729 spin_lock_init(&bucket->lock);
727 /* set summary to 1 to be called every time for the ISC */
728 *zpci_irq_si = 1;
729 set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); 730 set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
730 return 0; 731 return 0;
731 732
732out_ai: 733out_ai:
733 isc_unregister(PCI_ISC);
734 free_page((unsigned long) bucket->alloc); 734 free_page((unsigned long) bucket->alloc);
735out_alloc: 735out_alloc:
736 free_page((unsigned long) bucket->aisb); 736 free_page((unsigned long) bucket->aisb);
@@ -743,8 +743,7 @@ static void zpci_irq_exit(void)
743{ 743{
744 free_page((unsigned long) bucket->alloc); 744 free_page((unsigned long) bucket->alloc);
745 free_page((unsigned long) bucket->aisb); 745 free_page((unsigned long) bucket->aisb);
746 s390_unregister_adapter_interrupt(zpci_irq_si, PCI_ISC); 746 unregister_adapter_interrupt(&zpci_airq);
747 isc_unregister(PCI_ISC);
748 kfree(bucket); 747 kfree(bucket);
749} 748}
750 749