forked from luck/tmp_suning_uos_patched
[S390] cio: merge init calls
Define initialization sequence of css and ccw bus init calls by merging them into a single init call. Also introduce channel_subsystem_init_sync to wait for the initialization of devices to finish. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
43c1266ce4
commit
2f17644d1c
@ -601,8 +601,7 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
|
|||||||
css_evaluate_subchannel(mchk_schid, 0);
|
css_evaluate_subchannel(mchk_schid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init
|
static int __init setup_subchannel(struct subchannel_id schid, void *data)
|
||||||
__init_channel_subsystem(struct subchannel_id schid, void *data)
|
|
||||||
{
|
{
|
||||||
struct subchannel *sch;
|
struct subchannel *sch;
|
||||||
int ret;
|
int ret;
|
||||||
@ -854,14 +853,13 @@ static struct notifier_block css_power_notifier = {
|
|||||||
* The struct subchannel's are created during probing (except for the
|
* The struct subchannel's are created during probing (except for the
|
||||||
* static console subchannel).
|
* static console subchannel).
|
||||||
*/
|
*/
|
||||||
static int __init
|
static int __init css_bus_init(void)
|
||||||
init_channel_subsystem (void)
|
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
ret = chsc_determine_css_characteristics();
|
ret = chsc_determine_css_characteristics();
|
||||||
if (ret == -ENOMEM)
|
if (ret == -ENOMEM)
|
||||||
goto out; /* No need to continue. */
|
goto out;
|
||||||
|
|
||||||
ret = chsc_alloc_sei_area();
|
ret = chsc_alloc_sei_area();
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -934,7 +932,6 @@ init_channel_subsystem (void)
|
|||||||
/* Enable default isc for I/O subchannels. */
|
/* Enable default isc for I/O subchannels. */
|
||||||
isc_register(IO_SCH_ISC);
|
isc_register(IO_SCH_ISC);
|
||||||
|
|
||||||
for_each_subchannel(__init_channel_subsystem, NULL);
|
|
||||||
return 0;
|
return 0;
|
||||||
out_file:
|
out_file:
|
||||||
if (css_chsc_characteristics.secm)
|
if (css_chsc_characteristics.secm)
|
||||||
@ -966,6 +963,60 @@ init_channel_subsystem (void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init css_bus_cleanup(void)
|
||||||
|
{
|
||||||
|
struct channel_subsystem *css;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i <= __MAX_CSSID; i++) {
|
||||||
|
css = channel_subsystems[i];
|
||||||
|
device_unregister(&css->pseudo_subchannel->dev);
|
||||||
|
css->pseudo_subchannel = NULL;
|
||||||
|
if (css_chsc_characteristics.secm)
|
||||||
|
device_remove_file(&css->device, &dev_attr_cm_enable);
|
||||||
|
device_unregister(&css->device);
|
||||||
|
}
|
||||||
|
bus_unregister(&css_bus_type);
|
||||||
|
crw_unregister_handler(CRW_RSC_CSS);
|
||||||
|
chsc_free_sei_area();
|
||||||
|
kfree(slow_subchannel_set);
|
||||||
|
isc_unregister(IO_SCH_ISC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init channel_subsystem_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = css_bus_init();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = io_subchannel_init();
|
||||||
|
if (ret)
|
||||||
|
css_bus_cleanup();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
subsys_initcall(channel_subsystem_init);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the initialization of devices to finish, to make sure we are
|
||||||
|
* done with our setup if the search for the root device starts.
|
||||||
|
*/
|
||||||
|
static int __init channel_subsystem_init_sync(void)
|
||||||
|
{
|
||||||
|
/* Allocate and register subchannels. */
|
||||||
|
for_each_subchannel(setup_subchannel, NULL);
|
||||||
|
|
||||||
|
/* Wait for the initialization of ccw devices to finish. */
|
||||||
|
wait_event(ccw_device_init_wq,
|
||||||
|
atomic_read(&ccw_device_init_count) == 0);
|
||||||
|
flush_workqueue(ccw_device_work);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
subsys_initcall_sync(channel_subsystem_init_sync);
|
||||||
|
|
||||||
int sch_is_pseudo_sch(struct subchannel *sch)
|
int sch_is_pseudo_sch(struct subchannel *sch)
|
||||||
{
|
{
|
||||||
return sch == to_css(sch->dev.parent)->pseudo_subchannel;
|
return sch == to_css(sch->dev.parent)->pseudo_subchannel;
|
||||||
@ -1135,7 +1186,5 @@ void css_driver_unregister(struct css_driver *cdrv)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(css_driver_unregister);
|
EXPORT_SYMBOL_GPL(css_driver_unregister);
|
||||||
|
|
||||||
subsys_initcall(init_channel_subsystem);
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
EXPORT_SYMBOL(css_bus_type);
|
EXPORT_SYMBOL(css_bus_type);
|
||||||
|
@ -170,8 +170,7 @@ atomic_t ccw_device_init_count;
|
|||||||
|
|
||||||
static void recovery_func(unsigned long data);
|
static void recovery_func(unsigned long data);
|
||||||
|
|
||||||
static int __init
|
int __init io_subchannel_init(void)
|
||||||
init_ccw_bus_type (void)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -181,10 +180,10 @@ init_ccw_bus_type (void)
|
|||||||
|
|
||||||
ccw_device_work = create_singlethread_workqueue("cio");
|
ccw_device_work = create_singlethread_workqueue("cio");
|
||||||
if (!ccw_device_work)
|
if (!ccw_device_work)
|
||||||
return -ENOMEM; /* FIXME: better errno ? */
|
return -ENOMEM;
|
||||||
slow_path_wq = create_singlethread_workqueue("kslowcrw");
|
slow_path_wq = create_singlethread_workqueue("kslowcrw");
|
||||||
if (!slow_path_wq) {
|
if (!slow_path_wq) {
|
||||||
ret = -ENOMEM; /* FIXME: better errno ? */
|
ret = -ENOMEM;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
if ((ret = bus_register (&ccw_bus_type)))
|
if ((ret = bus_register (&ccw_bus_type)))
|
||||||
@ -194,9 +193,6 @@ init_ccw_bus_type (void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
wait_event(ccw_device_init_wq,
|
|
||||||
atomic_read(&ccw_device_init_count) == 0);
|
|
||||||
flush_workqueue(ccw_device_work);
|
|
||||||
return 0;
|
return 0;
|
||||||
out_err:
|
out_err:
|
||||||
if (ccw_device_work)
|
if (ccw_device_work)
|
||||||
@ -206,16 +202,6 @@ init_ccw_bus_type (void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit
|
|
||||||
cleanup_ccw_bus_type (void)
|
|
||||||
{
|
|
||||||
css_driver_unregister(&io_subchannel_driver);
|
|
||||||
bus_unregister(&ccw_bus_type);
|
|
||||||
destroy_workqueue(ccw_device_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
subsys_initcall(init_ccw_bus_type);
|
|
||||||
module_exit(cleanup_ccw_bus_type);
|
|
||||||
|
|
||||||
/************************ device handling **************************/
|
/************************ device handling **************************/
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ dev_fsm_final_state(struct ccw_device *cdev)
|
|||||||
extern struct workqueue_struct *ccw_device_work;
|
extern struct workqueue_struct *ccw_device_work;
|
||||||
extern wait_queue_head_t ccw_device_init_wq;
|
extern wait_queue_head_t ccw_device_init_wq;
|
||||||
extern atomic_t ccw_device_init_count;
|
extern atomic_t ccw_device_init_count;
|
||||||
|
int __init io_subchannel_init(void);
|
||||||
|
|
||||||
void io_subchannel_recog_done(struct ccw_device *cdev);
|
void io_subchannel_recog_done(struct ccw_device *cdev);
|
||||||
void io_subchannel_init_config(struct subchannel *sch);
|
void io_subchannel_init_config(struct subchannel *sch);
|
||||||
|
Loading…
Reference in New Issue
Block a user