Commit 86b8bff7 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Mark Brown

spi: Convert to use predefined time multipliers

We have a lot of hard coded values in nanoseconds or other units.
Use predefined constants to make it more clear.

While at it, add or amend comments in the corresponding functions.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20210510131120.49253-1-andriy.shevchenko@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent d6e58e37
...@@ -1118,10 +1118,20 @@ static int spi_transfer_wait(struct spi_controller *ctlr, ...@@ -1118,10 +1118,20 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
if (!speed_hz) if (!speed_hz)
speed_hz = 100000; speed_hz = 100000;
ms = 8LL * 1000LL * xfer->len; /*
* For each byte we wait for 8 cycles of the SPI clock.
* Since speed is defined in Hz and we want milliseconds,
* use respective multiplier, but before the division,
* otherwise we may get 0 for short transfers.
*/
ms = 8LL * MSEC_PER_SEC * xfer->len;
do_div(ms, speed_hz); do_div(ms, speed_hz);
ms += ms + 200; /* some tolerance */
/*
* Increase it twice and add 200 ms tolerance, use
* predefined maximum in case of overflow.
*/
ms += ms + 200;
if (ms > UINT_MAX) if (ms > UINT_MAX)
ms = UINT_MAX; ms = UINT_MAX;
...@@ -1144,10 +1154,10 @@ static void _spi_transfer_delay_ns(u32 ns) ...@@ -1144,10 +1154,10 @@ static void _spi_transfer_delay_ns(u32 ns)
{ {
if (!ns) if (!ns)
return; return;
if (ns <= 1000) { if (ns <= NSEC_PER_USEC) {
ndelay(ns); ndelay(ns);
} else { } else {
u32 us = DIV_ROUND_UP(ns, 1000); u32 us = DIV_ROUND_UP(ns, NSEC_PER_USEC);
if (us <= 10) if (us <= 10)
udelay(us); udelay(us);
...@@ -1167,21 +1177,25 @@ int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer) ...@@ -1167,21 +1177,25 @@ int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer)
switch (unit) { switch (unit) {
case SPI_DELAY_UNIT_USECS: case SPI_DELAY_UNIT_USECS:
delay *= 1000; delay *= NSEC_PER_USEC;
break; break;
case SPI_DELAY_UNIT_NSECS: /* nothing to do here */ case SPI_DELAY_UNIT_NSECS:
/* Nothing to do here */
break; break;
case SPI_DELAY_UNIT_SCK: case SPI_DELAY_UNIT_SCK:
/* clock cycles need to be obtained from spi_transfer */ /* clock cycles need to be obtained from spi_transfer */
if (!xfer) if (!xfer)
return -EINVAL; return -EINVAL;
/* if there is no effective speed know, then approximate /*
* by underestimating with half the requested hz * If there is unknown effective speed, approximate it
* by underestimating with half of the requested hz.
*/ */
hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2; hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2;
if (!hz) if (!hz)
return -EINVAL; return -EINVAL;
delay *= DIV_ROUND_UP(1000000000, hz);
/* Convert delay to nanoseconds */
delay *= DIV_ROUND_UP(NSEC_PER_SEC, hz);
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -1213,6 +1227,7 @@ EXPORT_SYMBOL_GPL(spi_delay_exec); ...@@ -1213,6 +1227,7 @@ EXPORT_SYMBOL_GPL(spi_delay_exec);
static void _spi_transfer_cs_change_delay(struct spi_message *msg, static void _spi_transfer_cs_change_delay(struct spi_message *msg,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
u32 default_delay_ns = 10 * NSEC_PER_USEC;
u32 delay = xfer->cs_change_delay.value; u32 delay = xfer->cs_change_delay.value;
u32 unit = xfer->cs_change_delay.unit; u32 unit = xfer->cs_change_delay.unit;
int ret; int ret;
...@@ -1220,16 +1235,16 @@ static void _spi_transfer_cs_change_delay(struct spi_message *msg, ...@@ -1220,16 +1235,16 @@ static void _spi_transfer_cs_change_delay(struct spi_message *msg,
/* return early on "fast" mode - for everything but USECS */ /* return early on "fast" mode - for everything but USECS */
if (!delay) { if (!delay) {
if (unit == SPI_DELAY_UNIT_USECS) if (unit == SPI_DELAY_UNIT_USECS)
_spi_transfer_delay_ns(10000); _spi_transfer_delay_ns(default_delay_ns);
return; return;
} }
ret = spi_delay_exec(&xfer->cs_change_delay, xfer); ret = spi_delay_exec(&xfer->cs_change_delay, xfer);
if (ret) { if (ret) {
dev_err_once(&msg->spi->dev, dev_err_once(&msg->spi->dev,
"Use of unsupported delay unit %i, using default of 10us\n", "Use of unsupported delay unit %i, using default of %luus\n",
unit); unit, default_delay_ns / NSEC_PER_USEC);
_spi_transfer_delay_ns(10000); _spi_transfer_delay_ns(default_delay_ns);
} }
} }
......
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