diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-15 07:05:03 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-15 07:05:03 +0200 |
commit | c0fa2373f8cfed90437d8d7b17e0b1a84009a10a (patch) | |
tree | 43fb2edd0c11874d0b2e56714e53894d10321e19 /drivers/clk/rockchip/clk-pll.c | |
parent | Merge tag 'mfd-for-linus-3.18' of git://git.kernel.org/pub/scm/linux/kernel/g... (diff) | |
parent | clk: pxa clocks build system fix (diff) | |
download | linux-c0fa2373f8cfed90437d8d7b17e0b1a84009a10a.tar.xz linux-c0fa2373f8cfed90437d8d7b17e0b1a84009a10a.zip |
Merge tag 'clk-for-linus-3.18' of git://git.linaro.org/people/mike.turquette/linux
Pull clock tree updates from Mike Turquette:
"The clk tree changes for 3.18 are dominated by clock drivers. Mostly
fixes and enhancements to existing drivers as well as new drivers.
This tag contains a bit more arch code than I usually take due to some
OMAP2+ changes. Additionally it contains the restart notifier
handlers which are merged as a dependency into several trees.
The PXA changes are the only messy part. Due to having a stable tree
I had to revert one patch and follow up with one more fix near the tip
of this tag. Some dead code is introduced but it will soon become
live code after 3.18-rc1 is released as the rest of the PXA family is
converted over to the common clock framework.
Another trend in this tag is that multiple vendors have started to
push the complexity of changing their CPU frequency into the clock
driver, whereas this used to be done in CPUfreq drivers.
Changes to the clk core include a generic gpio-clock type and a
clk_set_phase() function added to the top-level clk.h api. Due to
some confusion on the fbdev mailing list the kernel boot parameters
documentation was updated to further explain the clk_ignore_unused
parameter, which is often required by users of the simplefb driver.
Finally some fixes to the locking around the clock debugfs stuff was
done to prevent deadlocks when interacting with other subsystems."
* tag 'clk-for-linus-3.18' of git://git.linaro.org/people/mike.turquette/linux: (99 commits)
clk: pxa clocks build system fix
Revert "arm: pxa: Transition pxa27x to clk framework"
clk: samsung: register restart handlers for s3c2412 and s3c2443
clk: rockchip: add restart handler
clk: rockchip: rk3288: i2s_frac adds flag to set parent's rate
doc/kernel-parameters.txt: clarify clk_ignore_unused
arm: pxa: Transition pxa27x to clk framework
dts: add devicetree bindings for pxa27x clocks
clk: add pxa27x clock drivers
arm: pxa: add clock pll selection bits
clk: dts: document pxa clock binding
clk: add pxa clocks infrastructure
clk: gpio-gate: Ensure gpiod_ APIs are prototyped
clk: ti: dra7-atl-clock: Mark the device as pm_runtime_irq_safe
clk: ti: LLVMLinux: Move __init outside of type definition
clk: ti: consider the fact that of_clk_get() might return an error
clk: ti: dra7-atl-clock: fix a memory leak
clk: ti: change clock init to use generic of_clk_init
clk: hix5hd2: add I2C clocks
clk: hix5hd2: add watchdog0 clocks
...
Diffstat (limited to 'drivers/clk/rockchip/clk-pll.c')
-rw-r--r-- | drivers/clk/rockchip/clk-pll.c | 63 |
1 files changed, 13 insertions, 50 deletions
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index f2a1c7abf4d9..a3e886a38480 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -34,7 +34,6 @@ struct rockchip_clk_pll { const struct clk_ops *pll_mux_ops; struct notifier_block clk_nb; - bool rate_change_remuxed; void __iomem *reg_base; int lock_offset; @@ -109,38 +108,6 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) } /** - * Set pll mux when changing the pll rate. - * This makes sure to move the pll mux away from the actual pll before - * changing its rate and back to the original parent after the change. - */ -static int rockchip_pll_notifier_cb(struct notifier_block *nb, - unsigned long event, void *data) -{ - struct rockchip_clk_pll *pll = to_rockchip_clk_pll_nb(nb); - struct clk_mux *pll_mux = &pll->pll_mux; - const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; - int cur_parent; - - switch (event) { - case PRE_RATE_CHANGE: - cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); - if (cur_parent == PLL_MODE_NORM) { - pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); - pll->rate_change_remuxed = 1; - } - break; - case POST_RATE_CHANGE: - if (pll->rate_change_remuxed) { - pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); - pll->rate_change_remuxed = 0; - } - break; - } - - return NOTIFY_OK; -} - -/** * PLL used in RK3066, RK3188 and RK3288 */ @@ -194,6 +161,10 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, const struct rockchip_pll_rate_table *rate; unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); struct regmap *grf = rockchip_clk_get_grf(); + struct clk_mux *pll_mux = &pll->pll_mux; + const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; + int rate_change_remuxed = 0; + int cur_parent; int ret; if (IS_ERR(grf)) { @@ -216,6 +187,12 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", __func__, rate->rate, rate->nr, rate->no, rate->nf); + cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); + if (cur_parent == PLL_MODE_NORM) { + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); + rate_change_remuxed = 1; + } + /* enter reset mode */ writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0), pll->reg_base + RK3066_PLLCON(3)); @@ -247,6 +224,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, rockchip_rk3066_pll_set_rate(hw, old_rate, prate); } + if (rate_change_remuxed) + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); + return ret; } @@ -310,7 +290,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, struct clk_mux *pll_mux; struct clk *pll_clk, *mux_clk; char pll_name[20]; - int ret; if (num_parents != 2) { pr_err("%s: needs two parent clocks\n", __func__); @@ -367,7 +346,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, pll->lock_offset = grf_lock_offset; pll->lock_shift = lock_shift; pll->lock = lock; - pll->clk_nb.notifier_call = rockchip_pll_notifier_cb; pll_clk = clk_register(NULL, &pll->hw); if (IS_ERR(pll_clk)) { @@ -377,14 +355,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, goto err_pll; } - ret = clk_notifier_register(pll_clk, &pll->clk_nb); - if (ret) { - pr_err("%s: failed to register clock notifier for %s : %d\n", - __func__, name, ret); - mux_clk = ERR_PTR(ret); - goto err_pll_notifier; - } - /* create the mux on top of the real pll */ pll->pll_mux_ops = &clk_mux_ops; pll_mux = &pll->pll_mux; @@ -417,13 +387,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, return mux_clk; err_mux: - ret = clk_notifier_unregister(pll_clk, &pll->clk_nb); - if (ret) { - pr_err("%s: could not unregister clock notifier in error path : %d\n", - __func__, ret); - return mux_clk; - } -err_pll_notifier: clk_unregister(pll_clk); err_pll: kfree(pll); |