aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk/imx/clk-scu.c
diff options
context:
space:
mode:
authorGravatar Dong Aisheng <aisheng.dong@nxp.com> 2021-04-23 11:33:33 +0800
committerGravatar Abel Vesa <abel.vesa@nxp.com> 2021-06-14 12:33:19 +0300
commit5964012ce37e66d2588a9bc82f7184a008851cac (patch)
tree890c37c2e502c4d6209764f3476c91361dfd8e27 /drivers/clk/imx/clk-scu.c
parentclk: imx: scu: add gpr clocks support (diff)
downloadlinux-5964012ce37e66d2588a9bc82f7184a008851cac.tar.gz
linux-5964012ce37e66d2588a9bc82f7184a008851cac.tar.bz2
linux-5964012ce37e66d2588a9bc82f7184a008851cac.zip
clk: imx8qxp: add clock valid checking mechnism
clk-imx8qxp is a common SCU clock driver used by both QM and QXP platforms. The clock numbers vary a bit between those two platforms. This patch introduces a mechanism to only register the valid clocks for one platform by checking the clk resource id table. Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com> Reviewed-by: Abel Vesa <abel.vesa@nxp.com> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
Diffstat (limited to 'drivers/clk/imx/clk-scu.c')
-rw-r--r--drivers/clk/imx/clk-scu.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index bd169083350c..f4efb3b76c86 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018 NXP
+ * Copyright 2018-2021 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/arm-smccc.h>
+#include <linux/bsearch.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/of_platform.h>
@@ -22,6 +23,7 @@
static struct imx_sc_ipc *ccm_ipc_handle;
static struct device_node *pd_np;
static struct platform_driver imx_clk_scu_driver;
+static const struct imx_clk_scu_rsrc_table *rsrc_table;
struct imx_scu_clk_node {
const char *name;
@@ -167,7 +169,26 @@ static inline struct clk_scu *to_clk_scu(struct clk_hw *hw)
return container_of(hw, struct clk_scu, hw);
}
-int imx_clk_scu_init(struct device_node *np)
+static inline int imx_scu_clk_search_cmp(const void *rsrc, const void *rsrc_p)
+{
+ return *(u32 *)rsrc - *(u32 *)rsrc_p;
+}
+
+static bool imx_scu_clk_is_valid(u32 rsrc_id)
+{
+ void *p;
+
+ if (!rsrc_table)
+ return true;
+
+ p = bsearch(&rsrc_id, rsrc_table->rsrc, rsrc_table->num,
+ sizeof(rsrc_table->rsrc[0]), imx_scu_clk_search_cmp);
+
+ return p != NULL;
+}
+
+int imx_clk_scu_init(struct device_node *np,
+ const struct imx_clk_scu_rsrc_table *data)
{
u32 clk_cells;
int ret, i;
@@ -186,6 +207,8 @@ int imx_clk_scu_init(struct device_node *np)
pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd");
if (!pd_np)
return -EINVAL;
+
+ rsrc_table = data;
}
return platform_driver_register(&imx_clk_scu_driver);
@@ -583,6 +606,9 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
struct platform_device *pdev;
int ret;
+ if (!imx_scu_clk_is_valid(rsrc_id))
+ return ERR_PTR(-EINVAL);
+
pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
if (!pdev) {
pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n",
@@ -750,6 +776,9 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na
if (!clk_node)
return ERR_PTR(-ENOMEM);
+ if (!imx_scu_clk_is_valid(rsrc_id))
+ return ERR_PTR(-EINVAL);
+
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk) {
kfree(clk_node);