aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s3c24xx
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko@sntech.de>2011-10-14 02:08:56 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-10-14 02:15:52 -0400
commitf9f7c7503f7002deffe4cb8409ccada075a52522 (patch)
tree6613230fdc583300e66be800d9debd0b38890052 /arch/arm/plat-s3c24xx
parent5f33bd76f5c4df45cd5b2e4132c6451dac8afee9 (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.c27
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