aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2009-09-22 16:58:33 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-09-22 16:58:41 -0400
commit2f17644d1cd0121daa0a997ff4eca5b3b44d1fae (patch)
tree898504831cd8424525304eb9e35851f744a03d24 /drivers/s390
parent43c1266ce4dc06bfd236cec31e11e9ecd69c0bef (diff)
[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>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/css.c65
-rw-r--r--drivers/s390/cio/device.c20
-rw-r--r--drivers/s390/cio/device.h1
3 files changed, 61 insertions, 25 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 393c73c47f87..95805da2bb26 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -601,8 +601,7 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
601 css_evaluate_subchannel(mchk_schid, 0); 601 css_evaluate_subchannel(mchk_schid, 0);
602} 602}
603 603
604static int __init 604static int __init setup_subchannel(struct subchannel_id schid, void *data)
605__init_channel_subsystem(struct subchannel_id schid, void *data)
606{ 605{
607 struct subchannel *sch; 606 struct subchannel *sch;
608 int ret; 607 int ret;
@@ -854,14 +853,13 @@ static struct notifier_block css_power_notifier = {
854 * The struct subchannel's are created during probing (except for the 853 * The struct subchannel's are created during probing (except for the
855 * static console subchannel). 854 * static console subchannel).
856 */ 855 */
857static int __init 856static int __init css_bus_init(void)
858init_channel_subsystem (void)
859{ 857{
860 int ret, i; 858 int ret, i;
861 859
862 ret = chsc_determine_css_characteristics(); 860 ret = chsc_determine_css_characteristics();
863 if (ret == -ENOMEM) 861 if (ret == -ENOMEM)
864 goto out; /* No need to continue. */ 862 goto out;
865 863
866 ret = chsc_alloc_sei_area(); 864 ret = chsc_alloc_sei_area();
867 if (ret) 865 if (ret)
@@ -934,7 +932,6 @@ init_channel_subsystem (void)
934 /* Enable default isc for I/O subchannels. */ 932 /* Enable default isc for I/O subchannels. */
935 isc_register(IO_SCH_ISC); 933 isc_register(IO_SCH_ISC);
936 934
937 for_each_subchannel(__init_channel_subsystem, NULL);
938 return 0; 935 return 0;
939out_file: 936out_file:
940 if (css_chsc_characteristics.secm) 937 if (css_chsc_characteristics.secm)
@@ -966,6 +963,60 @@ out:
966 return ret; 963 return ret;
967} 964}
968 965
966static void __init css_bus_cleanup(void)
967{
968 struct channel_subsystem *css;
969 int i;
970
971 for (i = 0; i <= __MAX_CSSID; i++) {
972 css = channel_subsystems[i];
973 device_unregister(&css->pseudo_subchannel->dev);
974 css->pseudo_subchannel = NULL;
975 if (css_chsc_characteristics.secm)
976 device_remove_file(&css->device, &dev_attr_cm_enable);
977 device_unregister(&css->device);
978 }
979 bus_unregister(&css_bus_type);
980 crw_unregister_handler(CRW_RSC_CSS);
981 chsc_free_sei_area();
982 kfree(slow_subchannel_set);
983 isc_unregister(IO_SCH_ISC);
984}
985
986static int __init channel_subsystem_init(void)
987{
988 int ret;
989
990 ret = css_bus_init();
991 if (ret)
992 return ret;
993
994 ret = io_subchannel_init();
995 if (ret)
996 css_bus_cleanup();
997
998 return ret;
999}
1000subsys_initcall(channel_subsystem_init);
1001
1002/*
1003 * Wait for the initialization of devices to finish, to make sure we are
1004 * done with our setup if the search for the root device starts.
1005 */
1006static int __init channel_subsystem_init_sync(void)
1007{
1008 /* Allocate and register subchannels. */
1009 for_each_subchannel(setup_subchannel, NULL);
1010
1011 /* Wait for the initialization of ccw devices to finish. */
1012 wait_event(ccw_device_init_wq,
1013 atomic_read(&ccw_device_init_count) == 0);
1014 flush_workqueue(ccw_device_work);
1015
1016 return 0;
1017}
1018subsys_initcall_sync(channel_subsystem_init_sync);
1019
969int sch_is_pseudo_sch(struct subchannel *sch) 1020int sch_is_pseudo_sch(struct subchannel *sch)
970{ 1021{
971 return sch == to_css(sch->dev.parent)->pseudo_subchannel; 1022 return sch == to_css(sch->dev.parent)->pseudo_subchannel;
@@ -1135,7 +1186,5 @@ void css_driver_unregister(struct css_driver *cdrv)
1135} 1186}
1136EXPORT_SYMBOL_GPL(css_driver_unregister); 1187EXPORT_SYMBOL_GPL(css_driver_unregister);
1137 1188
1138subsys_initcall(init_channel_subsystem);
1139
1140MODULE_LICENSE("GPL"); 1189MODULE_LICENSE("GPL");
1141EXPORT_SYMBOL(css_bus_type); 1190EXPORT_SYMBOL(css_bus_type);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 6527f3f34493..4093adc12f2c 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -170,8 +170,7 @@ atomic_t ccw_device_init_count;
170 170
171static void recovery_func(unsigned long data); 171static void recovery_func(unsigned long data);
172 172
173static int __init 173int __init io_subchannel_init(void)
174init_ccw_bus_type (void)
175{ 174{
176 int ret; 175 int ret;
177 176
@@ -181,10 +180,10 @@ init_ccw_bus_type (void)
181 180
182 ccw_device_work = create_singlethread_workqueue("cio"); 181 ccw_device_work = create_singlethread_workqueue("cio");
183 if (!ccw_device_work) 182 if (!ccw_device_work)
184 return -ENOMEM; /* FIXME: better errno ? */ 183 return -ENOMEM;
185 slow_path_wq = create_singlethread_workqueue("kslowcrw"); 184 slow_path_wq = create_singlethread_workqueue("kslowcrw");
186 if (!slow_path_wq) { 185 if (!slow_path_wq) {
187 ret = -ENOMEM; /* FIXME: better errno ? */ 186 ret = -ENOMEM;
188 goto out_err; 187 goto out_err;
189 } 188 }
190 if ((ret = bus_register (&ccw_bus_type))) 189 if ((ret = bus_register (&ccw_bus_type)))
@@ -194,9 +193,6 @@ init_ccw_bus_type (void)
194 if (ret) 193 if (ret)
195 goto out_err; 194 goto out_err;
196 195
197 wait_event(ccw_device_init_wq,
198 atomic_read(&ccw_device_init_count) == 0);
199 flush_workqueue(ccw_device_work);
200 return 0; 196 return 0;
201out_err: 197out_err:
202 if (ccw_device_work) 198 if (ccw_device_work)
@@ -206,16 +202,6 @@ out_err:
206 return ret; 202 return ret;
207} 203}
208 204
209static void __exit
210cleanup_ccw_bus_type (void)
211{
212 css_driver_unregister(&io_subchannel_driver);
213 bus_unregister(&ccw_bus_type);
214 destroy_workqueue(ccw_device_work);
215}
216
217subsys_initcall(init_ccw_bus_type);
218module_exit(cleanup_ccw_bus_type);
219 205
220/************************ device handling **************************/ 206/************************ device handling **************************/
221 207
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index e3975107a578..ed39a2caaf47 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -74,6 +74,7 @@ dev_fsm_final_state(struct ccw_device *cdev)
74extern struct workqueue_struct *ccw_device_work; 74extern struct workqueue_struct *ccw_device_work;
75extern wait_queue_head_t ccw_device_init_wq; 75extern wait_queue_head_t ccw_device_init_wq;
76extern atomic_t ccw_device_init_count; 76extern atomic_t ccw_device_init_count;
77int __init io_subchannel_init(void);
77 78
78void io_subchannel_recog_done(struct ccw_device *cdev); 79void io_subchannel_recog_done(struct ccw_device *cdev);
79void io_subchannel_init_config(struct subchannel *sch); 80void io_subchannel_init_config(struct subchannel *sch);