public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] driver core: generalize driver_override infrastructure
@ 2026-03-03 11:53 Danilo Krummrich
  2026-03-03 11:53 ` [PATCH v2 1/4] driver core: generalize driver_override in struct device Danilo Krummrich
                   ` (6 more replies)
  0 siblings, 7 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 11:53 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh, Danilo Krummrich

Currently, there are 12 busses (including platform and PCI) that duplicate the
driver_override logic for their individual devices.

All of them seem to be prone to the bug described in [1].

While this could be solved for every bus individually using a separate lock,
solving this in the driver-core generically results in less (and cleaner)
changes overall.

Thus, move driver_override to struct device, provide corresponding accessors for
busses and handle locking with a separate lock internally.

In particular, add device_set_driver_override(), device_has_driver_override(),
device_match_driver_override() and a helper, DEVICE_ATTR_DRIVER_OVERRIDE(), to
declare the corresponding sysfs store() and show() callbacks.

Until all busses have migrated, keep driver_set_override() in place.

Note that we can't use the device lock for the reasons described in [2].

This patch series includes the migration of the platform bus; patches for all
other affected busses still need to be extracted as a follow-up of the WIP
treewide patch in [3].

[1] https://bugzilla.kernel.org/show_bug.cgi?id=220789
[2] https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/
[3] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=driver_override

Changes in v2:
  - Drop DEVICE_ATTR_DRIVER_OVERRIDE() and make driver_override a
    struct bus_type feature instead.
  - Add driver_override documentation in .../driver-model/binding.rst.
  - Move kfree(dev->driver_override.name) before release().
  - hwmon: axi-fan: Use NULL instead of dev_name() in
    devm_request_threaded_irq().

Danilo Krummrich (4):
  driver core: generalize driver_override in struct device
  docs: driver-model: document driver_override
  hwmon: axi-fan: don't use driver_override as IRQ name
  driver core: platform: use generic driver_override infrastructure

 .../driver-api/driver-model/binding.rst       | 48 +++++++++++++++
 arch/sh/drivers/platform_early.c              |  6 +-
 drivers/base/bus.c                            | 43 ++++++++++++-
 drivers/base/core.c                           |  2 +
 drivers/base/dd.c                             | 60 +++++++++++++++++++
 drivers/base/platform.c                       | 37 ++----------
 drivers/bus/simple-pm-bus.c                   |  4 +-
 drivers/clk/imx/clk-scu.c                     |  3 +-
 drivers/hwmon/axi-fan-control.c               |  2 +-
 drivers/slimbus/qcom-ngd-ctrl.c               |  6 +-
 include/linux/device.h                        | 54 +++++++++++++++++
 include/linux/device/bus.h                    |  4 ++
 include/linux/platform_device.h               |  5 --
 sound/soc/samsung/i2s.c                       |  6 +-
 14 files changed, 228 insertions(+), 52 deletions(-)


base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
-- 
2.53.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v2 1/4] driver core: generalize driver_override in struct device
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
@ 2026-03-03 11:53 ` Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
  2026-03-04  2:27   ` Gui-Dong Han
  2026-03-03 11:53 ` [PATCH v2 2/4] docs: driver-model: document driver_override Danilo Krummrich
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 11:53 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh, Danilo Krummrich

Currently, there are 12 busses (including platform and PCI) that
duplicate the driver_override logic for their individual devices.

All of them seem to be prone to the bug described in [1].

While this could be solved for every bus individually using a separate
lock, solving this in the driver-core generically results in less (and
cleaner) changes overall.

Thus, move driver_override to struct device, provide corresponding
accessors for busses and handle locking with a separate lock internally.

In particular, add device_set_driver_override(),
device_has_driver_override(), device_match_driver_override() and a
helper, DEVICE_ATTR_DRIVER_OVERRIDE(), to declare the corresponding
sysfs store() and show() callbacks.

Until all busses have migrated, keep driver_set_override() in place.

Note that we can't use the device lock for the reasons described in [2].

Link: https://bugzilla.kernel.org/show_bug.cgi?id=220789 [1]
Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [2]
Co-developed-by: Gui-Dong Han <hanguidong02@gmail.com>
Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 drivers/base/bus.c         | 43 ++++++++++++++++++++++++++-
 drivers/base/core.c        |  2 ++
 drivers/base/dd.c          | 60 ++++++++++++++++++++++++++++++++++++++
 include/linux/device.h     | 54 ++++++++++++++++++++++++++++++++++
 include/linux/device/bus.h |  4 +++
 5 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index bb61d8adbab1..c734e7162b74 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -504,6 +504,36 @@ int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start,
 }
 EXPORT_SYMBOL_GPL(bus_for_each_drv);
 
+static ssize_t driver_override_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	int ret;
+
+	ret = __device_set_driver_override(dev, buf, count);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static ssize_t driver_override_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	guard(spinlock)(&dev->driver_override.lock);
+	return sysfs_emit(buf, "%s\n", dev->driver_override.name);
+}
+static DEVICE_ATTR_RW(driver_override);
+
+static struct attribute *driver_override_dev_attrs[] = {
+	&dev_attr_driver_override.attr,
+	NULL,
+};
+
+static const struct attribute_group driver_override_dev_group = {
+	.attrs = driver_override_dev_attrs,
+};
+
 /**
  * bus_add_device - add device to bus
  * @dev: device being added
@@ -537,9 +567,15 @@ int bus_add_device(struct device *dev)
 	if (error)
 		goto out_put;
 
+	if (sp->bus->driver_override) {
+		error = device_add_group(dev, &driver_override_dev_group);
+		if (error)
+			goto out_groups;
+	}
+
 	error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev));
 	if (error)
-		goto out_groups;
+		goto out_override;
 
 	error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem");
 	if (error)
@@ -550,6 +586,9 @@ int bus_add_device(struct device *dev)
 
 out_subsys:
 	sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev));
+out_override:
+	if (dev->bus->driver_override)
+		device_remove_group(dev, &driver_override_dev_group);
 out_groups:
 	device_remove_groups(dev, sp->bus->dev_groups);
 out_put:
@@ -607,6 +646,8 @@ void bus_remove_device(struct device *dev)
 
 	sysfs_remove_link(&dev->kobj, "subsystem");
 	sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev));
+	if (dev->bus->driver_override)
+		device_remove_group(dev, &driver_override_dev_group);
 	device_remove_groups(dev, dev->bus->dev_groups);
 	if (klist_node_attached(&dev->p->knode_bus))
 		klist_del(&dev->p->knode_bus);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 791f9e444df8..09b98f02f559 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2556,6 +2556,7 @@ static void device_release(struct kobject *kobj)
 	devres_release_all(dev);
 
 	kfree(dev->dma_range_map);
+	kfree(dev->driver_override.name);
 
 	if (dev->release)
 		dev->release(dev);
@@ -3159,6 +3160,7 @@ void device_initialize(struct device *dev)
 	kobject_init(&dev->kobj, &device_ktype);
 	INIT_LIST_HEAD(&dev->dma_pools);
 	mutex_init(&dev->mutex);
+	spin_lock_init(&dev->driver_override.lock);
 	lockdep_set_novalidate_class(&dev->mutex);
 	spin_lock_init(&dev->devres_lock);
 	INIT_LIST_HEAD(&dev->devres_head);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0354f209529c..697e36e63cab 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -381,6 +381,66 @@ static void __exit deferred_probe_exit(void)
 }
 __exitcall(deferred_probe_exit);
 
+int __device_set_driver_override(struct device *dev, const char *s, size_t len)
+{
+	const char *new, *old;
+	char *cp;
+
+	if (!s)
+		return -EINVAL;
+
+	/*
+	 * The stored value will be used in sysfs show callback (sysfs_emit()),
+	 * which has a length limit of PAGE_SIZE and adds a trailing newline.
+	 * Thus we can store one character less to avoid truncation during sysfs
+	 * show.
+	 */
+	if (len >= (PAGE_SIZE - 1))
+		return -EINVAL;
+
+	/*
+	 * Compute the real length of the string in case userspace sends us a
+	 * bunch of \0 characters like python likes to do.
+	 */
+	len = strlen(s);
+
+	if (!len) {
+		/* Empty string passed - clear override */
+		spin_lock(&dev->driver_override.lock);
+		old = dev->driver_override.name;
+		dev->driver_override.name = NULL;
+		spin_unlock(&dev->driver_override.lock);
+		kfree(old);
+
+		return 0;
+	}
+
+	cp = strnchr(s, len, '\n');
+	if (cp)
+		len = cp - s;
+
+	new = kstrndup(s, len, GFP_KERNEL);
+	if (!new)
+		return -ENOMEM;
+
+	spin_lock(&dev->driver_override.lock);
+	old = dev->driver_override.name;
+	if (cp != s) {
+		dev->driver_override.name = new;
+		spin_unlock(&dev->driver_override.lock);
+	} else {
+		/* "\n" passed - clear override */
+		dev->driver_override.name = NULL;
+		spin_unlock(&dev->driver_override.lock);
+
+		kfree(new);
+	}
+	kfree(old);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__device_set_driver_override);
+
 /**
  * device_is_bound() - Check if device is bound to a driver
  * @dev: device to check
diff --git a/include/linux/device.h b/include/linux/device.h
index 0be95294b6e6..e65d564f01cd 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -483,6 +483,8 @@ struct device_physical_location {
  * 		on.  This shrinks the "Board Support Packages" (BSPs) and
  * 		minimizes board-specific #ifdefs in drivers.
  * @driver_data: Private pointer for driver specific info.
+ * @driver_override: Driver name to force a match.  Do not touch directly; use
+ *		     device_set_driver_override() instead.
  * @links:	Links to suppliers and consumers of this device.
  * @power:	For device power management.
  *		See Documentation/driver-api/pm/devices.rst for details.
@@ -576,6 +578,10 @@ struct device {
 					   core doesn't touch it */
 	void		*driver_data;	/* Driver data, set and get with
 					   dev_set_drvdata/dev_get_drvdata */
+	struct {
+		const char	*name;
+		spinlock_t	lock;
+	} driver_override;
 	struct mutex		mutex;	/* mutex to synchronize calls to
 					 * its driver.
 					 */
@@ -701,6 +707,54 @@ struct device_link {
 
 #define kobj_to_dev(__kobj)	container_of_const(__kobj, struct device, kobj)
 
+int __device_set_driver_override(struct device *dev, const char *s, size_t len);
+
+/**
+ * device_set_driver_override() - Helper to set or clear driver override.
+ * @dev: Device to change
+ * @s: NUL-terminated string, new driver name to force a match, pass empty
+ *     string to clear it ("" or "\n", where the latter is only for sysfs
+ *     interface).
+ *
+ * Helper to set or clear driver override of a device.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int device_set_driver_override(struct device *dev, const char *s)
+{
+	return __device_set_driver_override(dev, s, s ? strlen(s) : 0);
+}
+
+/**
+ * device_has_driver_override() - Check if a driver override has been set.
+ * @dev: device to check
+ *
+ * Returns true if a driver override has been set for this device.
+ */
+static inline bool device_has_driver_override(struct device *dev)
+{
+	guard(spinlock)(&dev->driver_override.lock);
+	return !!dev->driver_override.name;
+}
+
+/**
+ * device_match_driver_override() - Match a driver against the device's driver_override.
+ * @dev: device to check
+ * @drv: driver to match against
+ *
+ * Returns > 0 if a driver override is set and matches the given driver, 0 if a
+ * driver override is set but does not match, or < 0 if a driver override is not
+ * set at all.
+ */
+static inline int device_match_driver_override(struct device *dev,
+					       const struct device_driver *drv)
+{
+	guard(spinlock)(&dev->driver_override.lock);
+	if (dev->driver_override.name)
+		return !strcmp(dev->driver_override.name, drv->name);
+	return -1;
+}
+
 /**
  * device_iommu_mapped - Returns true when the device DMA is translated
  *			 by an IOMMU
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 99c3c83ea520..cda597812324 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -63,6 +63,9 @@ struct fwnode_handle;
  *			this bus.
  * @pm:		Power management operations of this bus, callback the specific
  *		device driver's pm-ops.
+ * @driver_override:	Set to true if this bus supports the driver_override
+ *			mechanism, which allows userspace to force a specific
+ *			driver to bind to a device via a sysfs attribute.
  * @need_parent_lock:	When probing or removing a device on this bus, the
  *			device core should lock the device's parent.
  *
@@ -104,6 +107,7 @@ struct bus_type {
 
 	const struct dev_pm_ops *pm;
 
+	bool driver_override;
 	bool need_parent_lock;
 };
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 2/4] docs: driver-model: document driver_override
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
  2026-03-03 11:53 ` [PATCH v2 1/4] driver core: generalize driver_override in struct device Danilo Krummrich
@ 2026-03-03 11:53 ` Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
  2026-03-03 11:53 ` [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name Danilo Krummrich
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 11:53 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh, Danilo Krummrich

Now that we support driver_override as a driver-core feature through
struct device and struct bus_type, add some documentation in the context
of how a device / driver binding is established.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 .../driver-api/driver-model/binding.rst       | 48 +++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/Documentation/driver-api/driver-model/binding.rst b/Documentation/driver-api/driver-model/binding.rst
index d1d311a4011f..fa0888c2b3b9 100644
--- a/Documentation/driver-api/driver-model/binding.rst
+++ b/Documentation/driver-api/driver-model/binding.rst
@@ -99,3 +99,51 @@ of the driver is decremented. All symlinks between the two are removed.
 When a driver is removed, the list of devices that it supports is
 iterated over, and the driver's remove callback is called for each
 one. The device is removed from that list and the symlinks removed.
+
+
+Driver Override
+~~~~~~~~~~~~~~~
+
+Userspace may override the standard matching by writing a driver name to
+a device's ``driver_override`` sysfs attribute.  When set, only a driver
+whose name matches the override will be considered during binding.  This
+bypasses all bus-specific matching (OF, ACPI, ID tables, etc.).
+
+The override may be cleared by writing an empty string, which returns
+the device to standard matching rules.  Writing to ``driver_override``
+does not automatically unbind the device from its current driver or
+make any attempt to load the specified driver.
+
+Buses opt into this mechanism by setting the ``driver_override`` flag in
+their ``struct bus_type``::
+
+  const struct bus_type example_bus_type = {
+      ...
+      .driver_override = true,
+  };
+
+When the flag is set, the driver core automatically creates the
+``driver_override`` sysfs attribute for every device on that bus.
+
+The bus's ``match()`` callback should check the override before performing
+its own matching, using ``device_match_driver_override()``::
+
+  static int example_match(struct device *dev, const struct device_driver *drv)
+  {
+      int ret;
+
+      ret = device_match_driver_override(dev, drv);
+      if (ret >= 0)
+          return ret;
+
+      /* Fall through to bus-specific matching... */
+  }
+
+``device_match_driver_override()`` returns > 0 if the override matches
+the given driver, 0 if the override is set but does not match, or < 0 if
+no override is set at all.
+
+Additional helpers are available:
+
+- ``device_set_driver_override()`` - set or clear the override from kernel code.
+- ``device_has_driver_override()`` - check whether an override is set.
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
  2026-03-03 11:53 ` [PATCH v2 1/4] driver core: generalize driver_override in struct device Danilo Krummrich
  2026-03-03 11:53 ` [PATCH v2 2/4] docs: driver-model: document driver_override Danilo Krummrich
@ 2026-03-03 11:53 ` Danilo Krummrich
  2026-03-03 14:53   ` Nuno Sá
                     ` (2 more replies)
  2026-03-03 11:53 ` [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure Danilo Krummrich
                   ` (3 subsequent siblings)
  6 siblings, 3 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 11:53 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh, Danilo Krummrich

Do not use driver_override as IRQ name, as it is not guaranteed to point
to a valid string; use NULL instead (which makes the devm IRQ helpers
use dev_name()).

Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 drivers/hwmon/axi-fan-control.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c
index b7bb325c3ad9..01590dfa55e6 100644
--- a/drivers/hwmon/axi-fan-control.c
+++ b/drivers/hwmon/axi-fan-control.c
@@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev)
 	ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL,
 					axi_fan_control_irq_handler,
 					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
-					pdev->driver_override, ctl);
+					NULL, ctl);
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret,
 				     "failed to request an irq\n");
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
                   ` (2 preceding siblings ...)
  2026-03-03 11:53 ` [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name Danilo Krummrich
@ 2026-03-03 11:53 ` Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
                     ` (2 more replies)
  2026-03-03 13:03 ` [PATCH v2 0/4] driver core: generalize " Gui-Dong Han
                   ` (2 subsequent siblings)
  6 siblings, 3 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 11:53 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh, Danilo Krummrich

When a driver is probed through __driver_attach(), the bus' match()
callback is called without the device lock held, thus accessing the
driver_override field without a lock, which can cause a UAF.

Fix this by using the driver-core driver_override infrastructure taking
care of proper locking internally.

Note that calling match() from __driver_attach() without the device lock
held is intentional. [1]

Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [1]
Reported-by: Gui-Dong Han <hanguidong02@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789
Fixes: 3d713e0e382e ("driver core: platform: add device binding path 'driver_override'")
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 arch/sh/drivers/platform_early.c |  6 ++++--
 drivers/base/platform.c          | 37 +++++---------------------------
 drivers/bus/simple-pm-bus.c      |  4 ++--
 drivers/clk/imx/clk-scu.c        |  3 +--
 drivers/slimbus/qcom-ngd-ctrl.c  |  6 ++----
 include/linux/platform_device.h  |  5 -----
 sound/soc/samsung/i2s.c          |  6 +++---
 7 files changed, 17 insertions(+), 50 deletions(-)

diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
index 143747c45206..3cd17bb0be67 100644
--- a/arch/sh/drivers/platform_early.c
+++ b/arch/sh/drivers/platform_early.c
@@ -25,10 +25,12 @@ static int platform_match(struct device *dev, struct device_driver *drv)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct platform_driver *pdrv = to_platform_driver(drv);
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
-	if (pdev->driver_override)
-		return !strcmp(pdev->driver_override, drv->name);
+	ret = device_match_driver_override(dev, drv);
+	if (ret >= 0)
+		return ret;
 
 	/* Then try to match against the id table */
 	if (pdrv->id_table)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index b45d41b018ca..d44591d52e36 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -603,7 +603,6 @@ static void platform_device_release(struct device *dev)
 	kfree(pa->pdev.dev.platform_data);
 	kfree(pa->pdev.mfd_cell);
 	kfree(pa->pdev.resource);
-	kfree(pa->pdev.driver_override);
 	kfree(pa);
 }
 
@@ -1306,38 +1305,9 @@ static ssize_t numa_node_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(numa_node);
 
-static ssize_t driver_override_show(struct device *dev,
-				    struct device_attribute *attr, char *buf)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	ssize_t len;
-
-	device_lock(dev);
-	len = sysfs_emit(buf, "%s\n", pdev->driver_override);
-	device_unlock(dev);
-
-	return len;
-}
-
-static ssize_t driver_override_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	int ret;
-
-	ret = driver_set_override(dev, &pdev->driver_override, buf, count);
-	if (ret)
-		return ret;
-
-	return count;
-}
-static DEVICE_ATTR_RW(driver_override);
-
 static struct attribute *platform_dev_attrs[] = {
 	&dev_attr_modalias.attr,
 	&dev_attr_numa_node.attr,
-	&dev_attr_driver_override.attr,
 	NULL,
 };
 
@@ -1377,10 +1347,12 @@ static int platform_match(struct device *dev, const struct device_driver *drv)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct platform_driver *pdrv = to_platform_driver(drv);
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
-	if (pdev->driver_override)
-		return !strcmp(pdev->driver_override, drv->name);
+	ret = device_match_driver_override(dev, drv);
+	if (ret >= 0)
+		return ret;
 
 	/* Attempt an OF style match first */
 	if (of_driver_match_device(dev, drv))
@@ -1516,6 +1488,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = {
 const struct bus_type platform_bus_type = {
 	.name		= "platform",
 	.dev_groups	= platform_dev_groups,
+	.driver_override = true,
 	.match		= platform_match,
 	.uevent		= platform_uevent,
 	.probe		= platform_probe,
diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
index 3f00d953fb9a..c920bd6fbaaf 100644
--- a/drivers/bus/simple-pm-bus.c
+++ b/drivers/bus/simple-pm-bus.c
@@ -36,7 +36,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 	 * that's not listed in simple_pm_bus_of_match. We don't want to do any
 	 * of the simple-pm-bus tasks for these devices, so return early.
 	 */
-	if (pdev->driver_override)
+	if (device_has_driver_override(&pdev->dev))
 		return 0;
 
 	match = of_match_device(dev->driver->of_match_table, dev);
@@ -78,7 +78,7 @@ static void simple_pm_bus_remove(struct platform_device *pdev)
 {
 	const void *data = of_device_get_match_data(&pdev->dev);
 
-	if (pdev->driver_override || data)
+	if (device_has_driver_override(&pdev->dev) || data)
 		return;
 
 	dev_dbg(&pdev->dev, "%s\n", __func__);
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index a85ec48a798b..9b33df9967ec 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -706,8 +706,7 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
 	if (ret)
 		goto put_device;
 
-	ret = driver_set_override(&pdev->dev, &pdev->driver_override,
-				  "imx-scu-clk", strlen("imx-scu-clk"));
+	ret = device_set_driver_override(&pdev->dev, "imx-scu-clk");
 	if (ret)
 		goto put_device;
 
diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c
index 9aa7218b4e8d..1ed6be6e85d2 100644
--- a/drivers/slimbus/qcom-ngd-ctrl.c
+++ b/drivers/slimbus/qcom-ngd-ctrl.c
@@ -1535,10 +1535,8 @@ static int of_qcom_slim_ngd_register(struct device *parent,
 		ngd->id = id;
 		ngd->pdev->dev.parent = parent;
 
-		ret = driver_set_override(&ngd->pdev->dev,
-					  &ngd->pdev->driver_override,
-					  QCOM_SLIM_NGD_DRV_NAME,
-					  strlen(QCOM_SLIM_NGD_DRV_NAME));
+		ret = device_set_driver_override(&ngd->pdev->dev,
+						 QCOM_SLIM_NGD_DRV_NAME);
 		if (ret) {
 			platform_device_put(ngd->pdev);
 			kfree(ngd);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 813da101b5bf..ed1d50d1c3c1 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -31,11 +31,6 @@ struct platform_device {
 	struct resource	*resource;
 
 	const struct platform_device_id	*id_entry;
-	/*
-	 * Driver name to force a match.  Do not set directly, because core
-	 * frees it.  Use driver_set_override() to set or clear it.
-	 */
-	const char *driver_override;
 
 	/* MFD cell pointer */
 	struct mfd_cell *mfd_cell;
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index e9964f0e010a..140907a41a70 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1360,10 +1360,10 @@ static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
 	if (!pdev_sec)
 		return -ENOMEM;
 
-	pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL);
-	if (!pdev_sec->driver_override) {
+	ret = device_set_driver_override(&pdev_sec->dev, "samsung-i2s");
+	if (ret) {
 		platform_device_put(pdev_sec);
-		return -ENOMEM;
+		return ret;
 	}
 
 	ret = platform_device_add(pdev_sec);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/4] driver core: generalize driver_override infrastructure
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
                   ` (3 preceding siblings ...)
  2026-03-03 11:53 ` [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure Danilo Krummrich
@ 2026-03-03 13:03 ` Gui-Dong Han
  2026-03-12 15:21 ` Greg KH
  2026-03-17 20:17 ` Danilo Krummrich
  6 siblings, 0 replies; 23+ messages in thread
From: Gui-Dong Han @ 2026-03-03 13:03 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ysato, dalias, glaubitz, abelvesa, srini,
	s.nawrocki, nuno.sa, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh, Wang Jiayue

On Tue, Mar 3, 2026 at 7:57 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> Currently, there are 12 busses (including platform and PCI) that duplicate the
> driver_override logic for their individual devices.
>
> All of them seem to be prone to the bug described in [1].
>
> While this could be solved for every bus individually using a separate lock,
> solving this in the driver-core generically results in less (and cleaner)
> changes overall.
>
> Thus, move driver_override to struct device, provide corresponding accessors for
> busses and handle locking with a separate lock internally.
>
> In particular, add device_set_driver_override(), device_has_driver_override(),
> device_match_driver_override() and a helper, DEVICE_ATTR_DRIVER_OVERRIDE(), to
> declare the corresponding sysfs store() and show() callbacks.

Hi Danilo,

Thanks for the v2. The code looks good and the bus_type approach is
much cleaner.

Just a minor note on the commit messages for the cover letter and
patch 1: they still mention adding the DEVICE_ATTR_DRIVER_OVERRIDE()
helper, even though it was correctly dropped in this version.

Thanks.

>
> Until all busses have migrated, keep driver_set_override() in place.
>
> Note that we can't use the device lock for the reasons described in [2].
>
> This patch series includes the migration of the platform bus; patches for all
> other affected busses still need to be extracted as a follow-up of the WIP
> treewide patch in [3].
>
> [1] https://bugzilla.kernel.org/show_bug.cgi?id=220789
> [2] https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=driver_override
>
> Changes in v2:
>   - Drop DEVICE_ATTR_DRIVER_OVERRIDE() and make driver_override a
>     struct bus_type feature instead.
>   - Add driver_override documentation in .../driver-model/binding.rst.
>   - Move kfree(dev->driver_override.name) before release().
>   - hwmon: axi-fan: Use NULL instead of dev_name() in
>     devm_request_threaded_irq().
>
> Danilo Krummrich (4):
>   driver core: generalize driver_override in struct device
>   docs: driver-model: document driver_override
>   hwmon: axi-fan: don't use driver_override as IRQ name
>   driver core: platform: use generic driver_override infrastructure
>
>  .../driver-api/driver-model/binding.rst       | 48 +++++++++++++++
>  arch/sh/drivers/platform_early.c              |  6 +-
>  drivers/base/bus.c                            | 43 ++++++++++++-
>  drivers/base/core.c                           |  2 +
>  drivers/base/dd.c                             | 60 +++++++++++++++++++
>  drivers/base/platform.c                       | 37 ++----------
>  drivers/bus/simple-pm-bus.c                   |  4 +-
>  drivers/clk/imx/clk-scu.c                     |  3 +-
>  drivers/hwmon/axi-fan-control.c               |  2 +-
>  drivers/slimbus/qcom-ngd-ctrl.c               |  6 +-
>  include/linux/device.h                        | 54 +++++++++++++++++
>  include/linux/device/bus.h                    |  4 ++
>  include/linux/platform_device.h               |  5 --
>  sound/soc/samsung/i2s.c                       |  6 +-
>  14 files changed, 228 insertions(+), 52 deletions(-)
>
>
> base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 11:53 ` [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name Danilo Krummrich
@ 2026-03-03 14:53   ` Nuno Sá
  2026-03-03 16:23   ` Guenter Roeck
  2026-03-03 21:01   ` Frank Li
  2 siblings, 0 replies; 23+ messages in thread
From: Nuno Sá @ 2026-03-03 14:53 UTC (permalink / raw)
  To: Danilo Krummrich, gregkh, rafael, hanguidong02, ysato, dalias,
	glaubitz, abelvesa, srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh

On Tue, 2026-03-03 at 12:53 +0100, Danilo Krummrich wrote:
> Do not use driver_override as IRQ name, as it is not guaranteed to point
> to a valid string; use NULL instead (which makes the devm IRQ helpers
> use dev_name()).
> 
> Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> ---

Reviewed-by: Nuno Sá <nuno.sa@analog.com>

>  drivers/hwmon/axi-fan-control.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c
> index b7bb325c3ad9..01590dfa55e6 100644
> --- a/drivers/hwmon/axi-fan-control.c
> +++ b/drivers/hwmon/axi-fan-control.c
> @@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev)
>  	ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL,
>  					axi_fan_control_irq_handler,
>  					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
> -					pdev->driver_override, ctl);
> +					NULL, ctl);
>  	if (ret)
>  		return dev_err_probe(&pdev->dev, ret,
>  				     "failed to request an irq\n");

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 11:53 ` [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name Danilo Krummrich
  2026-03-03 14:53   ` Nuno Sá
@ 2026-03-03 16:23   ` Guenter Roeck
  2026-03-03 16:25     ` Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
  2 siblings, 1 reply; 23+ messages in thread
From: Guenter Roeck @ 2026-03-03 16:23 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa, driver-core, linux-kernel, imx,
	linux-hwmon, linux-arm-msm, linux-sound, linux-sh

On Tue, Mar 03, 2026 at 12:53:20PM +0100, Danilo Krummrich wrote:
> Do not use driver_override as IRQ name, as it is not guaranteed to point
> to a valid string; use NULL instead (which makes the devm IRQ helpers
> use dev_name()).
> 
> Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> Reviewed-by: Nuno Sá <nuno.sa@analog.com>

Applied.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 16:23   ` Guenter Roeck
@ 2026-03-03 16:25     ` Danilo Krummrich
  2026-03-03 16:57       ` Guenter Roeck
  0 siblings, 1 reply; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 16:25 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa, driver-core, linux-kernel, imx,
	linux-hwmon, linux-arm-msm, linux-sound, linux-sh, Guenter Roeck

On Tue Mar 3, 2026 at 5:23 PM CET, Guenter Roeck wrote:
> On Tue, Mar 03, 2026 at 12:53:20PM +0100, Danilo Krummrich wrote:
>> Do not use driver_override as IRQ name, as it is not guaranteed to point
>> to a valid string; use NULL instead (which makes the devm IRQ helpers
>> use dev_name()).
>> 
>> Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
>> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>> Reviewed-by: Nuno Sá <nuno.sa@analog.com>
>
> Applied.

I need this patch in the driver-core tree, otherwise I can't land patch 4 of
this series [1]. :(

Any chance you can drop it from your tree?

[1] https://lore.kernel.org/driver-core/20260303115720.48783-5-dakr@kernel.org/

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 16:25     ` Danilo Krummrich
@ 2026-03-03 16:57       ` Guenter Roeck
  2026-03-03 19:18         ` Danilo Krummrich
  0 siblings, 1 reply; 23+ messages in thread
From: Guenter Roeck @ 2026-03-03 16:57 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa, driver-core, linux-kernel, imx,
	linux-hwmon, linux-arm-msm, linux-sound, linux-sh, Guenter Roeck

On 3/3/26 08:25, Danilo Krummrich wrote:
> On Tue Mar 3, 2026 at 5:23 PM CET, Guenter Roeck wrote:
>> On Tue, Mar 03, 2026 at 12:53:20PM +0100, Danilo Krummrich wrote:
>>> Do not use driver_override as IRQ name, as it is not guaranteed to point
>>> to a valid string; use NULL instead (which makes the devm IRQ helpers
>>> use dev_name()).
>>>
>>> Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
>>> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>>> Reviewed-by: Nuno Sá <nuno.sa@analog.com>
>>
>> Applied.
> 
> I need this patch in the driver-core tree, otherwise I can't land patch 4 of
> this series [1]. :(
> 
> Any chance you can drop it from your tree?
> 
> [1] https://lore.kernel.org/driver-core/20260303115720.48783-5-dakr@kernel.org/
> 

Sure, I'll drop it. Please add

Acked-by: Guenter Roeck <linux@roeck-us.net>

Thanks,
Guenter


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 16:57       ` Guenter Roeck
@ 2026-03-03 19:18         ` Danilo Krummrich
  0 siblings, 0 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-03 19:18 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa, driver-core, linux-kernel, imx,
	linux-hwmon, linux-arm-msm, linux-sound, linux-sh, Guenter Roeck

On Tue Mar 3, 2026 at 5:57 PM CET, Guenter Roeck wrote:
> On 3/3/26 08:25, Danilo Krummrich wrote:
>> On Tue Mar 3, 2026 at 5:23 PM CET, Guenter Roeck wrote:
>>> On Tue, Mar 03, 2026 at 12:53:20PM +0100, Danilo Krummrich wrote:
>>>> Do not use driver_override as IRQ name, as it is not guaranteed to point
>>>> to a valid string; use NULL instead (which makes the devm IRQ helpers
>>>> use dev_name()).
>>>>
>>>> Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
>>>> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>>>> Reviewed-by: Nuno Sá <nuno.sa@analog.com>
>>>
>>> Applied.
>> 
>> I need this patch in the driver-core tree, otherwise I can't land patch 4 of
>> this series [1]. :(
>> 
>> Any chance you can drop it from your tree?
>> 
>> [1] https://lore.kernel.org/driver-core/20260303115720.48783-5-dakr@kernel.org/
>> 
>
> Sure, I'll drop it. Please add
>
> Acked-by: Guenter Roeck <linux@roeck-us.net>

Thanks!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/4] driver core: generalize driver_override in struct device
  2026-03-03 11:53 ` [PATCH v2 1/4] driver core: generalize driver_override in struct device Danilo Krummrich
@ 2026-03-03 21:01   ` Frank Li
  2026-03-04  2:27   ` Gui-Dong Han
  1 sibling, 0 replies; 23+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: Frank Li, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh, Danilo Krummrich

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> +static ssize_t driver_override_store(struct device *dev,
> +				     struct device_attribute *attr,
> +				     const char *buf, size_t count)
> +{
> +	int ret;
> +
> +	ret = __device_set_driver_override(dev, buf, count);
> +	if (ret)
> +		return ret;
> +
> +	return count;
> +}

Potential issue: if __device_set_driver_override() succeeds but
modifies state, returning 'count' may not reflect actual bytes
consumed if buf contains embedded nulls. Consider documenting
expected behavior or validating input length upfront.

> +static ssize_t driver_override_show(struct device *dev,
> +				    struct device_attribute *attr, char *buf)
> +{
> +	guard(spinlock)(&dev->driver_override.lock);
> +	return sysfs_emit(buf, "%s\n", dev->driver_override.name);
> +}

Potential NULL dereference: if dev->driver_override.name is NULL,
sysfs_emit() will print "(null)". Add explicit check or document
that NULL is acceptable output.

> +	if (sp->bus->driver_override) {
> +		error = device_add_group(dev, &driver_override_dev_group);
> +		if (error)
> +			goto out_groups;
> +	}

Error path bug: on device_add_group() failure, code jumps to
out_groups but should jump to out_override (which doesn't exist
yet). This leaks the sysfs link created below. Reorder or add
intermediate label.

> +	error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev));
> +	if (error)
> -		goto out_groups;
> +		goto out_override;

Good: label renamed to match new cleanup order.

> +out_override:
> +	if (dev->bus->driver_override)
> +		device_remove_group(dev, &driver_override_dev_group);

Potential issue: dev->bus may be NULL or different from sp->bus at
this point. Use sp->bus for consistency with the add path above.

> +int __device_set_driver_override(struct device *dev, const char *s, size_t len)
> +{
> +	const char *new, *old;
> +	char *cp;
> +
> +	if (!s)
> +		return -EINVAL;

Inconsistency: len parameter is passed but then recalculated via
strlen(s) below. If len is meant to be trusted, don't recalculate.
If not, remove the parameter or document why both exist.

> +	len = strlen(s);

This overwrites the len parameter, making the initial bounds check
at PAGE_SIZE potentially useless. Clarify intent: is len from
userspace or always recomputed?

> +	new = kstrndup(s, len, GFP_KERNEL);
> +	if (!new)
> +		return -ENOMEM;
> +
> +	spin_lock(&dev->driver_override.lock);
> +	old = dev->driver_override.name;
> +	if (cp != s) {
> +		dev->driver_override.name = new;
> +		spin_unlock(&dev->driver_override.lock);
> +	} else {
> +		/* "\n" passed - clear override */
> +		dev->driver_override.name = NULL;
> +		spin_unlock(&dev->driver_override.lock);
> +
> +		kfree(new);
> +	}
> +	kfree(old);

Logic is correct but confusing: cp is set only if '\n' is found, so
the condition `if (cp != s)` is checking "was newline NOT at start".
Add a comment explaining the two paths (newline-at-start clears,
otherwise

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 2/4] docs: driver-model: document driver_override
  2026-03-03 11:53 ` [PATCH v2 2/4] docs: driver-model: document driver_override Danilo Krummrich
@ 2026-03-03 21:01   ` Frank Li
  0 siblings, 0 replies; 23+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: Frank Li, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh, Danilo Krummrich

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> +Driver Override
> +~~~~~~~~~~~~~~~
> +
> +Userspace may override the standard matching by writing a driver name to
> +a device's ``driver_override`` sysfs attribute.  When set, only a driver
> +whose name matches the override will be considered during binding.  This
> +bypasses all bus-specific matching (OF, ACPI, ID tables, etc.).
> +
> +The override may be cleared by writing an empty string, which returns
> +the device to standard matching rules.  Writing to ``driver_override``
> +does not automatically unbind the device from its current driver or
> +make any attempt to load the specified driver.
> +
> +Buses opt into this mechanism by setting the ``driver_override`` flag in
> +their ``struct bus_type``::
> +
> +  const struct bus_type example_bus_type = {
> +      ...
> +      .driver_override = true,
> +  };
> +
> +When the flag is set, the driver core automatically creates the
> +``driver_override`` sysfs attribute for every device on that bus.
> +
> +The bus's ``match()`` callback should check the override before performing
> +its own matching, using ``device_match_driver_override()``::
> +
> +  static int example_match(struct device *dev, const struct device_driver *drv)
> +  {
> +      int ret;
> +
> +      ret = device_match_driver_override(dev, drv);
> +      if (ret >= 0)
> +          return ret;
> +
> +      /* Fall through to bus-specific matching... */
> +  }
> +
> +``device_match_driver_override()`` returns > 0 if the override matches
> +the given driver, 0 if the override is set but does not match, or < 0 if
> +no override is set at all.
> +
> +Additional helpers are available:
> +
> +- ``device_set_driver_override()`` - set or clear the override from kernel code.
> +- ``device_has_driver_override()`` - check whether an override is set.

Minor: Consider adding a note that the override persists across unbind/rebind
cycles, or clarify the lifetime semantics. The current text doesn't explicitly
state whether the override survives device removal or driver unload.

Also, the example code comment "Fall through to bus-specific matching..." is
slightly misleading—there's no actual fallthrough; the function returns. Consider
rewording to "Continue with bus-specific matching logic" for clarity.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name
  2026-03-03 11:53 ` [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name Danilo Krummrich
  2026-03-03 14:53   ` Nuno Sá
  2026-03-03 16:23   ` Guenter Roeck
@ 2026-03-03 21:01   ` Frank Li
  2 siblings, 0 replies; 23+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: Frank Li, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh, Danilo Krummrich

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> 	ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL,
> 					axi_fan_control_irq_handler,
> 					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
> -					pdev->driver_override, ctl);
> +					NULL, ctl);

Good catch. Using driver_override as IRQ name is indeed unsafe since it's
not guaranteed to be a valid string. Passing NULL is correct here; the
devm IRQ helpers will fall back to dev_name() which is always valid.

The fix is minimal and addresses the root cause. The error handling path
below looks fine—dev_err_probe() will still work correctly with the NULL
name.

Looks good to me.

AI bot review and may be useless.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-03 11:53 ` [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure Danilo Krummrich
@ 2026-03-03 21:01   ` Frank Li
  2026-03-05 12:42   ` Danilo Krummrich
  2026-03-16 23:56   ` Danilo Krummrich
  2 siblings, 0 replies; 23+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: Frank Li, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh, Danilo Krummrich

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> @@ -25,10 +25,12 @@ static int platform_match(struct device *dev, struct device_driver *drv)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct platform_driver *pdrv = to_platform_driver(drv);
> +	int ret;
>  
>  	/* When driver_override is set, only bind to the matching driver */
> -	if (pdev->driver_override)
> -		return !strcmp(pdev->driver_override, drv->name);
> +	ret = device_match_driver_override(dev, drv);
> +	if (ret >= 0)
> +		return ret;

Good: centralizes locking logic. Verify device_match_driver_override()
handles -1 return for "not set" case consistently across all callers.

> @@ -603,7 +603,6 @@ static void platform_device_release(struct device *dev)
>  	kfree(pa->pdev.dev.platform_data);
>  	kfree(pa->pdev.mfd_cell);
>  	kfree(pa->pdev.resource);
> -	kfree(pa->pdev.driver_override);

Correct: driver_override now managed by generic infrastructure, not
platform_device. Ensure device_release() in driver-core handles cleanup.

> -static ssize_t driver_override_show(struct device *dev,
> -				    struct device_attribute *attr, char *buf)
> -{
> -	struct platform_device *pdev = to_platform_device(dev);
> -	ssize_t len;
> -
> -	device_lock(dev);
> -	len = sysfs_emit(buf, "%s\n", pdev->driver_override);
> -	device_unlock(dev);
> -
> -	return len;
> -}

Good: removes duplicate sysfs attribute. Verify generic implementation
in device-core provides equivalent locking and sysfs_emit() behavior.

> @@ -1377,10 +1347,12 @@ static int platform_match(struct device *dev, const struct device_driver *drv)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct platform_driver *pdrv = to_platform_driver(drv);
> +	int ret;
>  
>  	/* When driver_override is set, only bind to the matching driver */
> -	if (pdev->driver_override)
> -		return !strcmp(pdev->driver_override, drv->name);
> +	ret = device_match_driver_override(dev, drv);
> +	if (ret >= 0)
> +		return ret;

Same pattern as arch/sh. Consistent refactoring across platform code.

> +	.driver_override = true,

Verify this flag is documented in struct bus_type definition and that
all bus_type users expecting driver_override support have this set.

> -	if (pdev->driver_override)
> +	if (device_has_driver_override(&pdev->dev))

Good: accessor function prevents direct field access. Confirm
device_has_driver_override() is properly exported and inlined where
needed for performance.

> -	ret = driver_set_override(&pdev->dev, &pdev->driver_override,
> -				  "imx-scu-clk", strlen("imx-scu-clk"));
> +	ret = device_set_driver_override(&pdev->dev, "imx-scu-clk");

Good: removes strlen() call; generic function should handle length
internally. Verify no callers relied on old signature.

> -	pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL);
> -	if (!pdev_sec->driver_override) {
> +	ret = device_set_driver_override(&pdev_sec->dev, "samsung

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/4] driver core: generalize driver_override in struct device
  2026-03-03 11:53 ` [PATCH v2 1/4] driver core: generalize driver_override in struct device Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
@ 2026-03-04  2:27   ` Gui-Dong Han
  1 sibling, 0 replies; 23+ messages in thread
From: Gui-Dong Han @ 2026-03-04  2:27 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ysato, dalias, glaubitz, abelvesa, srini,
	s.nawrocki, nuno.sa, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh, Wang Jiayue

On Tue, Mar 3, 2026 at 7:57 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> Currently, there are 12 busses (including platform and PCI) that
> duplicate the driver_override logic for their individual devices.
>
> All of them seem to be prone to the bug described in [1].
>
> While this could be solved for every bus individually using a separate
> lock, solving this in the driver-core generically results in less (and
> cleaner) changes overall.
>
> Thus, move driver_override to struct device, provide corresponding
> accessors for busses and handle locking with a separate lock internally.
>
> In particular, add device_set_driver_override(),
> device_has_driver_override(), device_match_driver_override() and a
> helper, DEVICE_ATTR_DRIVER_OVERRIDE(), to declare the corresponding
> sysfs store() and show() callbacks.
>
> Until all busses have migrated, keep driver_set_override() in place.
>
> Note that we can't use the device lock for the reasons described in [2].
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=220789 [1]
> Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [2]
> Co-developed-by: Gui-Dong Han <hanguidong02@gmail.com>
> Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>

Tested this on QEMU PCI with various debug options enabled.
Everything looks good so far, no issues found.

Will keep testing.

> ---
>  drivers/base/bus.c         | 43 ++++++++++++++++++++++++++-
>  drivers/base/core.c        |  2 ++
>  drivers/base/dd.c          | 60 ++++++++++++++++++++++++++++++++++++++
>  include/linux/device.h     | 54 ++++++++++++++++++++++++++++++++++
>  include/linux/device/bus.h |  4 +++
>  5 files changed, 162 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index bb61d8adbab1..c734e7162b74 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -504,6 +504,36 @@ int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start,
>  }
>  EXPORT_SYMBOL_GPL(bus_for_each_drv);
>
> +static ssize_t driver_override_store(struct device *dev,
> +                                    struct device_attribute *attr,
> +                                    const char *buf, size_t count)
> +{
> +       int ret;
> +
> +       ret = __device_set_driver_override(dev, buf, count);
> +       if (ret)
> +               return ret;
> +
> +       return count;
> +}
> +
> +static ssize_t driver_override_show(struct device *dev,
> +                                   struct device_attribute *attr, char *buf)
> +{
> +       guard(spinlock)(&dev->driver_override.lock);
> +       return sysfs_emit(buf, "%s\n", dev->driver_override.name);
> +}
> +static DEVICE_ATTR_RW(driver_override);
> +
> +static struct attribute *driver_override_dev_attrs[] = {
> +       &dev_attr_driver_override.attr,
> +       NULL,
> +};
> +
> +static const struct attribute_group driver_override_dev_group = {
> +       .attrs = driver_override_dev_attrs,
> +};
> +
>  /**
>   * bus_add_device - add device to bus
>   * @dev: device being added
> @@ -537,9 +567,15 @@ int bus_add_device(struct device *dev)
>         if (error)
>                 goto out_put;
>
> +       if (sp->bus->driver_override) {
> +               error = device_add_group(dev, &driver_override_dev_group);
> +               if (error)
> +                       goto out_groups;
> +       }
> +
>         error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev));
>         if (error)
> -               goto out_groups;
> +               goto out_override;
>
>         error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem");
>         if (error)
> @@ -550,6 +586,9 @@ int bus_add_device(struct device *dev)
>
>  out_subsys:
>         sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev));
> +out_override:
> +       if (dev->bus->driver_override)
> +               device_remove_group(dev, &driver_override_dev_group);
>  out_groups:
>         device_remove_groups(dev, sp->bus->dev_groups);
>  out_put:
> @@ -607,6 +646,8 @@ void bus_remove_device(struct device *dev)
>
>         sysfs_remove_link(&dev->kobj, "subsystem");
>         sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev));
> +       if (dev->bus->driver_override)
> +               device_remove_group(dev, &driver_override_dev_group);
>         device_remove_groups(dev, dev->bus->dev_groups);
>         if (klist_node_attached(&dev->p->knode_bus))
>                 klist_del(&dev->p->knode_bus);
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 791f9e444df8..09b98f02f559 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -2556,6 +2556,7 @@ static void device_release(struct kobject *kobj)
>         devres_release_all(dev);
>
>         kfree(dev->dma_range_map);
> +       kfree(dev->driver_override.name);
>
>         if (dev->release)
>                 dev->release(dev);
> @@ -3159,6 +3160,7 @@ void device_initialize(struct device *dev)
>         kobject_init(&dev->kobj, &device_ktype);
>         INIT_LIST_HEAD(&dev->dma_pools);
>         mutex_init(&dev->mutex);
> +       spin_lock_init(&dev->driver_override.lock);
>         lockdep_set_novalidate_class(&dev->mutex);
>         spin_lock_init(&dev->devres_lock);
>         INIT_LIST_HEAD(&dev->devres_head);
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 0354f209529c..697e36e63cab 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -381,6 +381,66 @@ static void __exit deferred_probe_exit(void)
>  }
>  __exitcall(deferred_probe_exit);
>
> +int __device_set_driver_override(struct device *dev, const char *s, size_t len)
> +{
> +       const char *new, *old;
> +       char *cp;
> +
> +       if (!s)
> +               return -EINVAL;
> +
> +       /*
> +        * The stored value will be used in sysfs show callback (sysfs_emit()),
> +        * which has a length limit of PAGE_SIZE and adds a trailing newline.
> +        * Thus we can store one character less to avoid truncation during sysfs
> +        * show.
> +        */
> +       if (len >= (PAGE_SIZE - 1))
> +               return -EINVAL;
> +
> +       /*
> +        * Compute the real length of the string in case userspace sends us a
> +        * bunch of \0 characters like python likes to do.
> +        */
> +       len = strlen(s);
> +
> +       if (!len) {
> +               /* Empty string passed - clear override */
> +               spin_lock(&dev->driver_override.lock);
> +               old = dev->driver_override.name;
> +               dev->driver_override.name = NULL;
> +               spin_unlock(&dev->driver_override.lock);
> +               kfree(old);
> +
> +               return 0;
> +       }
> +
> +       cp = strnchr(s, len, '\n');
> +       if (cp)
> +               len = cp - s;
> +
> +       new = kstrndup(s, len, GFP_KERNEL);
> +       if (!new)
> +               return -ENOMEM;
> +
> +       spin_lock(&dev->driver_override.lock);
> +       old = dev->driver_override.name;
> +       if (cp != s) {
> +               dev->driver_override.name = new;
> +               spin_unlock(&dev->driver_override.lock);
> +       } else {
> +               /* "\n" passed - clear override */
> +               dev->driver_override.name = NULL;
> +               spin_unlock(&dev->driver_override.lock);
> +
> +               kfree(new);
> +       }
> +       kfree(old);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(__device_set_driver_override);
> +
>  /**
>   * device_is_bound() - Check if device is bound to a driver
>   * @dev: device to check
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 0be95294b6e6..e65d564f01cd 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -483,6 +483,8 @@ struct device_physical_location {
>   *             on.  This shrinks the "Board Support Packages" (BSPs) and
>   *             minimizes board-specific #ifdefs in drivers.
>   * @driver_data: Private pointer for driver specific info.
> + * @driver_override: Driver name to force a match.  Do not touch directly; use
> + *                  device_set_driver_override() instead.
>   * @links:     Links to suppliers and consumers of this device.
>   * @power:     For device power management.
>   *             See Documentation/driver-api/pm/devices.rst for details.
> @@ -576,6 +578,10 @@ struct device {
>                                            core doesn't touch it */
>         void            *driver_data;   /* Driver data, set and get with
>                                            dev_set_drvdata/dev_get_drvdata */
> +       struct {
> +               const char      *name;
> +               spinlock_t      lock;
> +       } driver_override;
>         struct mutex            mutex;  /* mutex to synchronize calls to
>                                          * its driver.
>                                          */
> @@ -701,6 +707,54 @@ struct device_link {
>
>  #define kobj_to_dev(__kobj)    container_of_const(__kobj, struct device, kobj)
>
> +int __device_set_driver_override(struct device *dev, const char *s, size_t len);
> +
> +/**
> + * device_set_driver_override() - Helper to set or clear driver override.
> + * @dev: Device to change
> + * @s: NUL-terminated string, new driver name to force a match, pass empty
> + *     string to clear it ("" or "\n", where the latter is only for sysfs
> + *     interface).
> + *
> + * Helper to set or clear driver override of a device.
> + *
> + * Returns: 0 on success or a negative error code on failure.
> + */
> +static inline int device_set_driver_override(struct device *dev, const char *s)
> +{
> +       return __device_set_driver_override(dev, s, s ? strlen(s) : 0);
> +}
> +
> +/**
> + * device_has_driver_override() - Check if a driver override has been set.
> + * @dev: device to check
> + *
> + * Returns true if a driver override has been set for this device.
> + */
> +static inline bool device_has_driver_override(struct device *dev)
> +{
> +       guard(spinlock)(&dev->driver_override.lock);
> +       return !!dev->driver_override.name;
> +}
> +
> +/**
> + * device_match_driver_override() - Match a driver against the device's driver_override.
> + * @dev: device to check
> + * @drv: driver to match against
> + *
> + * Returns > 0 if a driver override is set and matches the given driver, 0 if a
> + * driver override is set but does not match, or < 0 if a driver override is not
> + * set at all.
> + */
> +static inline int device_match_driver_override(struct device *dev,
> +                                              const struct device_driver *drv)
> +{
> +       guard(spinlock)(&dev->driver_override.lock);
> +       if (dev->driver_override.name)
> +               return !strcmp(dev->driver_override.name, drv->name);
> +       return -1;
> +}
> +
>  /**
>   * device_iommu_mapped - Returns true when the device DMA is translated
>   *                      by an IOMMU
> diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
> index 99c3c83ea520..cda597812324 100644
> --- a/include/linux/device/bus.h
> +++ b/include/linux/device/bus.h
> @@ -63,6 +63,9 @@ struct fwnode_handle;
>   *                     this bus.
>   * @pm:                Power management operations of this bus, callback the specific
>   *             device driver's pm-ops.
> + * @driver_override:   Set to true if this bus supports the driver_override
> + *                     mechanism, which allows userspace to force a specific
> + *                     driver to bind to a device via a sysfs attribute.
>   * @need_parent_lock:  When probing or removing a device on this bus, the
>   *                     device core should lock the device's parent.
>   *
> @@ -104,6 +107,7 @@ struct bus_type {
>
>         const struct dev_pm_ops *pm;
>
> +       bool driver_override;
>         bool need_parent_lock;
>  };
>
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-03 11:53 ` [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
@ 2026-03-05 12:42   ` Danilo Krummrich
  2026-03-12 20:15     ` Danilo Krummrich
  2026-03-16 23:56   ` Danilo Krummrich
  2 siblings, 1 reply; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-05 12:42 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh

On Tue Mar 3, 2026 at 12:53 PM CET, Danilo Krummrich wrote:
>  arch/sh/drivers/platform_early.c |  6 ++++--
>  drivers/clk/imx/clk-scu.c        |  3 +--
>  drivers/slimbus/qcom-ngd-ctrl.c  |  6 ++----
>  sound/soc/samsung/i2s.c          |  6 +++---

Some ACKs would be appreciated. :)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/4] driver core: generalize driver_override infrastructure
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
                   ` (4 preceding siblings ...)
  2026-03-03 13:03 ` [PATCH v2 0/4] driver core: generalize " Gui-Dong Han
@ 2026-03-12 15:21 ` Greg KH
  2026-03-17 20:17 ` Danilo Krummrich
  6 siblings, 0 replies; 23+ messages in thread
From: Greg KH @ 2026-03-12 15:21 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa, srini,
	s.nawrocki, nuno.sa, driver-core, linux-kernel, imx, linux-hwmon,
	linux-arm-msm, linux-sound, linux-sh

On Tue, Mar 03, 2026 at 12:53:17PM +0100, Danilo Krummrich wrote:
> Currently, there are 12 busses (including platform and PCI) that duplicate the
> driver_override logic for their individual devices.
> 
> All of them seem to be prone to the bug described in [1].
> 
> While this could be solved for every bus individually using a separate lock,
> solving this in the driver-core generically results in less (and cleaner)
> changes overall.
> 
> Thus, move driver_override to struct device, provide corresponding accessors for
> busses and handle locking with a separate lock internally.
> 
> In particular, add device_set_driver_override(), device_has_driver_override(),
> device_match_driver_override() and a helper, DEVICE_ATTR_DRIVER_OVERRIDE(), to
> declare the corresponding sysfs store() and show() callbacks.
> 
> Until all busses have migrated, keep driver_set_override() in place.
> 
> Note that we can't use the device lock for the reasons described in [2].
> 
> This patch series includes the migration of the platform bus; patches for all
> other affected busses still need to be extracted as a follow-up of the WIP
> treewide patch in [3].
> 
> [1] https://bugzilla.kernel.org/show_bug.cgi?id=220789
> [2] https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=driver_override

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-05 12:42   ` Danilo Krummrich
@ 2026-03-12 20:15     ` Danilo Krummrich
  0 siblings, 0 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-12 20:15 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh

On Thu Mar 5, 2026 at 1:42 PM CET, Danilo Krummrich wrote:
> On Tue Mar 3, 2026 at 12:53 PM CET, Danilo Krummrich wrote:
>>  arch/sh/drivers/platform_early.c |  6 ++++--
>>  drivers/clk/imx/clk-scu.c        |  3 +--
>>  drivers/slimbus/qcom-ngd-ctrl.c  |  6 ++----
>>  sound/soc/samsung/i2s.c          |  6 +++---
>
> Some ACKs would be appreciated. :)

Looking forward to pick this up soon, please let me know if there are any
concerns.

Thanks,
Danilo

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-03 11:53 ` [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure Danilo Krummrich
  2026-03-03 21:01   ` Frank Li
  2026-03-05 12:42   ` Danilo Krummrich
@ 2026-03-16 23:56   ` Danilo Krummrich
  2026-03-17  5:06     ` Greg KH
  2026-03-17  8:36     ` Geert Uytterhoeven
  2 siblings, 2 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-16 23:56 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa, brgl
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh

(Cc: Bartosz)

On Tue Mar 3, 2026 at 12:53 PM CET, Danilo Krummrich wrote:
> diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
> index 143747c45206..3cd17bb0be67 100644
> --- a/arch/sh/drivers/platform_early.c
> +++ b/arch/sh/drivers/platform_early.c
> @@ -25,10 +25,12 @@ static int platform_match(struct device *dev, struct device_driver *drv)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct platform_driver *pdrv = to_platform_driver(drv);
> +	int ret;
>  
>  	/* When driver_override is set, only bind to the matching driver */
> -	if (pdev->driver_override)
> -		return !strcmp(pdev->driver_override, drv->name);
> +	ret = device_match_driver_override(dev, drv);
> +	if (ret >= 0)
> +		return ret;
>  
>  	/* Then try to match against the id table */
>  	if (pdrv->id_table)

I was just about to pick up this series, but then noticed that checking for
driver_override in the platform_early case doesn't make sense in the first place
and was accidentally added when the platform_match() callback was copied over in
commit 507fd01d5333 ("drivers: move the early platform device support to
arch/sh").

Thus, I'm going to drop this hunk and add in the following patch; please let me
know if there are any concerns.

commit 39cae4095efda4b00b436c0fc46f21de84128969
Author: Danilo Krummrich <dakr@kernel.org>
Date:   Tue Mar 17 00:37:15 2026 +0100

    sh: platform_early: remove pdev->driver_override check

    In commit 507fd01d5333 ("drivers: move the early platform device support to
    arch/sh") platform_match() was copied over to the sh platform_early
    code, accidentally including the driver_override check.

    This check does not make sense for platform_early, as sysfs is not even
    available in first place at this point in the boot process, hence remove
    the check.

    Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh")
    Signed-off-by: Danilo Krummrich <dakr@kernel.org>

diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
index 143747c45206..48ddbc547bd9 100644
--- a/arch/sh/drivers/platform_early.c
+++ b/arch/sh/drivers/platform_early.c
@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv)
        struct platform_device *pdev = to_platform_device(dev);
        struct platform_driver *pdrv = to_platform_driver(drv);

-       /* When driver_override is set, only bind to the matching driver */
-       if (pdev->driver_override)
-               return !strcmp(pdev->driver_override, drv->name);
-
        /* Then try to match against the id table */
        if (pdrv->id_table)
                return platform_match_id(pdrv->id_table, pdev) != NULL;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-16 23:56   ` Danilo Krummrich
@ 2026-03-17  5:06     ` Greg KH
  2026-03-17  8:36     ` Geert Uytterhoeven
  1 sibling, 0 replies; 23+ messages in thread
From: Greg KH @ 2026-03-17  5:06 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa, srini,
	s.nawrocki, nuno.sa, brgl, driver-core, linux-kernel, imx,
	linux-hwmon, linux-arm-msm, linux-sound, linux-sh

On Tue, Mar 17, 2026 at 12:56:52AM +0100, Danilo Krummrich wrote:
> (Cc: Bartosz)
> 
> On Tue Mar 3, 2026 at 12:53 PM CET, Danilo Krummrich wrote:
> > diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
> > index 143747c45206..3cd17bb0be67 100644
> > --- a/arch/sh/drivers/platform_early.c
> > +++ b/arch/sh/drivers/platform_early.c
> > @@ -25,10 +25,12 @@ static int platform_match(struct device *dev, struct device_driver *drv)
> >  {
> >  	struct platform_device *pdev = to_platform_device(dev);
> >  	struct platform_driver *pdrv = to_platform_driver(drv);
> > +	int ret;
> >  
> >  	/* When driver_override is set, only bind to the matching driver */
> > -	if (pdev->driver_override)
> > -		return !strcmp(pdev->driver_override, drv->name);
> > +	ret = device_match_driver_override(dev, drv);
> > +	if (ret >= 0)
> > +		return ret;
> >  
> >  	/* Then try to match against the id table */
> >  	if (pdrv->id_table)
> 
> I was just about to pick up this series, but then noticed that checking for
> driver_override in the platform_early case doesn't make sense in the first place
> and was accidentally added when the platform_match() callback was copied over in
> commit 507fd01d5333 ("drivers: move the early platform device support to
> arch/sh").
> 
> Thus, I'm going to drop this hunk and add in the following patch; please let me
> know if there are any concerns.
> 
> commit 39cae4095efda4b00b436c0fc46f21de84128969
> Author: Danilo Krummrich <dakr@kernel.org>
> Date:   Tue Mar 17 00:37:15 2026 +0100
> 
>     sh: platform_early: remove pdev->driver_override check
> 
>     In commit 507fd01d5333 ("drivers: move the early platform device support to
>     arch/sh") platform_match() was copied over to the sh platform_early
>     code, accidentally including the driver_override check.
> 
>     This check does not make sense for platform_early, as sysfs is not even
>     available in first place at this point in the boot process, hence remove
>     the check.
> 
>     Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh")
>     Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> 
> diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
> index 143747c45206..48ddbc547bd9 100644
> --- a/arch/sh/drivers/platform_early.c
> +++ b/arch/sh/drivers/platform_early.c
> @@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv)
>         struct platform_device *pdev = to_platform_device(dev);
>         struct platform_driver *pdrv = to_platform_driver(drv);
> 
> -       /* When driver_override is set, only bind to the matching driver */
> -       if (pdev->driver_override)
> -               return !strcmp(pdev->driver_override, drv->name);
> -
>         /* Then try to match against the id table */
>         if (pdrv->id_table)
>                 return platform_match_id(pdrv->id_table, pdev) != NULL;
> 
> 

Makes sense to me, good catch!

Reviewed--by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure
  2026-03-16 23:56   ` Danilo Krummrich
  2026-03-17  5:06     ` Greg KH
@ 2026-03-17  8:36     ` Geert Uytterhoeven
  1 sibling, 0 replies; 23+ messages in thread
From: Geert Uytterhoeven @ 2026-03-17  8:36 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa, brgl, driver-core, linux-kernel, imx,
	linux-hwmon, linux-arm-msm, linux-sound, linux-sh

Hi Danilo,

On Tue, 17 Mar 2026 at 00:57, Danilo Krummrich <dakr@kernel.org> wrote:
> On Tue Mar 3, 2026 at 12:53 PM CET, Danilo Krummrich wrote:
> > diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
> > index 143747c45206..3cd17bb0be67 100644
> > --- a/arch/sh/drivers/platform_early.c
> > +++ b/arch/sh/drivers/platform_early.c
> > @@ -25,10 +25,12 @@ static int platform_match(struct device *dev, struct device_driver *drv)
> >  {
> >       struct platform_device *pdev = to_platform_device(dev);
> >       struct platform_driver *pdrv = to_platform_driver(drv);
> > +     int ret;
> >
> >       /* When driver_override is set, only bind to the matching driver */
> > -     if (pdev->driver_override)
> > -             return !strcmp(pdev->driver_override, drv->name);
> > +     ret = device_match_driver_override(dev, drv);
> > +     if (ret >= 0)
> > +             return ret;
> >
> >       /* Then try to match against the id table */
> >       if (pdrv->id_table)
>
> I was just about to pick up this series, but then noticed that checking for
> driver_override in the platform_early case doesn't make sense in the first place
> and was accidentally added when the platform_match() callback was copied over in
> commit 507fd01d5333 ("drivers: move the early platform device support to
> arch/sh").
>
> Thus, I'm going to drop this hunk and add in the following patch; please let me
> know if there are any concerns.
>
> commit 39cae4095efda4b00b436c0fc46f21de84128969
> Author: Danilo Krummrich <dakr@kernel.org>
> Date:   Tue Mar 17 00:37:15 2026 +0100
>
>     sh: platform_early: remove pdev->driver_override check
>
>     In commit 507fd01d5333 ("drivers: move the early platform device support to
>     arch/sh") platform_match() was copied over to the sh platform_early
>     code, accidentally including the driver_override check.
>
>     This check does not make sense for platform_early, as sysfs is not even
>     available in first place at this point in the boot process, hence remove
>     the check.
>
>     Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh")
>     Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>
> diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
> index 143747c45206..48ddbc547bd9 100644
> --- a/arch/sh/drivers/platform_early.c
> +++ b/arch/sh/drivers/platform_early.c
> @@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv)
>         struct platform_device *pdev = to_platform_device(dev);
>         struct platform_driver *pdrv = to_platform_driver(drv);
>
> -       /* When driver_override is set, only bind to the matching driver */
> -       if (pdev->driver_override)
> -               return !strcmp(pdev->driver_override, drv->name);
> -
>         /* Then try to match against the id table */
>         if (pdrv->id_table)
>                 return platform_match_id(pdrv->id_table, pdev) != NULL;

Nice catch!
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/4] driver core: generalize driver_override infrastructure
  2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
                   ` (5 preceding siblings ...)
  2026-03-12 15:21 ` Greg KH
@ 2026-03-17 20:17 ` Danilo Krummrich
  6 siblings, 0 replies; 23+ messages in thread
From: Danilo Krummrich @ 2026-03-17 20:17 UTC (permalink / raw)
  To: gregkh, rafael, hanguidong02, ysato, dalias, glaubitz, abelvesa,
	srini, s.nawrocki, nuno.sa
  Cc: driver-core, linux-kernel, imx, linux-hwmon, linux-arm-msm,
	linux-sound, linux-sh

On Tue Mar 3, 2026 at 12:53 PM CET, Danilo Krummrich wrote:

Applied to driver-core-linus, thanks!

>   driver core: generalize driver_override in struct device

    [ Use dev->bus instead of sp->bus for consistency; fix commit message to
      refer to the struct bus_type's driver_override feature flag. - Danilo ]

>   docs: driver-model: document driver_override
>   hwmon: axi-fan: don't use driver_override as IRQ name

    sh: platform_early: remove pdev->driver_override check

>   driver core: platform: use generic driver_override infrastructure

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2026-03-17 20:17 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-03 11:53 [PATCH v2 0/4] driver core: generalize driver_override infrastructure Danilo Krummrich
2026-03-03 11:53 ` [PATCH v2 1/4] driver core: generalize driver_override in struct device Danilo Krummrich
2026-03-03 21:01   ` Frank Li
2026-03-04  2:27   ` Gui-Dong Han
2026-03-03 11:53 ` [PATCH v2 2/4] docs: driver-model: document driver_override Danilo Krummrich
2026-03-03 21:01   ` Frank Li
2026-03-03 11:53 ` [PATCH v2 3/4] hwmon: axi-fan: don't use driver_override as IRQ name Danilo Krummrich
2026-03-03 14:53   ` Nuno Sá
2026-03-03 16:23   ` Guenter Roeck
2026-03-03 16:25     ` Danilo Krummrich
2026-03-03 16:57       ` Guenter Roeck
2026-03-03 19:18         ` Danilo Krummrich
2026-03-03 21:01   ` Frank Li
2026-03-03 11:53 ` [PATCH v2 4/4] driver core: platform: use generic driver_override infrastructure Danilo Krummrich
2026-03-03 21:01   ` Frank Li
2026-03-05 12:42   ` Danilo Krummrich
2026-03-12 20:15     ` Danilo Krummrich
2026-03-16 23:56   ` Danilo Krummrich
2026-03-17  5:06     ` Greg KH
2026-03-17  8:36     ` Geert Uytterhoeven
2026-03-03 13:03 ` [PATCH v2 0/4] driver core: generalize " Gui-Dong Han
2026-03-12 15:21 ` Greg KH
2026-03-17 20:17 ` Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox