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

Commit 151ef38f authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

[PATCH] driver core: Add the ability to unbind drivers to devices from userspace



This adds a single file, "unbind", to the sysfs directory of every
device that is currently bound to a driver.  To unbind the driver from
the device, write anything to this file and they will be disconnected
from each other.

Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 0edb5860
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -133,6 +133,34 @@ static struct kobj_type ktype_bus = {
decl_subsys(bus, &ktype_bus, NULL);


/* Manually detach a device from it's associated driver. */
static int driver_helper(struct device *dev, void *data)
{
	const char *name = data;

	if (strcmp(name, dev->bus_id) == 0)
		return 1;
	return 0;
}

static ssize_t driver_unbind(struct device_driver *drv,
			     const char *buf, size_t count)
{
	struct bus_type *bus = get_bus(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
	if ((dev) &&
	    (dev->driver == drv)) {
		device_release_driver(dev);
		err = count;
	}
	return err;
}
static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);


static struct device * next_device(struct klist_iter * i)
{
	struct klist_node * n = klist_next(i);
@@ -396,6 +424,7 @@ int bus_add_driver(struct device_driver * drv)
		module_add_driver(drv->owner, drv);

		driver_add_attrs(bus, drv);
		driver_create_file(drv, &driver_attr_unbind);
	}
	return error;
}
@@ -413,6 +442,7 @@ int bus_add_driver(struct device_driver * drv)
void bus_remove_driver(struct device_driver * drv)
{
	if (drv->bus) {
		driver_remove_file(drv, &driver_attr_unbind);
		driver_remove_attrs(drv->bus, drv);
		klist_remove(&drv->knode_bus);
		pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);