aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2002-04-09 15:14:34 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 13:57:29 -0400
commit74e9f5fa1570f956c96dd5d3f1053daedbbf01a0 (patch)
tree095bfed9efced3538507d16eb93010d91c074f5f
parentc6a46696f97ff260a4ecce5e287f8de4b9d7fe14 (diff)
Driver core: remove unneeded completion from driver release path
The completion in the driver release path is due to ancient history in the _very_ early 2.5 days when we were not tracking the module reference count of attributes. It is not needed at all and can be removed. Note, we now have an empty release function for the driver structure. This is due to the fact that drivers are statically allocated in the system at this point in time, something which I want to change in the future. But remember, drivers are really code, which is reference counted by the module, unlike devices, which are data and _must_ be reference counted properly in order to work correctly. Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/bus.c15
-rw-r--r--drivers/base/driver.c20
-rw-r--r--include/linux/device.h1
3 files changed, 13 insertions, 23 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 20b6dc8706fa..1a5a350eca15 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -63,8 +63,19 @@ static struct sysfs_ops driver_sysfs_ops = {
63 63
64static void driver_release(struct kobject * kobj) 64static void driver_release(struct kobject * kobj)
65{ 65{
66 struct device_driver * drv = to_driver(kobj); 66 /*
67 complete(&drv->unloaded); 67 * Yes this is an empty release function, it is this way because struct
68 * device is always a static object, not a dynamic one. Yes, this is
69 * not nice and bad, but remember, drivers are code, reference counted
70 * by the module count, not a device, which is really data. And yes,
71 * in the future I do want to have all drivers be created dynamically,
72 * and am working toward that goal, but it will take a bit longer...
73 *
74 * But do not let this example give _anyone_ the idea that they can
75 * create a release function without any code in it at all, to do that
76 * is almost always wrong. If you have any questions about this,
77 * please send an email to <greg@kroah.com>
78 */
68} 79}
69 80
70static struct kobj_type ktype_driver = { 81static struct kobj_type ktype_driver = {
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 082bfded3854..eb11475293ed 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -149,10 +149,6 @@ void put_driver(struct device_driver * drv)
149 * We pass off most of the work to the bus_add_driver() call, 149 * We pass off most of the work to the bus_add_driver() call,
150 * since most of the things we have to do deal with the bus 150 * since most of the things we have to do deal with the bus
151 * structures. 151 * structures.
152 *
153 * The one interesting aspect is that we setup @drv->unloaded
154 * as a completion that gets complete when the driver reference
155 * count reaches 0.
156 */ 152 */
157int driver_register(struct device_driver * drv) 153int driver_register(struct device_driver * drv)
158{ 154{
@@ -162,35 +158,19 @@ int driver_register(struct device_driver * drv)
162 printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); 158 printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
163 } 159 }
164 klist_init(&drv->klist_devices, NULL, NULL); 160 klist_init(&drv->klist_devices, NULL, NULL);
165 init_completion(&drv->unloaded);
166 return bus_add_driver(drv); 161 return bus_add_driver(drv);
167} 162}
168 163
169
170/** 164/**
171 * driver_unregister - remove driver from system. 165 * driver_unregister - remove driver from system.
172 * @drv: driver. 166 * @drv: driver.
173 * 167 *
174 * Again, we pass off most of the work to the bus-level call. 168 * Again, we pass off most of the work to the bus-level call.
175 *
176 * Though, once that is done, we wait until @drv->unloaded is completed.
177 * This will block until the driver refcount reaches 0, and it is
178 * released. Only modular drivers will call this function, and we
179 * have to guarantee that it won't complete, letting the driver
180 * unload until all references are gone.
181 */ 169 */
182 170
183void driver_unregister(struct device_driver * drv) 171void driver_unregister(struct device_driver * drv)
184{ 172{
185 bus_remove_driver(drv); 173 bus_remove_driver(drv);
186 /*
187 * If the driver is a module, we are probably in
188 * the module unload path, and we want to wait
189 * for everything to unload before we can actually
190 * finish the unload.
191 */
192 if (drv->owner)
193 wait_for_completion(&drv->unloaded);
194} 174}
195 175
196/** 176/**
diff --git a/include/linux/device.h b/include/linux/device.h
index eb1fff0b1d2a..c9dc458e8e50 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -126,7 +126,6 @@ struct device_driver {
126 const char * name; 126 const char * name;
127 struct bus_type * bus; 127 struct bus_type * bus;
128 128
129 struct completion unloaded;
130 struct kobject kobj; 129 struct kobject kobj;
131 struct klist klist_devices; 130 struct klist klist_devices;
132 struct klist_node knode_bus; 131 struct klist_node knode_bus;