Commit 170660cc authored by Holger Dengler's avatar Holger Dengler Committed by Alexander Gordeev

s390/ap: rework ap initialization

Rework the ap initialization and add missing cleanups to the error path.
Errors during the registration of IRQ handler is now also detected.
Suggested-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarHolger Dengler <dengler@linux.ibm.com>
Reviewed-by: default avatarHarald Freudenberger <freude@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 8dec9cb9
...@@ -2273,7 +2273,66 @@ static void ap_scan_bus_wq_callback(struct work_struct *unused) ...@@ -2273,7 +2273,66 @@ static void ap_scan_bus_wq_callback(struct work_struct *unused)
} }
} }
static int __init ap_debug_init(void) static inline int __init ap_async_init(void)
{
int rc;
/* Setup the AP bus rescan timer. */
timer_setup(&ap_scan_bus_timer, ap_scan_bus_timer_callback, 0);
/*
* Setup the high resolution poll timer.
* If we are running under z/VM adjust polling to z/VM polling rate.
*/
if (MACHINE_IS_VM)
poll_high_timeout = 1500000;
hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
ap_poll_timer.function = ap_poll_timeout;
queue_work(system_long_wq, &ap_scan_bus_work);
/* Start the low priority AP bus poll thread. */
if (!ap_thread_flag)
return 0;
rc = ap_poll_thread_start();
if (rc)
goto out;
return 0;
out:
cancel_work(&ap_scan_bus_work);
hrtimer_cancel(&ap_poll_timer);
timer_delete(&ap_scan_bus_timer);
return rc;
}
static inline void ap_irq_exit(void)
{
if (ap_irq_flag)
unregister_adapter_interrupt(&ap_airq);
}
static inline int __init ap_irq_init(void)
{
int rc;
if (!ap_interrupts_available() || !ap_useirq)
return 0;
rc = register_adapter_interrupt(&ap_airq);
ap_irq_flag = (rc == 0);
return rc;
}
static inline void ap_debug_exit(void)
{
debug_unregister(ap_dbf_info);
}
static inline int __init ap_debug_init(void)
{ {
ap_dbf_info = debug_register("ap", 2, 1, ap_dbf_info = debug_register("ap", 2, 1,
AP_DBF_MAX_SPRINTF_ARGS * sizeof(long)); AP_DBF_MAX_SPRINTF_ARGS * sizeof(long));
...@@ -2342,15 +2401,14 @@ static int __init ap_module_init(void) ...@@ -2342,15 +2401,14 @@ static int __init ap_module_init(void)
} }
/* enable interrupts if available */ /* enable interrupts if available */
if (ap_interrupts_available() && ap_useirq) { rc = ap_irq_init();
rc = register_adapter_interrupt(&ap_airq); if (rc)
ap_irq_flag = (rc == 0); goto out;
}
/* Create /sys/bus/ap. */ /* Create /sys/bus/ap. */
rc = bus_register(&ap_bus_type); rc = bus_register(&ap_bus_type);
if (rc) if (rc)
goto out; goto out_irq;
/* Create /sys/devices/ap. */ /* Create /sys/devices/ap. */
ap_root_device = root_device_register("ap"); ap_root_device = root_device_register("ap");
...@@ -2359,37 +2417,21 @@ static int __init ap_module_init(void) ...@@ -2359,37 +2417,21 @@ static int __init ap_module_init(void)
goto out_bus; goto out_bus;
ap_root_device->bus = &ap_bus_type; ap_root_device->bus = &ap_bus_type;
/* Setup the AP bus rescan timer. */ /* Setup asynchronous work (timers, workqueue, etc). */
timer_setup(&ap_scan_bus_timer, ap_scan_bus_timer_callback, 0); rc = ap_async_init();
if (rc)
/* goto out_device;
* Setup the high resolution poll timer.
* If we are running under z/VM adjust polling to z/VM polling rate.
*/
if (MACHINE_IS_VM)
poll_high_timeout = 1500000;
hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
ap_poll_timer.function = ap_poll_timeout;
/* Start the low priority AP bus poll thread. */
if (ap_thread_flag) {
rc = ap_poll_thread_start();
if (rc)
goto out_work;
}
queue_work(system_long_wq, &ap_scan_bus_work);
return 0; return 0;
out_work: out_device:
hrtimer_cancel(&ap_poll_timer);
root_device_unregister(ap_root_device); root_device_unregister(ap_root_device);
out_bus: out_bus:
bus_unregister(&ap_bus_type); bus_unregister(&ap_bus_type);
out_irq:
ap_irq_exit();
out: out:
if (ap_irq_flag) ap_debug_exit();
unregister_adapter_interrupt(&ap_airq);
return rc; return rc;
} }
device_initcall(ap_module_init); device_initcall(ap_module_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment