This is a note to let you know that I've just added the patch titled driver core: Refactor multiple copies of device cleanup to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: driver-core-refactor-multiple-copies-of-device-clean.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 7026884fd91f17a98191dca0a3b00cce394226d4 Author: Rob Herring <robh@xxxxxxxxxx> Date: Wed Feb 23 16:52:56 2022 -0600 driver core: Refactor multiple copies of device cleanup [ Upstream commit 9ad307213fa4081f4bc2f2daa31d4f2d35d7a213 ] There are 3 copies of the same device cleanup code used for probe failure, testing re-probing, and device unbinding. Changes to this code often miss at least one of the copies of the code. See commits d0243bbd5dd3 ("drivers core: Free dma_range_map when driver probe failed") and d8f7a5484f21 ("driver core: Free DMA range map when device is released") for example. Let's refactor the code to its own function. Signed-off-by: Rob Herring <robh@xxxxxxxxxx> Link: https://lore.kernel.org/r/20220223225257.1681968-2-robh@xxxxxxxxxx Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Stable-dep-of: 2e84dc379200 ("driver core: Release all resources during unbind before updating device links") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/base/dd.c b/drivers/base/dd.c index f5371daf4fd29..81683c99d6293 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -505,6 +505,19 @@ 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 int call_driver_probe(struct device *dev, struct device_driver *drv) { @@ -627,16 +640,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) 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; 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; } @@ -666,16 +671,7 @@ static int really_probe(struct device *dev, struct device_driver *drv) 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; } @@ -1230,17 +1226,7 @@ static void __device_release_driver(struct device *dev, struct device *parent) drv->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);