diff options
author | Heiko Stuebner <heiko@sntech.de> | 2011-10-14 02:08:56 -0400 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2011-10-14 02:15:52 -0400 |
commit | f9f7c7503f7002deffe4cb8409ccada075a52522 (patch) | |
tree | 6613230fdc583300e66be800d9debd0b38890052 /arch/arm/plat-s3c24xx | |
parent | 5f33bd76f5c4df45cd5b2e4132c6451dac8afee9 (diff) |
ARM: S3C2443: handle unset armdiv values gracefully
The armdiv array may contain unset divider values.
Check the relevant value to prevent division by zero
errors. Also check for set nr_armdiv and armdivmask
before meddling with clkdiv0.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/plat-s3c24xx')
-rw-r--r-- | arch/arm/plat-s3c24xx/s3c2443-clock.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index fea3d5c0252..31f97f1bb36 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c | |||
@@ -179,11 +179,16 @@ static unsigned long s3c2443_armclk_roundrate(struct clk *clk, | |||
179 | unsigned div; | 179 | unsigned div; |
180 | int ptr; | 180 | int ptr; |
181 | 181 | ||
182 | if (!nr_armdiv) | ||
183 | return -EINVAL; | ||
184 | |||
182 | for (ptr = 0; ptr < nr_armdiv; ptr++) { | 185 | for (ptr = 0; ptr < nr_armdiv; ptr++) { |
183 | div = armdiv[ptr]; | 186 | div = armdiv[ptr]; |
184 | calc = parent / div; | 187 | if (div) { |
185 | if (calc <= rate && div < best) | 188 | calc = parent / div; |
186 | best = div; | 189 | if (calc <= rate && div < best) |
190 | best = div; | ||
191 | } | ||
187 | } | 192 | } |
188 | 193 | ||
189 | return parent / best; | 194 | return parent / best; |
@@ -195,6 +200,9 @@ static unsigned long s3c2443_armclk_getrate(struct clk *clk) | |||
195 | unsigned long clkcon0; | 200 | unsigned long clkcon0; |
196 | int val; | 201 | int val; |
197 | 202 | ||
203 | if (!nr_armdiv || !armdivmask) | ||
204 | return -EINVAL; | ||
205 | |||
198 | clkcon0 = __raw_readl(S3C2443_CLKDIV0); | 206 | clkcon0 = __raw_readl(S3C2443_CLKDIV0); |
199 | clkcon0 &= armdivmask; | 207 | clkcon0 &= armdivmask; |
200 | val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT; | 208 | val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT; |
@@ -211,12 +219,17 @@ static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) | |||
211 | int ptr; | 219 | int ptr; |
212 | int val = -1; | 220 | int val = -1; |
213 | 221 | ||
222 | if (!nr_armdiv || !armdivmask) | ||
223 | return -EINVAL; | ||
224 | |||
214 | for (ptr = 0; ptr < nr_armdiv; ptr++) { | 225 | for (ptr = 0; ptr < nr_armdiv; ptr++) { |
215 | div = armdiv[ptr]; | 226 | div = armdiv[ptr]; |
216 | calc = parent / div; | 227 | if (div) { |
217 | if (calc <= rate && div < best) { | 228 | calc = parent / div; |
218 | best = div; | 229 | if (calc <= rate && div < best) { |
219 | val = ptr; | 230 | best = div; |
231 | val = ptr; | ||
232 | } | ||
220 | } | 233 | } |
221 | } | 234 | } |
222 | 235 | ||