forked from Minki/linux
spi/omap_mcspi: Off-by-one error in finding the right divisor
Off-by-one error, gave erroneous divisor value 16 if speed_hz is over zero but less than OMAP2_MCSPI_MAX_FREQ / (1 << 15), that is, [1..1463]. Also few overly complex bit shifts in divisor fixed. Also one dev_dgb line fixed, which indicated max speed exceeding transfer speed. Introducing a new function omap2_mcspi_calc_divisor() for getting the right divisor in omap2_mcspi_setup_transfer(). Signed-off-by: Phil Carmody <ext-phil.2.carmody@nokia.com> Signed-off-by: Hannu Heikkinen <ext-hannu.m.heikkinen@nokia.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
This commit is contained in:
parent
1648237dc2
commit
57d9c10dd9
@ -651,6 +651,17 @@ out:
|
||||
return count - c;
|
||||
}
|
||||
|
||||
static u32 omap2_mcspi_calc_divisor(u32 speed_hz)
|
||||
{
|
||||
u32 div;
|
||||
|
||||
for (div = 0; div < 15; div++)
|
||||
if (speed_hz >= (OMAP2_MCSPI_MAX_FREQ >> div))
|
||||
return div;
|
||||
|
||||
return 15;
|
||||
}
|
||||
|
||||
/* called only when no transfer is active to this device */
|
||||
static int omap2_mcspi_setup_transfer(struct spi_device *spi,
|
||||
struct spi_transfer *t)
|
||||
@ -673,12 +684,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
|
||||
if (t && t->speed_hz)
|
||||
speed_hz = t->speed_hz;
|
||||
|
||||
if (speed_hz) {
|
||||
while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div))
|
||||
> speed_hz)
|
||||
div++;
|
||||
} else
|
||||
div = 15;
|
||||
speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
|
||||
div = omap2_mcspi_calc_divisor(speed_hz);
|
||||
|
||||
l = mcspi_cached_chconf0(spi);
|
||||
|
||||
@ -715,7 +722,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
|
||||
mcspi_write_chconf0(spi, l);
|
||||
|
||||
dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
|
||||
OMAP2_MCSPI_MAX_FREQ / (1 << div),
|
||||
OMAP2_MCSPI_MAX_FREQ >> div,
|
||||
(spi->mode & SPI_CPHA) ? "trailing" : "leading",
|
||||
(spi->mode & SPI_CPOL) ? "inverted" : "normal");
|
||||
|
||||
@ -1015,10 +1022,10 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
|
||||
t->bits_per_word);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (t->speed_hz && t->speed_hz < OMAP2_MCSPI_MAX_FREQ/(1<<16)) {
|
||||
dev_dbg(&spi->dev, "%d Hz max exceeds %d\n",
|
||||
t->speed_hz,
|
||||
OMAP2_MCSPI_MAX_FREQ/(1<<16));
|
||||
if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) {
|
||||
dev_dbg(&spi->dev, "speed_hz %d below minimum %d Hz\n",
|
||||
t->speed_hz,
|
||||
OMAP2_MCSPI_MAX_FREQ >> 15);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user