summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@linux-m68k.org>2014-02-04 11:06:24 +0100
committerMark Brown <broonie@linaro.org>2014-02-04 12:11:46 +0100
commit5dd1ad23af689591d70be06ee6efcc57d1ec2d16 (patch)
tree4d86b6e0c10b16211211720f91b8234856123b2c
parentspi: rspi: fix build error when CONFIG_OF is not set (diff)
downloadlinux-5dd1ad23af689591d70be06ee6efcc57d1ec2d16.tar.xz
linux-5dd1ad23af689591d70be06ee6efcc57d1ec2d16.zip
spi: rspi: Only enable interrupts when there's a need to wait
rspi_wait_for_interrupt() unconditionally enables interrupts, even when the wait condition is already satisfied. This causes a high interrupt load (2 interrupts/byte for full-duplex Single SPI transfers, 1 interrupt/byte for RSPI with TX Only mode, or QSPI in unidirectional Dual or Quad Transfer mode). Change this to return immediately when the wait condition is satisfied. This dramatically reduces the interrupt load, especially in high-speed Quad Transfer mode, and increases transfer speed, as no interrupts need to be handled when there's space available in the output FIFO, or data available in the input FIFO. Benchmark results for QSPI on r8a7791 while reading 1 MiB from 30 MHz SPI FLASH on the Koelsch development board: Before: Single SPI Dual SPI Quad SPI Interrupts: 2096856 1048592 1048594 Mbps: 0.9 1.6 1.6 After: Single SPI Dual SPI Quad SPI Interrupts: 1048569 21295 8 Mbps: 0.7 10.8 12.9 I don't know why Single SPI slowed down a bit. I've also verified functionality for RSPI-RZ on r7s72100, but don't have benchmark results as there's no SPI FLASH connected to RSPI on the Genmai development board. Unlike RSPI and QSPI, RSPI-RZ has separate interrupts for RX and TX, which shows that Single SPI transfers now generate (mostly) RX interrupts, as expected. Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--drivers/spi/spi-rspi.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index e5cfc3d77b8c..04528888a53f 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -391,6 +391,9 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
int ret;
rspi->spsr = rspi_read8(rspi, RSPI_SPSR);
+ if (rspi->spsr & wait_mask)
+ return 0;
+
rspi_enable_irq(rspi, enable_bit);
ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ);
if (ret == 0 && !(rspi->spsr & wait_mask))