diff options
author | James Hogan <james.hogan@imgtec.com> | 2013-07-29 07:25:01 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2013-08-19 15:27:17 -0400 |
commit | 819c1de344c5b8350bffd35be9a0fa74541292d3 (patch) | |
tree | a7829ac81de6d968cc24516f17c87da98c528d06 /drivers/clk/zynq | |
parent | 71472c0c06cf9a3d1540762ea205654c584e3bc4 (diff) |
clk: add CLK_SET_RATE_NO_REPARENT flag
Add a CLK_SET_RATE_NO_REPARENT clock flag, which will prevent muxes
being reparented during clk_set_rate.
To avoid breaking existing platforms, all callers of clk_register_mux()
are adjusted to pass the new flag. Platform maintainers are encouraged
to remove the flag if they wish to allow mux reparenting on set_rate.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Haojian Zhuang <haojian.zhuang@linaro.org>
Cc: Chao Xie <xiechao.mail@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: "Emilio López" <emilio@elopez.com.ar>
Cc: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Andrew Chew <achew@nvidia.com>
Cc: Doug Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Paul Walmsley <pwalmsley@nvidia.com>
Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
Cc: Thomas Abraham <thomas.abraham@linaro.org>
Cc: Tomasz Figa <t.figa@samsung.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: spear-devel@list.st.com
Cc: linux-tegra@vger.kernel.org
Tested-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Acked-by: Stephen Warren <swarren@nvidia.com> [tegra]
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> [sunxi]
Acked-by: Sören Brinkmann <soren.brinkmann@xilinx.com> [Zynq]
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/zynq')
-rw-r--r-- | drivers/clk/zynq/clkc.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 5c205b60a82a..e05c9e3f1385 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c | |||
@@ -124,8 +124,9 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, | |||
124 | div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); | 124 | div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); |
125 | div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); | 125 | div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); |
126 | 126 | ||
127 | clk = clk_register_mux(NULL, mux_name, parents, 4, 0, | 127 | clk = clk_register_mux(NULL, mux_name, parents, 4, |
128 | fclk_ctrl_reg, 4, 2, 0, fclk_lock); | 128 | CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0, |
129 | fclk_lock); | ||
129 | 130 | ||
130 | clk = clk_register_divider(NULL, div0_name, mux_name, | 131 | clk = clk_register_divider(NULL, div0_name, mux_name, |
131 | 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED | | 132 | 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED | |
@@ -167,8 +168,8 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, | |||
167 | mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0); | 168 | mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0); |
168 | div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0); | 169 | div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0); |
169 | 170 | ||
170 | clk = clk_register_mux(NULL, mux_name, parents, 4, 0, | 171 | clk = clk_register_mux(NULL, mux_name, parents, 4, |
171 | clk_ctrl, 4, 2, 0, lock); | 172 | CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock); |
172 | 173 | ||
173 | clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6, | 174 | clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6, |
174 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock); | 175 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock); |
@@ -235,25 +236,26 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
235 | clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, | 236 | clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, |
236 | SLCR_PLL_STATUS, 0, &armpll_lock); | 237 | SLCR_PLL_STATUS, 0, &armpll_lock); |
237 | clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll], | 238 | clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll], |
238 | armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0, | 239 | armpll_parents, 2, CLK_SET_RATE_NO_REPARENT, |
239 | &armpll_lock); | 240 | SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock); |
240 | 241 | ||
241 | clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL, | 242 | clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL, |
242 | SLCR_PLL_STATUS, 1, &ddrpll_lock); | 243 | SLCR_PLL_STATUS, 1, &ddrpll_lock); |
243 | clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll], | 244 | clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll], |
244 | ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0, | 245 | ddrpll_parents, 2, CLK_SET_RATE_NO_REPARENT, |
245 | &ddrpll_lock); | 246 | SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock); |
246 | 247 | ||
247 | clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL, | 248 | clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL, |
248 | SLCR_PLL_STATUS, 2, &iopll_lock); | 249 | SLCR_PLL_STATUS, 2, &iopll_lock); |
249 | clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll], | 250 | clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll], |
250 | iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0, | 251 | iopll_parents, 2, CLK_SET_RATE_NO_REPARENT, |
251 | &iopll_lock); | 252 | SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock); |
252 | 253 | ||
253 | /* CPU clocks */ | 254 | /* CPU clocks */ |
254 | tmp = readl(SLCR_621_TRUE) & 1; | 255 | tmp = readl(SLCR_621_TRUE) & 1; |
255 | clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0, | 256 | clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, |
256 | SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock); | 257 | CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0, |
258 | &armclk_lock); | ||
257 | clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0, | 259 | clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0, |
258 | SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | | 260 | SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | |
259 | CLK_DIVIDER_ALLOW_ZERO, &armclk_lock); | 261 | CLK_DIVIDER_ALLOW_ZERO, &armclk_lock); |
@@ -292,8 +294,9 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
292 | swdt_ext_clk_mux_parents[i + 1] = dummy_nm; | 294 | swdt_ext_clk_mux_parents[i + 1] = dummy_nm; |
293 | } | 295 | } |
294 | clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], | 296 | clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], |
295 | swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT, | 297 | swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT | |
296 | SLCR_SWDT_CLK_SEL, 0, 1, 0, &gem0clk_lock); | 298 | CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0, |
299 | &gem0clk_lock); | ||
297 | 300 | ||
298 | /* DDR clocks */ | 301 | /* DDR clocks */ |
299 | clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, | 302 | clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, |
@@ -355,8 +358,9 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
355 | gem0_mux_parents[i + 1] = of_clk_get_parent_name(np, | 358 | gem0_mux_parents[i + 1] = of_clk_get_parent_name(np, |
356 | idx); | 359 | idx); |
357 | } | 360 | } |
358 | clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0, | 361 | clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, |
359 | SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock); | 362 | CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 4, 2, 0, |
363 | &gem0clk_lock); | ||
360 | clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0, | 364 | clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0, |
361 | SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | | 365 | SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | |
362 | CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); | 366 | CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); |
@@ -364,8 +368,9 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
364 | CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6, | 368 | CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6, |
365 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, | 369 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, |
366 | &gem0clk_lock); | 370 | &gem0clk_lock); |
367 | clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, 0, | 371 | clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, |
368 | SLCR_GEM0_CLK_CTRL, 6, 1, 0, &gem0clk_lock); | 372 | CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0, |
373 | &gem0clk_lock); | ||
369 | clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], | 374 | clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], |
370 | "gem0_emio_mux", CLK_SET_RATE_PARENT, | 375 | "gem0_emio_mux", CLK_SET_RATE_PARENT, |
371 | SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock); | 376 | SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock); |
@@ -377,8 +382,9 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
377 | gem1_mux_parents[i + 1] = of_clk_get_parent_name(np, | 382 | gem1_mux_parents[i + 1] = of_clk_get_parent_name(np, |
378 | idx); | 383 | idx); |
379 | } | 384 | } |
380 | clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0, | 385 | clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, |
381 | SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock); | 386 | CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 4, 2, 0, |
387 | &gem1clk_lock); | ||
382 | clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0, | 388 | clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0, |
383 | SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | | 389 | SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | |
384 | CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); | 390 | CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); |
@@ -386,8 +392,9 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
386 | CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6, | 392 | CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6, |
387 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, | 393 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, |
388 | &gem1clk_lock); | 394 | &gem1clk_lock); |
389 | clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, 0, | 395 | clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, |
390 | SLCR_GEM1_CLK_CTRL, 6, 1, 0, &gem1clk_lock); | 396 | CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0, |
397 | &gem1clk_lock); | ||
391 | clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], | 398 | clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], |
392 | "gem1_emio_mux", CLK_SET_RATE_PARENT, | 399 | "gem1_emio_mux", CLK_SET_RATE_PARENT, |
393 | SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); | 400 | SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); |
@@ -406,8 +413,9 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
406 | can_mio_mux_parents[i] = dummy_nm; | 413 | can_mio_mux_parents[i] = dummy_nm; |
407 | } | 414 | } |
408 | kfree(clk_name); | 415 | kfree(clk_name); |
409 | clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0, | 416 | clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, |
410 | SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock); | 417 | CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0, |
418 | &canclk_lock); | ||
411 | clk = clk_register_divider(NULL, "can_div0", "can_mux", 0, | 419 | clk = clk_register_divider(NULL, "can_div0", "can_mux", 0, |
412 | SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | | 420 | SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | |
413 | CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); | 421 | CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); |
@@ -422,17 +430,21 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
422 | CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0, | 430 | CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0, |
423 | &canclk_lock); | 431 | &canclk_lock); |
424 | clk = clk_register_mux(NULL, "can0_mio_mux", | 432 | clk = clk_register_mux(NULL, "can0_mio_mux", |
425 | can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, | 433 | can_mio_mux_parents, 54, CLK_SET_RATE_PARENT | |
426 | SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock); | 434 | CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, |
435 | &canmioclk_lock); | ||
427 | clk = clk_register_mux(NULL, "can1_mio_mux", | 436 | clk = clk_register_mux(NULL, "can1_mio_mux", |
428 | can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, | 437 | can_mio_mux_parents, 54, CLK_SET_RATE_PARENT | |
429 | SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock); | 438 | CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6, |
439 | 0, &canmioclk_lock); | ||
430 | clks[can0] = clk_register_mux(NULL, clk_output_name[can0], | 440 | clks[can0] = clk_register_mux(NULL, clk_output_name[can0], |
431 | can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, | 441 | can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT | |
432 | SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock); | 442 | CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, |
443 | &canmioclk_lock); | ||
433 | clks[can1] = clk_register_mux(NULL, clk_output_name[can1], | 444 | clks[can1] = clk_register_mux(NULL, clk_output_name[can1], |
434 | can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, | 445 | can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT | |
435 | SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock); | 446 | CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1, |
447 | 0, &canmioclk_lock); | ||
436 | 448 | ||
437 | for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) { | 449 | for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) { |
438 | int idx = of_property_match_string(np, "clock-names", | 450 | int idx = of_property_match_string(np, "clock-names", |
@@ -441,13 +453,15 @@ static void __init zynq_clk_setup(struct device_node *np) | |||
441 | dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np, | 453 | dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np, |
442 | idx); | 454 | idx); |
443 | } | 455 | } |
444 | clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0, | 456 | clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, |
445 | SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock); | 457 | CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 4, 2, 0, |
458 | &dbgclk_lock); | ||
446 | clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0, | 459 | clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0, |
447 | SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | | 460 | SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | |
448 | CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock); | 461 | CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock); |
449 | clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0, | 462 | clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, |
450 | SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock); | 463 | CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 6, 1, 0, |
464 | &dbgclk_lock); | ||
451 | clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc], | 465 | clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc], |
452 | "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL, | 466 | "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL, |
453 | 0, 0, &dbgclk_lock); | 467 | 0, 0, &dbgclk_lock); |