[PATCH V2] spi: bcm2835: enabling polling mode for transfers shorter than 30us
Martin Sperl
kernel at martin.sperl.org
Sat Apr 18 06:31:13 PDT 2015
> On 18.04.2015, at 14:27, Mark Brown <broonie at kernel.org> wrote:
> That's probably fine, though the 40ms is a bit on the long side. The
> 30s timeout could use pulling in too, that's going to fail very badly if
> anything does go wronng.
Anything below 2 jiffies will give enough false positives during a kernel
recompile - the original code has had 2 jiffies as the effective minimum,
because the calculated delivery-time of max 30us is still orders of magnitudes
smaller than a single jiffy, but a reschedule can happen, which would be the
main reason why we have had triggered timeouts before.
SO IMO anything shorter than 2-3 jifies would need to use a new framework to
get access to high-resolution timers - and I do not know how to do that.
We can implement it as 3 jiffies or 30ms if that seems more acceptable.
Would look something like this:
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index 37875cf..1bbfccd 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -68,8 +68,7 @@
#define BCM2835_SPI_CS_CS_10 0x00000002
#define BCM2835_SPI_CS_CS_01 0x00000001
-#define BCM2835_SPI_POLLING_LIMIT_US 30
-#define BCM2835_SPI_TIMEOUT_MS 30000
+#define BCM2835_SPI_POLLING_LIMIT_MS 30
#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS | SPI_3WIRE)
@@ -164,8 +163,9 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
unsigned long xfer_time_us)
{
struct bcm2835_spi *bs = spi_master_get_devdata(master);
- /* set timeout to 1 second of maximum polling */
- unsigned long timeout = jiffies + HZ;
+ /* set timeout and then fall back to interrupts */
+ unsigned long timeout = jiffies +
+ HZ * BCM2835_SPI_POLLING_LIMIT_MS / 1000;
/* enable HW block without interrupts */
bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
@@ -177,13 +177,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
/* fill in tx fifo as much as possible */
bcm2835_wr_fifo(bs);
/* if we still expect some data after the read,
- * check for a possible timeout
+ * check for a possible timeout and if we reach that
+ * then fallback to interrupt mode...
*/
if (bs->rx_len && time_after(jiffies, timeout)) {
- /* Transfer complete - reset SPI HW */
- bcm2835_spi_reset_hw(master);
- /* and return timeout */
- return -ETIMEDOUT;
+ return bcm2835_spi_transfer_one_irq(master, spi,
+ tfr,cs);
}
}
I will need to test it and then I will submit it as a patch against
the 1s timeout patch (so what is already in for-next).
Martin
More information about the linux-rpi-kernel
mailing list