2 * Copyright (C) 2014 Google, Inc.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
10 #include <linux/clk-provider.h>
11 #include <linux/kernel.h>
13 #include <linux/of_address.h>
14 #include <linux/slab.h>
18 struct pistachio_clk_provider
*
19 pistachio_clk_alloc_provider(struct device_node
*node
, unsigned int num_clks
)
21 struct pistachio_clk_provider
*p
;
23 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
27 p
->clk_data
.clks
= kcalloc(num_clks
, sizeof(struct clk
*), GFP_KERNEL
);
28 if (!p
->clk_data
.clks
)
30 p
->clk_data
.clk_num
= num_clks
;
32 p
->base
= of_iomap(node
, 0);
34 pr_err("Failed to map clock provider registers\n");
41 kfree(p
->clk_data
.clks
);
47 void pistachio_clk_register_provider(struct pistachio_clk_provider
*p
)
51 for (i
= 0; i
< p
->clk_data
.clk_num
; i
++) {
52 if (IS_ERR(p
->clk_data
.clks
[i
]))
53 pr_warn("Failed to register clock %d: %ld\n", i
,
54 PTR_ERR(p
->clk_data
.clks
[i
]));
57 of_clk_add_provider(p
->node
, of_clk_src_onecell_get
, &p
->clk_data
);
60 void pistachio_clk_register_gate(struct pistachio_clk_provider
*p
,
61 struct pistachio_gate
*gate
,
67 for (i
= 0; i
< num
; i
++) {
68 clk
= clk_register_gate(NULL
, gate
[i
].name
, gate
[i
].parent
,
70 p
->base
+ gate
[i
].reg
, gate
[i
].shift
,
72 p
->clk_data
.clks
[gate
[i
].id
] = clk
;
76 void pistachio_clk_register_mux(struct pistachio_clk_provider
*p
,
77 struct pistachio_mux
*mux
,
83 for (i
= 0; i
< num
; i
++) {
84 clk
= clk_register_mux(NULL
, mux
[i
].name
, mux
[i
].parents
,
86 CLK_SET_RATE_NO_REPARENT
,
87 p
->base
+ mux
[i
].reg
, mux
[i
].shift
,
88 get_count_order(mux
[i
].num_parents
),
90 p
->clk_data
.clks
[mux
[i
].id
] = clk
;
94 void pistachio_clk_register_div(struct pistachio_clk_provider
*p
,
95 struct pistachio_div
*div
,
101 for (i
= 0; i
< num
; i
++) {
102 clk
= clk_register_divider(NULL
, div
[i
].name
, div
[i
].parent
,
103 0, p
->base
+ div
[i
].reg
, 0,
104 div
[i
].width
, div
[i
].div_flags
,
106 p
->clk_data
.clks
[div
[i
].id
] = clk
;
110 void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider
*p
,
111 struct pistachio_fixed_factor
*ff
,
117 for (i
= 0; i
< num
; i
++) {
118 clk
= clk_register_fixed_factor(NULL
, ff
[i
].name
, ff
[i
].parent
,
120 p
->clk_data
.clks
[ff
[i
].id
] = clk
;
124 void pistachio_clk_force_enable(struct pistachio_clk_provider
*p
,
125 unsigned int *clk_ids
, unsigned int num
)
130 for (i
= 0; i
< num
; i
++) {
131 struct clk
*clk
= p
->clk_data
.clks
[clk_ids
[i
]];
136 err
= clk_prepare_enable(clk
);
138 pr_err("Failed to enable clock %s: %d\n",
139 __clk_get_name(clk
), err
);