mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
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:
parent
50ce749d0d
commit
82003c3e60
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user