2 * Hisilicon clock driver
4 * Copyright (c) 2012-2013 Hisilicon Limited.
5 * Copyright (c) 2012-2013 Linaro Limited.
7 * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
8 * Xin Li <li.xin@linaro.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <linux/kernel.h>
27 #include <linux/clk-provider.h>
28 #include <linux/clkdev.h>
29 #include <linux/delay.h>
32 #include <linux/of_address.h>
33 #include <linux/of_device.h>
34 #include <linux/slab.h>
35 #include <linux/clk.h>
39 static DEFINE_SPINLOCK(hisi_clk_lock
);
40 static struct clk
**clk_table
;
41 static struct clk_onecell_data clk_data
;
43 void __init
hisi_clk_init(struct device_node
*np
, int nr_clks
)
45 clk_table
= kzalloc(sizeof(struct clk
*) * nr_clks
, GFP_KERNEL
);
47 pr_err("%s: could not allocate clock lookup table\n", __func__
);
50 clk_data
.clks
= clk_table
;
51 clk_data
.clk_num
= nr_clks
;
52 of_clk_add_provider(np
, of_clk_src_onecell_get
, &clk_data
);
55 void __init
hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock
*clks
,
56 int nums
, void __iomem
*base
)
61 for (i
= 0; i
< nums
; i
++) {
62 clk
= clk_register_fixed_rate(NULL
, clks
[i
].name
,
67 pr_err("%s: failed to register clock %s\n",
68 __func__
, clks
[i
].name
);
74 void __init
hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock
*clks
,
75 int nums
, void __iomem
*base
)
80 for (i
= 0; i
< nums
; i
++) {
81 clk
= clk_register_fixed_factor(NULL
, clks
[i
].name
,
83 clks
[i
].flags
, clks
[i
].mult
,
86 pr_err("%s: failed to register clock %s\n",
87 __func__
, clks
[i
].name
);
93 void __init
hisi_clk_register_mux(struct hisi_mux_clock
*clks
,
94 int nums
, void __iomem
*base
)
99 for (i
= 0; i
< nums
; i
++) {
100 clk
= clk_register_mux(NULL
, clks
[i
].name
, clks
[i
].parent_names
,
101 clks
[i
].num_parents
, clks
[i
].flags
,
102 base
+ clks
[i
].offset
, clks
[i
].shift
,
103 clks
[i
].width
, clks
[i
].mux_flags
,
106 pr_err("%s: failed to register clock %s\n",
107 __func__
, clks
[i
].name
);
112 clk_register_clkdev(clk
, clks
[i
].alias
, NULL
);
114 clk_table
[clks
[i
].id
] = clk
;
118 void __init
hisi_clk_register_divider(struct hisi_divider_clock
*clks
,
119 int nums
, void __iomem
*base
)
124 for (i
= 0; i
< nums
; i
++) {
125 clk
= clk_register_divider_table(NULL
, clks
[i
].name
,
128 base
+ clks
[i
].offset
,
129 clks
[i
].shift
, clks
[i
].width
,
134 pr_err("%s: failed to register clock %s\n",
135 __func__
, clks
[i
].name
);
140 clk_register_clkdev(clk
, clks
[i
].alias
, NULL
);
142 clk_table
[clks
[i
].id
] = clk
;
146 void __init
hisi_clk_register_gate_sep(struct hisi_gate_clock
*clks
,
147 int nums
, void __iomem
*base
)
152 for (i
= 0; i
< nums
; i
++) {
153 clk
= hisi_register_clkgate_sep(NULL
, clks
[i
].name
,
156 base
+ clks
[i
].offset
,
161 pr_err("%s: failed to register clock %s\n",
162 __func__
, clks
[i
].name
);
167 clk_register_clkdev(clk
, clks
[i
].alias
, NULL
);
169 clk_table
[clks
[i
].id
] = clk
;