[RFC 3/3] firmware: scmi: add a sanity check against protocol version

AKASHI Takahiro takahiro.akashi at linaro.org
Fri Jul 28 02:33:13 CEST 2023


SCMI_PROTOCOL_VERSION is a mandatory command for all the SCMI protocols.
With this patch, this command is implemented on each protocol.
Then, we can assure that the feature set implemented by SCMI Server
(firmware) is compatible with U-Boot, that is, each protocol's version
must be equal to or higher than the one that U-Boot's corresponding driver
expects.

Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
 drivers/clk/clk_scmi.c                   |  6 ++++++
 drivers/power/regulator/scmi_regulator.c |  6 ++++++
 drivers/reset/reset-scmi.c               | 14 +++++++++++++-
 include/scmi_protocols.h                 |  6 ++++++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 34a49363a51a..3591acb6d3a9 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -138,12 +138,18 @@ static int scmi_clk_probe(struct udevice *dev)
 {
 	struct clk *clk;
 	size_t num_clocks, i;
+	u32 version;
 	int ret;
 
 	ret = devm_scmi_of_get_channel(dev);
 	if (ret)
 		return ret;
 
+	ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_CLOCK,
+					    &version);
+	if (ret || version < SCMI_CLOCK_PROTOCOL_VERSION)
+		return -EINVAL;
+
 	if (!CONFIG_IS_ENABLED(CLK_CCF))
 		return 0;
 
diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c
index 08918b20872c..936768d0eeeb 100644
--- a/drivers/power/regulator/scmi_regulator.c
+++ b/drivers/power/regulator/scmi_regulator.c
@@ -138,12 +138,18 @@ static int scmi_regulator_probe(struct udevice *dev)
 		.out_msg = (u8 *)&out,
 		.out_msg_sz = sizeof(out),
 	};
+	u32 version;
 	int ret;
 
 	ret = devm_scmi_of_get_channel(dev);
 	if (ret)
 		return ret;
 
+	ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
+					    &version);
+	if (ret || version < SCMI_VOLTDOM_PROTOCOL_VERSION)
+		return -EINVAL;
+
 	/* Check voltage domain is known from SCMI server */
 	in.domain_id = pdata->domain_id;
 
diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
index b76711f0a8fb..dbd98dbdbc4f 100644
--- a/drivers/reset/reset-scmi.c
+++ b/drivers/reset/reset-scmi.c
@@ -73,7 +73,19 @@ static const struct reset_ops scmi_reset_domain_ops = {
 
 static int scmi_reset_probe(struct udevice *dev)
 {
-	return devm_scmi_of_get_channel(dev);
+	u32 version;
+	int ret;
+
+	ret = devm_scmi_of_get_channel(dev);
+	if (ret)
+		return ret;
+
+	ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_RESET_DOMAIN,
+					    &version);
+	if (ret || version < SCMI_RESETDOM_PROTOCOL_VERSION)
+		return -EINVAL;
+
+	return 0;
 }
 
 U_BOOT_DRIVER(scmi_reset_domain) = {
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 64fd740472b5..6ab16efd49cc 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -398,6 +398,8 @@ int scmi_generic_protocol_version(struct udevice *dev,
  * SCMI Clock Protocol
  */
 
+#define SCMI_CLOCK_PROTOCOL_VERSION 0x20000
+
 enum scmi_clock_message_id {
 	SCMI_CLOCK_ATTRIBUTES = 0x3,
 	SCMI_CLOCK_RATE_SET = 0x5,
@@ -509,6 +511,8 @@ struct scmi_clk_rate_set_out {
  * SCMI Reset Domain Protocol
  */
 
+#define SCMI_RESETDOM_PROTOCOL_VERSION 0x30000
+
 enum scmi_reset_domain_message_id {
 	SCMI_RESET_DOMAIN_ATTRIBUTES = 0x3,
 	SCMI_RESET_DOMAIN_RESET = 0x4,
@@ -569,6 +573,8 @@ struct scmi_rd_reset_out {
  * SCMI Voltage Domain Protocol
  */
 
+#define SCMI_VOLTDOM_PROTOCOL_VERSION 0x20000
+
 enum scmi_voltage_domain_message_id {
 	SCMI_VOLTAGE_DOMAIN_ATTRIBUTES = 0x3,
 	SCMI_VOLTAGE_DOMAIN_CONFIG_SET = 0x5,
-- 
2.41.0



More information about the U-Boot mailing list