[PATCH V2] drivers: clk: zynqmp: remove clock name dependency

From: Naman Trivedi
Date: Mon Jul 22 2024 - 08:19:32 EST


From: Naman Trivedi Manojbhai <naman.trivedimanojbhai@xxxxxxx>

Use struct clk_parent_data to register the clock parents with the clock
framework instead of parent name.

Signed-off-by: Naman Trivedi Manojbhai <naman.trivedimanojbhai@xxxxxxx>
---
V1: https://lore.kernel.org/lkml/20240103072017.1646007-1-naman.trivedimanojbhai@xxxxxxx
V1 -> V2:
- Used struct clk_parent_data instead of parent names to register clock
parents with the clock framework
---
drivers/clk/zynqmp/clk-gate-zynqmp.c | 8 +--
drivers/clk/zynqmp/clk-mux-zynqmp.c | 9 +--
drivers/clk/zynqmp/clk-zynqmp.h | 26 ++++-----
drivers/clk/zynqmp/clkc.c | 83 +++++++++++++++++++---------
drivers/clk/zynqmp/divider.c | 8 +--
drivers/clk/zynqmp/pll.c | 9 +--
6 files changed, 89 insertions(+), 54 deletions(-)

diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
index b89e55737198..6bb9704ee1d3 100644
--- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
@@ -104,8 +104,8 @@ static const struct clk_ops zynqmp_clk_gate_ops = {
*
* Return: clock hardware of the registered clock gate
*/
-struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
- const char * const *parents,
+struct clk_hw *zynqmp_clk_register_gate(struct device_node *np, const char *name, u32 clk_id,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes)
{
@@ -124,7 +124,7 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,

init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);

- init.parent_names = parents;
+ init.parent_data = parents;
init.num_parents = 1;

/* struct clk_gate assignments */
@@ -133,7 +133,7 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
gate->clk_id = clk_id;

hw = &gate->hw;
- ret = clk_hw_register(NULL, hw);
+ ret = of_clk_hw_register(np, hw);
if (ret) {
kfree(gate);
hw = ERR_PTR(ret);
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
index 9b5d3050b742..30daf1f77b4c 100644
--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
@@ -128,8 +128,9 @@ static inline unsigned long zynqmp_clk_map_mux_ccf_flags(
*
* Return: clock hardware of the registered clock mux
*/
-struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,
- const char * const *parents,
+struct clk_hw *zynqmp_clk_register_mux(struct device_node *np,
+ const char *name, u32 clk_id,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes)
{
@@ -150,14 +151,14 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,

init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);

- init.parent_names = parents;
+ init.parent_data = parents;
init.num_parents = num_parents;
mux->flags = zynqmp_clk_map_mux_ccf_flags(nodes->type_flag);
mux->hw.init = &init;
mux->clk_id = clk_id;

hw = &mux->hw;
- ret = clk_hw_register(NULL, hw);
+ ret = of_clk_hw_register(np, hw);
if (ret) {
kfree(mux);
hw = ERR_PTR(ret);
diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
index 60cbc0674a9e..6343cfb57a4f 100644
--- a/drivers/clk/zynqmp/clk-zynqmp.h
+++ b/drivers/clk/zynqmp/clk-zynqmp.h
@@ -67,31 +67,31 @@ struct clock_topology {

unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag);

-struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
- const char * const *parents,
+struct clk_hw *zynqmp_clk_register_pll(struct device_node *np, const char *name, u32 clk_id,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes);

-struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
- const char * const *parents,
+struct clk_hw *zynqmp_clk_register_gate(struct device_node *np, const char *name, u32 clk_id,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes);

-struct clk_hw *zynqmp_clk_register_divider(const char *name,
+struct clk_hw *zynqmp_clk_register_divider(struct device_node *np, const char *name,
u32 clk_id,
- const char * const *parents,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes);

-struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,
- const char * const *parents,
+struct clk_hw *zynqmp_clk_register_mux(struct device_node *np, const char *name, u32 clk_id,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes);

-struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name,
- u32 clk_id,
- const char * const *parents,
- u8 num_parents,
- const struct clock_topology *nodes);
+struct clk_hw *zynqmp_clk_register_fixed_factor(struct device_node *np, const char *name,
+ u32 clk_id,
+ const struct clk_parent_data *parents,
+ u8 num_parents,
+ const struct clock_topology *nodes);

#endif
diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index a91d98e238c2..b791a459280e 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -12,6 +12,7 @@
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -119,11 +120,10 @@ static const char clk_type_postfix[][10] = {
[TYPE_PLL] = ""
};

-static struct clk_hw *(* const clk_topology[]) (const char *name, u32 clk_id,
- const char * const *parents,
- u8 num_parents,
- const struct clock_topology *nodes)
- = {
+static struct clk_hw *(* const clk_topology[]) (struct device_node *np, const char *name,
+ u32 clk_id, const struct clk_parent_data *parents,
+ u8 num_parents,
+ const struct clock_topology *nodes) = {
[TYPE_INVALID] = NULL,
[TYPE_MUX] = zynqmp_clk_register_mux,
[TYPE_PLL] = zynqmp_clk_register_pll,
@@ -307,14 +307,16 @@ unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag)
*
* Return: clock hardware to the registered clock
*/
-struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
- const char * const *parents,
- u8 num_parents,
- const struct clock_topology *nodes)
+struct clk_hw *zynqmp_clk_register_fixed_factor(struct device_node *np, const char *name,
+ u32 clk_id,
+ const struct clk_parent_data *parents,
+ u8 num_parents,
+ const struct clock_topology *nodes)
{
u32 mult, div;
struct clk_hw *hw;
struct zynqmp_pm_query_data qdata = {0};
+ struct platform_device *plat_dev;
u32 ret_payload[PAYLOAD_ARG_CNT];
int ret;
unsigned long flag;
@@ -331,10 +333,19 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,

flag = zynqmp_clk_map_common_ccf_flags(nodes->flag);

- hw = clk_hw_register_fixed_factor(NULL, name,
- parents[0],
- flag, mult,
- div);
+ plat_dev = of_find_device_by_node(np);
+ if (!plat_dev)
+ return NULL;
+
+ if (parents->name)
+ hw = clk_hw_register_fixed_factor(NULL, name,
+ parents->name,
+ flag, mult,
+ div);
+ else
+ hw = devm_clk_hw_register_fixed_factor_index(&plat_dev->dev, name,
+ parents->index,
+ flag, mult, div);

return hw;
}
@@ -543,7 +554,7 @@ static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
* Return: 0 on success else error+reason
*/
static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,
- const char **parent_list, u32 *num_parents)
+ struct clk_parent_data *parent_list, u32 *num_parents)
{
int i = 0, ret;
u32 total_parents = clock[clk_id].num_parents;
@@ -555,18 +566,30 @@ static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,

for (i = 0; i < total_parents; i++) {
if (!parents[i].flag) {
- parent_list[i] = parents[i].name;
+ ret = of_property_match_string(np, "clock-names",
+ parents[i].name);
+ if (ret >= 0) {
+ parent_list[i].index = ret;
+ } else {
+ parent_list[i].fw_name = parents[i].name;
+ parent_list[i].name = parents[i].name;
+ }
} else if (parents[i].flag == PARENT_CLK_EXTERNAL) {
ret = of_property_match_string(np, "clock-names",
parents[i].name);
- if (ret < 0)
+ if (ret >= 0) {
+ parent_list[i].index = ret;
+ } else {
strcpy(parents[i].name, "dummy_name");
- parent_list[i] = parents[i].name;
+ parent_list[i].fw_name = parents[i].name;
+ parent_list[i].name = parents[i].name;
+ }
} else {
strcat(parents[i].name,
clk_type_postfix[clk_nodes[parents[i].flag - 1].
type]);
- parent_list[i] = parents[i].name;
+ parent_list[i].fw_name = parents[i].name;
+ parent_list[i].name = parents[i].name;
}
}

@@ -583,9 +606,9 @@ static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,
*
* Return: Returns either clock hardware or error+reason
*/
-static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
- int num_parents,
- const char **parent_names)
+static struct clk_hw *zynqmp_register_clk_topology(struct device_node *np, int clk_id,
+ char *clk_name, int num_parents,
+ struct clk_parent_data *parent_names)
{
int j;
u32 num_nodes, clk_dev_id;
@@ -612,7 +635,7 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
if (!clk_topology[nodes[j].type])
continue;

- hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id,
+ hw = (*clk_topology[nodes[j].type])(np, clk_out[j], clk_dev_id,
parent_names,
num_parents,
&nodes[j]);
@@ -621,7 +644,10 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
__func__, clk_dev_id, clk_name,
PTR_ERR(hw));

- parent_names[0] = clk_out[j];
+ if (parent_names->fw_name) {
+ parent_names->name = clk_out[j];
+ parent_names->fw_name = clk_out[j];
+ }
}

for (j = 0; j < num_nodes; j++)
@@ -640,9 +666,14 @@ static int zynqmp_register_clocks(struct device_node *np)
{
int ret;
u32 i, total_parents = 0, type = 0;
- const char *parent_names[MAX_PARENT];
+ struct clk_parent_data *parent_names;
+
+ parent_names = kmalloc(sizeof(*parent_names) * MAX_PARENT, GFP_KERNEL);
+ if (!parent_names)
+ return -ENOMEM;

for (i = 0; i < clock_max_idx; i++) {
+ memset(parent_names, 0, sizeof(struct clk_parent_data) * MAX_PARENT);
char clk_name[MAX_NAME_LEN];

/* get clock name, continue to next clock if name not found */
@@ -665,7 +696,7 @@ static int zynqmp_register_clocks(struct device_node *np)
}

zynqmp_data->hws[i] =
- zynqmp_register_clk_topology(i, clk_name,
+ zynqmp_register_clk_topology(np, i, clk_name,
total_parents,
parent_names);
}
@@ -677,6 +708,8 @@ static int zynqmp_register_clocks(struct device_node *np)
WARN_ON(1);
}
}
+
+ kfree(parent_names);
return 0;
}

diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index 5a00487ae408..7c0905be2f26 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -269,9 +269,9 @@ static inline unsigned long zynqmp_clk_map_divider_ccf_flags(
*
* Return: clock hardware to registered clock divider
*/
-struct clk_hw *zynqmp_clk_register_divider(const char *name,
+struct clk_hw *zynqmp_clk_register_divider(struct device_node *np, const char *name,
u32 clk_id,
- const char * const *parents,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes)
{
@@ -293,7 +293,7 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,

init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);

- init.parent_names = parents;
+ init.parent_data = parents;
init.num_parents = 1;

/* struct clk_divider assignments */
@@ -311,7 +311,7 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
div->max_div = zynqmp_clk_get_max_divisor(clk_id, nodes->type);

hw = &div->hw;
- ret = clk_hw_register(NULL, hw);
+ ret = of_clk_hw_register(np, hw);
if (ret) {
kfree(div);
hw = ERR_PTR(ret);
diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
index 7411a7fd50ac..4bd93efed9f2 100644
--- a/drivers/clk/zynqmp/pll.c
+++ b/drivers/clk/zynqmp/pll.c
@@ -309,8 +309,9 @@ static const struct clk_ops zynqmp_pll_ops = {
*
* Return: clock hardware to the registered clock
*/
-struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
- const char * const *parents,
+struct clk_hw *zynqmp_clk_register_pll(struct device_node *np,
+ const char *name, u32 clk_id,
+ const struct clk_parent_data *parents,
u8 num_parents,
const struct clock_topology *nodes)
{
@@ -324,7 +325,7 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,

init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);

- init.parent_names = parents;
+ init.parent_data = parents;
init.num_parents = 1;

pll = kzalloc(sizeof(*pll), GFP_KERNEL);
@@ -335,7 +336,7 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
pll->clk_id = clk_id;

hw = &pll->hw;
- ret = clk_hw_register(NULL, hw);
+ ret = of_clk_hw_register(np, hw);
if (ret) {
kfree(pll);
return ERR_PTR(ret);
--
2.25.1