diff options
author | Alex Frid <afrid@nvidia.com> | 2012-07-28 18:38:48 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:31:12 -0700 |
commit | 1fe0509410ff4ffb1f733206f4b70765da4818d7 (patch) | |
tree | 8f65a6c39eb51e414d2008ae6eaef58e0a43f3ad /arch/arm/mach-tegra/clock.h | |
parent | 44d8a41f87fa99ac729bd9facefde6b5c8ebbb7e (diff) |
ARM: tegra: clock: Implement clk_prepare/clk_unprepare
Implemented clk_prepare/clk_unprepare APIs that will be used after
CONFIG_HAVE_CLK_PREPARE is set. Then, these APIs will be called only
in non-atomic context, and can hold mutex. On the other hand current
clk_enable/clk_disable will be no longer allowed to hold mutex, as
they may be called in atomic context.
Implementation took advantage of tegra clock "cansleep" attribute
that indicates if clock requires preparation. Hence, the interfaces
are splitted respectively: all work on sleeping clocks is done only
in clk_prepare/clk_unprepare, and all work for non-sleeping clocks
is done only in clk_enable/clk_disable APIs. Calling "complimentary"
APIs on either type of clocks is allowed, and actually expected,
since clients may not know the clock attributes. However, calling
clk_enable on non-prepared sleeping clock would fail.
When macro CONFIG_HAVE_CLK_PREPARE is not set, there is no changes
in behavior of clk_enable/clk_disable APIs, with one exception:
propagation of enable/disable state to sleeping parent passes through
might_sleep macro, which may help to catch clock tree inconsistencies
(e.g., non-sleeping child of sleeping parent).
On code base with CONFIG_HAVE_CLK_PREPARE not set, and might_sleep is
resolved to NOP, this commit does not change clk_enable/clk_disable
at all.
Change-Id: I09bbae7845903054cadb4de84aee1cb3fb0def4b
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/119187
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Rebase-Id: R8f2a15f29fc6c561e85bf367c492f52b302190df
Diffstat (limited to 'arch/arm/mach-tegra/clock.h')
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h index f78fc59a27c5..aaa37205b92b 100644 --- a/arch/arm/mach-tegra/clock.h +++ b/arch/arm/mach-tegra/clock.h @@ -27,6 +27,7 @@ #include <linux/clk-provider.h> #include <linux/clkdev.h> +#include <linux/clk.h> #include <linux/list.h> #include <linux/mutex.h> #include <linux/spinlock.h> @@ -399,6 +400,21 @@ static inline void clk_unlock_restore(struct clk *c, unsigned long *flags) } } +static inline int tegra_clk_prepare_enable(struct clk *c) +{ + if (clk_cansleep(c)) + return clk_prepare_enable(c); + return clk_enable(c); +} + +static inline void tegra_clk_disable_unprepare(struct clk *c) +{ + if (clk_cansleep(c)) + clk_disable_unprepare(c); + else + clk_disable(c); +} + static inline void clk_lock_init(struct clk *c) { mutex_init(&c->mutex); |