s390/ccwgroup: introduce ccwgroup_create_dev
Add a new interface for drivers to create a group device. Via the old interface ccwgroup_create_from_string we would create a virtual device in a way that only the caller of this function would match and bind to. Via the new ccwgroup_create_dev we stop playing games with the driver core and directly set the driver of the new group device. For drivers which have todo additional setup steps (like setting driver_data) provide a new setup driver callback. Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
eda0c6d6b0
Коммит
f2962dae0e
|
@ -31,6 +31,7 @@ struct ccwgroup_device {
|
||||||
* struct ccwgroup_driver - driver for ccw group devices
|
* struct ccwgroup_driver - driver for ccw group devices
|
||||||
* @max_slaves: maximum number of slave devices
|
* @max_slaves: maximum number of slave devices
|
||||||
* @driver_id: unique id
|
* @driver_id: unique id
|
||||||
|
* @setup: function called during device creation to setup the device
|
||||||
* @probe: function called on probe
|
* @probe: function called on probe
|
||||||
* @remove: function called on remove
|
* @remove: function called on remove
|
||||||
* @set_online: function called when device is set online
|
* @set_online: function called when device is set online
|
||||||
|
@ -47,6 +48,7 @@ struct ccwgroup_driver {
|
||||||
int max_slaves;
|
int max_slaves;
|
||||||
unsigned long driver_id;
|
unsigned long driver_id;
|
||||||
|
|
||||||
|
int (*setup) (struct ccwgroup_device *);
|
||||||
int (*probe) (struct ccwgroup_device *);
|
int (*probe) (struct ccwgroup_device *);
|
||||||
void (*remove) (struct ccwgroup_device *);
|
void (*remove) (struct ccwgroup_device *);
|
||||||
int (*set_online) (struct ccwgroup_device *);
|
int (*set_online) (struct ccwgroup_device *);
|
||||||
|
@ -63,6 +65,9 @@ struct ccwgroup_driver {
|
||||||
|
|
||||||
extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver);
|
extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver);
|
||||||
extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
|
extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
|
||||||
|
int ccwgroup_create_dev(struct device *root, unsigned int creator_id,
|
||||||
|
struct ccw_driver *cdrv, struct ccwgroup_driver *gdrv,
|
||||||
|
int num_devices, const char *buf);
|
||||||
int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
|
int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
|
||||||
struct ccw_driver *cdrv, int num_devices,
|
struct ccw_driver *cdrv, int num_devices,
|
||||||
const char *buf);
|
const char *buf);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* bus driver for ccwgroup
|
* bus driver for ccwgroup
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2002, 2009
|
* Copyright IBM Corp. 2002, 2012
|
||||||
*
|
*
|
||||||
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
|
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
|
||||||
* Cornelia Huck (cornelia.huck@de.ibm.com)
|
* Cornelia Huck (cornelia.huck@de.ibm.com)
|
||||||
|
@ -291,14 +291,15 @@ static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ccwgroup_create_from_string() - create and register a ccw group device
|
* ccwgroup_create_dev() - create and register a ccw group device
|
||||||
* @root: parent device for the new device
|
* @parent: parent device for the new device
|
||||||
* @creator_id: identifier of creating driver
|
* @creator_id: identifier of creating driver
|
||||||
* @cdrv: ccw driver of slave devices
|
* @cdrv: ccw driver of slave devices
|
||||||
|
* @gdrv: driver for the new group device
|
||||||
* @num_devices: number of slave devices
|
* @num_devices: number of slave devices
|
||||||
* @buf: buffer containing comma separated bus ids of slave devices
|
* @buf: buffer containing comma separated bus ids of slave devices
|
||||||
*
|
*
|
||||||
* Create and register a new ccw group device as a child of @root. Slave
|
* Create and register a new ccw group device as a child of @parent. Slave
|
||||||
* devices are obtained from the list of bus ids given in @buf and must all
|
* devices are obtained from the list of bus ids given in @buf and must all
|
||||||
* belong to @cdrv.
|
* belong to @cdrv.
|
||||||
* Returns:
|
* Returns:
|
||||||
|
@ -306,9 +307,9 @@ static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
|
||||||
* Context:
|
* Context:
|
||||||
* non-atomic
|
* non-atomic
|
||||||
*/
|
*/
|
||||||
int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
|
int ccwgroup_create_dev(struct device *parent, unsigned int creator_id,
|
||||||
struct ccw_driver *cdrv, int num_devices,
|
struct ccw_driver *cdrv, struct ccwgroup_driver *gdrv,
|
||||||
const char *buf)
|
int num_devices, const char *buf)
|
||||||
{
|
{
|
||||||
struct ccwgroup_device *gdev;
|
struct ccwgroup_device *gdev;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
@ -323,10 +324,13 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
|
||||||
atomic_set(&gdev->onoff, 0);
|
atomic_set(&gdev->onoff, 0);
|
||||||
mutex_init(&gdev->reg_mutex);
|
mutex_init(&gdev->reg_mutex);
|
||||||
mutex_lock(&gdev->reg_mutex);
|
mutex_lock(&gdev->reg_mutex);
|
||||||
gdev->creator_id = creator_id;
|
if (gdrv)
|
||||||
|
gdev->creator_id = gdrv->driver_id;
|
||||||
|
else
|
||||||
|
gdev->creator_id = creator_id;
|
||||||
gdev->count = num_devices;
|
gdev->count = num_devices;
|
||||||
gdev->dev.bus = &ccwgroup_bus_type;
|
gdev->dev.bus = &ccwgroup_bus_type;
|
||||||
gdev->dev.parent = root;
|
gdev->dev.parent = parent;
|
||||||
gdev->dev.release = ccwgroup_release;
|
gdev->dev.release = ccwgroup_release;
|
||||||
device_initialize(&gdev->dev);
|
device_initialize(&gdev->dev);
|
||||||
|
|
||||||
|
@ -373,6 +377,13 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
|
||||||
|
|
||||||
dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
|
dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
|
||||||
gdev->dev.groups = ccwgroup_attr_groups;
|
gdev->dev.groups = ccwgroup_attr_groups;
|
||||||
|
|
||||||
|
if (gdrv) {
|
||||||
|
gdev->dev.driver = &gdrv->driver;
|
||||||
|
rc = gdrv->setup ? gdrv->setup(gdev) : 0;
|
||||||
|
if (rc)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
rc = device_add(&gdev->dev);
|
rc = device_add(&gdev->dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -397,6 +408,31 @@ error:
|
||||||
put_device(&gdev->dev);
|
put_device(&gdev->dev);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(ccwgroup_create_dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ccwgroup_create_from_string() - create and register a ccw group device
|
||||||
|
* @root: parent device for the new device
|
||||||
|
* @creator_id: identifier of creating driver
|
||||||
|
* @cdrv: ccw driver of slave devices
|
||||||
|
* @num_devices: number of slave devices
|
||||||
|
* @buf: buffer containing comma separated bus ids of slave devices
|
||||||
|
*
|
||||||
|
* Create and register a new ccw group device as a child of @root. Slave
|
||||||
|
* devices are obtained from the list of bus ids given in @buf and must all
|
||||||
|
* belong to @cdrv.
|
||||||
|
* Returns:
|
||||||
|
* %0 on success and an error code on failure.
|
||||||
|
* Context:
|
||||||
|
* non-atomic
|
||||||
|
*/
|
||||||
|
int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
|
||||||
|
struct ccw_driver *cdrv, int num_devices,
|
||||||
|
const char *buf)
|
||||||
|
{
|
||||||
|
return ccwgroup_create_dev(root, creator_id, cdrv, NULL,
|
||||||
|
num_devices, buf);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(ccwgroup_create_from_string);
|
EXPORT_SYMBOL(ccwgroup_create_from_string);
|
||||||
|
|
||||||
static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
|
static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче