aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2005-10-20 17:22:58 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 17:15:54 -0500
commitcfd320fbfcf2ff0137d8e26f46ba4b66dae96083 (patch)
treeb27bf728473a8e5d7159876053be1763ec94304f
parent4fc67fbe52d7c34dfd3e03a1a79f3e078904bba2 (diff)
[MTD] NAND s3c2410.c: Fix timing calculation bugs
Spotted by basprog@mail.ru Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/mtd/nand/s3c2410.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 41f2078225a5..24f4199eaee8 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -17,8 +17,9 @@
17 * 02-May-2005 BJD Reduced hwcontrol decode 17 * 02-May-2005 BJD Reduced hwcontrol decode
18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug 18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied 19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
20 * 20-Oct-2005 BJD Fix timing calculation bug
20 * 21 *
21 * $Id: s3c2410.c,v 1.17 2005/10/10 10:27:02 bjd Exp $ 22 * $Id: s3c2410.c,v 1.18 2005/10/20 21:22:55 bjd Exp $
22 * 23 *
23 * This program is free software; you can redistribute it and/or modify 24 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by 25 * it under the terms of the GNU General Public License as published by
@@ -136,13 +137,13 @@ static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
136 137
137/* timing calculations */ 138/* timing calculations */
138 139
139#define NS_IN_KHZ 10000000 140#define NS_IN_KHZ 1000000
140 141
141static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) 142static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
142{ 143{
143 int result; 144 int result;
144 145
145 result = (wanted * NS_IN_KHZ) / clk; 146 result = (wanted * clk) / NS_IN_KHZ;
146 result++; 147 result++;
147 148
148 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 149 pr_debug("result %d from %ld, %d\n", result, clk, wanted);
@@ -159,7 +160,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
159 return result; 160 return result;
160} 161}
161 162
162#define to_ns(ticks,clk) (((clk) * (ticks)) / NS_IN_KHZ) 163#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
163 164
164/* controller setup */ 165/* controller setup */
165 166
@@ -167,12 +168,14 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
167 struct device *dev) 168 struct device *dev)
168{ 169{
169 struct s3c2410_platform_nand *plat = to_nand_plat(dev); 170 struct s3c2410_platform_nand *plat = to_nand_plat(dev);
170 unsigned int tacls, twrph0, twrph1;
171 unsigned long clkrate = clk_get_rate(info->clk); 171 unsigned long clkrate = clk_get_rate(info->clk);
172 int tacls, twrph0, twrph1;
172 unsigned long cfg; 173 unsigned long cfg;
173 174
174 /* calculate the timing information for the controller */ 175 /* calculate the timing information for the controller */
175 176
177 clkrate /= 1000; /* turn clock into kHz for ease of use */
178
176 if (plat != NULL) { 179 if (plat != NULL) {
177 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); 180 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
178 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 181 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
@@ -189,10 +192,10 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
189 return -EINVAL; 192 return -EINVAL;
190 } 193 }
191 194
192 printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n", 195 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
193 to_ns(tacls, clkrate), 196 tacls, to_ns(tacls, clkrate),
194 to_ns(twrph0, clkrate), 197 twrph0, to_ns(twrph0, clkrate),
195 to_ns(twrph1, clkrate)); 198 twrph1, to_ns(twrph1, clkrate));
196 199
197 if (!info->is_s3c2440) { 200 if (!info->is_s3c2440) {
198 cfg = S3C2410_NFCONF_EN; 201 cfg = S3C2410_NFCONF_EN;