]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
spi/davinci: Fix clock prescale factor computation
authorThomas Koeller <thomas.koeller@baslerweb.com>
Mon, 26 Apr 2010 09:01:45 +0000 (09:01 +0000)
committerGrant Likely <grant.likely@secretlab.ca>
Tue, 25 May 2010 06:23:54 +0000 (00:23 -0600)
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>
drivers/spi/davinci_spi.c

index 95afb6b77395f3c60b4c8a18bafe2b4146369229..b85090caf7cf57df0a596f131944a13d64588d70 100644 (file)
@@ -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;
 }