1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014 Google, Inc.
7 #include <linux/clk-provider.h>
8 #include <linux/kernel.h>
10 #include <linux/of_address.h>
11 #include <linux/slab.h>
15 struct pistachio_clk_provider
*
16 pistachio_clk_alloc_provider(struct device_node
*node
, unsigned int num_clks
)
18 struct pistachio_clk_provider
*p
;
20 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
24 p
->clk_data
.clks
= kcalloc(num_clks
, sizeof(struct clk
*), GFP_KERNEL
);
25 if (!p
->clk_data
.clks
)
27 p
->clk_data
.clk_num
= num_clks
;
29 p
->base
= of_iomap(node
, 0);
31 pr_err("Failed to map clock provider registers\n");
38 kfree(p
->clk_data
.clks
);
44 void pistachio_clk_register_provider(struct pistachio_clk_provider
*p
)
48 for (i
= 0; i
< p
->clk_data
.clk_num
; i
++) {
49 if (IS_ERR(p
->clk_data
.clks
[i
]))
50 pr_warn("Failed to register clock %d: %ld\n", i
,
51 PTR_ERR(p
->clk_data
.clks
[i
]));
54 of_clk_add_provider(p
->node
, of_clk_src_onecell_get
, &p
->clk_data
);
57 void pistachio_clk_register_gate(struct pistachio_clk_provider
*p
,
58 struct pistachio_gate
*gate
,
64 for (i
= 0; i
< num
; i
++) {
65 clk
= clk_register_gate(NULL
, gate
[i
].name
, gate
[i
].parent
,
67 p
->base
+ gate
[i
].reg
, gate
[i
].shift
,
69 p
->clk_data
.clks
[gate
[i
].id
] = clk
;
73 void pistachio_clk_register_mux(struct pistachio_clk_provider
*p
,
74 struct pistachio_mux
*mux
,
80 for (i
= 0; i
< num
; i
++) {
81 clk
= clk_register_mux(NULL
, mux
[i
].name
, mux
[i
].parents
,
83 CLK_SET_RATE_NO_REPARENT
,
84 p
->base
+ mux
[i
].reg
, mux
[i
].shift
,
85 get_count_order(mux
[i
].num_parents
),
87 p
->clk_data
.clks
[mux
[i
].id
] = clk
;
91 void pistachio_clk_register_div(struct pistachio_clk_provider
*p
,
92 struct pistachio_div
*div
,
98 for (i
= 0; i
< num
; i
++) {
99 clk
= clk_register_divider(NULL
, div
[i
].name
, div
[i
].parent
,
100 0, p
->base
+ div
[i
].reg
, 0,
101 div
[i
].width
, div
[i
].div_flags
,
103 p
->clk_data
.clks
[div
[i
].id
] = clk
;
107 void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider
*p
,
108 struct pistachio_fixed_factor
*ff
,
114 for (i
= 0; i
< num
; i
++) {
115 clk
= clk_register_fixed_factor(NULL
, ff
[i
].name
, ff
[i
].parent
,
117 p
->clk_data
.clks
[ff
[i
].id
] = clk
;
121 void pistachio_clk_force_enable(struct pistachio_clk_provider
*p
,
122 unsigned int *clk_ids
, unsigned int num
)
127 for (i
= 0; i
< num
; i
++) {
128 struct clk
*clk
= p
->clk_data
.clks
[clk_ids
[i
]];
133 err
= clk_prepare_enable(clk
);
135 pr_err("Failed to enable clock %s: %d\n",
136 __clk_get_name(clk
), err
);