[PATCH v1 1/4] driver core: allow certain drivers prohibit override via sysfs
From: Andy Shevchenko
Date: Fri May 08 2026 - 05:55:13 EST
Many drivers, that may be instantiate via ACPI, OF, or, in some cases,
user space won't work without necessary driver data. These are, e.g.,
most of the drivers in IIO subsystem. Trying to override the driver
for the device that has no matching entry makes no sense in such cases
and might lead to a crash, when the driver is not prepared for that.
Instead of adding a NULL check for driver data pointer in each of that
drivers, effectively meaning a dead code for normal functionality,
introduce a special attribute in the struct device_driver to allow
drivers just to hide the attribute for good.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
---
Documentation/driver-api/driver-model/binding.rst | 4 ++++
drivers/base/bus.c | 4 ++--
include/linux/device/driver.h | 2 ++
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Documentation/driver-api/driver-model/binding.rst b/Documentation/driver-api/driver-model/binding.rst
index fa0888c2b3b9..19b565a2de86 100644
--- a/Documentation/driver-api/driver-model/binding.rst
+++ b/Documentation/driver-api/driver-model/binding.rst
@@ -147,3 +147,7 @@ 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.
+
+Any driver, which bus has ``driver_override`` flag set, can suppress that
+behaviour by setting the ``suppress_override_attrs`` flag in their ``struct
+device_driver``. In this case the sysfs attribute will not show.
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91490ee..16a530b91a00 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -594,7 +594,7 @@ 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)
+ if (dev->bus->driver_override && !dev->driver->suppress_override_attrs)
device_remove_group(dev, &driver_override_dev_group);
out_groups:
device_remove_groups(dev, sp->bus->dev_groups);
@@ -653,7 +653,7 @@ 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)
+ if (dev->bus->driver_override && !dev->driver->suppress_override_attrs)
device_remove_group(dev, &driver_override_dev_group);
device_remove_groups(dev, dev->bus->dev_groups);
if (klist_node_attached(&dev->p->knode_bus))
diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
index bbc67ec513ed..4b1c1774fd43 100644
--- a/include/linux/device/driver.h
+++ b/include/linux/device/driver.h
@@ -55,6 +55,7 @@ enum probe_type {
* @owner: The module owner.
* @mod_name: Used for built-in modules.
* @suppress_bind_attrs: Disables bind/unbind via sysfs.
+ * @suppress_override_attrs: Disables driver_override via sysfs.
* @probe_type: Type of the probe (synchronous or asynchronous) to use.
* @of_match_table: The open firmware table.
* @acpi_match_table: The ACPI match table.
@@ -103,6 +104,7 @@ struct device_driver {
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
+ bool suppress_override_attrs; /* disables driver_override via sysfs */
enum probe_type probe_type;
const struct of_device_id *of_match_table;
--
2.50.1