diff options
author | Chao Xie <chao.xie@marvell.com> | 2014-10-30 22:13:42 -0400 |
---|---|---|
committer | Michael Turquette <mturquette@linaro.org> | 2014-11-12 19:33:37 -0500 |
commit | 61256133919e76ea51e458c9713a9ee9d9ec4a67 (patch) | |
tree | 5b6b31808520277a486cd68b039eba2eb0ac85aa | |
parent | 2bd1e256e45052f2244403f822fd85aa64a6aa00 (diff) |
clk: mmp: add spin lock for clk-frac
The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.
Signed-off-by: Chao Xie <chao.xie@marvell.com>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Michael Turquette <mturquette@linaro.org>
-rw-r--r-- | drivers/clk/mmp/clk-frac.c | 11 | ||||
-rw-r--r-- | drivers/clk/mmp/clk-mmp2.c | 2 | ||||
-rw-r--r-- | drivers/clk/mmp/clk-pxa168.c | 2 | ||||
-rw-r--r-- | drivers/clk/mmp/clk-pxa910.c | 2 | ||||
-rw-r--r-- | drivers/clk/mmp/clk.h | 3 |
5 files changed, 15 insertions, 5 deletions
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 3fbc9cab53a6..e29d006ab85e 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c | |||
@@ -29,6 +29,7 @@ struct mmp_clk_factor { | |||
29 | struct mmp_clk_factor_masks *masks; | 29 | struct mmp_clk_factor_masks *masks; |
30 | struct mmp_clk_factor_tbl *ftbl; | 30 | struct mmp_clk_factor_tbl *ftbl; |
31 | unsigned int ftbl_cnt; | 31 | unsigned int ftbl_cnt; |
32 | spinlock_t *lock; | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, | 35 | static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, |
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | |||
86 | int i; | 87 | int i; |
87 | unsigned long val; | 88 | unsigned long val; |
88 | unsigned long prev_rate, rate = 0; | 89 | unsigned long prev_rate, rate = 0; |
90 | unsigned long flags = 0; | ||
89 | 91 | ||
90 | for (i = 0; i < factor->ftbl_cnt; i++) { | 92 | for (i = 0; i < factor->ftbl_cnt; i++) { |
91 | prev_rate = rate; | 93 | prev_rate = rate; |
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | |||
97 | if (i > 0) | 99 | if (i > 0) |
98 | i--; | 100 | i--; |
99 | 101 | ||
102 | if (factor->lock) | ||
103 | spin_lock_irqsave(factor->lock, flags); | ||
104 | |||
100 | val = readl_relaxed(factor->base); | 105 | val = readl_relaxed(factor->base); |
101 | 106 | ||
102 | val &= ~(masks->num_mask << masks->num_shift); | 107 | val &= ~(masks->num_mask << masks->num_shift); |
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | |||
107 | 112 | ||
108 | writel_relaxed(val, factor->base); | 113 | writel_relaxed(val, factor->base); |
109 | 114 | ||
115 | if (factor->lock) | ||
116 | spin_unlock_irqrestore(factor->lock, flags); | ||
117 | |||
110 | return 0; | 118 | return 0; |
111 | } | 119 | } |
112 | 120 | ||
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, | |||
120 | unsigned long flags, void __iomem *base, | 128 | unsigned long flags, void __iomem *base, |
121 | struct mmp_clk_factor_masks *masks, | 129 | struct mmp_clk_factor_masks *masks, |
122 | struct mmp_clk_factor_tbl *ftbl, | 130 | struct mmp_clk_factor_tbl *ftbl, |
123 | unsigned int ftbl_cnt) | 131 | unsigned int ftbl_cnt, spinlock_t *lock) |
124 | { | 132 | { |
125 | struct mmp_clk_factor *factor; | 133 | struct mmp_clk_factor *factor; |
126 | struct clk_init_data init; | 134 | struct clk_init_data init; |
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, | |||
143 | factor->ftbl = ftbl; | 151 | factor->ftbl = ftbl; |
144 | factor->ftbl_cnt = ftbl_cnt; | 152 | factor->ftbl_cnt = ftbl_cnt; |
145 | factor->hw.init = &init; | 153 | factor->hw.init = &init; |
154 | factor->lock = lock; | ||
146 | 155 | ||
147 | init.name = name; | 156 | init.name = name; |
148 | init.ops = &clk_factor_ops; | 157 | init.ops = &clk_factor_ops; |
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c index 7083f12ef422..5c90a4230fa3 100644 --- a/drivers/clk/mmp/clk-mmp2.c +++ b/drivers/clk/mmp/clk-mmp2.c | |||
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void) | |||
191 | clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0, | 191 | clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0, |
192 | mpmu_base + MPMU_UART_PLL, | 192 | mpmu_base + MPMU_UART_PLL, |
193 | &uart_factor_masks, uart_factor_tbl, | 193 | &uart_factor_masks, uart_factor_tbl, |
194 | ARRAY_SIZE(uart_factor_tbl)); | 194 | ARRAY_SIZE(uart_factor_tbl), &clk_lock); |
195 | clk_set_rate(clk, 14745600); | 195 | clk_set_rate(clk, 14745600); |
196 | clk_register_clkdev(clk, "uart_pll", NULL); | 196 | clk_register_clkdev(clk, "uart_pll", NULL); |
197 | 197 | ||
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c index 75266ac80829..93e967c0f972 100644 --- a/drivers/clk/mmp/clk-pxa168.c +++ b/drivers/clk/mmp/clk-pxa168.c | |||
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void) | |||
158 | uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, | 158 | uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, |
159 | mpmu_base + MPMU_UART_PLL, | 159 | mpmu_base + MPMU_UART_PLL, |
160 | &uart_factor_masks, uart_factor_tbl, | 160 | &uart_factor_masks, uart_factor_tbl, |
161 | ARRAY_SIZE(uart_factor_tbl)); | 161 | ARRAY_SIZE(uart_factor_tbl), &clk_lock); |
162 | clk_set_rate(uart_pll, 14745600); | 162 | clk_set_rate(uart_pll, 14745600); |
163 | clk_register_clkdev(uart_pll, "uart_pll", NULL); | 163 | clk_register_clkdev(uart_pll, "uart_pll", NULL); |
164 | 164 | ||
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c index f81799987451..993abcdb32cc 100644 --- a/drivers/clk/mmp/clk-pxa910.c +++ b/drivers/clk/mmp/clk-pxa910.c | |||
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void) | |||
163 | uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, | 163 | uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, |
164 | mpmu_base + MPMU_UART_PLL, | 164 | mpmu_base + MPMU_UART_PLL, |
165 | &uart_factor_masks, uart_factor_tbl, | 165 | &uart_factor_masks, uart_factor_tbl, |
166 | ARRAY_SIZE(uart_factor_tbl)); | 166 | ARRAY_SIZE(uart_factor_tbl), &clk_lock); |
167 | clk_set_rate(uart_pll, 14745600); | 167 | clk_set_rate(uart_pll, 14745600); |
168 | clk_register_clkdev(uart_pll, "uart_pll", NULL); | 168 | clk_register_clkdev(uart_pll, "uart_pll", NULL); |
169 | 169 | ||
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h index 3fe92be9e054..b71b717cdb24 100644 --- a/drivers/clk/mmp/clk.h +++ b/drivers/clk/mmp/clk.h | |||
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name, | |||
31 | extern struct clk *mmp_clk_register_factor(const char *name, | 31 | extern struct clk *mmp_clk_register_factor(const char *name, |
32 | const char *parent_name, unsigned long flags, | 32 | const char *parent_name, unsigned long flags, |
33 | void __iomem *base, struct mmp_clk_factor_masks *masks, | 33 | void __iomem *base, struct mmp_clk_factor_masks *masks, |
34 | struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt); | 34 | struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt, |
35 | spinlock_t *lock); | ||
35 | #endif | 36 | #endif |