diff options
-rw-r--r-- | drivers/base/bus.c | 15 | ||||
-rw-r--r-- | drivers/base/driver.c | 20 | ||||
-rw-r--r-- | include/linux/device.h | 1 |
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 | ||
64 | static void driver_release(struct kobject * kobj) | 64 | static 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 | ||
70 | static struct kobj_type ktype_driver = { | 81 | static 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 | */ |
157 | int driver_register(struct device_driver * drv) | 153 | int 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 | ||
183 | void driver_unregister(struct device_driver * drv) | 171 | void 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; |