diff mbox series

[v2,3/5] scmi: change parameter dev in devm_scmi_process_msg

Message ID 20220221082242.6349-3-etienne.carriere@linaro.org
State New
Headers show
Series [v2,1/5] doc: binding: scmi: link to latest Linux kernel binding | expand

Commit Message

Etienne Carriere Feb. 21, 2022, 8:22 a.m. UTC
Changes devm_scmi_process_msg() first argument from target parent device
to current SCMI device and lookup the SCMI agent device among SCMI device
parents for find the SCMI agent operator needed for communication with
the firmware.

This change is needed in order to support CCF in clk_scmi driver unless
what CCF will fail to find the right udevice related to exposed SCMI
clocks.

This patch allows to simplify the caller sequence, using SCMI device
reference as parameter instead of knowing SCMI uclass topology. This
change also adds some protection in case devm_scmi_process_msg() API
function is called for an invalid device type.

Cc: Lukasz Majewski <lukma@denx.de>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
---
Changes since v1:
- Apply R-b tag.
---
 drivers/clk/clk_scmi.c                    |  6 +++---
 drivers/firmware/scmi/scmi_agent-uclass.c | 17 +++++++++++++++--
 drivers/power/regulator/scmi_regulator.c  | 10 +++++-----
 drivers/reset/reset-scmi.c                |  4 ++--
 include/scmi_agent.h                      |  2 +-
 5 files changed, 26 insertions(+), 13 deletions(-)

Comments

Tom Rini March 3, 2022, 7:16 p.m. UTC | #1
On Mon, Feb 21, 2022 at 09:22:40AM +0100, Etienne Carriere wrote:

> Changes devm_scmi_process_msg() first argument from target parent device
> to current SCMI device and lookup the SCMI agent device among SCMI device
> parents for find the SCMI agent operator needed for communication with
> the firmware.
> 
> This change is needed in order to support CCF in clk_scmi driver unless
> what CCF will fail to find the right udevice related to exposed SCMI
> clocks.
> 
> This patch allows to simplify the caller sequence, using SCMI device
> reference as parameter instead of knowing SCMI uclass topology. This
> change also adds some protection in case devm_scmi_process_msg() API
> function is called for an invalid device type.
> 
> Cc: Lukasz Majewski <lukma@denx.de>
> Cc: Sean Anderson <seanga2@gmail.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>

Applied to u-boot/next, thanks!
diff mbox series

Patch

diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 9a0a6f6643..42fbab0d21 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -24,7 +24,7 @@  static int scmi_clk_gate(struct clk *clk, int enable)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(clk->dev->parent, &msg);
+	ret = devm_scmi_process_msg(clk->dev, &msg);
 	if (ret)
 		return ret;
 
@@ -52,7 +52,7 @@  static ulong scmi_clk_get_rate(struct clk *clk)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(clk->dev->parent, &msg);
+	ret = devm_scmi_process_msg(clk->dev, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -77,7 +77,7 @@  static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(clk->dev->parent, &msg);
+	ret = devm_scmi_process_msg(clk->dev, &msg);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 4f5870b483..3819f2fa99 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -116,10 +116,23 @@  static const struct scmi_agent_ops *transport_dev_ops(struct udevice *dev)
 
 int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg)
 {
-	const struct scmi_agent_ops *ops = transport_dev_ops(dev);
+	const struct scmi_agent_ops *ops;
+	struct udevice *parent = dev;
+
+	/* Find related SCMI agent device */
+	do {
+		parent = dev_get_parent(parent);
+	} while (parent && device_get_uclass_id(parent) != UCLASS_SCMI_AGENT);
+
+	if (!parent) {
+		dev_err(dev, "Invalid SCMI device, agent not found\n");
+		return -ENODEV;
+	}
+
+	ops = transport_dev_ops(parent);
 
 	if (ops->process_msg)
-		return ops->process_msg(dev, msg);
+		return ops->process_msg(parent, msg);
 
 	return -EPROTONOSUPPORT;
 }
diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c
index 3ddeaf4adc..2966bdcf83 100644
--- a/drivers/power/regulator/scmi_regulator.c
+++ b/drivers/power/regulator/scmi_regulator.c
@@ -38,7 +38,7 @@  static int scmi_voltd_set_enable(struct udevice *dev, bool enable)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(dev->parent->parent, &msg);
+	ret = devm_scmi_process_msg(dev, &msg);
 	if (ret)
 		return ret;
 
@@ -61,7 +61,7 @@  static int scmi_voltd_get_enable(struct udevice *dev)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(dev->parent->parent, &msg);
+	ret = devm_scmi_process_msg(dev, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -85,7 +85,7 @@  static int scmi_voltd_set_voltage_level(struct udevice *dev, int uV)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(dev->parent->parent, &msg);
+	ret = devm_scmi_process_msg(dev, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -104,7 +104,7 @@  static int scmi_voltd_get_voltage_level(struct udevice *dev)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(dev->parent->parent, &msg);
+	ret = devm_scmi_process_msg(dev, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -147,7 +147,7 @@  static int scmi_regulator_probe(struct udevice *dev)
 	/* Check voltage domain is known from SCMI server */
 	in.domain_id = pdata->domain_id;
 
-	ret = devm_scmi_process_msg(dev->parent->parent, &scmi_msg);
+	ret = devm_scmi_process_msg(dev, &scmi_msg);
 	if (ret) {
 		dev_err(dev, "Failed to query voltage domain %u: %d\n",
 			pdata->domain_id, ret);
diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
index ca0135a420..850cb18886 100644
--- a/drivers/reset/reset-scmi.c
+++ b/drivers/reset/reset-scmi.c
@@ -26,7 +26,7 @@  static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert)
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(rst->dev->parent, &msg);
+	ret = devm_scmi_process_msg(rst->dev, &msg);
 	if (ret)
 		return ret;
 
@@ -58,7 +58,7 @@  static int scmi_reset_request(struct reset_ctl *rst)
 	 * We don't really care about the attribute, just check
 	 * the reset domain exists.
 	 */
-	ret = devm_scmi_process_msg(rst->dev->parent, &msg);
+	ret = devm_scmi_process_msg(rst->dev, &msg);
 	if (ret)
 		return ret;
 
diff --git a/include/scmi_agent.h b/include/scmi_agent.h
index 5015c06be9..18bcd48a9d 100644
--- a/include/scmi_agent.h
+++ b/include/scmi_agent.h
@@ -51,7 +51,7 @@  struct scmi_msg {
  * Caller sets scmi_msg::out_msg_sz to the output message buffer size.
  * On return, scmi_msg::out_msg_sz stores the response payload size.
  *
- * @dev:	SCMI agent device
+ * @dev:	SCMI device
  * @msg:	Message structure reference
  * Return: 0 on success and a negative errno on failure
  */