aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2013-09-04 07:35:45 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2013-09-04 11:19:13 -0400
commit82003c3e606905ca20c78a0ceca9f412e6f71474 (patch)
tree846dc04eec40aaa7e25915cb8131ed52da97e334
parent50ce749d0d107aaed8c2d702b987529f978a40f7 (diff)
s390/irq: rework irq subclass handling
Let's not add a function for every external interrupt subclass for which we need reference counting. Just have two register/unregister functions which have a subclass parameter: void irq_subclass_register(enum irq_subclass subclass); void irq_subclass_unregister(enum irq_subclass subclass); Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
-rw-r--r--arch/s390/include/asm/irq.h12
-rw-r--r--arch/s390/kernel/irq.c55
-rw-r--r--arch/s390/kernel/perf_cpum_cf.c4
-rw-r--r--arch/s390/kernel/runtime_instr.c4
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/s390/oprofile/hwsampler.c6
-rw-r--r--drivers/s390/block/dasd_diag.c4
-rw-r--r--drivers/s390/char/sclp.c6
-rw-r--r--drivers/s390/kvm/kvm_virtio.c2
9 files changed, 38 insertions, 57 deletions
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index 1eaa3625803c..5f8bcc5fe423 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -78,10 +78,14 @@ typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long);
78 78
79int register_external_interrupt(u16 code, ext_int_handler_t handler); 79int register_external_interrupt(u16 code, ext_int_handler_t handler);
80int unregister_external_interrupt(u16 code, ext_int_handler_t handler); 80int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
81void service_subclass_irq_register(void); 81
82void service_subclass_irq_unregister(void); 82enum irq_subclass {
83void measurement_alert_subclass_register(void); 83 IRQ_SUBCLASS_MEASUREMENT_ALERT = 5,
84void measurement_alert_subclass_unregister(void); 84 IRQ_SUBCLASS_SERVICE_SIGNAL = 9,
85};
86
87void irq_subclass_register(enum irq_subclass subclass);
88void irq_subclass_unregister(enum irq_subclass subclass);
85 89
86#define irq_canonicalize(irq) (irq) 90#define irq_canonicalize(irq) (irq)
87 91
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 4ecf017f697c..6834277124c9 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -290,48 +290,25 @@ void __init init_ext_interrupts(void)
290 setup_irq(EXT_INTERRUPT, &external_interrupt); 290 setup_irq(EXT_INTERRUPT, &external_interrupt);
291} 291}
292 292
293static DEFINE_SPINLOCK(sc_irq_lock); 293static DEFINE_SPINLOCK(irq_subclass_lock);
294static int sc_irq_refcount; 294static unsigned char irq_subclass_refcount[64];
295 295
296void service_subclass_irq_register(void) 296void irq_subclass_register(enum irq_subclass subclass)
297{ 297{
298 spin_lock(&sc_irq_lock); 298 spin_lock(&irq_subclass_lock);
299 if (!sc_irq_refcount) 299 if (!irq_subclass_refcount[subclass])
300 ctl_set_bit(0, 9); 300 ctl_set_bit(0, subclass);
301 sc_irq_refcount++; 301 irq_subclass_refcount[subclass]++;
302 spin_unlock(&sc_irq_lock); 302 spin_unlock(&irq_subclass_lock);
303} 303}
304EXPORT_SYMBOL(service_subclass_irq_register); 304EXPORT_SYMBOL(irq_subclass_register);
305 305
306void service_subclass_irq_unregister(void) 306void irq_subclass_unregister(enum irq_subclass subclass)
307{ 307{
308 spin_lock(&sc_irq_lock); 308 spin_lock(&irq_subclass_lock);
309 sc_irq_refcount--; 309 irq_subclass_refcount[subclass]--;
310 if (!sc_irq_refcount) 310 if (!irq_subclass_refcount[subclass])
311 ctl_clear_bit(0, 9); 311 ctl_clear_bit(0, subclass);
312 spin_unlock(&sc_irq_lock); 312 spin_unlock(&irq_subclass_lock);
313} 313}
314EXPORT_SYMBOL(service_subclass_irq_unregister); 314EXPORT_SYMBOL(irq_subclass_unregister);
315
316static DEFINE_SPINLOCK(ma_subclass_lock);
317static int ma_subclass_refcount;
318
319void measurement_alert_subclass_register(void)
320{
321 spin_lock(&ma_subclass_lock);
322 if (!ma_subclass_refcount)
323 ctl_set_bit(0, 5);
324 ma_subclass_refcount++;
325 spin_unlock(&ma_subclass_lock);
326}
327EXPORT_SYMBOL(measurement_alert_subclass_register);
328
329void measurement_alert_subclass_unregister(void)
330{
331 spin_lock(&ma_subclass_lock);
332 ma_subclass_refcount--;
333 if (!ma_subclass_refcount)
334 ctl_clear_bit(0, 5);
335 spin_unlock(&ma_subclass_lock);
336}
337EXPORT_SYMBOL(measurement_alert_subclass_unregister);
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index fb99c2057b85..1105502bf6e9 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -274,7 +274,7 @@ static int reserve_pmc_hardware(void)
274 int flags = PMC_INIT; 274 int flags = PMC_INIT;
275 275
276 on_each_cpu(setup_pmc_cpu, &flags, 1); 276 on_each_cpu(setup_pmc_cpu, &flags, 1);
277 measurement_alert_subclass_register(); 277 irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
278 278
279 return 0; 279 return 0;
280} 280}
@@ -285,7 +285,7 @@ static void release_pmc_hardware(void)
285 int flags = PMC_RELEASE; 285 int flags = PMC_RELEASE;
286 286
287 on_each_cpu(setup_pmc_cpu, &flags, 1); 287 on_each_cpu(setup_pmc_cpu, &flags, 1);
288 measurement_alert_subclass_unregister(); 288 irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
289} 289}
290 290
291/* Release the PMU if event is the last perf event */ 291/* Release the PMU if event is the last perf event */
diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c
index 077a99389b07..e1c9d1c292fa 100644
--- a/arch/s390/kernel/runtime_instr.c
+++ b/arch/s390/kernel/runtime_instr.c
@@ -139,10 +139,10 @@ static int __init runtime_instr_init(void)
139 if (!runtime_instr_avail()) 139 if (!runtime_instr_avail())
140 return 0; 140 return 0;
141 141
142 measurement_alert_subclass_register(); 142 irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
143 rc = register_external_interrupt(0x1407, runtime_instr_int_handler); 143 rc = register_external_interrupt(0x1407, runtime_instr_int_handler);
144 if (rc) 144 if (rc)
145 measurement_alert_subclass_unregister(); 145 irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
146 else 146 else
147 pr_info("Runtime instrumentation facility initialized\n"); 147 pr_info("Runtime instrumentation facility initialized\n");
148 return rc; 148 return rc;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index f00aefb66a4e..7de4469915f0 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -673,7 +673,7 @@ static int __init pfault_irq_init(void)
673 rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP; 673 rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP;
674 if (rc) 674 if (rc)
675 goto out_pfault; 675 goto out_pfault;
676 service_subclass_irq_register(); 676 irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
677 hotcpu_notifier(pfault_cpu_notify, 0); 677 hotcpu_notifier(pfault_cpu_notify, 0);
678 return 0; 678 return 0;
679 679
diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c
index b5b2916895e0..231cecafc2f1 100644
--- a/arch/s390/oprofile/hwsampler.c
+++ b/arch/s390/oprofile/hwsampler.c
@@ -1001,7 +1001,7 @@ int hwsampler_deallocate(void)
1001 if (hws_state != HWS_STOPPED) 1001 if (hws_state != HWS_STOPPED)
1002 goto deallocate_exit; 1002 goto deallocate_exit;
1003 1003
1004 measurement_alert_subclass_unregister(); 1004 irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
1005 deallocate_sdbt(); 1005 deallocate_sdbt();
1006 1006
1007 hws_state = HWS_DEALLOCATED; 1007 hws_state = HWS_DEALLOCATED;
@@ -1115,7 +1115,7 @@ int hwsampler_shutdown(void)
1115 mutex_lock(&hws_sem); 1115 mutex_lock(&hws_sem);
1116 1116
1117 if (hws_state == HWS_STOPPED) { 1117 if (hws_state == HWS_STOPPED) {
1118 measurement_alert_subclass_unregister(); 1118 irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
1119 deallocate_sdbt(); 1119 deallocate_sdbt();
1120 } 1120 }
1121 if (hws_wq) { 1121 if (hws_wq) {
@@ -1190,7 +1190,7 @@ start_all_exit:
1190 hws_oom = 1; 1190 hws_oom = 1;
1191 hws_flush_all = 0; 1191 hws_flush_all = 0;
1192 /* now let them in, 1407 CPUMF external interrupts */ 1192 /* now let them in, 1407 CPUMF external interrupts */
1193 measurement_alert_subclass_register(); 1193 irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
1194 1194
1195 return 0; 1195 return 0;
1196} 1196}
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index feca317b33de..92bd22ce6760 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -645,7 +645,7 @@ dasd_diag_init(void)
645 } 645 }
646 ASCEBC(dasd_diag_discipline.ebcname, 4); 646 ASCEBC(dasd_diag_discipline.ebcname, 4);
647 647
648 service_subclass_irq_register(); 648 irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
649 register_external_interrupt(0x2603, dasd_ext_handler); 649 register_external_interrupt(0x2603, dasd_ext_handler);
650 dasd_diag_discipline_pointer = &dasd_diag_discipline; 650 dasd_diag_discipline_pointer = &dasd_diag_discipline;
651 return 0; 651 return 0;
@@ -655,7 +655,7 @@ static void __exit
655dasd_diag_cleanup(void) 655dasd_diag_cleanup(void)
656{ 656{
657 unregister_external_interrupt(0x2603, dasd_ext_handler); 657 unregister_external_interrupt(0x2603, dasd_ext_handler);
658 service_subclass_irq_unregister(); 658 irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
659 dasd_diag_discipline_pointer = NULL; 659 dasd_diag_discipline_pointer = NULL;
660} 660}
661 661
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 3e4fb4e858da..a3aa374799dc 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -910,12 +910,12 @@ sclp_check_interface(void)
910 spin_unlock_irqrestore(&sclp_lock, flags); 910 spin_unlock_irqrestore(&sclp_lock, flags);
911 /* Enable service-signal interruption - needs to happen 911 /* Enable service-signal interruption - needs to happen
912 * with IRQs enabled. */ 912 * with IRQs enabled. */
913 service_subclass_irq_register(); 913 irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
914 /* Wait for signal from interrupt or timeout */ 914 /* Wait for signal from interrupt or timeout */
915 sclp_sync_wait(); 915 sclp_sync_wait();
916 /* Disable service-signal interruption - needs to happen 916 /* Disable service-signal interruption - needs to happen
917 * with IRQs enabled. */ 917 * with IRQs enabled. */
918 service_subclass_irq_unregister(); 918 irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
919 spin_lock_irqsave(&sclp_lock, flags); 919 spin_lock_irqsave(&sclp_lock, flags);
920 del_timer(&sclp_request_timer); 920 del_timer(&sclp_request_timer);
921 if (sclp_init_req.status == SCLP_REQ_DONE && 921 if (sclp_init_req.status == SCLP_REQ_DONE &&
@@ -1131,7 +1131,7 @@ sclp_init(void)
1131 spin_unlock_irqrestore(&sclp_lock, flags); 1131 spin_unlock_irqrestore(&sclp_lock, flags);
1132 /* Enable service-signal external interruption - needs to happen with 1132 /* Enable service-signal external interruption - needs to happen with
1133 * IRQs enabled. */ 1133 * IRQs enabled. */
1134 service_subclass_irq_register(); 1134 irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
1135 sclp_init_mask(1); 1135 sclp_init_mask(1);
1136 return 0; 1136 return 0;
1137 1137
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 2ea6165366b6..af2166fa5159 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -472,7 +472,7 @@ static int __init kvm_devices_init(void)
472 472
473 INIT_WORK(&hotplug_work, hotplug_devices); 473 INIT_WORK(&hotplug_work, hotplug_devices);
474 474
475 service_subclass_irq_register(); 475 irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
476 register_external_interrupt(0x2603, kvm_extint_handler); 476 register_external_interrupt(0x2603, kvm_extint_handler);
477 477
478 scan_devices(); 478 scan_devices();