Skip to content

Commit

Permalink
Driver core: allow certain drivers prohibit bind/unbind via sysfs
Browse files Browse the repository at this point in the history
Platform drivers registered via platform_driver_probe() can be bound
to devices only once, upon registration, because discard their probe()
routines to save memory. Unbinding the driver through sysfs 'unbind'
leaves the device stranded and confuses users so let's not create
bind and unbind attributes for such drivers.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Éric Piel <eric.piel@tremplin-utc.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Dmitry Torokhov authored and Greg Kroah-Hartman committed Oct 30, 2009
1 parent 39acbc1 commit 1a6f2a7
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
17 changes: 11 additions & 6 deletions drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,15 +689,19 @@ int bus_add_driver(struct device_driver *drv)
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__func__, drv->name);
}
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);

if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
}
}

kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;

out_unregister:
kfree(drv->p);
drv->p = NULL;
Expand All @@ -720,7 +724,8 @@ void bus_remove_driver(struct device_driver *drv)
if (!drv->bus)
return;

remove_bind_files(drv);
if (!drv->suppress_bind_attrs)
remove_bind_files(drv);
driver_remove_attrs(drv->bus, drv);
driver_remove_file(drv, &driver_attr_uevent);
klist_remove(&drv->p->knode_bus);
Expand Down
6 changes: 5 additions & 1 deletion drivers/base/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,15 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
{
int retval, code;

/* make sure driver won't have bind/unbind attributes */
drv->driver.suppress_bind_attrs = true;

/* temporary section violation during probe() */
drv->probe = probe;
retval = code = platform_driver_register(drv);

/* Fixup that section violation, being paranoid about code scanning
/*
* Fixup that section violation, being paranoid about code scanning
* the list of drivers in order to probe new devices. Check to see
* if the probe was successful, and make sure any forced probes of
* new devices fail.
Expand Down
4 changes: 3 additions & 1 deletion include/linux/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ struct device_driver {
struct bus_type *bus;

struct module *owner;
const char *mod_name; /* used for built-in modules */
const char *mod_name; /* used for built-in modules */

bool suppress_bind_attrs; /* disables bind/unbind via sysfs */

int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
Expand Down

0 comments on commit 1a6f2a7

Please sign in to comment.