[PATCH/RFC 05/14] firmware: arm_scmi: Add scmi_get_base_info()

Geert Uytterhoeven
2026-04-21T18:12:23Z

Currently non-SCMI drivers cannot find out what the specific versions of
each SCMI provider implementation on the running system are.

However, different versions may use different ABIs (e.g. different clock
IDs), or behave different, requiring remapping or workarounds in other
drivers.

Add a public function to obtain base protocol information for the
selected SCMI provider. This will be used by the R-Car X5H Clock Pulse
Generator and Module Controller drivers.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/firmware/arm_scmi/driver.c | 31 ++++++++++++++++++++++++++++++
include/linux/scmi_protocol.h | 8 ++++++++
2 files changed, 39 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3e0d975ec94c4485..dfa8961775aa952d 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -3504,6 +3504,37 @@ int scmi_inflight_count(const struct scmi_handle *handle)
}
}

+/**
+ * scmi_get_base_info() - Get SCMI base protocol information
+ *
+ * @of_node: pointer to a device node for an SCMI provider
+ * @version: pointer to write base protocol information
+ *
+ * Check if an SCMI device has been instantiated for the passed device node
+ * pointer, and, if found, return its base info.
+
+ * Return: 0 on Success or -ENOENT.
+ */
+int scmi_get_base_info(struct device_node *of_node,
+ struct scmi_base_info *version)
+{
+ struct scmi_info *info;
+ int ret = -ENOENT;
+
+ mutex_lock(&scmi_list_mutex);
+ list_for_each_entry(info, &scmi_list, node) {
+ if (info->dev->of_node == of_node) {
+ *version = info->version;
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&scmi_list_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(scmi_get_base_info);
+
static int __init scmi_driver_init(void)
{
scmi_quirks_initialize();
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 49cc39e0cbca5a0b..52eba920de264bd7 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -972,6 +972,8 @@ struct scmi_driver {
int scmi_driver_register(struct scmi_driver *driver,
struct module *owner, const char *mod_name);
void scmi_driver_unregister(struct scmi_driver *driver);
+int scmi_get_base_info(struct device_node *of_node,
+ struct scmi_base_info *version);
#else
static inline int
scmi_driver_register(struct scmi_driver *driver, struct module *owner,
@@ -981,6 +983,12 @@ scmi_driver_register(struct scmi_driver *driver, struct module *owner,
}

static inline void scmi_driver_unregister(struct scmi_driver *driver) {}
+
+static inline int scmi_get_base_info(struct device_node *of_node,
+ struct scmi_base_info *version)
+{
+ return -ENOENT;
+}
#endif /* CONFIG_ARM_SCMI_PROTOCOL */

#define scmi_register(driver) \
--
2.43.0