1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/clk-provider.h>
4 #include <linux/slab.h>
6 #include <linux/of_address.h>
10 void mmp_clk_init(struct device_node
*np
, struct mmp_clk_unit
*unit
,
13 struct clk
**clk_table
;
15 clk_table
= kcalloc(nr_clks
, sizeof(struct clk
*), GFP_KERNEL
);
19 unit
->clk_table
= clk_table
;
20 unit
->nr_clks
= nr_clks
;
21 unit
->clk_data
.clks
= clk_table
;
22 unit
->clk_data
.clk_num
= nr_clks
;
23 of_clk_add_provider(np
, of_clk_src_onecell_get
, &unit
->clk_data
);
26 void mmp_register_fixed_rate_clks(struct mmp_clk_unit
*unit
,
27 struct mmp_param_fixed_rate_clk
*clks
,
33 for (i
= 0; i
< size
; i
++) {
34 clk
= clk_register_fixed_rate(NULL
, clks
[i
].name
,
39 pr_err("%s: failed to register clock %s\n",
40 __func__
, clks
[i
].name
);
44 unit
->clk_table
[clks
[i
].id
] = clk
;
48 void mmp_register_fixed_factor_clks(struct mmp_clk_unit
*unit
,
49 struct mmp_param_fixed_factor_clk
*clks
,
55 for (i
= 0; i
< size
; i
++) {
56 clk
= clk_register_fixed_factor(NULL
, clks
[i
].name
,
58 clks
[i
].flags
, clks
[i
].mult
,
61 pr_err("%s: failed to register clock %s\n",
62 __func__
, clks
[i
].name
);
66 unit
->clk_table
[clks
[i
].id
] = clk
;
70 void mmp_register_general_gate_clks(struct mmp_clk_unit
*unit
,
71 struct mmp_param_general_gate_clk
*clks
,
72 void __iomem
*base
, int size
)
77 for (i
= 0; i
< size
; i
++) {
78 clk
= clk_register_gate(NULL
, clks
[i
].name
,
81 base
+ clks
[i
].offset
,
87 pr_err("%s: failed to register clock %s\n",
88 __func__
, clks
[i
].name
);
92 unit
->clk_table
[clks
[i
].id
] = clk
;
96 void mmp_register_gate_clks(struct mmp_clk_unit
*unit
,
97 struct mmp_param_gate_clk
*clks
,
98 void __iomem
*base
, int size
)
103 for (i
= 0; i
< size
; i
++) {
104 clk
= mmp_clk_register_gate(NULL
, clks
[i
].name
,
107 base
+ clks
[i
].offset
,
115 pr_err("%s: failed to register clock %s\n",
116 __func__
, clks
[i
].name
);
120 unit
->clk_table
[clks
[i
].id
] = clk
;
124 void mmp_register_mux_clks(struct mmp_clk_unit
*unit
,
125 struct mmp_param_mux_clk
*clks
,
126 void __iomem
*base
, int size
)
131 for (i
= 0; i
< size
; i
++) {
132 clk
= clk_register_mux(NULL
, clks
[i
].name
,
136 base
+ clks
[i
].offset
,
143 pr_err("%s: failed to register clock %s\n",
144 __func__
, clks
[i
].name
);
148 unit
->clk_table
[clks
[i
].id
] = clk
;
152 void mmp_register_div_clks(struct mmp_clk_unit
*unit
,
153 struct mmp_param_div_clk
*clks
,
154 void __iomem
*base
, int size
)
159 for (i
= 0; i
< size
; i
++) {
160 clk
= clk_register_divider(NULL
, clks
[i
].name
,
163 base
+ clks
[i
].offset
,
170 pr_err("%s: failed to register clock %s\n",
171 __func__
, clks
[i
].name
);
175 unit
->clk_table
[clks
[i
].id
] = clk
;
179 void mmp_clk_add(struct mmp_clk_unit
*unit
, unsigned int id
,
182 if (IS_ERR_OR_NULL(clk
)) {
183 pr_err("CLK %d has invalid pointer %p\n", id
, clk
);
186 if (id
>= unit
->nr_clks
) {
187 pr_err("CLK %d is invalid\n", id
);
191 unit
->clk_table
[id
] = clk
;