aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/hisilicon
diff options
context:
space:
mode:
authorMike Turquette <mturquette@linaro.org>2014-03-19 15:54:03 -0400
committerMike Turquette <mturquette@linaro.org>2014-03-19 15:54:03 -0400
commit78761147987b2750b6a848c9719967df0c5eff73 (patch)
tree7abe3a7808c5708d8b46177f465a7b9d5097f90d /drivers/clk/hisilicon
parent9ce71ca10fb8aeb900aeb319dde05750467554bf (diff)
parent75af25f581b1ffc63e06cb01547b3141d4cd5f58 (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/Makefile5
-rw-r--r--drivers/clk/hisilicon/clk-hi3620.c25
-rw-r--r--drivers/clk/hisilicon/clk-hip04.c58
-rw-r--r--drivers/clk/hisilicon/clk.c62
-rw-r--r--drivers/clk/hisilicon/clk.h17
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
5obj-y += clk.o clkgate-separated.o clk-hi3620.o 5obj-y += clk.o clkgate-separated.o
6
7obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o
8obj-$(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
211static void __init hi3620_clk_init(struct device_node *np) 211static 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}
242CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init); 233CLK_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 */
40static 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
46static 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}
58CLK_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
39static DEFINE_SPINLOCK(hisi_clk_lock); 39static DEFINE_SPINLOCK(hisi_clk_lock);
40static struct clk **clk_table;
41static struct clk_onecell_data clk_data;
42 40
43void __init hisi_clk_init(struct device_node *np, int nr_clks) 41struct 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;
75err_data:
76 kfree(clk_data);
77err:
78 return NULL;
53} 79}
54 80
55void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, 81void __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
74void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, 101void __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
93void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, 122void __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
118void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, 148void __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
146void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, 177void __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
33struct hisi_clock_data {
34 struct clk_onecell_data clk_data;
35 void __iomem *base;
36};
37
33struct hisi_fixed_rate_clock { 38struct 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
92void __init hisi_clk_init(struct device_node *, int); 97struct hisi_clock_data __init *hisi_clk_init(struct device_node *, int);
93void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, 98void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *,
94 int, void __iomem *); 99 int, struct hisi_clock_data *);
95void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, 100void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *,
96 int, void __iomem *); 101 int, struct hisi_clock_data *);
97void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, 102void __init hisi_clk_register_mux(struct hisi_mux_clock *, int,
98 void __iomem *); 103 struct hisi_clock_data *);
99void __init hisi_clk_register_divider(struct hisi_divider_clock *, 104void __init hisi_clk_register_divider(struct hisi_divider_clock *,
100 int, void __iomem *); 105 int, struct hisi_clock_data *);
101void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *, 106void __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 */