firmware: arm_scmi: Add scmi_get_base_info() 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>
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 3e0d975..dfa8961 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 49cc39e..52eba92 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) \