[PATCH v2 1/2] module: add SCMI device table alias support
Bjorn Andersson <[email protected]> Thu, 18 Jun 2026 15:56:34 +0000
| Newsgroups | org.kernel.vger.arm-scmi,dev.linux.lists.imx,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-clk,org.kernel.vger.linux-hwmon,org.kernel.vger.linux-iio,org.kernel.vger.linux-input,org.kernel.vger.linux-kbuild,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm,org.kernel.vger.linux-rtc |
|---|---|
| Message-ID | <[email protected]> |
SCMI client drivers already describe their bus match data with MODULE_DEVICE_TABLE(scmi, ...), but modpost does not know how to consume SCMI device tables. As a result, SCMI modules do not get generated module aliases from their id tables. Move struct scmi_device_id to mod_devicetable.h so it has a fixed layout visible to modpost, add the corresponding generated offsets and teach file2alias to emit scmi:<protocol>:<name> aliases. Use the same stable alias format for SCMI device uevents and sysfs modaliases. The previous string included the instance-specific device name, which is not useful for matching modules. Assisted-by: Codex:GPT-5.5 Reviewed-by: Hans de Goede <[email protected]> Signed-off-by: Bjorn Andersson <[email protected]> --- drivers/clk/clk-scmi.c | 1 + drivers/cpufreq/scmi-cpufreq.c | 1 + drivers/firmware/arm_scmi/bus.c | 20 ++++++++++---------- drivers/firmware/arm_scmi/driver.c | 1 + drivers/firmware/arm_scmi/scmi_power_control.c | 1 + drivers/firmware/imx/sm-cpu.c | 1 + drivers/firmware/imx/sm-lmm.c | 1 + drivers/firmware/imx/sm-misc.c | 1 + drivers/hwmon/scmi-hwmon.c | 1 + drivers/iio/common/scmi_sensors/scmi_iio.c | 1 + drivers/input/keyboard/imx-sm-bbm-key.c | 1 + drivers/pmdomain/arm/scmi_perf_domain.c | 1 + drivers/pmdomain/arm/scmi_pm_domain.c | 1 + drivers/powercap/arm_scmi_powercap.c | 1 + drivers/regulator/scmi-regulator.c | 1 + drivers/reset/reset-scmi.c | 1 + drivers/rtc/rtc-imx-sm-bbm.c | 1 + include/linux/mod_devicetable.h | 11 +++++++++++ include/linux/scmi_protocol.h | 5 +---- scripts/mod/devicetable-offsets.c | 4 ++++ scripts/mod/file2alias.c | 11 +++++++++++ 21 files changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index 7c562559ad8b..b9e29e124302 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -11,6 +11,7 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/scmi_protocol.h> #define NOT_ATOMIC false diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index 4edb4f7a8aa9..affa005bf8b1 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -15,6 +15,7 @@ #include <linux/energy_model.h> #include <linux/export.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/pm_opp.h> #include <linux/pm_qos.h> diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 793be9eabaed..70781146fa61 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -10,14 +10,16 @@ #include <linux/atomic.h> #include <linux/types.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/device.h> #include "common.h" -#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s" +#define SCMI_UEVENT_MODALIAS_FMT SCMI_MODULE_PREFIX "%02x:%s" BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh); EXPORT_SYMBOL_GPL(scmi_requested_devices_nh); @@ -141,7 +143,7 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table) int ret = 0; const struct scmi_device_id *entry; - for (entry = id_table; entry->name && ret == 0; entry++) + for (entry = id_table; entry->name[0] && ret == 0; entry++) ret = scmi_protocol_device_request(entry); return ret; @@ -197,18 +199,18 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table) { const struct scmi_device_id *entry; - for (entry = id_table; entry->name; entry++) + for (entry = id_table; entry->name[0]; entry++) scmi_protocol_device_unrequest(entry); } static int scmi_dev_match_by_id_table(struct scmi_device *scmi_dev, const struct scmi_device_id *id_table) { - if (!id_table || !id_table->name) + if (!id_table || !id_table->name[0]) return 0; /* Always skip transport devices from matching */ - for (; id_table->protocol_id && id_table->name; id_table++) + for (; id_table->protocol_id && id_table->name[0]; id_table++) if (id_table->protocol_id == scmi_dev->protocol_id && strncmp(scmi_dev->name, "__scmi_transport_device", 23) && !strcmp(id_table->name, scmi_dev->name)) @@ -245,7 +247,7 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent, struct device *dev; id_table[0].protocol_id = prot_id; - id_table[0].name = name; + strscpy(id_table[0].name, name, sizeof(id_table[0].name)); dev = device_find_child(parent, &id_table, scmi_match_by_id_table); if (!dev) @@ -282,8 +284,7 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env * const struct scmi_device *scmi_dev = to_scmi_dev(dev); return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT, - dev_name(&scmi_dev->dev), scmi_dev->protocol_id, - scmi_dev->name); + scmi_dev->protocol_id, scmi_dev->name); } static ssize_t modalias_show(struct device *dev, @@ -292,8 +293,7 @@ static ssize_t modalias_show(struct device *dev, struct scmi_device *scmi_dev = to_scmi_dev(dev); return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT, - dev_name(&scmi_dev->dev), scmi_dev->protocol_id, - scmi_dev->name); + scmi_dev->protocol_id, scmi_dev->name); } static DEVICE_ATTR_RO(modalias); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 3e0d975ec94c..0fd6a947499e 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -30,6 +30,7 @@ #include <linux/hashtable.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/processor.h> diff --git a/drivers/firmware/arm_scmi/scmi_power_control.c b/drivers/firmware/arm_scmi/scmi_power_control.c index 955736336061..1900bb77383e 100644 --- a/drivers/firmware/arm_scmi/scmi_power_control.c +++ b/drivers/firmware/arm_scmi/scmi_power_control.c @@ -45,6 +45,7 @@ #include <linux/math.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/pm.h> #include <linux/printk.h> diff --git a/drivers/firmware/imx/sm-cpu.c b/drivers/firmware/imx/sm-cpu.c index 091b014f739f..53a8d1cee5ea 100644 --- a/drivers/firmware/imx/sm-cpu.c +++ b/drivers/firmware/imx/sm-cpu.c @@ -5,6 +5,7 @@ #include <linux/firmware/imx/sm.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/scmi_protocol.h> diff --git a/drivers/firmware/imx/sm-lmm.c b/drivers/firmware/imx/sm-lmm.c index 6807bf563c03..f4dc198187a8 100644 --- a/drivers/firmware/imx/sm-lmm.c +++ b/drivers/firmware/imx/sm-lmm.c @@ -5,6 +5,7 @@ #include <linux/firmware/imx/sm.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/scmi_protocol.h> diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c index ac9af824c2d4..5e39e79a9d8a 100644 --- a/drivers/firmware/imx/sm-misc.c +++ b/drivers/firmware/imx/sm-misc.c @@ -7,6 +7,7 @@ #include <linux/device/devres.h> #include <linux/firmware/imx/sm.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/scmi_protocol.h> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c index eec223d174c0..57b91e931c5d 100644 --- a/drivers/hwmon/scmi-hwmon.c +++ b/drivers/hwmon/scmi-hwmon.c @@ -8,6 +8,7 @@ #include <linux/hwmon.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/scmi_protocol.h> #include <linux/slab.h> #include <linux/sysfs.h> diff --git a/drivers/iio/common/scmi_sensors/scmi_iio.c b/drivers/iio/common/scmi_sensors/scmi_iio.c index 442b40ef27cf..3babc4261965 100644 --- a/drivers/iio/common/scmi_sensors/scmi_iio.c +++ b/drivers/iio/common/scmi_sensors/scmi_iio.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/kthread.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/scmi_protocol.h> #include <linux/time.h> diff --git a/drivers/input/keyboard/imx-sm-bbm-key.c b/drivers/input/keyboard/imx-sm-bbm-key.c index 96486bd23d60..36e349136ee7 100644 --- a/drivers/input/keyboard/imx-sm-bbm-key.c +++ b/drivers/input/keyboard/imx-sm-bbm-key.c @@ -6,6 +6,7 @@ #include <linux/input.h> #include <linux/jiffies.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/rtc.h> diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c index 3693423459c9..741375ad325b 100644 --- a/drivers/pmdomain/arm/scmi_perf_domain.c +++ b/drivers/pmdomain/arm/scmi_perf_domain.c @@ -8,6 +8,7 @@ #include <linux/err.h> #include <linux/device.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/pm_domain.h> #include <linux/pm_opp.h> #include <linux/scmi_protocol.h> diff --git a/drivers/pmdomain/arm/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c index 3d73aef21d2f..0948d05c9e3c 100644 --- a/drivers/pmdomain/arm/scmi_pm_domain.c +++ b/drivers/pmdomain/arm/scmi_pm_domain.c @@ -8,6 +8,7 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/pm_domain.h> #include <linux/scmi_protocol.h> diff --git a/drivers/powercap/arm_scmi_powercap.c b/drivers/powercap/arm_scmi_powercap.c index ab66e9a3b1e2..332e4e26f1e5 100644 --- a/drivers/powercap/arm_scmi_powercap.c +++ b/drivers/powercap/arm_scmi_powercap.c @@ -10,6 +10,7 @@ #include <linux/limits.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/powercap.h> #include <linux/scmi_protocol.h> #include <linux/slab.h> diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c index c005e65ba0ec..f55f228cb133 100644 --- a/drivers/regulator/scmi-regulator.c +++ b/drivers/regulator/scmi-regulator.c @@ -25,6 +25,7 @@ #include <linux/linear_range.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c index 4335811e0cfa..a6739df1d3c2 100644 --- a/drivers/reset/reset-scmi.c +++ b/drivers/reset/reset-scmi.c @@ -6,6 +6,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/device.h> #include <linux/reset-controller.h> diff --git a/drivers/rtc/rtc-imx-sm-bbm.c b/drivers/rtc/rtc-imx-sm-bbm.c index daa472be7c80..c8643718cef1 100644 --- a/drivers/rtc/rtc-imx-sm-bbm.c +++ b/drivers/rtc/rtc-imx-sm-bbm.c @@ -5,6 +5,7 @@ #include <linux/jiffies.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/rtc.h> #include <linux/scmi_protocol.h> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 3b0c9a251a2e..769382f2eadd 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -473,6 +473,17 @@ struct rpmsg_device_id { kernel_ulong_t driver_data; }; +/* scmi */ + +#define SCMI_NAME_SIZE 32 +#define SCMI_MODULE_PREFIX "scmi:" + +struct scmi_device_id { + __u8 protocol_id; + char name[SCMI_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + /* i2c */ #define I2C_NAME_SIZE 20 diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 5ab73b1ab9aa..61f5ecfe0133 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -951,10 +951,7 @@ struct scmi_device { #define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev) -struct scmi_device_id { - u8 protocol_id; - const char *name; -}; +struct scmi_device_id; struct scmi_driver { const char *name; diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index b4178c42d08f..da5bd712c8da 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -144,6 +144,10 @@ int main(void) DEVID(rpmsg_device_id); DEVID_FIELD(rpmsg_device_id, name); + DEVID(scmi_device_id); + DEVID_FIELD(scmi_device_id, protocol_id); + DEVID_FIELD(scmi_device_id, name); + DEVID(i2c_device_id); DEVID_FIELD(i2c_device_id, name); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8d36c74dec2d..a5283f4c8e6f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -852,6 +852,16 @@ static void do_rpmsg_entry(struct module *mod, void *symval) module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name); } +/* Looks like: scmi:NN:S */ +static void do_scmi_entry(struct module *mod, void *symval) +{ + DEF_FIELD(symval, scmi_device_id, protocol_id); + DEF_FIELD_ADDR(symval, scmi_device_id, name); + + module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s", + protocol_id, *name); +} + /* Looks like: i2c:S */ static void do_i2c_entry(struct module *mod, void *symval) { @@ -1491,6 +1501,7 @@ static const struct devtable devtable[] = { {"virtio", SIZE_virtio_device_id, do_virtio_entry}, {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry}, {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, + {"scmi", SIZE_scmi_device_id, do_scmi_entry}, {"i2c", SIZE_i2c_device_id, do_i2c_entry}, {"i3c", SIZE_i3c_device_id, do_i3c_entry}, {"slim", SIZE_slim_device_id, do_slim_entry}, -- 2.53.0