Skip to content

Commit

Permalink
spi: Only call transfer_one() if we have buffers to transfer
Browse files Browse the repository at this point in the history
Client drivers such as the ChomeOS EC driver sometimes use transfers with
no buffers and only a delay specified in order to allow a delay after the
assertion of /CS. Rather than require controller drivers handle this noop
case gracefully put checks in the core to ensure that we don't call into
the controller for such transfers.

Reported-by: Addy Ke <addy.ke@rock-chips.com>
Tested-by: Doug Anderson <dianders@chromium.org>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
  • Loading branch information
Mark Brown committed Aug 19, 2014
1 parent 7d1311b commit 38ec10f
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions drivers/spi/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,27 +789,35 @@ static int spi_transfer_one_message(struct spi_master *master,
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
trace_spi_transfer_start(msg, xfer);

reinit_completion(&master->xfer_completion);

ret = master->transfer_one(master, msg->spi, xfer);
if (ret < 0) {
dev_err(&msg->spi->dev,
"SPI transfer failed: %d\n", ret);
goto out;
}
if (xfer->tx_buf || xfer->rx_buf) {
reinit_completion(&master->xfer_completion);

ret = master->transfer_one(master, msg->spi, xfer);
if (ret < 0) {
dev_err(&msg->spi->dev,
"SPI transfer failed: %d\n", ret);
goto out;
}

if (ret > 0) {
ret = 0;
ms = xfer->len * 8 * 1000 / xfer->speed_hz;
ms += ms + 100; /* some tolerance */
if (ret > 0) {
ret = 0;
ms = xfer->len * 8 * 1000 / xfer->speed_hz;
ms += ms + 100; /* some tolerance */

ms = wait_for_completion_timeout(&master->xfer_completion,
msecs_to_jiffies(ms));
}
ms = wait_for_completion_timeout(&master->xfer_completion,
msecs_to_jiffies(ms));
}

if (ms == 0) {
dev_err(&msg->spi->dev, "SPI transfer timed out\n");
msg->status = -ETIMEDOUT;
if (ms == 0) {
dev_err(&msg->spi->dev,
"SPI transfer timed out\n");
msg->status = -ETIMEDOUT;
}
} else {
if (xfer->len)
dev_err(&msg->spi->dev,
"Bufferless transfer has length %u\n",
xfer->len);
}

trace_spi_transfer_stop(msg, xfer);
Expand Down

0 comments on commit 38ec10f

Please sign in to comment.