|
|
@@ -725,15 +725,6 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
|
|
|
bool async_allowed;
|
|
|
int ret;
|
|
|
|
|
|
- /*
|
|
|
- * Check if device has already been claimed. This may
|
|
|
- * happen with driver loading, device discovery/registration,
|
|
|
- * and deferred probe processing happens all at once with
|
|
|
- * multiple threads.
|
|
|
- */
|
|
|
- if (dev->driver)
|
|
|
- return -EBUSY;
|
|
|
-
|
|
|
ret = driver_match_device(drv, dev);
|
|
|
if (ret == 0) {
|
|
|
/* no match */
|
|
|
@@ -768,6 +759,15 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
|
|
|
|
|
|
device_lock(dev);
|
|
|
|
|
|
+ /*
|
|
|
+ * Check if device has already been removed or claimed. This may
|
|
|
+ * happen with driver loading, device discovery/registration,
|
|
|
+ * and deferred probe processing happens all at once with
|
|
|
+ * multiple threads.
|
|
|
+ */
|
|
|
+ if (dev->p->dead || dev->driver)
|
|
|
+ goto out_unlock;
|
|
|
+
|
|
|
if (dev->parent)
|
|
|
pm_runtime_get_sync(dev->parent);
|
|
|
|
|
|
@@ -778,7 +778,7 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
|
|
|
|
|
|
if (dev->parent)
|
|
|
pm_runtime_put(dev->parent);
|
|
|
-
|
|
|
+out_unlock:
|
|
|
device_unlock(dev);
|
|
|
|
|
|
put_device(dev);
|
|
|
@@ -891,7 +891,7 @@ static int __driver_attach(struct device *dev, void *data)
|
|
|
if (dev->parent && dev->bus->need_parent_lock)
|
|
|
device_lock(dev->parent);
|
|
|
device_lock(dev);
|
|
|
- if (!dev->driver)
|
|
|
+ if (!dev->p->dead && !dev->driver)
|
|
|
driver_probe_device(drv, dev);
|
|
|
device_unlock(dev);
|
|
|
if (dev->parent && dev->bus->need_parent_lock)
|