diff options
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r-- | drivers/base/dd.c | 88 |
1 files changed, 34 insertions, 54 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index f47cab21430f..af6bea56f4e2 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -152,7 +152,7 @@ void driver_deferred_probe_del(struct device *dev) mutex_unlock(&deferred_probe_mutex); } -static bool driver_deferred_probe_enable = false; +static bool driver_deferred_probe_enable; /** * driver_deferred_probe_trigger() - Kick off re-probing deferred devices * @@ -506,6 +506,30 @@ static ssize_t state_synced_show(struct device *dev, } static DEVICE_ATTR_RO(state_synced); +static void device_unbind_cleanup(struct device *dev) +{ + devres_release_all(dev); + arch_teardown_dma_ops(dev); + kfree(dev->dma_range_map); + dev->dma_range_map = NULL; + dev->driver = NULL; + dev_set_drvdata(dev, NULL); + if (dev->pm_domain && dev->pm_domain->dismiss) + dev->pm_domain->dismiss(dev); + pm_runtime_reinit(dev); + dev_pm_set_driver_flags(dev, 0); +} + +static void device_remove(struct device *dev) +{ + device_remove_file(dev, &dev_attr_state_synced); + device_remove_groups(dev, dev->driver->dev_groups); + + if (dev->bus && dev->bus->remove) + dev->bus->remove(dev); + else if (dev->driver->remove) + dev->driver->remove(dev); +} static int call_driver_probe(struct device *dev, struct device_driver *drv) { @@ -620,24 +644,9 @@ re_probe: if (test_remove) { test_remove = false; - device_remove_file(dev, &dev_attr_state_synced); - device_remove_groups(dev, drv->dev_groups); - - if (dev->bus->remove) - dev->bus->remove(dev); - else if (drv->remove) - drv->remove(dev); - - devres_release_all(dev); - arch_teardown_dma_ops(dev); - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; + device_remove(dev); driver_sysfs_remove(dev); - dev->driver = NULL; - dev_set_drvdata(dev, NULL); - if (dev->pm_domain && dev->pm_domain->dismiss) - dev->pm_domain->dismiss(dev); - pm_runtime_reinit(dev); + device_unbind_cleanup(dev); goto re_probe; } @@ -653,12 +662,8 @@ re_probe: goto done; dev_sysfs_state_synced_failed: - device_remove_groups(dev, drv->dev_groups); dev_groups_failed: - if (dev->bus->remove) - dev->bus->remove(dev); - else if (drv->remove) - drv->remove(dev); + device_remove(dev); probe_failed: driver_sysfs_remove(dev); sysfs_failed: @@ -667,16 +672,7 @@ sysfs_failed: BUS_NOTIFY_DRIVER_NOT_BOUND, dev); pinctrl_bind_failed: device_links_no_driver(dev); - devres_release_all(dev); - arch_teardown_dma_ops(dev); - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; - dev->driver = NULL; - dev_set_drvdata(dev, NULL); - if (dev->pm_domain && dev->pm_domain->dismiss) - dev->pm_domain->dismiss(dev); - pm_runtime_reinit(dev); - dev_pm_set_driver_flags(dev, 0); + device_unbind_cleanup(dev); done: return ret; } @@ -810,7 +806,7 @@ static int __init save_async_options(char *buf) pr_warn("Too long list of driver names for 'driver_async_probe'!\n"); strlcpy(async_probe_drv_names, buf, ASYNC_DRV_NAMES_MAX_LEN); - return 0; + return 1; } __setup("driver_async_probe=", save_async_options); @@ -838,7 +834,7 @@ struct device_attach_data { struct device *dev; /* - * Indicates whether we are are considering asynchronous probing or + * Indicates whether we are considering asynchronous probing or * not. Only initial binding after device or driver registration * (including deferral processing) may be done asynchronously, the * rest is always synchronous, as we expect it is being done by @@ -1042,7 +1038,7 @@ static void __device_driver_lock(struct device *dev, struct device *parent) * @parent: Parent device. Needed if the bus requires parent lock * * This function will release the required locks for manipulating dev->drv. - * Normally this will just be the the @dev lock, but when called for a + * Normally this will just be the @dev lock, but when called for a * USB interface, @parent lock will be released as well. */ static void __device_driver_unlock(struct device *dev, struct device *parent) @@ -1200,26 +1196,10 @@ static void __device_release_driver(struct device *dev, struct device *parent) pm_runtime_put_sync(dev); - device_remove_file(dev, &dev_attr_state_synced); - device_remove_groups(dev, drv->dev_groups); - - if (dev->bus && dev->bus->remove) - dev->bus->remove(dev); - else if (drv->remove) - drv->remove(dev); + device_remove(dev); device_links_driver_cleanup(dev); - - devres_release_all(dev); - arch_teardown_dma_ops(dev); - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; - dev->driver = NULL; - dev_set_drvdata(dev, NULL); - if (dev->pm_domain && dev->pm_domain->dismiss) - dev->pm_domain->dismiss(dev); - pm_runtime_reinit(dev); - dev_pm_set_driver_flags(dev, 0); + device_unbind_cleanup(dev); klist_remove(&dev->p->knode_driver); device_pm_check_callbacks(dev); |