diff options
author | Ben Dooks <ben@simtec.co.uk> | 2005-10-20 17:22:58 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-11-06 17:15:54 -0500 |
commit | cfd320fbfcf2ff0137d8e26f46ba4b66dae96083 (patch) | |
tree | b27bf728473a8e5d7159876053be1763ec94304f /drivers/mtd/nand/s3c2410.c | |
parent | 4fc67fbe52d7c34dfd3e03a1a79f3e078904bba2 (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>
Diffstat (limited to 'drivers/mtd/nand/s3c2410.c')
-rw-r--r-- | drivers/mtd/nand/s3c2410.c | 21 |
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 | ||
141 | static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) | 142 | static 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; |