clk: scmi: support SCMI multi-channel

Update SCMI clock driver to get its assigned SCMI channel during
initialization. This change allows SCMI clock protocol to use a
dedicated channel when defined in the DT. The reference is saved
in SCMI clock driver private data.

Cc: Lukasz Majewski <lukma@denx.de>
Cc: Sean Anderson <seanga2@gmail.com>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 0d0bb72..d172fed 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2019-2020 Linaro Limited
+ * Copyright (C) 2019-2022 Linaro Limited
  */
 
 #define LOG_CATEGORY UCLASS_CLK
@@ -13,8 +13,17 @@
 #include <asm/types.h>
 #include <linux/clk-provider.h>
 
+/**
+ * struct scmi_clk_priv - Private data for SCMI clocks
+ * @channel: Reference to the SCMI channel to use
+ */
+struct scmi_clk_priv {
+	struct scmi_channel *channel;
+};
+
 static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks)
 {
+	struct scmi_clk_priv *priv = dev_get_priv(dev);
 	struct scmi_clk_protocol_attr_out out;
 	struct scmi_msg msg = {
 		.protocol_id = SCMI_PROTOCOL_ID_CLOCK,
@@ -24,7 +33,7 @@
 	};
 	int ret;
 
-	ret = devm_scmi_process_msg(dev, NULL, &msg);
+	ret = devm_scmi_process_msg(dev, priv->channel, &msg);
 	if (ret)
 		return ret;
 
@@ -35,6 +44,7 @@
 
 static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name)
 {
+	struct scmi_clk_priv *priv = dev_get_priv(dev);
 	struct scmi_clk_attribute_in in = {
 		.clock_id = clkid,
 	};
@@ -49,7 +59,7 @@
 	};
 	int ret;
 
-	ret = devm_scmi_process_msg(dev, NULL, &msg);
+	ret = devm_scmi_process_msg(dev, priv->channel, &msg);
 	if (ret)
 		return ret;
 
@@ -60,6 +70,7 @@
 
 static int scmi_clk_gate(struct clk *clk, int enable)
 {
+	struct scmi_clk_priv *priv = dev_get_priv(clk->dev);
 	struct scmi_clk_state_in in = {
 		.clock_id = clk->id,
 		.attributes = enable,
@@ -70,7 +81,7 @@
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(clk->dev, NULL, &msg);
+	ret = devm_scmi_process_msg(clk->dev, priv->channel, &msg);
 	if (ret)
 		return ret;
 
@@ -89,6 +100,7 @@
 
 static ulong scmi_clk_get_rate(struct clk *clk)
 {
+	struct scmi_clk_priv *priv = dev_get_priv(clk->dev);
 	struct scmi_clk_rate_get_in in = {
 		.clock_id = clk->id,
 	};
@@ -98,7 +110,7 @@
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(clk->dev, NULL, &msg);
+	ret = devm_scmi_process_msg(clk->dev, priv->channel, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -111,6 +123,7 @@
 
 static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
 {
+	struct scmi_clk_priv *priv = dev_get_priv(clk->dev);
 	struct scmi_clk_rate_set_in in = {
 		.clock_id = clk->id,
 		.flags = SCMI_CLK_RATE_ROUND_CLOSEST,
@@ -123,7 +136,7 @@
 					  in, out);
 	int ret;
 
-	ret = devm_scmi_process_msg(clk->dev, NULL, &msg);
+	ret = devm_scmi_process_msg(clk->dev, priv->channel, &msg);
 	if (ret < 0)
 		return ret;
 
@@ -136,10 +149,15 @@
 
 static int scmi_clk_probe(struct udevice *dev)
 {
+	struct scmi_clk_priv *priv = dev_get_priv(dev);
 	struct clk *clk;
 	size_t num_clocks, i;
 	int ret;
 
+	ret = devm_scmi_of_get_channel(dev, &priv->channel);
+	if (ret)
+		return ret;
+
 	if (!CONFIG_IS_ENABLED(CLK_CCF))
 		return 0;
 
@@ -186,5 +204,6 @@
 	.name = "scmi_clk",
 	.id = UCLASS_CLK,
 	.ops = &scmi_clk_ops,
-	.probe = &scmi_clk_probe,
+	.probe = scmi_clk_probe,
+	.priv_auto = sizeof(struct scmi_clk_priv *),
 };