Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2962dae authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

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: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent eda0c6d6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct ccwgroup_device {
 * struct ccwgroup_driver - driver for ccw group devices
 * @max_slaves: maximum number of slave devices
 * @driver_id: unique id
 * @setup: function called during device creation to setup the device
 * @probe: function called on probe
 * @remove: function called on remove
 * @set_online: function called when device is set online
@@ -47,6 +48,7 @@ struct ccwgroup_driver {
	int max_slaves;
	unsigned long driver_id;

	int (*setup) (struct ccwgroup_device *);
	int (*probe) (struct ccwgroup_device *);
	void (*remove) (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 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,
				struct ccw_driver *cdrv, int num_devices,
				const char *buf);
+45 −9
Original line number Diff line number Diff line
/*
 *  bus driver for ccwgroup
 *
 *  Copyright IBM Corp. 2002, 2009
 *  Copyright IBM Corp. 2002, 2012
 *
 *  Author(s): Arnd Bergmann (arndb@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
 * @root: parent device for the new device
 * ccwgroup_create_dev() - create and register a ccw group device
 * @parent: parent device for the new device
 * @creator_id: identifier of creating driver
 * @cdrv: ccw driver of slave devices
 * @gdrv: driver for the new group device
 * @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
 * 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
 * belong to @cdrv.
 * Returns:
@@ -306,9 +307,9 @@ static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
 * 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)
int ccwgroup_create_dev(struct device *parent, unsigned int creator_id,
			struct ccw_driver *cdrv, struct ccwgroup_driver *gdrv,
			int num_devices, const char *buf)
{
	struct ccwgroup_device *gdev;
	int rc, i;
@@ -323,10 +324,13 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
	atomic_set(&gdev->onoff, 0);
	mutex_init(&gdev->reg_mutex);
	mutex_lock(&gdev->reg_mutex);
	if (gdrv)
		gdev->creator_id = gdrv->driver_id;
	else
		gdev->creator_id = creator_id;
	gdev->count = num_devices;
	gdev->dev.bus = &ccwgroup_bus_type;
	gdev->dev.parent = root;
	gdev->dev.parent = parent;
	gdev->dev.release = ccwgroup_release;
	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));
	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);
	if (rc)
		goto error;
@@ -397,6 +408,31 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
	put_device(&gdev->dev);
	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);

static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,