From 21ee965267bcbdd733be0f35344fa0f0226d7861 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 31 Jan 2025 14:18:20 +0000 Subject: [PATCH 1/3] firmware: arm_scmi: Relax duplicate name constraint across protocol ids Currently in scmi_protocol_device_request(), no duplicate scmi device name is allowed across any protocol. However scmi_dev_match_id() first matches the protocol id and then the name. So, there is no strict requirement to keep this scmi device name unique across all the protocols. Relax the constraint on the duplicate name across the protocols and inhibit only within the same protocol id. Message-Id: <20250131141822.514342-1-sudeep.holla@arm.com> Reviewed-by: Dhruva Gole Reviewed-by: Peng Fan Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/bus.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index a3386bf36de5..8acf33ccfd21 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -42,7 +42,7 @@ static atomic_t scmi_syspower_registered = ATOMIC_INIT(0); * This helper let an SCMI driver request specific devices identified by the * @id_table to be created for each active SCMI instance. * - * The requested device name MUST NOT be already existent for any protocol; + * The requested device name MUST NOT be already existent for this protocol; * at first the freshly requested @id_table is annotated in the IDR table * @scmi_requested_devices and then the requested device is advertised to any * registered party via the @scmi_requested_devices_nh notification chain. @@ -52,7 +52,6 @@ static atomic_t scmi_syspower_registered = ATOMIC_INIT(0); static int scmi_protocol_device_request(const struct scmi_device_id *id_table) { int ret = 0; - unsigned int id = 0; struct list_head *head, *phead = NULL; struct scmi_requested_dev *rdev; @@ -67,19 +66,13 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) } /* - * Search for the matching protocol rdev list and then search - * of any existent equally named device...fails if any duplicate found. + * Find the matching protocol rdev list and then search of any + * existent equally named device...fails if any duplicate found. */ mutex_lock(&scmi_requested_devices_mtx); - idr_for_each_entry(&scmi_requested_devices, head, id) { - if (!phead) { - /* A list found registered in the IDR is never empty */ - rdev = list_first_entry(head, struct scmi_requested_dev, - node); - if (rdev->id_table->protocol_id == - id_table->protocol_id) - phead = head; - } + phead = idr_find(&scmi_requested_devices, id_table->protocol_id); + if (phead) { + head = phead; list_for_each_entry(rdev, head, node) { if (!strcmp(rdev->id_table->name, id_table->name)) { pr_err("Ignoring duplicate request [%d] %s\n", From feaea74fd697231e1a75d1cc4cf07a6e4f1d99c6 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 31 Jan 2025 14:18:21 +0000 Subject: [PATCH 2/3] firmware: arm_scmi: Add name and protocol id attributes Add the name and the protocol id attributes to the SCMI devices on the bus so that they are exposed to the user-space via the sysfs. Message-Id: <20250131141822.514342-2-sudeep.holla@arm.com> Reviewed-by: Dhruva Gole Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/bus.c | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 8acf33ccfd21..862dd34eca62 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -17,6 +17,8 @@ #include "common.h" +#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s" + BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh); EXPORT_SYMBOL_GPL(scmi_requested_devices_nh); @@ -276,11 +278,47 @@ static void scmi_dev_remove(struct device *dev) scmi_drv->remove(scmi_dev); } +static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env *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); +} + +static ssize_t protocol_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct scmi_device *scmi_dev = to_scmi_dev(dev); + + return sprintf(buf, "0x%02x\n", scmi_dev->protocol_id); +} +static DEVICE_ATTR_RO(protocol_id); + +static ssize_t name_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scmi_device *scmi_dev = to_scmi_dev(dev); + + return sprintf(buf, "%s\n", scmi_dev->name); +} +static DEVICE_ATTR_RO(name); + +static struct attribute *scmi_device_attributes_attrs[] = { + &dev_attr_protocol_id.attr, + &dev_attr_name.attr, + NULL, +}; +ATTRIBUTE_GROUPS(scmi_device_attributes); + const struct bus_type scmi_bus_type = { .name = "scmi_protocol", .match = scmi_dev_match, .probe = scmi_dev_probe, .remove = scmi_dev_remove, + .uevent = scmi_device_uevent, + .dev_groups = scmi_device_attributes_groups, }; EXPORT_SYMBOL_GPL(scmi_bus_type); From d069c33f5ce2fe8f13489ba396080fcf28c10f60 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 31 Jan 2025 14:18:22 +0000 Subject: [PATCH 3/3] firmware: arm_scmi: Emit modalias for SCMI devices In order to enable libkmod lookups for SCMI device objects to their corresponding module, add 'modalias' to the base attribute of SCMI devices. Message-Id: <20250131141822.514342-3-sudeep.holla@arm.com> Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/bus.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 862dd34eca62..7af01664ce7e 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -287,6 +287,17 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env * scmi_dev->name); } +static ssize_t modalias_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + 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); +} +static DEVICE_ATTR_RO(modalias); + static ssize_t protocol_id_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -308,6 +319,7 @@ static DEVICE_ATTR_RO(name); static struct attribute *scmi_device_attributes_attrs[] = { &dev_attr_protocol_id.attr, &dev_attr_name.attr, + &dev_attr_modalias.attr, NULL, }; ATTRIBUTE_GROUPS(scmi_device_attributes);