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.
9 #include <linux/clk-provider.h>
10 #include <linux/kernel.h>
12 #include <linux/of_address.h>
13 #include <linux/slab.h>
17 struct pistachio_clk_provider
*
18 pistachio_clk_alloc_provider(struct device_node
*node
, unsigned int num_clks
)
20 struct pistachio_clk_provider
*p
;
22 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
26 p
->clk_data
.clks
= kcalloc(num_clks
, sizeof(struct clk
*), GFP_KERNEL
);
27 if (!p
->clk_data
.clks
)
29 p
->clk_data
.clk_num
= num_clks
;
31 p
->base
= of_iomap(node
, 0);
33 pr_err("Failed to map clock provider registers\n");
40 kfree(p
->clk_data
.clks
);
46 void pistachio_clk_register_provider(struct pistachio_clk_provider
*p
)
50 for (i
= 0; i
< p
->clk_data
.clk_num
; i
++) {
51 if (IS_ERR(p
->clk_data
.clks
[i
]))
52 pr_warn("Failed to register clock %d: %ld\n", i
,
53 PTR_ERR(p
->clk_data
.clks
[i
]));
56 of_clk_add_provider(p
->node
, of_clk_src_onecell_get
, &p
->clk_data
);
59 void pistachio_clk_register_gate(struct pistachio_clk_provider
*p
,
60 struct pistachio_gate
*gate
,
66 for (i
= 0; i
< num
; i
++) {
67 clk
= clk_register_gate(NULL
, gate
[i
].name
, gate
[i
].parent
,
69 p
->base
+ gate
[i
].reg
, gate
[i
].shift
,
71 p
->clk_data
.clks
[gate
[i
].id
] = clk
;
75 void pistachio_clk_register_mux(struct pistachio_clk_provider
*p
,
76 struct pistachio_mux
*mux
,
82 for (i
= 0; i
< num
; i
++) {
83 clk
= clk_register_mux(NULL
, mux
[i
].name
, mux
[i
].parents
,
85 CLK_SET_RATE_NO_REPARENT
,
86 p
->base
+ mux
[i
].reg
, mux
[i
].shift
,
87 get_count_order(mux
[i
].num_parents
),
89 p
->clk_data
.clks
[mux
[i
].id
] = clk
;
93 void pistachio_clk_register_div(struct pistachio_clk_provider
*p
,
94 struct pistachio_div
*div
,
100 for (i
= 0; i
< num
; i
++) {
101 clk
= clk_register_divider(NULL
, div
[i
].name
, div
[i
].parent
,
102 0, p
->base
+ div
[i
].reg
, 0,
103 div
[i
].width
, div
[i
].div_flags
,
105 p
->clk_data
.clks
[div
[i
].id
] = clk
;
109 void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider
*p
,
110 struct pistachio_fixed_factor
*ff
,
116 for (i
= 0; i
< num
; i
++) {
117 clk
= clk_register_fixed_factor(NULL
, ff
[i
].name
, ff
[i
].parent
,
119 p
->clk_data
.clks
[ff
[i
].id
] = clk
;
123 void pistachio_clk_force_enable(struct pistachio_clk_provider
*p
,
124 unsigned int *clk_ids
, unsigned int num
)
129 for (i
= 0; i
< num
; i
++) {
130 struct clk
*clk
= p
->clk_data
.clks
[clk_ids
[i
]];
135 err
= clk_prepare_enable(clk
);
137 pr_err("Failed to enable clock %s: %d\n",
138 __clk_get_name(clk
), err
);