Message ID | 1305807191-11704-1-git-send-email-linus.walleij@stericsson.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On Thu, May 19, 2011 at 2:44 PM, Wolfram Sang <w.sang@pengutronix.de> wrote: > Hi, > >> - /* 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); > > Won't you miss the transfer if you get interrupted here longer than > SPI_POLLING_TIMEOUT? Yeah... preempted for a second hm. >> + while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) { >> + if (time_after(jiffies, timeout)) { >> + dev_warn(&pl022->adev->dev, >> + "%s: timeout!\n", __func__); >> + message->state = STATE_ERROR; >> + goto out; >> + } >> readwriter(pl022); >> + } What about we move readerwriter() above if (time_after...) then it atleast gets one chance to run even if we're preempted for 10 seconds. Any other design patterns that'd be better? Yours, Linus Walleij ------------------------------------------------------------------------------ What Every C/C++ and Fortran developer Should Know! Read this article and learn how Intel has extended the reach of its next-generation tools to help Windows* and Linux* C/C++ and Fortran developers boost performance applications - including clusters. http://p.sf.net/sfu/intel-dev2devmay
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 08de58e..1f84a8a 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 timeout; chip = pl022->cur_chip; message = pl022->cur_msg; @@ -1415,9 +1413,17 @@ 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) { + if (time_after(jiffies, timeout)) { + dev_warn(&pl022->adev->dev, + "%s: timeout!\n", __func__); + message->state = STATE_ERROR; + goto out; + } readwriter(pl022); + } /* Update total byte transferred */ message->actual_length += pl022->cur_transfer->len; @@ -1426,7 +1432,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;