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>
This commit is contained in:
Heiko Carstens 2013-09-04 13:35:45 +02:00
parent 50ce749d0d
commit 82003c3e60
9 changed files with 38 additions and 57 deletions

View File

@ -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 unregister_external_interrupt(u16 code, ext_int_handler_t handler);
void service_subclass_irq_register(void);
void service_subclass_irq_unregister(void);
void measurement_alert_subclass_register(void);
void measurement_alert_subclass_unregister(void);
enum irq_subclass {
IRQ_SUBCLASS_MEASUREMENT_ALERT = 5,
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)

View File

@ -290,48 +290,25 @@ void __init init_ext_interrupts(void)
setup_irq(EXT_INTERRUPT, &external_interrupt);
}
static DEFINE_SPINLOCK(sc_irq_lock);
static int sc_irq_refcount;
static DEFINE_SPINLOCK(irq_subclass_lock);
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);
if (!sc_irq_refcount)
ctl_set_bit(0, 9);
sc_irq_refcount++;
spin_unlock(&sc_irq_lock);
spin_lock(&irq_subclass_lock);
if (!irq_subclass_refcount[subclass])
ctl_set_bit(0, subclass);
irq_subclass_refcount[subclass]++;
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);
sc_irq_refcount--;
if (!sc_irq_refcount)
ctl_clear_bit(0, 9);
spin_unlock(&sc_irq_lock);
spin_lock(&irq_subclass_lock);
irq_subclass_refcount[subclass]--;
if (!irq_subclass_refcount[subclass])
ctl_clear_bit(0, subclass);
spin_unlock(&irq_subclass_lock);
}
EXPORT_SYMBOL(service_subclass_irq_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);
EXPORT_SYMBOL(irq_subclass_unregister);

View File

@ -274,7 +274,7 @@ static int reserve_pmc_hardware(void)
int flags = PMC_INIT;
on_each_cpu(setup_pmc_cpu, &flags, 1);
measurement_alert_subclass_register();
irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
return 0;
}
@ -285,7 +285,7 @@ static void release_pmc_hardware(void)
int flags = PMC_RELEASE;
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 */

View File

@ -139,10 +139,10 @@ static int __init runtime_instr_init(void)
if (!runtime_instr_avail())
return 0;
measurement_alert_subclass_register();
irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
rc = register_external_interrupt(0x1407, runtime_instr_int_handler);
if (rc)
measurement_alert_subclass_unregister();
irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
else
pr_info("Runtime instrumentation facility initialized\n");
return rc;

View File

@ -673,7 +673,7 @@ static int __init pfault_irq_init(void)
rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP;
if (rc)
goto out_pfault;
service_subclass_irq_register();
irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
hotcpu_notifier(pfault_cpu_notify, 0);
return 0;

View File

@ -1001,7 +1001,7 @@ int hwsampler_deallocate(void)
if (hws_state != HWS_STOPPED)
goto deallocate_exit;
measurement_alert_subclass_unregister();
irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
deallocate_sdbt();
hws_state = HWS_DEALLOCATED;
@ -1115,7 +1115,7 @@ int hwsampler_shutdown(void)
mutex_lock(&hws_sem);
if (hws_state == HWS_STOPPED) {
measurement_alert_subclass_unregister();
irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
deallocate_sdbt();
}
if (hws_wq) {
@ -1190,7 +1190,7 @@ start_all_exit:
hws_oom = 1;
hws_flush_all = 0;
/* now let them in, 1407 CPUMF external interrupts */
measurement_alert_subclass_register();
irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
return 0;
}

View File

@ -645,7 +645,7 @@ dasd_diag_init(void)
}
ASCEBC(dasd_diag_discipline.ebcname, 4);
service_subclass_irq_register();
irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
register_external_interrupt(0x2603, dasd_ext_handler);
dasd_diag_discipline_pointer = &dasd_diag_discipline;
return 0;
@ -655,7 +655,7 @@ static void __exit
dasd_diag_cleanup(void)
{
unregister_external_interrupt(0x2603, dasd_ext_handler);
service_subclass_irq_unregister();
irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
dasd_diag_discipline_pointer = NULL;
}

View File

@ -910,12 +910,12 @@ sclp_check_interface(void)
spin_unlock_irqrestore(&sclp_lock, flags);
/* Enable service-signal interruption - needs to happen
* with IRQs enabled. */
service_subclass_irq_register();
irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
/* Wait for signal from interrupt or timeout */
sclp_sync_wait();
/* Disable service-signal interruption - needs to happen
* with IRQs enabled. */
service_subclass_irq_unregister();
irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
spin_lock_irqsave(&sclp_lock, flags);
del_timer(&sclp_request_timer);
if (sclp_init_req.status == SCLP_REQ_DONE &&
@ -1131,7 +1131,7 @@ sclp_init(void)
spin_unlock_irqrestore(&sclp_lock, flags);
/* Enable service-signal external interruption - needs to happen with
* IRQs enabled. */
service_subclass_irq_register();
irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
sclp_init_mask(1);
return 0;

View File

@ -472,7 +472,7 @@ static int __init kvm_devices_init(void)
INIT_WORK(&hotplug_work, hotplug_devices);
service_subclass_irq_register();
irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
register_external_interrupt(0x2603, kvm_extint_handler);
scan_devices();