提交 82003c3e 编写于 作者: H Heiko Carstens

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: NHeiko Carstens <heiko.carstens@de.ibm.com>
上级 50ce749d
...@@ -78,10 +78,14 @@ typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long); ...@@ -78,10 +78,14 @@ typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long);
int register_external_interrupt(u16 code, ext_int_handler_t handler); int register_external_interrupt(u16 code, ext_int_handler_t handler);
int unregister_external_interrupt(u16 code, ext_int_handler_t handler); int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
void service_subclass_irq_register(void);
void service_subclass_irq_unregister(void); enum irq_subclass {
void measurement_alert_subclass_register(void); IRQ_SUBCLASS_MEASUREMENT_ALERT = 5,
void measurement_alert_subclass_unregister(void); IRQ_SUBCLASS_SERVICE_SIGNAL = 9,
};
void irq_subclass_register(enum irq_subclass subclass);
void irq_subclass_unregister(enum irq_subclass subclass);
#define irq_canonicalize(irq) (irq) #define irq_canonicalize(irq) (irq)
......
...@@ -290,48 +290,25 @@ void __init init_ext_interrupts(void) ...@@ -290,48 +290,25 @@ void __init init_ext_interrupts(void)
setup_irq(EXT_INTERRUPT, &external_interrupt); setup_irq(EXT_INTERRUPT, &external_interrupt);
} }
static DEFINE_SPINLOCK(sc_irq_lock); static DEFINE_SPINLOCK(irq_subclass_lock);
static int sc_irq_refcount; static unsigned char irq_subclass_refcount[64];
void service_subclass_irq_register(void) void irq_subclass_register(enum irq_subclass subclass)
{ {
spin_lock(&sc_irq_lock); spin_lock(&irq_subclass_lock);
if (!sc_irq_refcount) if (!irq_subclass_refcount[subclass])
ctl_set_bit(0, 9); ctl_set_bit(0, subclass);
sc_irq_refcount++; irq_subclass_refcount[subclass]++;
spin_unlock(&sc_irq_lock); spin_unlock(&irq_subclass_lock);
} }
EXPORT_SYMBOL(service_subclass_irq_register); EXPORT_SYMBOL(irq_subclass_register);
void service_subclass_irq_unregister(void) void irq_subclass_unregister(enum irq_subclass subclass)
{ {
spin_lock(&sc_irq_lock); spin_lock(&irq_subclass_lock);
sc_irq_refcount--; irq_subclass_refcount[subclass]--;
if (!sc_irq_refcount) if (!irq_subclass_refcount[subclass])
ctl_clear_bit(0, 9); ctl_clear_bit(0, subclass);
spin_unlock(&sc_irq_lock); spin_unlock(&irq_subclass_lock);
} }
EXPORT_SYMBOL(service_subclass_irq_unregister); EXPORT_SYMBOL(irq_subclass_unregister);
static DEFINE_SPINLOCK(ma_subclass_lock);
static int ma_subclass_refcount;
void measurement_alert_subclass_register(void)
{
spin_lock(&ma_subclass_lock);
if (!ma_subclass_refcount)
ctl_set_bit(0, 5);
ma_subclass_refcount++;
spin_unlock(&ma_subclass_lock);
}
EXPORT_SYMBOL(measurement_alert_subclass_register);
void measurement_alert_subclass_unregister(void)
{
spin_lock(&ma_subclass_lock);
ma_subclass_refcount--;
if (!ma_subclass_refcount)
ctl_clear_bit(0, 5);
spin_unlock(&ma_subclass_lock);
}
EXPORT_SYMBOL(measurement_alert_subclass_unregister);
...@@ -274,7 +274,7 @@ static int reserve_pmc_hardware(void) ...@@ -274,7 +274,7 @@ static int reserve_pmc_hardware(void)
int flags = PMC_INIT; int flags = PMC_INIT;
on_each_cpu(setup_pmc_cpu, &flags, 1); on_each_cpu(setup_pmc_cpu, &flags, 1);
measurement_alert_subclass_register(); irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
return 0; return 0;
} }
...@@ -285,7 +285,7 @@ static void release_pmc_hardware(void) ...@@ -285,7 +285,7 @@ static void release_pmc_hardware(void)
int flags = PMC_RELEASE; int flags = PMC_RELEASE;
on_each_cpu(setup_pmc_cpu, &flags, 1); on_each_cpu(setup_pmc_cpu, &flags, 1);
measurement_alert_subclass_unregister(); irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
} }
/* Release the PMU if event is the last perf event */ /* Release the PMU if event is the last perf event */
......
...@@ -139,10 +139,10 @@ static int __init runtime_instr_init(void) ...@@ -139,10 +139,10 @@ static int __init runtime_instr_init(void)
if (!runtime_instr_avail()) if (!runtime_instr_avail())
return 0; return 0;
measurement_alert_subclass_register(); irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
rc = register_external_interrupt(0x1407, runtime_instr_int_handler); rc = register_external_interrupt(0x1407, runtime_instr_int_handler);
if (rc) if (rc)
measurement_alert_subclass_unregister(); irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
else else
pr_info("Runtime instrumentation facility initialized\n"); pr_info("Runtime instrumentation facility initialized\n");
return rc; return rc;
......
...@@ -673,7 +673,7 @@ static int __init pfault_irq_init(void) ...@@ -673,7 +673,7 @@ static int __init pfault_irq_init(void)
rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP; rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP;
if (rc) if (rc)
goto out_pfault; goto out_pfault;
service_subclass_irq_register(); irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
hotcpu_notifier(pfault_cpu_notify, 0); hotcpu_notifier(pfault_cpu_notify, 0);
return 0; return 0;
......
...@@ -1001,7 +1001,7 @@ int hwsampler_deallocate(void) ...@@ -1001,7 +1001,7 @@ int hwsampler_deallocate(void)
if (hws_state != HWS_STOPPED) if (hws_state != HWS_STOPPED)
goto deallocate_exit; goto deallocate_exit;
measurement_alert_subclass_unregister(); irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
deallocate_sdbt(); deallocate_sdbt();
hws_state = HWS_DEALLOCATED; hws_state = HWS_DEALLOCATED;
...@@ -1115,7 +1115,7 @@ int hwsampler_shutdown(void) ...@@ -1115,7 +1115,7 @@ int hwsampler_shutdown(void)
mutex_lock(&hws_sem); mutex_lock(&hws_sem);
if (hws_state == HWS_STOPPED) { if (hws_state == HWS_STOPPED) {
measurement_alert_subclass_unregister(); irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
deallocate_sdbt(); deallocate_sdbt();
} }
if (hws_wq) { if (hws_wq) {
...@@ -1190,7 +1190,7 @@ int hwsampler_start_all(unsigned long rate) ...@@ -1190,7 +1190,7 @@ int hwsampler_start_all(unsigned long rate)
hws_oom = 1; hws_oom = 1;
hws_flush_all = 0; hws_flush_all = 0;
/* now let them in, 1407 CPUMF external interrupts */ /* now let them in, 1407 CPUMF external interrupts */
measurement_alert_subclass_register(); irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
return 0; return 0;
} }
......
...@@ -645,7 +645,7 @@ dasd_diag_init(void) ...@@ -645,7 +645,7 @@ dasd_diag_init(void)
} }
ASCEBC(dasd_diag_discipline.ebcname, 4); ASCEBC(dasd_diag_discipline.ebcname, 4);
service_subclass_irq_register(); irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
register_external_interrupt(0x2603, dasd_ext_handler); register_external_interrupt(0x2603, dasd_ext_handler);
dasd_diag_discipline_pointer = &dasd_diag_discipline; dasd_diag_discipline_pointer = &dasd_diag_discipline;
return 0; return 0;
...@@ -655,7 +655,7 @@ static void __exit ...@@ -655,7 +655,7 @@ static void __exit
dasd_diag_cleanup(void) dasd_diag_cleanup(void)
{ {
unregister_external_interrupt(0x2603, dasd_ext_handler); unregister_external_interrupt(0x2603, dasd_ext_handler);
service_subclass_irq_unregister(); irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
dasd_diag_discipline_pointer = NULL; dasd_diag_discipline_pointer = NULL;
} }
......
...@@ -910,12 +910,12 @@ sclp_check_interface(void) ...@@ -910,12 +910,12 @@ sclp_check_interface(void)
spin_unlock_irqrestore(&sclp_lock, flags); spin_unlock_irqrestore(&sclp_lock, flags);
/* Enable service-signal interruption - needs to happen /* Enable service-signal interruption - needs to happen
* with IRQs enabled. */ * with IRQs enabled. */
service_subclass_irq_register(); irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
/* Wait for signal from interrupt or timeout */ /* Wait for signal from interrupt or timeout */
sclp_sync_wait(); sclp_sync_wait();
/* Disable service-signal interruption - needs to happen /* Disable service-signal interruption - needs to happen
* with IRQs enabled. */ * with IRQs enabled. */
service_subclass_irq_unregister(); irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
spin_lock_irqsave(&sclp_lock, flags); spin_lock_irqsave(&sclp_lock, flags);
del_timer(&sclp_request_timer); del_timer(&sclp_request_timer);
if (sclp_init_req.status == SCLP_REQ_DONE && if (sclp_init_req.status == SCLP_REQ_DONE &&
...@@ -1131,7 +1131,7 @@ sclp_init(void) ...@@ -1131,7 +1131,7 @@ sclp_init(void)
spin_unlock_irqrestore(&sclp_lock, flags); spin_unlock_irqrestore(&sclp_lock, flags);
/* Enable service-signal external interruption - needs to happen with /* Enable service-signal external interruption - needs to happen with
* IRQs enabled. */ * IRQs enabled. */
service_subclass_irq_register(); irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
sclp_init_mask(1); sclp_init_mask(1);
return 0; return 0;
......
...@@ -472,7 +472,7 @@ static int __init kvm_devices_init(void) ...@@ -472,7 +472,7 @@ static int __init kvm_devices_init(void)
INIT_WORK(&hotplug_work, hotplug_devices); INIT_WORK(&hotplug_work, hotplug_devices);
service_subclass_irq_register(); irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
register_external_interrupt(0x2603, kvm_extint_handler); register_external_interrupt(0x2603, kvm_extint_handler);
scan_devices(); scan_devices();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册