aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/cio/css.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 99fcf9d0ea14..366affcd9bbf 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -18,6 +18,7 @@
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/suspend.h> 20#include <linux/suspend.h>
21#include <linux/proc_fs.h>
21#include <asm/isc.h> 22#include <asm/isc.h>
22#include <asm/crw.h> 23#include <asm/crw.h>
23 24
@@ -1019,6 +1020,18 @@ static int css_settle(struct device_driver *drv, void *unused)
1019 return 0; 1020 return 0;
1020} 1021}
1021 1022
1023static inline void css_complete_work(void)
1024{
1025 int ret;
1026
1027 /* Wait for the evaluation of subchannels to finish. */
1028 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
1029 flush_workqueue(cio_work_q);
1030 /* Wait for the subchannel type specific initialization to finish */
1031 ret = bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
1032}
1033
1034
1022/* 1035/*
1023 * Wait for the initialization of devices to finish, to make sure we are 1036 * Wait for the initialization of devices to finish, to make sure we are
1024 * done with our setup if the search for the root device starts. 1037 * done with our setup if the search for the root device starts.
@@ -1027,14 +1040,38 @@ static int __init channel_subsystem_init_sync(void)
1027{ 1040{
1028 /* Start initial subchannel evaluation. */ 1041 /* Start initial subchannel evaluation. */
1029 css_schedule_eval_all(); 1042 css_schedule_eval_all();
1030 /* Wait for the evaluation of subchannels to finish. */ 1043 css_complete_work();
1031 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0); 1044 return 0;
1032 flush_workqueue(cio_work_q);
1033 /* Wait for the subchannel type specific initialization to finish */
1034 return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
1035} 1045}
1036subsys_initcall_sync(channel_subsystem_init_sync); 1046subsys_initcall_sync(channel_subsystem_init_sync);
1037 1047
1048#ifdef CONFIG_PROC_FS
1049static ssize_t cio_settle_write(struct file *file, const char __user *buf,
1050 size_t count, loff_t *ppos)
1051{
1052 /* Handle pending CRW's. */
1053 crw_wait_for_channel_report();
1054 css_complete_work();
1055 return count;
1056}
1057
1058static const struct file_operations cio_settle_proc_fops = {
1059 .write = cio_settle_write,
1060};
1061
1062static int __init cio_settle_init(void)
1063{
1064 struct proc_dir_entry *entry;
1065
1066 entry = proc_create("cio_settle", S_IWUSR, NULL,
1067 &cio_settle_proc_fops);
1068 if (!entry)
1069 return -ENOMEM;
1070 return 0;
1071}
1072device_initcall(cio_settle_init);
1073#endif /*CONFIG_PROC_FS*/
1074
1038int sch_is_pseudo_sch(struct subchannel *sch) 1075int sch_is_pseudo_sch(struct subchannel *sch)
1039{ 1076{
1040 return sch == to_css(sch->dev.parent)->pseudo_subchannel; 1077 return sch == to_css(sch->dev.parent)->pseudo_subchannel;