Commit 57d9c10d authored by Hannu Heikkinen's avatar Hannu Heikkinen Committed by Grant Likely

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: default avatarPhil Carmody <ext-phil.2.carmody@nokia.com>
Signed-off-by: default avatarHannu Heikkinen <ext-hannu.m.heikkinen@nokia.com>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 1648237d
...@@ -651,6 +651,17 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) ...@@ -651,6 +651,17 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
return count - c; 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 */ /* called only when no transfer is active to this device */
static int omap2_mcspi_setup_transfer(struct spi_device *spi, static int omap2_mcspi_setup_transfer(struct spi_device *spi,
struct spi_transfer *t) struct spi_transfer *t)
...@@ -673,12 +684,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, ...@@ -673,12 +684,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
if (t && t->speed_hz) if (t && t->speed_hz)
speed_hz = t->speed_hz; speed_hz = t->speed_hz;
if (speed_hz) { speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) div = omap2_mcspi_calc_divisor(speed_hz);
> speed_hz)
div++;
} else
div = 15;
l = mcspi_cached_chconf0(spi); l = mcspi_cached_chconf0(spi);
...@@ -715,7 +722,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, ...@@ -715,7 +722,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
mcspi_write_chconf0(spi, l); mcspi_write_chconf0(spi, l);
dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", 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_CPHA) ? "trailing" : "leading",
(spi->mode & SPI_CPOL) ? "inverted" : "normal"); (spi->mode & SPI_CPOL) ? "inverted" : "normal");
...@@ -1015,10 +1022,10 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) ...@@ -1015,10 +1022,10 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
t->bits_per_word); t->bits_per_word);
return -EINVAL; return -EINVAL;
} }
if (t->speed_hz && 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, "%d Hz max exceeds %d\n", dev_dbg(&spi->dev, "speed_hz %d below minimum %d Hz\n",
t->speed_hz, t->speed_hz,
OMAP2_MCSPI_MAX_FREQ/(1<<16)); OMAP2_MCSPI_MAX_FREQ >> 15);
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment