diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-20 06:28:59 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-12 12:32:36 -0500 |
commit | 0c452df9f08d4f0b829802cec3501d987390ada2 (patch) | |
tree | 215ee608d4ac0af8d32d8b32776f7745d10b7302 /arch | |
parent | 5413f7464e976e2c2ddb20686fc2e66ae8795b6e (diff) |
ARM: PNX4008: provide clock enable/disable methods and initialization
Acked-by: Vitaly Wool <vitalywool@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-pnx4008/clock.c | 35 | ||||
-rw-r--r-- | arch/arm/mach-pnx4008/clock.h | 4 |
2 files changed, 26 insertions, 13 deletions
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index f0cc91909090..3ad694e15968 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c | |||
@@ -57,18 +57,19 @@ static void propagate_rate(struct clk *clk) | |||
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | static inline void clk_reg_disable(struct clk *clk) | 60 | static void clk_reg_disable(struct clk *clk) |
61 | { | 61 | { |
62 | if (clk->enable_reg) | 62 | if (clk->enable_reg) |
63 | __raw_writel(__raw_readl(clk->enable_reg) & | 63 | __raw_writel(__raw_readl(clk->enable_reg) & |
64 | ~(1 << clk->enable_shift), clk->enable_reg); | 64 | ~(1 << clk->enable_shift), clk->enable_reg); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void clk_reg_enable(struct clk *clk) | 67 | static int clk_reg_enable(struct clk *clk) |
68 | { | 68 | { |
69 | if (clk->enable_reg) | 69 | if (clk->enable_reg) |
70 | __raw_writel(__raw_readl(clk->enable_reg) | | 70 | __raw_writel(__raw_readl(clk->enable_reg) | |
71 | (1 << clk->enable_shift), clk->enable_reg); | 71 | (1 << clk->enable_shift), clk->enable_reg); |
72 | return 0; | ||
72 | } | 73 | } |
73 | 74 | ||
74 | static inline void clk_reg_disable1(struct clk *clk) | 75 | static inline void clk_reg_disable1(struct clk *clk) |
@@ -814,7 +815,9 @@ static void local_clk_disable(struct clk *clk) | |||
814 | return; | 815 | return; |
815 | 816 | ||
816 | if (!(--clk->usecount)) { | 817 | if (!(--clk->usecount)) { |
817 | if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) | 818 | if (clk->disable) |
819 | clk->disable(clk); | ||
820 | else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) | ||
818 | clk->set_rate(clk, 0); | 821 | clk->set_rate(clk, 0); |
819 | if (clk->parent) | 822 | if (clk->parent) |
820 | local_clk_disable(clk->parent); | 823 | local_clk_disable(clk->parent); |
@@ -832,8 +835,10 @@ static int local_clk_enable(struct clk *clk) | |||
832 | goto out; | 835 | goto out; |
833 | } | 836 | } |
834 | 837 | ||
835 | if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate | 838 | if (clk->enable) |
836 | && clk->user_rate) | 839 | ret = clk->enable(clk); |
840 | else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate | ||
841 | && clk->user_rate) | ||
837 | ret = clk->set_rate(clk, clk->user_rate); | 842 | ret = clk->set_rate(clk, clk->user_rate); |
838 | 843 | ||
839 | if (ret != 0 && clk->parent) { | 844 | if (ret != 0 && clk->parent) { |
@@ -960,15 +965,21 @@ static int __init clk_init(void) | |||
960 | 965 | ||
961 | for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); | 966 | for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); |
962 | clkp++) { | 967 | clkp++) { |
963 | if (((*clkp)->flags & NEEDS_INITIALIZATION) | 968 | struct clk *clk = *clkp; |
964 | && ((*clkp)->set_rate)) { | 969 | if (clk->flags & NEEDS_INITIALIZATION) { |
965 | (*clkp)->user_rate = (*clkp)->rate; | 970 | if (clk->set_rate) { |
966 | local_set_rate((*clkp), (*clkp)->user_rate); | 971 | clk->user_rate = clk->rate; |
967 | if ((*clkp)->set_parent) | 972 | local_set_rate(clk, clk->user_rate); |
968 | (*clkp)->set_parent((*clkp), (*clkp)->parent); | 973 | if (clk->set_parent) |
974 | clk->set_parent(clk, clk->parent); | ||
975 | } | ||
976 | if (clk->enable && clk->usecount) | ||
977 | clk->enable(clk); | ||
978 | if (clk->disable && !clk->usecount) | ||
979 | clk->disable(clk); | ||
969 | } | 980 | } |
970 | pr_debug("%s: clock %s, rate %ld\n", | 981 | pr_debug("%s: clock %s, rate %ld\n", |
971 | __func__, (*clkp)->name, (*clkp)->rate); | 982 | __func__, clk->name, clk->rate); |
972 | } | 983 | } |
973 | 984 | ||
974 | local_clk_enable(&ck_pll4); | 985 | local_clk_enable(&ck_pll4); |
diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h index 933e18133b96..39720d6c0d01 100644 --- a/arch/arm/mach-pnx4008/clock.h +++ b/arch/arm/mach-pnx4008/clock.h | |||
@@ -27,9 +27,11 @@ struct clk { | |||
27 | u8 enable_shift1; | 27 | u8 enable_shift1; |
28 | u32 enable_reg1; | 28 | u32 enable_reg1; |
29 | u32 parent_switch_reg; | 29 | u32 parent_switch_reg; |
30 | u32(*round_rate) (struct clk *, u32); | 30 | u32(*round_rate) (struct clk *, u32); |
31 | int (*set_rate) (struct clk *, u32); | 31 | int (*set_rate) (struct clk *, u32); |
32 | int (*set_parent) (struct clk * clk, struct clk * parent); | 32 | int (*set_parent) (struct clk * clk, struct clk * parent); |
33 | int (*enable)(struct clk *); | ||
34 | void (*disable)(struct clk *); | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | /* Flags */ | 37 | /* Flags */ |