diff options
author | Mike Turquette <mturquette@linaro.org> | 2014-03-19 15:54:03 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-03-19 15:54:03 -0400 |
commit | 78761147987b2750b6a848c9719967df0c5eff73 (patch) | |
tree | 7abe3a7808c5708d8b46177f465a7b9d5097f90d /drivers/clk/hisilicon | |
parent | 9ce71ca10fb8aeb900aeb319dde05750467554bf (diff) | |
parent | 75af25f581b1ffc63e06cb01547b3141d4cd5f58 (diff) |
Merge tag 'clk-hisi' of https://git.kernel.org/pub/scm/linux/kernel/git/hzhuang1/linux into clk-next-hisilcon
updating clock drivers for Hisilicon
Diffstat (limited to 'drivers/clk/hisilicon')
-rw-r--r-- | drivers/clk/hisilicon/Makefile | 5 | ||||
-rw-r--r-- | drivers/clk/hisilicon/clk-hi3620.c | 25 | ||||
-rw-r--r-- | drivers/clk/hisilicon/clk-hip04.c | 58 | ||||
-rw-r--r-- | drivers/clk/hisilicon/clk.c | 62 | ||||
-rw-r--r-- | drivers/clk/hisilicon/clk.h | 17 |
5 files changed, 128 insertions, 39 deletions
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile index a049108341fc..40b33c6a8257 100644 --- a/drivers/clk/hisilicon/Makefile +++ b/drivers/clk/hisilicon/Makefile | |||
@@ -2,4 +2,7 @@ | |||
2 | # Hisilicon Clock specific Makefile | 2 | # Hisilicon Clock specific Makefile |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += clk.o clkgate-separated.o clk-hi3620.o | 5 | obj-y += clk.o clkgate-separated.o |
6 | |||
7 | obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o | ||
8 | obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o | ||
diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 38faa469d288..233eba22187a 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c | |||
@@ -210,34 +210,25 @@ static struct hisi_gate_clock hi3620_seperated_gate_clks[] __initdata = { | |||
210 | 210 | ||
211 | static void __init hi3620_clk_init(struct device_node *np) | 211 | static void __init hi3620_clk_init(struct device_node *np) |
212 | { | 212 | { |
213 | void __iomem *base; | 213 | struct hisi_clock_data *clk_data; |
214 | 214 | ||
215 | if (np) { | 215 | clk_data = hisi_clk_init(np, HI3620_NR_CLKS); |
216 | base = of_iomap(np, 0); | 216 | if (!clk_data) |
217 | if (!base) { | ||
218 | pr_err("failed to map Hi3620 clock registers\n"); | ||
219 | return; | ||
220 | } | ||
221 | } else { | ||
222 | pr_err("failed to find Hi3620 clock node in DTS\n"); | ||
223 | return; | 217 | return; |
224 | } | ||
225 | |||
226 | hisi_clk_init(np, HI3620_NR_CLKS); | ||
227 | 218 | ||
228 | hisi_clk_register_fixed_rate(hi3620_fixed_rate_clks, | 219 | hisi_clk_register_fixed_rate(hi3620_fixed_rate_clks, |
229 | ARRAY_SIZE(hi3620_fixed_rate_clks), | 220 | ARRAY_SIZE(hi3620_fixed_rate_clks), |
230 | base); | 221 | clk_data); |
231 | hisi_clk_register_fixed_factor(hi3620_fixed_factor_clks, | 222 | hisi_clk_register_fixed_factor(hi3620_fixed_factor_clks, |
232 | ARRAY_SIZE(hi3620_fixed_factor_clks), | 223 | ARRAY_SIZE(hi3620_fixed_factor_clks), |
233 | base); | 224 | clk_data); |
234 | hisi_clk_register_mux(hi3620_mux_clks, ARRAY_SIZE(hi3620_mux_clks), | 225 | hisi_clk_register_mux(hi3620_mux_clks, ARRAY_SIZE(hi3620_mux_clks), |
235 | base); | 226 | clk_data); |
236 | hisi_clk_register_divider(hi3620_div_clks, ARRAY_SIZE(hi3620_div_clks), | 227 | hisi_clk_register_divider(hi3620_div_clks, ARRAY_SIZE(hi3620_div_clks), |
237 | base); | 228 | clk_data); |
238 | hisi_clk_register_gate_sep(hi3620_seperated_gate_clks, | 229 | hisi_clk_register_gate_sep(hi3620_seperated_gate_clks, |
239 | ARRAY_SIZE(hi3620_seperated_gate_clks), | 230 | ARRAY_SIZE(hi3620_seperated_gate_clks), |
240 | base); | 231 | clk_data); |
241 | } | 232 | } |
242 | CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init); | 233 | CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init); |
243 | 234 | ||
diff --git a/drivers/clk/hisilicon/clk-hip04.c b/drivers/clk/hisilicon/clk-hip04.c new file mode 100644 index 000000000000..132b57a0ce09 --- /dev/null +++ b/drivers/clk/hisilicon/clk-hip04.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Hisilicon HiP04 clock driver | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Hisilicon Limited. | ||
5 | * Copyright (c) 2013-2014 Linaro Limited. | ||
6 | * | ||
7 | * Author: Haojian Zhuang <haojian.zhuang@linaro.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/clk-provider.h> | ||
27 | #include <linux/clkdev.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/of.h> | ||
30 | #include <linux/of_address.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/clk.h> | ||
34 | |||
35 | #include <dt-bindings/clock/hip04-clock.h> | ||
36 | |||
37 | #include "clk.h" | ||
38 | |||
39 | /* fixed rate clocks */ | ||
40 | static struct hisi_fixed_rate_clock hip04_fixed_rate_clks[] __initdata = { | ||
41 | { HIP04_OSC50M, "osc50m", NULL, CLK_IS_ROOT, 50000000, }, | ||
42 | { HIP04_CLK_50M, "clk50m", NULL, CLK_IS_ROOT, 50000000, }, | ||
43 | { HIP04_CLK_168M, "clk168m", NULL, CLK_IS_ROOT, 168750000, }, | ||
44 | }; | ||
45 | |||
46 | static void __init hip04_clk_init(struct device_node *np) | ||
47 | { | ||
48 | struct hisi_clock_data *clk_data; | ||
49 | |||
50 | clk_data = hisi_clk_init(np, HIP04_NR_CLKS); | ||
51 | if (!clk_data) | ||
52 | return; | ||
53 | |||
54 | hisi_clk_register_fixed_rate(hip04_fixed_rate_clks, | ||
55 | ARRAY_SIZE(hip04_fixed_rate_clks), | ||
56 | clk_data); | ||
57 | } | ||
58 | CLK_OF_DECLARE(hip04_clk, "hisilicon,hip04-clock", hip04_clk_init); | ||
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index a3a7152c92d9..276f672e7b1a 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c | |||
@@ -37,23 +37,49 @@ | |||
37 | #include "clk.h" | 37 | #include "clk.h" |
38 | 38 | ||
39 | static DEFINE_SPINLOCK(hisi_clk_lock); | 39 | static DEFINE_SPINLOCK(hisi_clk_lock); |
40 | static struct clk **clk_table; | ||
41 | static struct clk_onecell_data clk_data; | ||
42 | 40 | ||
43 | void __init hisi_clk_init(struct device_node *np, int nr_clks) | 41 | struct hisi_clock_data __init *hisi_clk_init(struct device_node *np, |
42 | int nr_clks) | ||
44 | { | 43 | { |
44 | struct hisi_clock_data *clk_data; | ||
45 | struct clk **clk_table; | ||
46 | void __iomem *base; | ||
47 | |||
48 | if (np) { | ||
49 | base = of_iomap(np, 0); | ||
50 | if (!base) { | ||
51 | pr_err("failed to map Hisilicon clock registers\n"); | ||
52 | goto err; | ||
53 | } | ||
54 | } else { | ||
55 | pr_err("failed to find Hisilicon clock node in DTS\n"); | ||
56 | goto err; | ||
57 | } | ||
58 | |||
59 | clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); | ||
60 | if (!clk_data) { | ||
61 | pr_err("%s: could not allocate clock data\n", __func__); | ||
62 | goto err; | ||
63 | } | ||
64 | clk_data->base = base; | ||
65 | |||
45 | clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); | 66 | clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); |
46 | if (!clk_table) { | 67 | if (!clk_table) { |
47 | pr_err("%s: could not allocate clock lookup table\n", __func__); | 68 | pr_err("%s: could not allocate clock lookup table\n", __func__); |
48 | return; | 69 | goto err_data; |
49 | } | 70 | } |
50 | clk_data.clks = clk_table; | 71 | clk_data->clk_data.clks = clk_table; |
51 | clk_data.clk_num = nr_clks; | 72 | clk_data->clk_data.clk_num = nr_clks; |
52 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 73 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data); |
74 | return clk_data; | ||
75 | err_data: | ||
76 | kfree(clk_data); | ||
77 | err: | ||
78 | return NULL; | ||
53 | } | 79 | } |
54 | 80 | ||
55 | void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, | 81 | void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, |
56 | int nums, void __iomem *base) | 82 | int nums, struct hisi_clock_data *data) |
57 | { | 83 | { |
58 | struct clk *clk; | 84 | struct clk *clk; |
59 | int i; | 85 | int i; |
@@ -68,11 +94,13 @@ void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, | |||
68 | __func__, clks[i].name); | 94 | __func__, clks[i].name); |
69 | continue; | 95 | continue; |
70 | } | 96 | } |
97 | data->clk_data.clks[clks[i].id] = clk; | ||
71 | } | 98 | } |
72 | } | 99 | } |
73 | 100 | ||
74 | void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, | 101 | void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, |
75 | int nums, void __iomem *base) | 102 | int nums, |
103 | struct hisi_clock_data *data) | ||
76 | { | 104 | { |
77 | struct clk *clk; | 105 | struct clk *clk; |
78 | int i; | 106 | int i; |
@@ -87,13 +115,15 @@ void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, | |||
87 | __func__, clks[i].name); | 115 | __func__, clks[i].name); |
88 | continue; | 116 | continue; |
89 | } | 117 | } |
118 | data->clk_data.clks[clks[i].id] = clk; | ||
90 | } | 119 | } |
91 | } | 120 | } |
92 | 121 | ||
93 | void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, | 122 | void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, |
94 | int nums, void __iomem *base) | 123 | int nums, struct hisi_clock_data *data) |
95 | { | 124 | { |
96 | struct clk *clk; | 125 | struct clk *clk; |
126 | void __iomem *base = data->base; | ||
97 | int i; | 127 | int i; |
98 | 128 | ||
99 | for (i = 0; i < nums; i++) { | 129 | for (i = 0; i < nums; i++) { |
@@ -111,14 +141,15 @@ void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, | |||
111 | if (clks[i].alias) | 141 | if (clks[i].alias) |
112 | clk_register_clkdev(clk, clks[i].alias, NULL); | 142 | clk_register_clkdev(clk, clks[i].alias, NULL); |
113 | 143 | ||
114 | clk_table[clks[i].id] = clk; | 144 | data->clk_data.clks[clks[i].id] = clk; |
115 | } | 145 | } |
116 | } | 146 | } |
117 | 147 | ||
118 | void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, | 148 | void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, |
119 | int nums, void __iomem *base) | 149 | int nums, struct hisi_clock_data *data) |
120 | { | 150 | { |
121 | struct clk *clk; | 151 | struct clk *clk; |
152 | void __iomem *base = data->base; | ||
122 | int i; | 153 | int i; |
123 | 154 | ||
124 | for (i = 0; i < nums; i++) { | 155 | for (i = 0; i < nums; i++) { |
@@ -139,14 +170,15 @@ void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, | |||
139 | if (clks[i].alias) | 170 | if (clks[i].alias) |
140 | clk_register_clkdev(clk, clks[i].alias, NULL); | 171 | clk_register_clkdev(clk, clks[i].alias, NULL); |
141 | 172 | ||
142 | clk_table[clks[i].id] = clk; | 173 | data->clk_data.clks[clks[i].id] = clk; |
143 | } | 174 | } |
144 | } | 175 | } |
145 | 176 | ||
146 | void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, | 177 | void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, |
147 | int nums, void __iomem *base) | 178 | int nums, struct hisi_clock_data *data) |
148 | { | 179 | { |
149 | struct clk *clk; | 180 | struct clk *clk; |
181 | void __iomem *base = data->base; | ||
150 | int i; | 182 | int i; |
151 | 183 | ||
152 | for (i = 0; i < nums; i++) { | 184 | for (i = 0; i < nums; i++) { |
@@ -166,6 +198,6 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, | |||
166 | if (clks[i].alias) | 198 | if (clks[i].alias) |
167 | clk_register_clkdev(clk, clks[i].alias, NULL); | 199 | clk_register_clkdev(clk, clks[i].alias, NULL); |
168 | 200 | ||
169 | clk_table[clks[i].id] = clk; | 201 | data->clk_data.clks[clks[i].id] = clk; |
170 | } | 202 | } |
171 | } | 203 | } |
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h index 4a6beebefb7a..43fa5da88f02 100644 --- a/drivers/clk/hisilicon/clk.h +++ b/drivers/clk/hisilicon/clk.h | |||
@@ -30,6 +30,11 @@ | |||
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | 32 | ||
33 | struct hisi_clock_data { | ||
34 | struct clk_onecell_data clk_data; | ||
35 | void __iomem *base; | ||
36 | }; | ||
37 | |||
33 | struct hisi_fixed_rate_clock { | 38 | struct hisi_fixed_rate_clock { |
34 | unsigned int id; | 39 | unsigned int id; |
35 | char *name; | 40 | char *name; |
@@ -89,15 +94,15 @@ struct clk *hisi_register_clkgate_sep(struct device *, const char *, | |||
89 | void __iomem *, u8, | 94 | void __iomem *, u8, |
90 | u8, spinlock_t *); | 95 | u8, spinlock_t *); |
91 | 96 | ||
92 | void __init hisi_clk_init(struct device_node *, int); | 97 | struct hisi_clock_data __init *hisi_clk_init(struct device_node *, int); |
93 | void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, | 98 | void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, |
94 | int, void __iomem *); | 99 | int, struct hisi_clock_data *); |
95 | void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, | 100 | void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, |
96 | int, void __iomem *); | 101 | int, struct hisi_clock_data *); |
97 | void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, | 102 | void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, |
98 | void __iomem *); | 103 | struct hisi_clock_data *); |
99 | void __init hisi_clk_register_divider(struct hisi_divider_clock *, | 104 | void __init hisi_clk_register_divider(struct hisi_divider_clock *, |
100 | int, void __iomem *); | 105 | int, struct hisi_clock_data *); |
101 | void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *, | 106 | void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *, |
102 | int, void __iomem *); | 107 | int, struct hisi_clock_data *); |
103 | #endif /* __HISI_CLK_H */ | 108 | #endif /* __HISI_CLK_H */ |