diff options
author | Tang Yuantian <yuantian.tang@freescale.com> | 2014-01-20 20:32:45 -0500 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-03-19 20:04:14 -0400 |
commit | 00fa6e5d138a87f1b1bc8ae634c5f6fe513338c6 (patch) | |
tree | b4d3fb9d0e444ea484bd76bf2a27cd990157ae97 /drivers/clk | |
parent | 141c71dd2c00ca7d807138ece55a17c61085c793 (diff) |
clk: mpc85xx: Update the driver to align to new clock bindings
The clock bindings for Freescale CoreNet platform are updated.
So, the driver needs to be updated accordingly.
The main changes include:
- Added a new node to present the input system clock
- Changed PLL and MUX's compatible string
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Acked-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/clk-ppc-corenet.c | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index c4f76ed914b0..8b284be4efa4 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c | |||
@@ -27,7 +27,6 @@ struct cmux_clk { | |||
27 | #define CLKSEL_ADJUST BIT(0) | 27 | #define CLKSEL_ADJUST BIT(0) |
28 | #define to_cmux_clk(p) container_of(p, struct cmux_clk, hw) | 28 | #define to_cmux_clk(p) container_of(p, struct cmux_clk, hw) |
29 | 29 | ||
30 | static void __iomem *base; | ||
31 | static unsigned int clocks_per_pll; | 30 | static unsigned int clocks_per_pll; |
32 | 31 | ||
33 | static int cmux_set_parent(struct clk_hw *hw, u8 idx) | 32 | static int cmux_set_parent(struct clk_hw *hw, u8 idx) |
@@ -100,7 +99,11 @@ static void __init core_mux_init(struct device_node *np) | |||
100 | pr_err("%s: could not allocate cmux_clk\n", __func__); | 99 | pr_err("%s: could not allocate cmux_clk\n", __func__); |
101 | goto err_name; | 100 | goto err_name; |
102 | } | 101 | } |
103 | cmux_clk->reg = base + offset; | 102 | cmux_clk->reg = of_iomap(np, 0); |
103 | if (!cmux_clk->reg) { | ||
104 | pr_err("%s: could not map register\n", __func__); | ||
105 | goto err_clk; | ||
106 | } | ||
104 | 107 | ||
105 | node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen"); | 108 | node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen"); |
106 | if (node && (offset >= 0x80)) | 109 | if (node && (offset >= 0x80)) |
@@ -143,38 +146,39 @@ err_name: | |||
143 | 146 | ||
144 | static void __init core_pll_init(struct device_node *np) | 147 | static void __init core_pll_init(struct device_node *np) |
145 | { | 148 | { |
146 | u32 offset, mult; | 149 | u32 mult; |
147 | int i, rc, count; | 150 | int i, rc, count; |
148 | const char *clk_name, *parent_name; | 151 | const char *clk_name, *parent_name; |
149 | struct clk_onecell_data *onecell_data; | 152 | struct clk_onecell_data *onecell_data; |
150 | struct clk **subclks; | 153 | struct clk **subclks; |
154 | void __iomem *base; | ||
151 | 155 | ||
152 | rc = of_property_read_u32(np, "reg", &offset); | 156 | base = of_iomap(np, 0); |
153 | if (rc) { | 157 | if (!base) { |
154 | pr_err("%s: could not get reg property\n", np->name); | 158 | pr_err("clk-ppc: iomap error\n"); |
155 | return; | 159 | return; |
156 | } | 160 | } |
157 | 161 | ||
158 | /* get the multiple of PLL */ | 162 | /* get the multiple of PLL */ |
159 | mult = ioread32be(base + offset); | 163 | mult = ioread32be(base); |
160 | 164 | ||
161 | /* check if this PLL is disabled */ | 165 | /* check if this PLL is disabled */ |
162 | if (mult & PLL_KILL) { | 166 | if (mult & PLL_KILL) { |
163 | pr_debug("PLL:%s is disabled\n", np->name); | 167 | pr_debug("PLL:%s is disabled\n", np->name); |
164 | return; | 168 | goto err_map; |
165 | } | 169 | } |
166 | mult = (mult >> 1) & 0x3f; | 170 | mult = (mult >> 1) & 0x3f; |
167 | 171 | ||
168 | parent_name = of_clk_get_parent_name(np, 0); | 172 | parent_name = of_clk_get_parent_name(np, 0); |
169 | if (!parent_name) { | 173 | if (!parent_name) { |
170 | pr_err("PLL: %s must have a parent\n", np->name); | 174 | pr_err("PLL: %s must have a parent\n", np->name); |
171 | return; | 175 | goto err_map; |
172 | } | 176 | } |
173 | 177 | ||
174 | count = of_property_count_strings(np, "clock-output-names"); | 178 | count = of_property_count_strings(np, "clock-output-names"); |
175 | if (count < 0 || count > 4) { | 179 | if (count < 0 || count > 4) { |
176 | pr_err("%s: clock is not supported\n", np->name); | 180 | pr_err("%s: clock is not supported\n", np->name); |
177 | return; | 181 | goto err_map; |
178 | } | 182 | } |
179 | 183 | ||
180 | /* output clock number per PLL */ | 184 | /* output clock number per PLL */ |
@@ -183,7 +187,7 @@ static void __init core_pll_init(struct device_node *np) | |||
183 | subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL); | 187 | subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL); |
184 | if (!subclks) { | 188 | if (!subclks) { |
185 | pr_err("%s: could not allocate subclks\n", __func__); | 189 | pr_err("%s: could not allocate subclks\n", __func__); |
186 | return; | 190 | goto err_map; |
187 | } | 191 | } |
188 | 192 | ||
189 | onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); | 193 | onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); |
@@ -230,30 +234,52 @@ static void __init core_pll_init(struct device_node *np) | |||
230 | goto err_cell; | 234 | goto err_cell; |
231 | } | 235 | } |
232 | 236 | ||
237 | iounmap(base); | ||
233 | return; | 238 | return; |
234 | err_cell: | 239 | err_cell: |
235 | kfree(onecell_data); | 240 | kfree(onecell_data); |
236 | err_clks: | 241 | err_clks: |
237 | kfree(subclks); | 242 | kfree(subclks); |
243 | err_map: | ||
244 | iounmap(base); | ||
245 | } | ||
246 | |||
247 | static void __init sysclk_init(struct device_node *node) | ||
248 | { | ||
249 | struct clk *clk; | ||
250 | const char *clk_name = node->name; | ||
251 | struct device_node *np = of_get_parent(node); | ||
252 | u32 rate; | ||
253 | |||
254 | if (!np) { | ||
255 | pr_err("ppc-clk: could not get parent node\n"); | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | if (of_property_read_u32(np, "clock-frequency", &rate)) { | ||
260 | of_node_put(node); | ||
261 | return; | ||
262 | } | ||
263 | |||
264 | of_property_read_string(np, "clock-output-names", &clk_name); | ||
265 | |||
266 | clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate); | ||
267 | if (!IS_ERR(clk)) | ||
268 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
238 | } | 269 | } |
239 | 270 | ||
240 | static const struct of_device_id clk_match[] __initconst = { | 271 | static const struct of_device_id clk_match[] __initconst = { |
241 | { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, | 272 | { .compatible = "fsl,qoriq-sysclk-1.0", .data = sysclk_init, }, |
242 | { .compatible = "fsl,core-pll-clock", .data = core_pll_init, }, | 273 | { .compatible = "fsl,qoriq-sysclk-2.0", .data = sysclk_init, }, |
243 | { .compatible = "fsl,core-mux-clock", .data = core_mux_init, }, | 274 | { .compatible = "fsl,qoriq-core-pll-1.0", .data = core_pll_init, }, |
275 | { .compatible = "fsl,qoriq-core-pll-2.0", .data = core_pll_init, }, | ||
276 | { .compatible = "fsl,qoriq-core-mux-1.0", .data = core_mux_init, }, | ||
277 | { .compatible = "fsl,qoriq-core-mux-2.0", .data = core_mux_init, }, | ||
244 | {} | 278 | {} |
245 | }; | 279 | }; |
246 | 280 | ||
247 | static int __init ppc_corenet_clk_probe(struct platform_device *pdev) | 281 | static int __init ppc_corenet_clk_probe(struct platform_device *pdev) |
248 | { | 282 | { |
249 | struct device_node *np; | ||
250 | |||
251 | np = pdev->dev.of_node; | ||
252 | base = of_iomap(np, 0); | ||
253 | if (!base) { | ||
254 | dev_err(&pdev->dev, "iomap error\n"); | ||
255 | return -ENOMEM; | ||
256 | } | ||
257 | of_clk_init(clk_match); | 283 | of_clk_init(clk_match); |
258 | 284 | ||
259 | return 0; | 285 | return 0; |