diff options
| author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2008-07-08 13:27:22 -0400 |
|---|---|---|
| committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-08 13:27:22 -0400 |
| commit | ffab6cf44e9058fe75a33aa86386b22e616a8f6f (patch) | |
| tree | b31a0bb763c731e380d23abc290f09d620745810 | |
| parent | a861beb1401d65e3f095fee074c13645ab06490e (diff) | |
palm_bk3710: fix IDECLK period calculation
The driver uses completely bogus rounding formula for calculating period from
the IDECLK frequency which gives one-off period values (e.g. 11 ns with 100 MHz
IDECLK) which in turn can lead to overclocked IDE transfer timings. Actually,
rounding is just wrong in this case, so use a mere division for a safe result.
While at it, also:
- give 'ide_palm_clk' variable a more suitable name;
- get rid of the useless 'ideclkp' variable;
- drop the LISP stype 'p' postfix from the 'clkp' variable's name. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: mcherkashin@ru.mvista.com
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
| -rw-r--r-- | drivers/ide/arm/palm_bk3710.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index cc24803fadff..2f2b4f4cf229 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c | |||
| @@ -76,7 +76,7 @@ struct palm_bk3710_udmatiming { | |||
| 76 | 76 | ||
| 77 | #include "../ide-timing.h" | 77 | #include "../ide-timing.h" |
| 78 | 78 | ||
| 79 | static long ide_palm_clk; | 79 | static unsigned ideclk_period; /* in nanoseconds */ |
| 80 | 80 | ||
| 81 | static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { | 81 | static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { |
| 82 | {160, 240}, /* UDMA Mode 0 */ | 82 | {160, 240}, /* UDMA Mode 0 */ |
| @@ -86,8 +86,6 @@ static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { | |||
| 86 | {85, 60}, /* UDMA Mode 4 */ | 86 | {85, 60}, /* UDMA Mode 4 */ |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | static struct clk *ideclkp; | ||
| 90 | |||
| 91 | static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, | 89 | static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, |
| 92 | unsigned int mode) | 90 | unsigned int mode) |
| 93 | { | 91 | { |
| @@ -97,10 +95,10 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, | |||
| 97 | 95 | ||
| 98 | /* DMA Data Setup */ | 96 | /* DMA Data Setup */ |
| 99 | t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime, | 97 | t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime, |
| 100 | ide_palm_clk) - 1; | 98 | ideclk_period) - 1; |
| 101 | tenv = DIV_ROUND_UP(20, ide_palm_clk) - 1; | 99 | tenv = DIV_ROUND_UP(20, ideclk_period) - 1; |
| 102 | trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime, | 100 | trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime, |
| 103 | ide_palm_clk) - 1; | 101 | ideclk_period) - 1; |
| 104 | 102 | ||
| 105 | /* udmatim Register */ | 103 | /* udmatim Register */ |
| 106 | val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); | 104 | val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); |
| @@ -141,8 +139,8 @@ static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev, | |||
| 141 | cycletime = max_t(int, t->cycle, min_cycle); | 139 | cycletime = max_t(int, t->cycle, min_cycle); |
| 142 | 140 | ||
| 143 | /* DMA Data Setup */ | 141 | /* DMA Data Setup */ |
| 144 | t0 = DIV_ROUND_UP(cycletime, ide_palm_clk); | 142 | t0 = DIV_ROUND_UP(cycletime, ideclk_period); |
| 145 | td = DIV_ROUND_UP(t->active, ide_palm_clk); | 143 | td = DIV_ROUND_UP(t->active, ideclk_period); |
| 146 | tkw = t0 - td - 1; | 144 | tkw = t0 - td - 1; |
| 147 | td -= 1; | 145 | td -= 1; |
| 148 | 146 | ||
| @@ -168,9 +166,9 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | |||
| 168 | struct ide_timing *t; | 166 | struct ide_timing *t; |
| 169 | 167 | ||
| 170 | /* PIO Data Setup */ | 168 | /* PIO Data Setup */ |
| 171 | t0 = DIV_ROUND_UP(cycletime, ide_palm_clk); | 169 | t0 = DIV_ROUND_UP(cycletime, ideclk_period); |
| 172 | t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active, | 170 | t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active, |
| 173 | ide_palm_clk); | 171 | ideclk_period); |
| 174 | 172 | ||
| 175 | t2i = t0 - t2 - 1; | 173 | t2i = t0 - t2 - 1; |
| 176 | t2 -= 1; | 174 | t2 -= 1; |
| @@ -192,8 +190,8 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | |||
| 192 | 190 | ||
| 193 | /* TASKFILE Setup */ | 191 | /* TASKFILE Setup */ |
| 194 | t = ide_timing_find_mode(XFER_PIO_0 + mode); | 192 | t = ide_timing_find_mode(XFER_PIO_0 + mode); |
| 195 | t0 = DIV_ROUND_UP(t->cyc8b, ide_palm_clk); | 193 | t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period); |
| 196 | t2 = DIV_ROUND_UP(t->act8b, ide_palm_clk); | 194 | t2 = DIV_ROUND_UP(t->act8b, ideclk_period); |
| 197 | 195 | ||
| 198 | t2i = t0 - t2 - 1; | 196 | t2i = t0 - t2 - 1; |
| 199 | t2 -= 1; | 197 | t2 -= 1; |
| @@ -350,22 +348,22 @@ static const struct ide_port_info __devinitdata palm_bk3710_port_info = { | |||
| 350 | 348 | ||
| 351 | static int __devinit palm_bk3710_probe(struct platform_device *pdev) | 349 | static int __devinit palm_bk3710_probe(struct platform_device *pdev) |
| 352 | { | 350 | { |
| 353 | struct clk *clkp; | 351 | struct clk *clk; |
| 354 | struct resource *mem, *irq; | 352 | struct resource *mem, *irq; |
| 355 | ide_hwif_t *hwif; | 353 | ide_hwif_t *hwif; |
| 356 | unsigned long base; | 354 | unsigned long base, rate; |
| 357 | int i; | 355 | int i; |
| 358 | hw_regs_t hw; | 356 | hw_regs_t hw; |
| 359 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 357 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
| 360 | 358 | ||
| 361 | clkp = clk_get(NULL, "IDECLK"); | 359 | clk = clk_get(NULL, "IDECLK"); |
| 362 | if (IS_ERR(clkp)) | 360 | if (IS_ERR(clk)) |
| 363 | return -ENODEV; | 361 | return -ENODEV; |
| 364 | 362 | ||
| 365 | ideclkp = clkp; | 363 | clk_enable(clk); |
| 366 | clk_enable(ideclkp); | 364 | rate = clk_get_rate(clk); |
| 367 | ide_palm_clk = clk_get_rate(ideclkp)/100000; | 365 | ideclk_period = 1000000000UL / rate; |
| 368 | ide_palm_clk = (10000/ide_palm_clk) + 1; | 366 | |
| 369 | /* Register the IDE interface with Linux ATA Interface */ | 367 | /* Register the IDE interface with Linux ATA Interface */ |
| 370 | memset(&hw, 0, sizeof(hw)); | 368 | memset(&hw, 0, sizeof(hw)); |
| 371 | 369 | ||
