[PATCH v3 2/3] firmware: arm_scmi: Pre-register protocol, name tupples for standard protocols
Hans de Goede <[email protected]>
| Newsgroups | org.kernel.vger.arm-scmi,dev.linux.lists.imx,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Cristian Marussi <[email protected]> Driver module auto-loading requires the devices to already be created for udev to get the necessary uevents based on which udev auto-loads modules. But SCMI devices are only created after their { protocol, name } tupples have been registered which is done from scmi_driver_register(). This creates a circular dependency where device creation is waiting for the driver to register and loading the module with the driver is waiting for the device to be created. Pre-register the tupples for standard protocols to break this circular dependency. Tested-by: Hans de Goede <[email protected]> Signed-off-by: Cristian Marussi <[email protected]> Signed-off-by: Hans de Goede <[email protected]> --- Changes in v3: - Drop adding of a bus uevent function this is already done - Update comments and commit message with a better explanation of why - Link to v1/RFC: https://patch.msgid.link/[email protected] --- drivers/firmware/arm_scmi/bus.c | 47 ++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index d12d5de15a1a..111727904a89 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -77,12 +77,13 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) if (phead) { head = phead; list_for_each_entry(rdev, head, node) { + /* pr_debug() because dups are expected for std protocols */ if (!strcmp(rdev->id_table->name, id_table->name)) { - pr_err("Ignoring duplicate request [%d] %s\n", - rdev->id_table->protocol_id, - rdev->id_table->name); - ret = -EINVAL; - goto out; + pr_debug("Device already requested [%d] %s\n", + rdev->id_table->protocol_id, + rdev->id_table->name); + mutex_unlock(&scmi_requested_devices_mtx); + return 0; } } } @@ -579,17 +580,49 @@ static void scmi_devices_unregister(void) bus_for_each_dev(&scmi_bus_type, NULL, NULL, __scmi_devices_unregister); } +/* Standard protocols table */ +static const struct scmi_device_id scmi_std_id_table[] = { + { SCMI_PROTOCOL_POWER, "genpd" }, + { SCMI_PROTOCOL_SYSTEM, "syspower" }, + { SCMI_PROTOCOL_PERF, "perf" }, + { SCMI_PROTOCOL_PERF, "cpufreq" }, + { SCMI_PROTOCOL_CLOCK, "clocks" }, + { SCMI_PROTOCOL_SENSOR, "hwmon" }, + { SCMI_PROTOCOL_SENSOR, "iiodev" }, + { SCMI_PROTOCOL_RESET, "reset" }, + { SCMI_PROTOCOL_VOLTAGE, "regulator" }, + { SCMI_PROTOCOL_POWERCAP, "powercap" }, + { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, + { SCMI_PROTOCOL_PINCTRL, "pinctrl-imx" }, + { }, +}; + static int __init scmi_bus_init(void) { int retval; retval = bus_register(&scmi_bus_type); - if (retval) + if (retval) { pr_err("SCMI protocol bus register failed (%d)\n", retval); + return retval; + } + + /* + * Driver module auto-loading requires the devices to already be created + * for udev to get the necessary uevents. But the devices are only + * created after their { protocol, name } tupples have been registered + * which is done from scmi_driver_register(). Pre-register the tupples + * for known (in tree) drivers to break this circular dependency. + */ + retval = scmi_protocol_table_register(scmi_std_id_table); + if (retval) { + bus_unregister(&scmi_bus_type); + return retval; + } pr_info("SCMI protocol bus registered\n"); - return retval; + return 0; } subsys_initcall(scmi_bus_init); -- 2.55.0