aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-10-12 23:17:41 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-10-30 17:59:51 -0400
commit1a6f2a7512021ceae3c4201c7aab07f032e9ce91 (patch)
tree03fdca9848003b3a6fda57113b3e750ec1e22a55 /drivers/base
parent39acbc12affcaa23ef1d887ba3d197baca8e6e47 (diff)
Driver core: allow certain drivers prohibit bind/unbind via sysfs
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>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/bus.c17
-rw-r--r--drivers/base/platform.c6
2 files changed, 16 insertions, 7 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 973bf2ad4e0..63c143e54a5 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -689,15 +689,19 @@ int bus_add_driver(struct device_driver *drv)
689 printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", 689 printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
690 __func__, drv->name); 690 __func__, drv->name);
691 } 691 }
692 error = add_bind_files(drv); 692
693 if (error) { 693 if (!drv->suppress_bind_attrs) {
694 /* Ditto */ 694 error = add_bind_files(drv);
695 printk(KERN_ERR "%s: add_bind_files(%s) failed\n", 695 if (error) {
696 __func__, drv->name); 696 /* Ditto */
697 printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
698 __func__, drv->name);
699 }
697 } 700 }
698 701
699 kobject_uevent(&priv->kobj, KOBJ_ADD); 702 kobject_uevent(&priv->kobj, KOBJ_ADD);
700 return 0; 703 return 0;
704
701out_unregister: 705out_unregister:
702 kfree(drv->p); 706 kfree(drv->p);
703 drv->p = NULL; 707 drv->p = NULL;
@@ -720,7 +724,8 @@ void bus_remove_driver(struct device_driver *drv)
720 if (!drv->bus) 724 if (!drv->bus)
721 return; 725 return;
722 726
723 remove_bind_files(drv); 727 if (!drv->suppress_bind_attrs)
728 remove_bind_files(drv);
724 driver_remove_attrs(drv->bus, drv); 729 driver_remove_attrs(drv->bus, drv);
725 driver_remove_file(drv, &driver_attr_uevent); 730 driver_remove_file(drv, &driver_attr_uevent);
726 klist_remove(&drv->p->knode_bus); 731 klist_remove(&drv->p->knode_bus);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ed156a13aa4..4fa954b07ac 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -521,11 +521,15 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
521{ 521{
522 int retval, code; 522 int retval, code;
523 523
524 /* make sure driver won't have bind/unbind attributes */
525 drv->driver.suppress_bind_attrs = true;
526
524 /* temporary section violation during probe() */ 527 /* temporary section violation during probe() */
525 drv->probe = probe; 528 drv->probe = probe;
526 retval = code = platform_driver_register(drv); 529 retval = code = platform_driver_register(drv);
527 530
528 /* Fixup that section violation, being paranoid about code scanning 531 /*
532 * Fixup that section violation, being paranoid about code scanning
529 * the list of drivers in order to probe new devices. Check to see 533 * the list of drivers in order to probe new devices. Check to see
530 * if the probe was successful, and make sure any forced probes of 534 * if the probe was successful, and make sure any forced probes of
531 * new devices fail. 535 * new devices fail.