Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752888AbbBQTEA (ORCPT ); Tue, 17 Feb 2015 14:04:00 -0500 Received: from devils.ext.ti.com ([198.47.26.153]:41530 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751587AbbBQTD6 (ORCPT ); Tue, 17 Feb 2015 14:03:58 -0500 From: Mugunthan V N To: CC: , , Mugunthan V N Subject: [PATCH 1/1] drivers: spi: ti-qspi: wait for busy bit clear before data write/read Date: Wed, 18 Feb 2015 00:33:51 +0530 Message-ID: <1424199831-5518-1-git-send-email-mugunthanvnm@ti.com> X-Mailer: git-send-email 2.2.1.62.g3f15098 MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2299 Lines: 72 Data corruption is seen while reading/writing large data from/to qspi device because the data register is over written or read before data is ready which is denoted by busy bit in status register. SO adding a busy bit check before writing/reading data to/from qspi device. Signed-off-by: Mugunthan V N --- drivers/spi/spi-ti-qspi.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 884a716..5c06168 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -101,6 +101,7 @@ struct ti_qspi { #define QSPI_FLEN(n) ((n - 1) << 0) /* STATUS REGISTER */ +#define BUSY 0x01 #define WC 0x02 /* INTERRUPT REGISTER */ @@ -199,6 +200,21 @@ static void ti_qspi_restore_ctx(struct ti_qspi *qspi) ti_qspi_write(qspi, ctx_reg->clkctrl, QSPI_SPI_CLOCK_CNTRL_REG); } +static inline u32 qspi_is_busy(struct ti_qspi *qspi) +{ + u32 stat; + unsigned long timeout = jiffies + QSPI_COMPLETION_TIMEOUT; + + stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); + while ((stat & BUSY) && time_after(timeout, jiffies)) { + cpu_relax(); + stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); + } + + WARN(stat & BUSY, "qspi busy\n"); + return stat & BUSY; +} + static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) { int wlen, count; @@ -211,6 +227,9 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) wlen = t->bits_per_word >> 3; /* in bytes */ while (count) { + if (qspi_is_busy(qspi)) + return -EBUSY; + switch (wlen) { case 1: dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", @@ -266,6 +285,9 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) while (count) { dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); + if (qspi_is_busy(qspi)) + return -EBUSY; + ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); if (!wait_for_completion_timeout(&qspi->transfer_complete, QSPI_COMPLETION_TIMEOUT)) { -- 2.2.1.62.g3f15098 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/