]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
driver core: introduce device_set_driver() helper
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 11 Mar 2025 05:24:15 +0000 (22:24 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Apr 2025 15:04:35 +0000 (17:04 +0200)
In preparation to closing a race when reading driver pointer in
dev_uevent() code, instead of setting device->driver pointer directly
introduce device_set_driver() helper.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Link: https://lore.kernel.org/r/20250311052417.1846985-2-dmitry.torokhov@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/base.h
drivers/base/core.c
drivers/base/dd.c

index 0042e4774b0ce796e71c9fd3e9c92db00f250f60..eb203cf8370bc9e8cfd35d2871cf94962a5075b5 100644 (file)
@@ -180,6 +180,12 @@ int driver_add_groups(const struct device_driver *drv, const struct attribute_gr
 void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups);
 void device_driver_detach(struct device *dev);
 
+static inline void device_set_driver(struct device *dev, const struct device_driver *drv)
+{
+       // FIXME - this cast should not be needed "soon"
+       dev->driver = (struct device_driver *)drv;
+}
+
 int devres_release_all(struct device *dev);
 void device_block_probing(void);
 void device_unblock_probing(void);
index f9c1c623bca5e1a0b0e92b2e4cebf0d6f5310929..b000ee61c1494e6e2000a9ea51a5f7e6848d63b6 100644 (file)
@@ -3697,7 +3697,7 @@ done:
        device_pm_remove(dev);
        dpm_sysfs_remove(dev);
  DPMError:
-       dev->driver = NULL;
+       device_set_driver(dev, NULL);
        bus_remove_device(dev);
  BusError:
        device_remove_attrs(dev);
index f0e4b4aba885c6a71b5a07b6930eb19d06e5e306..b526e0e0f52d79f0cccf9e3d34cd5d07a25729c6 100644 (file)
@@ -550,7 +550,7 @@ static void device_unbind_cleanup(struct device *dev)
        arch_teardown_dma_ops(dev);
        kfree(dev->dma_range_map);
        dev->dma_range_map = NULL;
-       dev->driver = NULL;
+       device_set_driver(dev, NULL);
        dev_set_drvdata(dev, NULL);
        if (dev->pm_domain && dev->pm_domain->dismiss)
                dev->pm_domain->dismiss(dev);
@@ -629,8 +629,7 @@ static int really_probe(struct device *dev, const struct device_driver *drv)
        }
 
 re_probe:
-       // FIXME - this cast should not be needed "soon"
-       dev->driver = (struct device_driver *)drv;
+       device_set_driver(dev, drv);
 
        /* If using pinctrl, bind pins now before probing */
        ret = pinctrl_bind_pins(dev);
@@ -1014,7 +1013,7 @@ static int __device_attach(struct device *dev, bool allow_async)
                if (ret == 0)
                        ret = 1;
                else {
-                       dev->driver = NULL;
+                       device_set_driver(dev, NULL);
                        ret = 0;
                }
        } else {