diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index ab99500604b7..3ab99d883888 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -749,9 +749,16 @@ int cio_is_console(struct subchannel_id schid) return schid_equal(&schid, &console_sch->schid); } -struct subchannel *cio_get_console_subchannel(void) +void cio_register_early_subchannels(void) { - return console_sch; + int ret; + + if (!console_sch) + return; + + ret = css_register_subchannel(console_sch); + if (ret) + put_device(&console_sch->dev); } #endif /* CONFIG_CCW_CONSOLE */ diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 78975471ef28..57b41ec2ed40 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -129,11 +129,11 @@ void do_IRQ(struct pt_regs *); #ifdef CONFIG_CCW_CONSOLE extern struct subchannel *cio_probe_console(void); extern int cio_is_console(struct subchannel_id); -extern struct subchannel *cio_get_console_subchannel(void); +extern void cio_register_early_subchannels(void); extern void cio_tsch(struct subchannel *sch); #else #define cio_is_console(schid) 0 -#define cio_get_console_subchannel() NULL +static inline void cio_register_early_subchannels(void) {} #endif #endif diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index fb0e64f1845a..3b2245f58bde 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -224,16 +224,11 @@ void css_update_ssd_info(struct subchannel *sch) { int ret; - if (cio_is_console(sch->schid)) { - /* Console is initialized too early for functions requiring - * memory allocation. */ + ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); + if (ret) ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); - } else { - ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); - if (ret) - ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); - ssd_register_chpids(&sch->ssd_info); - } + + ssd_register_chpids(&sch->ssd_info); } static ssize_t type_show(struct device *dev, struct device_attribute *attr, @@ -271,7 +266,7 @@ static const struct attribute_group *default_subch_attr_groups[] = { NULL, }; -static int css_register_subchannel(struct subchannel *sch) +int css_register_subchannel(struct subchannel *sch) { int ret; @@ -314,13 +309,10 @@ int css_probe_device(struct subchannel_id schid) int ret; struct subchannel *sch; - if (cio_is_console(schid)) - sch = cio_get_console_subchannel(); - else { - sch = css_alloc_subchannel(schid); - if (IS_ERR(sch)) - return PTR_ERR(sch); - } + sch = css_alloc_subchannel(schid); + if (IS_ERR(sch)) + return PTR_ERR(sch); + ret = css_register_subchannel(sch); if (ret) put_device(&sch->dev); @@ -864,8 +856,7 @@ static struct notifier_block css_power_notifier = { /* * Now that the driver core is running, we can setup our channel subsystem. - * The struct subchannel's are created during probing (except for the - * static console subchannel). + * The struct subchannel's are created during probing. */ static int __init css_bus_init(void) { @@ -1044,6 +1035,8 @@ int css_complete_work(void) */ static int __init channel_subsystem_init_sync(void) { + /* Register subchannels which are already in use. */ + cio_register_early_subchannels(); /* Start initial subchannel evaluation. */ css_schedule_eval_all(); css_complete_work(); diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 6ab424d753a9..2581b6986569 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -102,6 +102,7 @@ extern void css_driver_unregister(struct css_driver *); extern void css_sch_device_unregister(struct subchannel *); extern int css_probe_device(struct subchannel_id); +extern int css_register_subchannel(struct subchannel *); extern struct subchannel *css_alloc_subchannel(struct subchannel_id); extern struct subchannel *get_subchannel_by_schid(struct subchannel_id); extern int css_init_done;