diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-04-13 06:58:55 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 08:07:31 -0400 |
commit | c135ad1caffe2b35d6316758a605a2b63ca22bb3 (patch) | |
tree | f1b34819c6d3c1102cea9cc4d202013ef01d3fa9 /drivers/s390/cio | |
parent | f10ccca7a555f5e80ed7ecff58e7dfdab03860da (diff) |
s390/cio: split subchannel registration
Split the subchannel registration in device_initialize and device_add
and move the initialization part inside the allocation function. With
this change we can use refcounting during the complete lifespan of a
subchannel which is important for devices where we do the actually
registration at a later time.
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/css.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 658d9349c837..8a1294b1cbaf 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -137,8 +137,21 @@ out: | |||
137 | 137 | ||
138 | static void css_sch_todo(struct work_struct *work); | 138 | static void css_sch_todo(struct work_struct *work); |
139 | 139 | ||
140 | static struct subchannel * | 140 | static void css_subchannel_release(struct device *dev) |
141 | css_alloc_subchannel(struct subchannel_id schid) | 141 | { |
142 | struct subchannel *sch; | ||
143 | |||
144 | sch = to_subchannel(dev); | ||
145 | if (!cio_is_console(sch->schid)) { | ||
146 | /* Reset intparm to zeroes. */ | ||
147 | sch->config.intparm = 0; | ||
148 | cio_commit_config(sch); | ||
149 | kfree(sch->lock); | ||
150 | kfree(sch); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static struct subchannel *css_alloc_subchannel(struct subchannel_id schid) | ||
142 | { | 155 | { |
143 | struct subchannel *sch; | 156 | struct subchannel *sch; |
144 | int ret; | 157 | int ret; |
@@ -152,24 +165,11 @@ css_alloc_subchannel(struct subchannel_id schid) | |||
152 | return ERR_PTR(ret); | 165 | return ERR_PTR(ret); |
153 | } | 166 | } |
154 | INIT_WORK(&sch->todo_work, css_sch_todo); | 167 | INIT_WORK(&sch->todo_work, css_sch_todo); |
168 | sch->dev.release = &css_subchannel_release; | ||
169 | device_initialize(&sch->dev); | ||
155 | return sch; | 170 | return sch; |
156 | } | 171 | } |
157 | 172 | ||
158 | static void | ||
159 | css_subchannel_release(struct device *dev) | ||
160 | { | ||
161 | struct subchannel *sch; | ||
162 | |||
163 | sch = to_subchannel(dev); | ||
164 | if (!cio_is_console(sch->schid)) { | ||
165 | /* Reset intparm to zeroes. */ | ||
166 | sch->config.intparm = 0; | ||
167 | cio_commit_config(sch); | ||
168 | kfree(sch->lock); | ||
169 | kfree(sch); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static int css_sch_device_register(struct subchannel *sch) | 173 | static int css_sch_device_register(struct subchannel *sch) |
174 | { | 174 | { |
175 | int ret; | 175 | int ret; |
@@ -177,7 +177,7 @@ static int css_sch_device_register(struct subchannel *sch) | |||
177 | mutex_lock(&sch->reg_mutex); | 177 | mutex_lock(&sch->reg_mutex); |
178 | dev_set_name(&sch->dev, "0.%x.%04x", sch->schid.ssid, | 178 | dev_set_name(&sch->dev, "0.%x.%04x", sch->schid.ssid, |
179 | sch->schid.sch_no); | 179 | sch->schid.sch_no); |
180 | ret = device_register(&sch->dev); | 180 | ret = device_add(&sch->dev); |
181 | mutex_unlock(&sch->reg_mutex); | 181 | mutex_unlock(&sch->reg_mutex); |
182 | return ret; | 182 | return ret; |
183 | } | 183 | } |
@@ -282,7 +282,6 @@ static int css_register_subchannel(struct subchannel *sch) | |||
282 | /* Initialize the subchannel structure */ | 282 | /* Initialize the subchannel structure */ |
283 | sch->dev.parent = &channel_subsystems[0]->device; | 283 | sch->dev.parent = &channel_subsystems[0]->device; |
284 | sch->dev.bus = &css_bus_type; | 284 | sch->dev.bus = &css_bus_type; |
285 | sch->dev.release = &css_subchannel_release; | ||
286 | sch->dev.groups = default_subch_attr_groups; | 285 | sch->dev.groups = default_subch_attr_groups; |
287 | /* | 286 | /* |
288 | * We don't want to generate uevents for I/O subchannels that don't | 287 | * We don't want to generate uevents for I/O subchannels that don't |