aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/include/asm/ccwgroup.h5
-rw-r--r--drivers/s390/cio/ccwgroup.c54
2 files changed, 50 insertions, 9 deletions
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h
index f2ea2c56a7e1..f5cfb7925867 100644
--- a/arch/s390/include/asm/ccwgroup.h
+++ b/arch/s390/include/asm/ccwgroup.h
@@ -31,6 +31,7 @@ struct ccwgroup_device {
31 * struct ccwgroup_driver - driver for ccw group devices 31 * struct ccwgroup_driver - driver for ccw group devices
32 * @max_slaves: maximum number of slave devices 32 * @max_slaves: maximum number of slave devices
33 * @driver_id: unique id 33 * @driver_id: unique id
34 * @setup: function called during device creation to setup the device
34 * @probe: function called on probe 35 * @probe: function called on probe
35 * @remove: function called on remove 36 * @remove: function called on remove
36 * @set_online: function called when device is set online 37 * @set_online: function called when device is set online
@@ -47,6 +48,7 @@ struct ccwgroup_driver {
47 int max_slaves; 48 int max_slaves;
48 unsigned long driver_id; 49 unsigned long driver_id;
49 50
51 int (*setup) (struct ccwgroup_device *);
50 int (*probe) (struct ccwgroup_device *); 52 int (*probe) (struct ccwgroup_device *);
51 void (*remove) (struct ccwgroup_device *); 53 void (*remove) (struct ccwgroup_device *);
52 int (*set_online) (struct ccwgroup_device *); 54 int (*set_online) (struct ccwgroup_device *);
@@ -63,6 +65,9 @@ struct ccwgroup_driver {
63 65
64extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); 66extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver);
65extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); 67extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
68int ccwgroup_create_dev(struct device *root, unsigned int creator_id,
69 struct ccw_driver *cdrv, struct ccwgroup_driver *gdrv,
70 int num_devices, const char *buf);
66int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, 71int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
67 struct ccw_driver *cdrv, int num_devices, 72 struct ccw_driver *cdrv, int num_devices,
68 const char *buf); 73 const char *buf);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 5f1dc6fb5708..0c7ed30ac87e 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bus driver for ccwgroup 2 * bus driver for ccwgroup
3 * 3 *
4 * Copyright IBM Corp. 2002, 2009 4 * Copyright IBM Corp. 2002, 2012
5 * 5 *
6 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com) 7 * Cornelia Huck (cornelia.huck@de.ibm.com)
@@ -291,14 +291,15 @@ static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
291} 291}
292 292
293/** 293/**
294 * ccwgroup_create_from_string() - create and register a ccw group device 294 * ccwgroup_create_dev() - create and register a ccw group device
295 * @root: parent device for the new device 295 * @parent: parent device for the new device
296 * @creator_id: identifier of creating driver 296 * @creator_id: identifier of creating driver
297 * @cdrv: ccw driver of slave devices 297 * @cdrv: ccw driver of slave devices
298 * @gdrv: driver for the new group device
298 * @num_devices: number of slave devices 299 * @num_devices: number of slave devices
299 * @buf: buffer containing comma separated bus ids of slave devices 300 * @buf: buffer containing comma separated bus ids of slave devices
300 * 301 *
301 * Create and register a new ccw group device as a child of @root. Slave 302 * Create and register a new ccw group device as a child of @parent. Slave
302 * devices are obtained from the list of bus ids given in @buf and must all 303 * devices are obtained from the list of bus ids given in @buf and must all
303 * belong to @cdrv. 304 * belong to @cdrv.
304 * Returns: 305 * Returns:
@@ -306,9 +307,9 @@ static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
306 * Context: 307 * Context:
307 * non-atomic 308 * non-atomic
308 */ 309 */
309int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, 310int ccwgroup_create_dev(struct device *parent, unsigned int creator_id,
310 struct ccw_driver *cdrv, int num_devices, 311 struct ccw_driver *cdrv, struct ccwgroup_driver *gdrv,
311 const char *buf) 312 int num_devices, const char *buf)
312{ 313{
313 struct ccwgroup_device *gdev; 314 struct ccwgroup_device *gdev;
314 int rc, i; 315 int rc, i;
@@ -323,10 +324,13 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
323 atomic_set(&gdev->onoff, 0); 324 atomic_set(&gdev->onoff, 0);
324 mutex_init(&gdev->reg_mutex); 325 mutex_init(&gdev->reg_mutex);
325 mutex_lock(&gdev->reg_mutex); 326 mutex_lock(&gdev->reg_mutex);
326 gdev->creator_id = creator_id; 327 if (gdrv)
328 gdev->creator_id = gdrv->driver_id;
329 else
330 gdev->creator_id = creator_id;
327 gdev->count = num_devices; 331 gdev->count = num_devices;
328 gdev->dev.bus = &ccwgroup_bus_type; 332 gdev->dev.bus = &ccwgroup_bus_type;
329 gdev->dev.parent = root; 333 gdev->dev.parent = parent;
330 gdev->dev.release = ccwgroup_release; 334 gdev->dev.release = ccwgroup_release;
331 device_initialize(&gdev->dev); 335 device_initialize(&gdev->dev);
332 336
@@ -373,6 +377,13 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
373 377
374 dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); 378 dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
375 gdev->dev.groups = ccwgroup_attr_groups; 379 gdev->dev.groups = ccwgroup_attr_groups;
380
381 if (gdrv) {
382 gdev->dev.driver = &gdrv->driver;
383 rc = gdrv->setup ? gdrv->setup(gdev) : 0;
384 if (rc)
385 goto error;
386 }
376 rc = device_add(&gdev->dev); 387 rc = device_add(&gdev->dev);
377 if (rc) 388 if (rc)
378 goto error; 389 goto error;
@@ -397,6 +408,31 @@ error:
397 put_device(&gdev->dev); 408 put_device(&gdev->dev);
398 return rc; 409 return rc;
399} 410}
411EXPORT_SYMBOL(ccwgroup_create_dev);
412
413/**
414 * ccwgroup_create_from_string() - create and register a ccw group device
415 * @root: parent device for the new device
416 * @creator_id: identifier of creating driver
417 * @cdrv: ccw driver of slave devices
418 * @num_devices: number of slave devices
419 * @buf: buffer containing comma separated bus ids of slave devices
420 *
421 * Create and register a new ccw group device as a child of @root. Slave
422 * devices are obtained from the list of bus ids given in @buf and must all
423 * belong to @cdrv.
424 * Returns:
425 * %0 on success and an error code on failure.
426 * Context:
427 * non-atomic
428 */
429int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
430 struct ccw_driver *cdrv, int num_devices,
431 const char *buf)
432{
433 return ccwgroup_create_dev(root, creator_id, cdrv, NULL,
434 num_devices, buf);
435}
400EXPORT_SYMBOL(ccwgroup_create_from_string); 436EXPORT_SYMBOL(ccwgroup_create_from_string);
401 437
402static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, 438static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,