diff mbox

[U-Boot] spi: omap3: Fix timeout handling

Message ID 1427887960-6566-1-git-send-email-davidcdueck@googlemail.com
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Commit Message

David Dueck April 1, 2015, 11:32 a.m. UTC
The timeout value is never reset during the transfer. This means that when
transferring more data we eventually trigger the timeout.

This was reported on the mailing list:
"Spansion SPI flash read timeout with AM335x"

Signed-off-by: David Dueck <davidcdueck@googlemail.com>
CC: Tom Rini <trini@konsulko.com>
CC: Jagannadh Teki <jagannadh@teki@gmail.com>
CC: Stefan Roese <sr@denx.de>
CC: Andy Pont <andy.pont@sdcsystems.com>
---
 drivers/spi/omap3_spi.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

Comments

Jagan Teki April 1, 2015, 11:56 a.m. UTC | #1
On 1 April 2015 at 17:02, David Dueck <davidcdueck@googlemail.com> wrote:
> The timeout value is never reset during the transfer. This means that when
> transferring more data we eventually trigger the timeout.
>
> This was reported on the mailing list:
> "Spansion SPI flash read timeout with AM335x"
>
> Signed-off-by: David Dueck <davidcdueck@googlemail.com>
> CC: Tom Rini <trini@konsulko.com>
> CC: Jagannadh Teki <jagannadh@teki@gmail.com>
> CC: Stefan Roese <sr@denx.de>
> CC: Andy Pont <andy.pont@sdcsystems.com>
> ---
>  drivers/spi/omap3_spi.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
> index 651e46e..c1b4b33 100644
> --- a/drivers/spi/omap3_spi.c
> +++ b/drivers/spi/omap3_spi.c
> @@ -20,7 +20,7 @@
>  #include <asm/io.h>
>  #include "omap3_spi.h"
>
> -#define SPI_WAIT_TIMEOUT 3000000
> +#define SPI_WAIT_TIMEOUT 10
>
>  static void spi_reset(struct omap3_spi_slave *ds)
>  {
> @@ -227,7 +227,7 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
>  {
>         struct omap3_spi_slave *ds = to_omap3_spi(slave);
>         int i;
> -       int timeout = SPI_WAIT_TIMEOUT;
> +       ulong start;
>         int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
>
>         /* Enable the channel */
> @@ -241,9 +241,10 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
>
>         for (i = 0; i < len; i++) {
>                 /* wait till TX register is empty (TXS == 1) */
> +               start = get_timer(0);
>                 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
>                          OMAP3_MCSPI_CHSTAT_TXS)) {
> -                       if (--timeout <= 0) {
> +                       if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
>                                 printf("SPI TXS timed out, status=0x%08x\n",
>                                        readl(&ds->regs->channel[ds->slave.cs].chstat));
>                                 return -1;
> @@ -280,7 +281,7 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
>  {
>         struct omap3_spi_slave *ds = to_omap3_spi(slave);
>         int i;
> -       int timeout = SPI_WAIT_TIMEOUT;
> +       ulong start;
>         int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
>
>         /* Enable the channel */
> @@ -295,10 +296,11 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
>         writel(0, &ds->regs->channel[ds->slave.cs].tx);
>
>         for (i = 0; i < len; i++) {
> +               start = get_timer(0);
>                 /* Wait till RX register contains data (RXS == 1) */
>                 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
>                          OMAP3_MCSPI_CHSTAT_RXS)) {
> -                       if (--timeout <= 0) {
> +                       if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {

I think this is redundant, please check ie negation to start
what about this

start = get_timer(0);
-----

if (get_timer(start) >  SPI_WAIT_TIMEOUT) {

>                                 printf("SPI RXS timed out, status=0x%08x\n",
>                                        readl(&ds->regs->channel[ds->slave.cs].chstat));
>                                 return -1;
> @@ -332,7 +334,7 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
>                    const void *txp, void *rxp, unsigned long flags)
>  {
>         struct omap3_spi_slave *ds = to_omap3_spi(slave);
> -       int timeout = SPI_WAIT_TIMEOUT;
> +       ulong start;
>         int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
>         int irqstatus = readl(&ds->regs->irqstatus);
>         int i=0;
> @@ -350,9 +352,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
>         for (i=0; i < len; i++){
>                 /* Write: wait for TX empty (TXS == 1)*/
>                 irqstatus |= (1<< (4*(ds->slave.bus)));
> +               start = get_timer(0);
>                 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
>                          OMAP3_MCSPI_CHSTAT_TXS)) {
> -                       if (--timeout <= 0) {
> +                       if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
>                                 printf("SPI TXS timed out, status=0x%08x\n",
>                                        readl(&ds->regs->channel[ds->slave.cs].chstat));
>                                 return -1;
> @@ -368,9 +371,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
>                         writel(((u8 *)txp)[i], tx);
>
>                 /*Read: wait for RX containing data (RXS == 1)*/
> +               start = get_timer(0);
>                 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
>                          OMAP3_MCSPI_CHSTAT_RXS)) {
> -                       if (--timeout <= 0) {
> +                       if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
>                                 printf("SPI RXS timed out, status=0x%08x\n",
>                                        readl(&ds->regs->channel[ds->slave.cs].chstat));
>                                 return -1;
> --
> 2.3.4

thanks!
diff mbox

Patch

diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 651e46e..c1b4b33 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -20,7 +20,7 @@ 
 #include <asm/io.h>
 #include "omap3_spi.h"
 
-#define SPI_WAIT_TIMEOUT 3000000
+#define SPI_WAIT_TIMEOUT 10
 
 static void spi_reset(struct omap3_spi_slave *ds)
 {
@@ -227,7 +227,7 @@  int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
 {
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	int i;
-	int timeout = SPI_WAIT_TIMEOUT;
+	ulong start;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
 	/* Enable the channel */
@@ -241,9 +241,10 @@  int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
 
 	for (i = 0; i < len; i++) {
 		/* wait till TX register is empty (TXS == 1) */
+		start = get_timer(0);
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_TXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
 				printf("SPI TXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
@@ -280,7 +281,7 @@  int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
 {
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
 	int i;
-	int timeout = SPI_WAIT_TIMEOUT;
+	ulong start;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
 	/* Enable the channel */
@@ -295,10 +296,11 @@  int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
 	writel(0, &ds->regs->channel[ds->slave.cs].tx);
 
 	for (i = 0; i < len; i++) {
+		start = get_timer(0);
 		/* Wait till RX register contains data (RXS == 1) */
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_RXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
 				printf("SPI RXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
@@ -332,7 +334,7 @@  int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
 		   const void *txp, void *rxp, unsigned long flags)
 {
 	struct omap3_spi_slave *ds = to_omap3_spi(slave);
-	int timeout = SPI_WAIT_TIMEOUT;
+	ulong start;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 	int irqstatus = readl(&ds->regs->irqstatus);
 	int i=0;
@@ -350,9 +352,10 @@  int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
 	for (i=0; i < len; i++){
 		/* Write: wait for TX empty (TXS == 1)*/
 		irqstatus |= (1<< (4*(ds->slave.bus)));
+		start = get_timer(0);
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_TXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
 				printf("SPI TXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;
@@ -368,9 +371,10 @@  int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
 			writel(((u8 *)txp)[i], tx);
 
 		/*Read: wait for RX containing data (RXS == 1)*/
+		start = get_timer(0);
 		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
 			 OMAP3_MCSPI_CHSTAT_RXS)) {
-			if (--timeout <= 0) {
+			if (get_timer(0) - start > SPI_WAIT_TIMEOUT) {
 				printf("SPI RXS timed out, status=0x%08x\n",
 				       readl(&ds->regs->channel[ds->slave.cs].chstat));
 				return -1;