[PATCH] clk: imx: imx93: introduce clk_bypassed module parameter

Peng Fan (OSS) peng.fan at oss.nxp.com
Thu May 4 01:55:06 PDT 2023


From: Peng Fan <peng.fan at nxp.com>

With the clk names specified in clk_bypassed module parameter, give
user an option to bypass the clk from managing them by Linux kernel.

This is useful when Cortex-M33 and Cortex-A55 both running, A55 may
shutdown the clocks used by M33. Although we have mcore_booted module
parameter, but it is only for composite gate, the CCGR gate could still
be shutdown by Linux.

So let's use clk_bypassed parameter to handle clk root and clk ccgr both.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V1:
 Depends on: https://lore.kernel.org/all/20230504075754.372780-1-peng.fan@oss.nxp.com/

 drivers/clk/imx/clk-imx93.c | 55 +++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
index 07b4a043e449..88ed824ca2ff 100644
--- a/drivers/clk/imx/clk-imx93.c
+++ b/drivers/clk/imx/clk-imx93.c
@@ -255,6 +255,51 @@ static const struct imx93_clk_ccgr {
 static struct clk_hw_onecell_data *clk_hw_data;
 static struct clk_hw **clks;
 
+#define IMX_NUM_CLK_ENTRY	64
+
+static char clk_bypassed_names[SZ_512];
+static char *clk_names[IMX_NUM_CLK_ENTRY];
+
+/* The module args format as this: clk-imx93.clk_bypassed="lpi2c8_root,spdif" */
+static int imx_clk_bypass_setup(struct device *dev, char *str)
+{
+	char *pos = str, *next;
+	int i = 0;
+
+	while (pos != NULL && (next = strchr(pos, ',')) != NULL) {
+		clk_names[i++] = devm_kstrndup(dev, pos, next - pos, GFP_KERNEL);
+		pos = ++next;
+	}
+
+	clk_names[i] = devm_kstrdup(dev, pos, GFP_KERNEL);
+
+	return 0;
+}
+
+static bool imx_clk_bypass_check(char *name)
+{
+	int i;
+
+	for (i = 0; i < IMX_NUM_CLK_ENTRY; i++) {
+		if (!clk_names[i])
+			return false;
+		if (!strcmp(name, clk_names[i]))
+			return true;
+	}
+
+	return false;
+}
+
+static int imx_clk_bypass_free(struct device *dev)
+{
+	int i;
+
+	for (i = 0; i < IMX_NUM_CLK_ENTRY; i++)
+		devm_kfree(dev, clk_names[i]);
+
+	return 0;
+}
+
 static int imx93_clocks_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -264,6 +309,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
 	void __iomem *base, *anatop_base;
 	int i, ret;
 
+	imx_clk_bypass_setup(dev, clk_bypassed_names);
+
 	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
 					  IMX93_CLK_END), GFP_KERNEL);
 	if (!clk_hw_data)
@@ -310,6 +357,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
 
 	for (i = 0; i < ARRAY_SIZE(root_array); i++) {
 		root = &root_array[i];
+		if (unlikely(imx_clk_bypass_check(root->name)))
+			continue;
 		clks[root->clk] = imx93_clk_composite_flags(root->name,
 							    parent_names[root->sel],
 							    4, base + root->off, 3,
@@ -318,6 +367,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
 
 	for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) {
 		ccgr = &ccgr_array[i];
+		if (unlikely(imx_clk_bypass_check(ccgr->name)))
+			continue;
 		clks[ccgr->clk] = imx93_clk_gate(NULL, ccgr->name, ccgr->parent_name,
 						 ccgr->flags, base + ccgr->off, 0, 1, 1, 3,
 						 ccgr->shared_count);
@@ -341,6 +392,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
 
 	imx_register_uart_clocks();
 
+	imx_clk_bypass_free(dev);
+
 	return 0;
 
 unregister_hws:
@@ -367,6 +420,8 @@ static struct platform_driver imx93_clk_driver = {
 module_platform_driver(imx93_clk_driver);
 module_param(mcore_booted, bool, 0444);
 MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not");
+module_param_string(clk_bypassed, clk_bypassed_names, SZ_512, 0444);
+MODULE_PARM_DESC(clk_bypassed, "The clks will not be managed by Linux");
 
 MODULE_DESCRIPTION("NXP i.MX93 clock driver");
 MODULE_LICENSE("GPL v2");
-- 
2.37.1




More information about the linux-arm-kernel mailing list