diff options
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r-- | drivers/base/dd.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index da57ee9d63fe..6658da743c3a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -245,6 +245,10 @@ int device_attach(struct device *dev) | |||
245 | 245 | ||
246 | device_lock(dev); | 246 | device_lock(dev); |
247 | if (dev->driver) { | 247 | if (dev->driver) { |
248 | if (klist_node_attached(&dev->p->knode_driver)) { | ||
249 | ret = 1; | ||
250 | goto out_unlock; | ||
251 | } | ||
248 | ret = device_bind_driver(dev); | 252 | ret = device_bind_driver(dev); |
249 | if (ret == 0) | 253 | if (ret == 0) |
250 | ret = 1; | 254 | ret = 1; |
@@ -257,6 +261,7 @@ int device_attach(struct device *dev) | |||
257 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 261 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); |
258 | pm_runtime_put_sync(dev); | 262 | pm_runtime_put_sync(dev); |
259 | } | 263 | } |
264 | out_unlock: | ||
260 | device_unlock(dev); | 265 | device_unlock(dev); |
261 | return ret; | 266 | return ret; |
262 | } | 267 | } |
@@ -316,8 +321,7 @@ static void __device_release_driver(struct device *dev) | |||
316 | 321 | ||
317 | drv = dev->driver; | 322 | drv = dev->driver; |
318 | if (drv) { | 323 | if (drv) { |
319 | pm_runtime_get_noresume(dev); | 324 | pm_runtime_get_sync(dev); |
320 | pm_runtime_barrier(dev); | ||
321 | 325 | ||
322 | driver_sysfs_remove(dev); | 326 | driver_sysfs_remove(dev); |
323 | 327 | ||
@@ -326,6 +330,8 @@ static void __device_release_driver(struct device *dev) | |||
326 | BUS_NOTIFY_UNBIND_DRIVER, | 330 | BUS_NOTIFY_UNBIND_DRIVER, |
327 | dev); | 331 | dev); |
328 | 332 | ||
333 | pm_runtime_put_sync(dev); | ||
334 | |||
329 | if (dev->bus && dev->bus->remove) | 335 | if (dev->bus && dev->bus->remove) |
330 | dev->bus->remove(dev); | 336 | dev->bus->remove(dev); |
331 | else if (drv->remove) | 337 | else if (drv->remove) |
@@ -338,7 +344,6 @@ static void __device_release_driver(struct device *dev) | |||
338 | BUS_NOTIFY_UNBOUND_DRIVER, | 344 | BUS_NOTIFY_UNBOUND_DRIVER, |
339 | dev); | 345 | dev); |
340 | 346 | ||
341 | pm_runtime_put_sync(dev); | ||
342 | } | 347 | } |
343 | } | 348 | } |
344 | 349 | ||
@@ -408,17 +413,16 @@ void *dev_get_drvdata(const struct device *dev) | |||
408 | } | 413 | } |
409 | EXPORT_SYMBOL(dev_get_drvdata); | 414 | EXPORT_SYMBOL(dev_get_drvdata); |
410 | 415 | ||
411 | void dev_set_drvdata(struct device *dev, void *data) | 416 | int dev_set_drvdata(struct device *dev, void *data) |
412 | { | 417 | { |
413 | int error; | 418 | int error; |
414 | 419 | ||
415 | if (!dev) | ||
416 | return; | ||
417 | if (!dev->p) { | 420 | if (!dev->p) { |
418 | error = device_private_init(dev); | 421 | error = device_private_init(dev); |
419 | if (error) | 422 | if (error) |
420 | return; | 423 | return error; |
421 | } | 424 | } |
422 | dev->p->driver_data = data; | 425 | dev->p->driver_data = data; |
426 | return 0; | ||
423 | } | 427 | } |
424 | EXPORT_SYMBOL(dev_set_drvdata); | 428 | EXPORT_SYMBOL(dev_set_drvdata); |