diff options
Diffstat (limited to 'drivers/base/driver.c')
-rw-r--r-- | drivers/base/driver.c | 35 |
1 files changed, 5 insertions, 30 deletions
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index b631f7c59453..60e4f77ca662 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -153,34 +153,6 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, | |||
153 | } | 153 | } |
154 | EXPORT_SYMBOL_GPL(driver_add_kobj); | 154 | EXPORT_SYMBOL_GPL(driver_add_kobj); |
155 | 155 | ||
156 | /** | ||
157 | * get_driver - increment driver reference count. | ||
158 | * @drv: driver. | ||
159 | */ | ||
160 | struct device_driver *get_driver(struct device_driver *drv) | ||
161 | { | ||
162 | if (drv) { | ||
163 | struct driver_private *priv; | ||
164 | struct kobject *kobj; | ||
165 | |||
166 | kobj = kobject_get(&drv->p->kobj); | ||
167 | priv = to_driver(kobj); | ||
168 | return priv->driver; | ||
169 | } | ||
170 | return NULL; | ||
171 | } | ||
172 | EXPORT_SYMBOL_GPL(get_driver); | ||
173 | |||
174 | /** | ||
175 | * put_driver - decrement driver's refcount. | ||
176 | * @drv: driver. | ||
177 | */ | ||
178 | void put_driver(struct device_driver *drv) | ||
179 | { | ||
180 | kobject_put(&drv->p->kobj); | ||
181 | } | ||
182 | EXPORT_SYMBOL_GPL(put_driver); | ||
183 | |||
184 | static int driver_add_groups(struct device_driver *drv, | 156 | static int driver_add_groups(struct device_driver *drv, |
185 | const struct attribute_group **groups) | 157 | const struct attribute_group **groups) |
186 | { | 158 | { |
@@ -234,7 +206,6 @@ int driver_register(struct device_driver *drv) | |||
234 | 206 | ||
235 | other = driver_find(drv->name, drv->bus); | 207 | other = driver_find(drv->name, drv->bus); |
236 | if (other) { | 208 | if (other) { |
237 | put_driver(other); | ||
238 | printk(KERN_ERR "Error: Driver '%s' is already registered, " | 209 | printk(KERN_ERR "Error: Driver '%s' is already registered, " |
239 | "aborting...\n", drv->name); | 210 | "aborting...\n", drv->name); |
240 | return -EBUSY; | 211 | return -EBUSY; |
@@ -275,7 +246,9 @@ EXPORT_SYMBOL_GPL(driver_unregister); | |||
275 | * Call kset_find_obj() to iterate over list of drivers on | 246 | * Call kset_find_obj() to iterate over list of drivers on |
276 | * a bus to find driver by name. Return driver if found. | 247 | * a bus to find driver by name. Return driver if found. |
277 | * | 248 | * |
278 | * Note that kset_find_obj increments driver's reference count. | 249 | * This routine provides no locking to prevent the driver it returns |
250 | * from being unregistered or unloaded while the caller is using it. | ||
251 | * The caller is responsible for preventing this. | ||
279 | */ | 252 | */ |
280 | struct device_driver *driver_find(const char *name, struct bus_type *bus) | 253 | struct device_driver *driver_find(const char *name, struct bus_type *bus) |
281 | { | 254 | { |
@@ -283,6 +256,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus) | |||
283 | struct driver_private *priv; | 256 | struct driver_private *priv; |
284 | 257 | ||
285 | if (k) { | 258 | if (k) { |
259 | /* Drop reference added by kset_find_obj() */ | ||
260 | kobject_put(k); | ||
286 | priv = to_driver(k); | 261 | priv = to_driver(k); |
287 | return priv->driver; | 262 | return priv->driver; |
288 | } | 263 | } |