linux/drivers/clk
Saravana Kannan f8aa0bd5c9 clk: Fix race condition between clk_set_parent and clk_enable()
Without this patch, the following race condition is possible.
* clk-A has two parents - clk-X and clk-Y.
* All three are disabled and clk-X is current parent.
* Thread A: clk_set_parent(clk-A, clk-Y).
* Thread A: <snip execution flow>
* Thread A: Grabs enable lock.
* Thread A: Sees enable count of clk-A is 0, so doesn't enable clk-Y.
* Thread A: Updates clk-A SW parent to clk-Y
* Thread A: Releases enable lock.
* Thread B: clk_enable(clk-A).
* Thread B: clk_enable() enables clk-Y, then enabled clk-A and returns.

clk-A is now enabled in software, but not clocking in hardware since the
hardware parent is still clk-X.

The only way to avoid race conditions between clk_set_parent() and
clk_enable/disable() is to ensure that clk_enable/disable() calls don't
require changes to hardware enable state between changes to software clock
topology and hardware clock topology.

The options to achieve the above are:
1. Grab the enable lock before changing software/hardware topology and
   release it afterwards.
2. Keep the clock enabled for the duration of software/hardware topology
   change so that any additional enable/disable calls don't try to change
   the hardware state. Once the topology change is complete, the clock can
   be put back in its original enable state.

Option (1) is not an acceptable solution since the set_parent() ops might
need to sleep.

Therefore, this patch implements option (2).

This patch doesn't violate any API semantics. clk_disable() doesn't
guarantee that the clock is actually disabled. So, no clients of a clock
can assume that a clock is disabled after their last call to clk_disable().
So, enabling the clock during a parent change is not a violation of any API
semantics.

This also has the nice side effect of simplifying the error handling code.

Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
[mturquette@linaro.org: fixed up whitespace issue]
2013-05-28 22:50:32 -07:00
..
mmp ARM: pxa: remove cpu_is_xxx in gpio driver 2013-04-11 09:59:23 +08:00
mvebu Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2013-04-30 09:36:50 -07:00
mxs Merge branch 'depends/clk-for-3.10' into next/cleanup 2013-04-11 03:38:03 -07:00
samsung ARM: late Exynos multiplatform changes 2013-05-07 11:28:42 -07:00
socfpga ARM: socfpga: Upgrade clk driver for socfpga to make use of dts clock entries 2013-04-14 20:18:13 -07:00
spear ARM: arm-soc multiplatform updates for 3.10 2013-05-02 09:38:16 -07:00
sunxi clk: sun5i: Add compatibles for Allwinner A13 2013-05-28 22:50:31 -07:00
tegra clk: tegra: add ac97 controller clock 2013-05-20 23:24:34 -07:00
ux500 clk: ux500: abx500-clk: rename ux500 audio codec aliases 2013-05-28 22:50:31 -07:00
versatile clk: vexpress: Add separate SP810 driver 2013-04-18 11:41:10 -07:00
x86 ACPI / LPSS: register clock device for Lynxpoint DMA properly 2013-05-14 10:23:58 +05:30
clk-axi-clkgen.c clk: Add axi-clkgen driver 2013-03-19 17:20:30 -07:00
clk-bcm2835.c
clk-composite.c clk: composite: allow fixed rates & fixed dividers 2013-04-12 11:23:24 -07:00
clk-devres.c
clk-divider.c clk: divider: Introduce CLK_DIVIDER_ALLOW_ZERO flag 2013-04-03 12:56:30 -07:00
clk-fixed-factor.c clk: add device tree fixed-factor-clock binding support 2013-04-12 10:52:23 -07:00
clk-fixed-rate.c clk: add common of_clk_init() function 2013-01-24 11:09:28 -08:00
clk-gate.c
clk-highbank.c ACPI and power management updates for 3.9-rc1 2013-02-20 11:26:56 -08:00
clk-ls1x.c
clk-max77686.c clk: max77686: Avoid double free at remove time 2013-01-15 16:16:26 -08:00
clk-mux.c clk: add table lookup to mux 2013-03-22 15:18:18 -07:00
clk-nomadik.c
clk-ppc-corenet.c clk: add PowerPC corenet clock driver support 2013-05-28 22:50:31 -07:00
clk-prima2.c clk: prima2: fix return value check in sirfsoc_of_clk_init() 2013-03-22 15:16:31 -07:00
clk-si5351.c clk: si5351: declare all device IDs for module loading 2013-05-28 22:50:32 -07:00
clk-si5351.h clk: si5351: Allow user to define disabled state for every clock output 2013-05-28 22:50:31 -07:00
clk-twl6040.c
clk-u300.c
clk-vt8500.c The common clock framework changes for 3.10 include many fixes for 2013-04-29 16:43:54 -07:00
clk-wm831x.c
clk-zynq.c clk: zynq: Add missing zynq clk header 2013-03-27 08:44:07 -07:00
clk.c clk: Fix race condition between clk_set_parent and clk_enable() 2013-05-28 22:50:32 -07:00
clkdev.c
Kconfig clk: add PowerPC corenet clock driver support 2013-05-28 22:50:31 -07:00
Makefile clk: add PowerPC corenet clock driver support 2013-05-28 22:50:31 -07:00