diff options
| author | Magnus Templing <magnus.templing@stericsson.com> | 2011-05-19 18:05:34 +0200 | 
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2011-05-20 00:43:07 -0600 | 
| commit | a18c266f8e43004c85c56b4077f6158fcadb7707 (patch) | |
| tree | 9a1114717a81abc23a17449fd682ae24020dd1ba | |
| parent | 78fab4c04c76b8c9327541bd270f82b85b42bbf7 (diff) | |
spi/pl022: timeout on polled transfer v2
This adds the missing handling of polling timeouts and deletes
our last todo.
Signed-off-by: Magnus Templing <magnus.templing@stericsson.com>
Reviewed-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
[Fixups from review by Wolfram Sang]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
| -rw-r--r-- | drivers/spi/amba-pl022.c | 23 | 
1 files changed, 15 insertions, 8 deletions
| diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 08de58e7f59f..18667de436f1 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -24,11 +24,6 @@   * GNU General Public License for more details.   */ -/* - * TODO: - * - add timeout on polled transfers - */ -  #include <linux/init.h>  #include <linux/module.h>  #include <linux/device.h> @@ -287,6 +282,8 @@  #define CLEAR_ALL_INTERRUPTS  0x3 +#define SPI_POLLING_TIMEOUT 1000 +  /*   * The type of reading going on on this chip @@ -1378,6 +1375,7 @@ static void do_polling_transfer(struct pl022 *pl022)  	struct spi_transfer *transfer = NULL;  	struct spi_transfer *previous = NULL;  	struct chip_data *chip; +	unsigned long time, timeout;  	chip = pl022->cur_chip;  	message = pl022->cur_msg; @@ -1415,9 +1413,18 @@ static void do_polling_transfer(struct pl022 *pl022)  		       SSP_CR1(pl022->virtbase));  		dev_dbg(&pl022->adev->dev, "polling transfer ongoing ...\n"); -		/* FIXME: insert a timeout so we don't hang here indefinitely */ -		while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) + +		timeout = jiffies + msecs_to_jiffies(SPI_POLLING_TIMEOUT); +		while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) { +			time = jiffies;  			readwriter(pl022); +			if (time_after(time, timeout)) { +				dev_warn(&pl022->adev->dev, +				"%s: timeout!\n", __func__); +				message->state = STATE_ERROR; +				goto out; +			} +		}  		/* Update total byte transferred */  		message->actual_length += pl022->cur_transfer->len; @@ -1426,7 +1433,7 @@ static void do_polling_transfer(struct pl022 *pl022)  		/* Move to next transfer */  		message->state = next_transfer(pl022);  	} - +out:  	/* Handle end of message */  	if (message->state == STATE_DONE)  		message->status = 0; | 
