aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMagnus Templing <magnus.templing@stericsson.com>2011-05-19 12:05:34 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-05-20 02:43:07 -0400
commita18c266f8e43004c85c56b4077f6158fcadb7707 (patch)
tree9a1114717a81abc23a17449fd682ae24020dd1ba /drivers
parent78fab4c04c76b8c9327541bd270f82b85b42bbf7 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/amba-pl022.c23
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 @@
24 * GNU General Public License for more details. 24 * GNU General Public License for more details.
25 */ 25 */
26 26
27/*
28 * TODO:
29 * - add timeout on polled transfers
30 */
31
32#include <linux/init.h> 27#include <linux/init.h>
33#include <linux/module.h> 28#include <linux/module.h>
34#include <linux/device.h> 29#include <linux/device.h>
@@ -287,6 +282,8 @@
287 282
288#define CLEAR_ALL_INTERRUPTS 0x3 283#define CLEAR_ALL_INTERRUPTS 0x3
289 284
285#define SPI_POLLING_TIMEOUT 1000
286
290 287
291/* 288/*
292 * The type of reading going on on this chip 289 * The type of reading going on on this chip
@@ -1378,6 +1375,7 @@ static void do_polling_transfer(struct pl022 *pl022)
1378 struct spi_transfer *transfer = NULL; 1375 struct spi_transfer *transfer = NULL;
1379 struct spi_transfer *previous = NULL; 1376 struct spi_transfer *previous = NULL;
1380 struct chip_data *chip; 1377 struct chip_data *chip;
1378 unsigned long time, timeout;
1381 1379
1382 chip = pl022->cur_chip; 1380 chip = pl022->cur_chip;
1383 message = pl022->cur_msg; 1381 message = pl022->cur_msg;
@@ -1415,9 +1413,18 @@ static void do_polling_transfer(struct pl022 *pl022)
1415 SSP_CR1(pl022->virtbase)); 1413 SSP_CR1(pl022->virtbase));
1416 1414
1417 dev_dbg(&pl022->adev->dev, "polling transfer ongoing ...\n"); 1415 dev_dbg(&pl022->adev->dev, "polling transfer ongoing ...\n");
1418 /* FIXME: insert a timeout so we don't hang here indefinitely */ 1416
1419 while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) 1417 timeout = jiffies + msecs_to_jiffies(SPI_POLLING_TIMEOUT);
1418 while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) {
1419 time = jiffies;
1420 readwriter(pl022); 1420 readwriter(pl022);
1421 if (time_after(time, timeout)) {
1422 dev_warn(&pl022->adev->dev,
1423 "%s: timeout!\n", __func__);
1424 message->state = STATE_ERROR;
1425 goto out;
1426 }
1427 }
1421 1428
1422 /* Update total byte transferred */ 1429 /* Update total byte transferred */
1423 message->actual_length += pl022->cur_transfer->len; 1430 message->actual_length += pl022->cur_transfer->len;
@@ -1426,7 +1433,7 @@ static void do_polling_transfer(struct pl022 *pl022)
1426 /* Move to next transfer */ 1433 /* Move to next transfer */
1427 message->state = next_transfer(pl022); 1434 message->state = next_transfer(pl022);
1428 } 1435 }
1429 1436out:
1430 /* Handle end of message */ 1437 /* Handle end of message */
1431 if (message->state == STATE_DONE) 1438 if (message->state == STATE_DONE)
1432 message->status = 0; 1439 message->status = 0;