diff mbox series

[v3,2/3] spi: s3c64xx: add sleep during transfer

Message ID 20230502062813.112434-3-jaewon02.kim@samsung.com
State New
Headers show
Series Improve polling mode of s3c64xx driver | expand

Commit Message

Jaewon Kim May 2, 2023, 6:28 a.m. UTC
In polling mode, the status register is continuously read to check data
transfer completion. It can cause excessive CPU usage.
To reduce this, we can calculate the transfer time and put the sleep during
transfer.

When test on ExynosAuto9 SADK board, throughput remained the same, but
100% CPU utilization decreased to 40%.

Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
---
 drivers/spi/spi-s3c64xx.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Krzysztof Kozlowski May 5, 2023, 9:09 a.m. UTC | #1
On 02/05/2023 08:28, Jaewon Kim wrote:
> In polling mode, the status register is continuously read to check data
> transfer completion. It can cause excessive CPU usage.
> To reduce this, we can calculate the transfer time and put the sleep during
> transfer.
> 
> When test on ExynosAuto9 SADK board, throughput remained the same, but
> 100% CPU utilization decreased to 40%.
> 
> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof
diff mbox series

Patch

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 66ac94022a1b..2a8304678df9 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -561,11 +561,18 @@  static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
 	u32 cpy_len;
 	u8 *buf;
 	int ms;
+	unsigned long time_us;
 
-	/* millisecs to xfer 'len' bytes @ 'cur_speed' */
-	ms = xfer->len * 8 * 1000 / sdd->cur_speed;
+	/* microsecs to xfer 'len' bytes @ 'cur_speed' */
+	time_us = (xfer->len * 8 * 1000 * 1000) / sdd->cur_speed;
+	ms = (time_us / 1000);
 	ms += 10; /* some tolerance */
 
+	/* sleep during signal transfer time */
+	status = readl(regs + S3C64XX_SPI_STATUS);
+	if (RX_FIFO_LVL(status, sdd) < xfer->len)
+		usleep_range(time_us / 2, time_us);
+
 	val = msecs_to_loops(ms);
 	do {
 		status = readl(regs + S3C64XX_SPI_STATUS);