summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorThomas Koeller <thomas.koeller@baslerweb.com>2010-04-26 11:01:45 +0200
committerGrant Likely <grant.likely@secretlab.ca>2010-05-25 08:23:54 +0200
commit0c2a2ae32793e3500a15a449612485f5d17dd431 (patch)
tree36e31ce3b9f789d6ccc5c273d24a2f149f0e6d2b /drivers/spi
parentspi: move bitbang txrx utility functions to private header (diff)
downloadlinux-0c2a2ae32793e3500a15a449612485f5d17dd431.tar.xz
linux-0c2a2ae32793e3500a15a449612485f5d17dd431.zip
spi/davinci: Fix clock prescale factor computation
Computation of the clock prescaler value returned bogus results if the requested SPI clock was impossible to set. It now sets either the maximum or minimum clock frequency, as appropriate. Signed-off-by: Thomas Koeller <thomas.koeller@baslerweb.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/davinci_spi.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 95afb6b77395..b85090caf7cf 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -301,7 +301,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
struct davinci_spi *davinci_spi;
struct davinci_spi_platform_data *pdata;
u8 bits_per_word = 0;
- u32 hz = 0, prescale;
+ u32 hz = 0, prescale = 0, clkspeed;
davinci_spi = spi_master_get_devdata(spi->master);
pdata = davinci_spi->pdata;
@@ -338,10 +338,16 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f,
spi->chip_select);
- prescale = ((clk_get_rate(davinci_spi->clk) / hz) - 1) & 0xff;
+ clkspeed = clk_get_rate(davinci_spi->clk);
+ if (hz > clkspeed / 2)
+ prescale = 1 << 8;
+ if (hz < clkspeed / 256)
+ prescale = 255 << 8;
+ if (!prescale)
+ prescale = ((clkspeed / hz - 1) << 8) & 0x0000ff00;
clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select);
- set_fmt_bits(davinci_spi->base, prescale << 8, spi->chip_select);
+ set_fmt_bits(davinci_spi->base, prescale, spi->chip_select);
return 0;
}