* [PATCH v3 0/3] Improve polling mode of s3c64xx driver
[not found] <CGME20230502065025epcas2p16f5a02e6990d6f2b2257f001979ebcf9@epcas2p1.samsung.com>
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
Previously, polling mode was supported as quirk for SOC without DMA.
In order to use it more flexibly, it is supported when there is
no dmas property in devicetree, and the issue of using excessive CPU
usage in polling mode is solved by adding sleep during transfer time and
supporting interrupt mode.
Changes in V3.
- Fix patch commit message.
- Change of_find_property() to of_property_present() with code cleanup
- Remove cpu_relax() related patch.
- Changes use_irq variable type to bool
Changes in V2.
- Switched to polling mode if there is no dmas property in devicetree.
- Add cpu_releax() in polling loop
- Add lower limit in IRQ mode
Jaewon Kim (3):
spi: s3c64xx: change polling mode to optional
spi: s3c64xx: add sleep during transfer
spi: s3c64xx: support interrupt based pio mode
drivers/spi/spi-s3c64xx.c | 81 +++++++++++++++++++----
include/linux/platform_data/spi-s3c64xx.h | 1 +
2 files changed, 70 insertions(+), 12 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 0/3] Improve polling mode of s3c64xx driver
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
Previously, polling mode was supported as quirk for SOC without DMA.
In order to use it more flexibly, it is supported when there is
no dmas property in devicetree, and the issue of using excessive CPU
usage in polling mode is solved by adding sleep during transfer time and
supporting interrupt mode.
Changes in V3.
- Fix patch commit message.
- Change of_find_property() to of_property_present() with code cleanup
- Remove cpu_relax() related patch.
- Changes use_irq variable type to bool
Changes in V2.
- Switched to polling mode if there is no dmas property in devicetree.
- Add cpu_releax() in polling loop
- Add lower limit in IRQ mode
Jaewon Kim (3):
spi: s3c64xx: change polling mode to optional
spi: s3c64xx: add sleep during transfer
spi: s3c64xx: support interrupt based pio mode
drivers/spi/spi-s3c64xx.c | 81 +++++++++++++++++++----
include/linux/platform_data/spi-s3c64xx.h | 1 +
2 files changed, 70 insertions(+), 12 deletions(-)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 1/3] spi: s3c64xx: change polling mode to optional
[not found] ` <CGME20230502065025epcas2p4143c8ff3d44b7676ea8667c14618f2cd@epcas2p4.samsung.com>
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
Previously, Polling mode was supported as quirk for SOC without DMA.
To provide more flexible support for polling mode, it changed to polling
mode when the 'dmas' property is not present in the devicetree, rather than
using a quirk.
Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
---
drivers/spi/spi-s3c64xx.c | 4 ++--
include/linux/platform_data/spi-s3c64xx.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 71d324ec9a70..66ac94022a1b 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -19,7 +19,6 @@
#include <linux/platform_data/spi-s3c64xx.h>
#define MAX_SPI_PORTS 12
-#define S3C64XX_SPI_QUIRK_POLL (1 << 0)
#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
#define AUTOSUSPEND_TIMEOUT 2000
@@ -116,7 +115,7 @@
#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
-#define is_polling(x) (x->port_conf->quirks & S3C64XX_SPI_QUIRK_POLL)
+#define is_polling(x) (x->cntrlr_info->polling)
#define RXBUSY (1<<2)
#define TXBUSY (1<<3)
@@ -1068,6 +1067,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
}
sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback");
+ sci->polling = !of_property_present(dev->of_node, "dmas");
return sci;
}
diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h
index 5df1ace6d2c9..cb7b8ddc899f 100644
--- a/include/linux/platform_data/spi-s3c64xx.h
+++ b/include/linux/platform_data/spi-s3c64xx.h
@@ -35,6 +35,7 @@ struct s3c64xx_spi_info {
int src_clk_nr;
int num_cs;
bool no_cs;
+ bool polling;
int (*cfg_gpio)(void);
};
--
2.17.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 1/3] spi: s3c64xx: change polling mode to optional
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
Previously, Polling mode was supported as quirk for SOC without DMA.
To provide more flexible support for polling mode, it changed to polling
mode when the 'dmas' property is not present in the devicetree, rather than
using a quirk.
Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
---
drivers/spi/spi-s3c64xx.c | 4 ++--
include/linux/platform_data/spi-s3c64xx.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 71d324ec9a70..66ac94022a1b 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -19,7 +19,6 @@
#include <linux/platform_data/spi-s3c64xx.h>
#define MAX_SPI_PORTS 12
-#define S3C64XX_SPI_QUIRK_POLL (1 << 0)
#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
#define AUTOSUSPEND_TIMEOUT 2000
@@ -116,7 +115,7 @@
#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
-#define is_polling(x) (x->port_conf->quirks & S3C64XX_SPI_QUIRK_POLL)
+#define is_polling(x) (x->cntrlr_info->polling)
#define RXBUSY (1<<2)
#define TXBUSY (1<<3)
@@ -1068,6 +1067,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
}
sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback");
+ sci->polling = !of_property_present(dev->of_node, "dmas");
return sci;
}
diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h
index 5df1ace6d2c9..cb7b8ddc899f 100644
--- a/include/linux/platform_data/spi-s3c64xx.h
+++ b/include/linux/platform_data/spi-s3c64xx.h
@@ -35,6 +35,7 @@ struct s3c64xx_spi_info {
int src_clk_nr;
int num_cs;
bool no_cs;
+ bool polling;
int (*cfg_gpio)(void);
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 2/3] spi: s3c64xx: add sleep during transfer
[not found] ` <CGME20230502065025epcas2p11549db7400e6707c61bbb1cff1b22252@epcas2p1.samsung.com>
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
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(-)
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);
--
2.17.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 2/3] spi: s3c64xx: add sleep during transfer
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
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(-)
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);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
[not found] ` <CGME20230502065025epcas2p34507ffad60b32e091ff0efeced9bc12f@epcas2p3.samsung.com>
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
Support interrupt based pio mode to optimize cpu usage.
When transmitting data size is larget than 32 bytes, operates with
interrupt based pio mode.
By using the FIFORDY INT, an interrupt can be triggered when
the desired size of data has been received. Using this, we can support
interrupt based pio mode.
Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
---
drivers/spi/spi-s3c64xx.c | 66 ++++++++++++++++++++++++++++++++++-----
1 file changed, 58 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 2a8304678df9..323c6da9730b 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -58,6 +58,8 @@
#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
#define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
#define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
+#define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11)
+#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11
#define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3)
#define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
#define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
@@ -114,6 +116,8 @@
#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
+#define S3C64XX_SPI_POLLING_SIZE 32
+
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
#define is_polling(x) (x->cntrlr_info->polling)
@@ -552,7 +556,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
}
static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
- struct spi_transfer *xfer)
+ struct spi_transfer *xfer, bool use_irq)
{
void __iomem *regs = sdd->regs;
unsigned long val;
@@ -573,6 +577,12 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
if (RX_FIFO_LVL(status, sdd) < xfer->len)
usleep_range(time_us / 2, time_us);
+ if (use_irq) {
+ val = msecs_to_jiffies(ms);
+ if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
+ return -EIO;
+ }
+
val = msecs_to_loops(ms);
do {
status = readl(regs + S3C64XX_SPI_STATUS);
@@ -735,10 +745,13 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
void *rx_buf = NULL;
int target_len = 0, origin_len = 0;
int use_dma = 0;
+ bool use_irq = false;
int status;
u32 speed;
u8 bpw;
unsigned long flags;
+ u32 rdy_lv;
+ u32 val;
reinit_completion(&sdd->xfer_completion);
@@ -759,17 +772,46 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
sdd->rx_dma.ch && sdd->tx_dma.ch) {
use_dma = 1;
- } else if (xfer->len > fifo_len) {
+ } else if (xfer->len >= fifo_len) {
tx_buf = xfer->tx_buf;
rx_buf = xfer->rx_buf;
origin_len = xfer->len;
-
target_len = xfer->len;
- if (xfer->len > fifo_len)
- xfer->len = fifo_len;
+ xfer->len = fifo_len - 1;
}
do {
+ /* transfer size is greater than 32, change to IRQ mode */
+ if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
+ use_irq = true;
+
+ if (use_irq) {
+ reinit_completion(&sdd->xfer_completion);
+
+ rdy_lv = xfer->len;
+ /* Setup RDY_FIFO trigger Level
+ * RDY_LVL =
+ * fifo_lvl up to 64 byte -> N bytes
+ * 128 byte -> RDY_LVL * 2 bytes
+ * 256 byte -> RDY_LVL * 4 bytes
+ */
+ if (fifo_len == 128)
+ rdy_lv /= 2;
+ else if (fifo_len == 256)
+ rdy_lv /= 4;
+
+ val = readl(sdd->regs + S3C64XX_SPI_MODE_CFG);
+ val &= ~S3C64XX_SPI_MODE_RX_RDY_LVL;
+ val |= (rdy_lv << S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT);
+ writel(val, sdd->regs + S3C64XX_SPI_MODE_CFG);
+
+ /* Enable FIFO_RDY_EN IRQ */
+ val = readl(sdd->regs + S3C64XX_SPI_INT_EN);
+ writel((val | S3C64XX_SPI_INT_RX_FIFORDY_EN),
+ sdd->regs + S3C64XX_SPI_INT_EN);
+
+ }
+
spin_lock_irqsave(&sdd->lock, flags);
/* Pending only which is to be done */
@@ -791,7 +833,7 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
if (use_dma)
status = s3c64xx_wait_for_dma(sdd, xfer);
else
- status = s3c64xx_wait_for_pio(sdd, xfer);
+ status = s3c64xx_wait_for_pio(sdd, xfer, use_irq);
if (status) {
dev_err(&spi->dev,
@@ -830,8 +872,8 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
if (xfer->rx_buf)
xfer->rx_buf += xfer->len;
- if (target_len > fifo_len)
- xfer->len = fifo_len;
+ if (target_len >= fifo_len)
+ xfer->len = fifo_len - 1;
else
xfer->len = target_len;
}
@@ -1001,6 +1043,14 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
dev_err(&spi->dev, "TX underrun\n");
}
+ if (val & S3C64XX_SPI_ST_RX_FIFORDY) {
+ complete(&sdd->xfer_completion);
+ /* No pending clear irq, turn-off INT_EN_RX_FIFO_RDY */
+ val = readl(sdd->regs + S3C64XX_SPI_INT_EN);
+ writel((val & ~S3C64XX_SPI_INT_RX_FIFORDY_EN),
+ sdd->regs + S3C64XX_SPI_INT_EN);
+ }
+
/* Clear the pending irq by setting and then clearing it */
writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR);
writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR);
--
2.17.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
@ 2023-05-02 6:28 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-02 6:28 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Jaewon Kim
Support interrupt based pio mode to optimize cpu usage.
When transmitting data size is larget than 32 bytes, operates with
interrupt based pio mode.
By using the FIFORDY INT, an interrupt can be triggered when
the desired size of data has been received. Using this, we can support
interrupt based pio mode.
Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
---
drivers/spi/spi-s3c64xx.c | 66 ++++++++++++++++++++++++++++++++++-----
1 file changed, 58 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 2a8304678df9..323c6da9730b 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -58,6 +58,8 @@
#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
#define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
#define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
+#define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11)
+#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11
#define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3)
#define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
#define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
@@ -114,6 +116,8 @@
#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
+#define S3C64XX_SPI_POLLING_SIZE 32
+
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
#define is_polling(x) (x->cntrlr_info->polling)
@@ -552,7 +556,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
}
static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
- struct spi_transfer *xfer)
+ struct spi_transfer *xfer, bool use_irq)
{
void __iomem *regs = sdd->regs;
unsigned long val;
@@ -573,6 +577,12 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
if (RX_FIFO_LVL(status, sdd) < xfer->len)
usleep_range(time_us / 2, time_us);
+ if (use_irq) {
+ val = msecs_to_jiffies(ms);
+ if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
+ return -EIO;
+ }
+
val = msecs_to_loops(ms);
do {
status = readl(regs + S3C64XX_SPI_STATUS);
@@ -735,10 +745,13 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
void *rx_buf = NULL;
int target_len = 0, origin_len = 0;
int use_dma = 0;
+ bool use_irq = false;
int status;
u32 speed;
u8 bpw;
unsigned long flags;
+ u32 rdy_lv;
+ u32 val;
reinit_completion(&sdd->xfer_completion);
@@ -759,17 +772,46 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
sdd->rx_dma.ch && sdd->tx_dma.ch) {
use_dma = 1;
- } else if (xfer->len > fifo_len) {
+ } else if (xfer->len >= fifo_len) {
tx_buf = xfer->tx_buf;
rx_buf = xfer->rx_buf;
origin_len = xfer->len;
-
target_len = xfer->len;
- if (xfer->len > fifo_len)
- xfer->len = fifo_len;
+ xfer->len = fifo_len - 1;
}
do {
+ /* transfer size is greater than 32, change to IRQ mode */
+ if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
+ use_irq = true;
+
+ if (use_irq) {
+ reinit_completion(&sdd->xfer_completion);
+
+ rdy_lv = xfer->len;
+ /* Setup RDY_FIFO trigger Level
+ * RDY_LVL =
+ * fifo_lvl up to 64 byte -> N bytes
+ * 128 byte -> RDY_LVL * 2 bytes
+ * 256 byte -> RDY_LVL * 4 bytes
+ */
+ if (fifo_len == 128)
+ rdy_lv /= 2;
+ else if (fifo_len == 256)
+ rdy_lv /= 4;
+
+ val = readl(sdd->regs + S3C64XX_SPI_MODE_CFG);
+ val &= ~S3C64XX_SPI_MODE_RX_RDY_LVL;
+ val |= (rdy_lv << S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT);
+ writel(val, sdd->regs + S3C64XX_SPI_MODE_CFG);
+
+ /* Enable FIFO_RDY_EN IRQ */
+ val = readl(sdd->regs + S3C64XX_SPI_INT_EN);
+ writel((val | S3C64XX_SPI_INT_RX_FIFORDY_EN),
+ sdd->regs + S3C64XX_SPI_INT_EN);
+
+ }
+
spin_lock_irqsave(&sdd->lock, flags);
/* Pending only which is to be done */
@@ -791,7 +833,7 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
if (use_dma)
status = s3c64xx_wait_for_dma(sdd, xfer);
else
- status = s3c64xx_wait_for_pio(sdd, xfer);
+ status = s3c64xx_wait_for_pio(sdd, xfer, use_irq);
if (status) {
dev_err(&spi->dev,
@@ -830,8 +872,8 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
if (xfer->rx_buf)
xfer->rx_buf += xfer->len;
- if (target_len > fifo_len)
- xfer->len = fifo_len;
+ if (target_len >= fifo_len)
+ xfer->len = fifo_len - 1;
else
xfer->len = target_len;
}
@@ -1001,6 +1043,14 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
dev_err(&spi->dev, "TX underrun\n");
}
+ if (val & S3C64XX_SPI_ST_RX_FIFORDY) {
+ complete(&sdd->xfer_completion);
+ /* No pending clear irq, turn-off INT_EN_RX_FIFO_RDY */
+ val = readl(sdd->regs + S3C64XX_SPI_INT_EN);
+ writel((val & ~S3C64XX_SPI_INT_RX_FIFORDY_EN),
+ sdd->regs + S3C64XX_SPI_INT_EN);
+ }
+
/* Clear the pending irq by setting and then clearing it */
writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR);
writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 1/3] spi: s3c64xx: change polling mode to optional
2023-05-02 6:28 ` Jaewon Kim
@ 2023-05-05 9:09 ` Krzysztof Kozlowski
-1 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2023-05-05 9:09 UTC (permalink / raw)
To: Jaewon Kim, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On 02/05/2023 08:28, Jaewon Kim wrote:
> Previously, Polling mode was supported as quirk for SOC without DMA.
> To provide more flexible support for polling mode, it changed to polling
> mode when the 'dmas' property is not present in the devicetree, rather than
> using a quirk.
>
> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 1/3] spi: s3c64xx: change polling mode to optional
@ 2023-05-05 9:09 ` Krzysztof Kozlowski
0 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2023-05-05 9:09 UTC (permalink / raw)
To: Jaewon Kim, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On 02/05/2023 08:28, Jaewon Kim wrote:
> Previously, Polling mode was supported as quirk for SOC without DMA.
> To provide more flexible support for polling mode, it changed to polling
> mode when the 'dmas' property is not present in the devicetree, rather than
> using a quirk.
>
> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] spi: s3c64xx: add sleep during transfer
2023-05-02 6:28 ` Jaewon Kim
@ 2023-05-05 9:09 ` Krzysztof Kozlowski
-1 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2023-05-05 9:09 UTC (permalink / raw)
To: Jaewon Kim, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
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
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] spi: s3c64xx: add sleep during transfer
@ 2023-05-05 9:09 ` Krzysztof Kozlowski
0 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2023-05-05 9:09 UTC (permalink / raw)
To: Jaewon Kim, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
2023-05-02 6:28 ` Jaewon Kim
@ 2023-05-05 9:47 ` Krzysztof Kozlowski
-1 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2023-05-05 9:47 UTC (permalink / raw)
To: Jaewon Kim, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On 02/05/2023 08:28, Jaewon Kim wrote:
> Support interrupt based pio mode to optimize cpu usage.
> When transmitting data size is larget than 32 bytes, operates with
> interrupt based pio mode.
>
> By using the FIFORDY INT, an interrupt can be triggered when
> the desired size of data has been received. Using this, we can support
> interrupt based pio mode.
>
> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
> ---
> drivers/spi/spi-s3c64xx.c | 66 ++++++++++++++++++++++++++++++++++-----
> 1 file changed, 58 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 2a8304678df9..323c6da9730b 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -58,6 +58,8 @@
> #define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
> #define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
> #define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
> +#define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11)
> +#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11
> #define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3)
> #define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
> #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
> @@ -114,6 +116,8 @@
>
> #define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
>
> +#define S3C64XX_SPI_POLLING_SIZE 32
> +
> #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
> #define is_polling(x) (x->cntrlr_info->polling)
>
> @@ -552,7 +556,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
> }
>
> static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
> - struct spi_transfer *xfer)
> + struct spi_transfer *xfer, bool use_irq)
> {
> void __iomem *regs = sdd->regs;
> unsigned long val;
> @@ -573,6 +577,12 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
> if (RX_FIFO_LVL(status, sdd) < xfer->len)
> usleep_range(time_us / 2, time_us);
>
> + if (use_irq) {
> + val = msecs_to_jiffies(ms);
> + if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
> + return -EIO;
> + }
> +
> val = msecs_to_loops(ms);
> do {
> status = readl(regs + S3C64XX_SPI_STATUS);
> @@ -735,10 +745,13 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
> void *rx_buf = NULL;
> int target_len = 0, origin_len = 0;
> int use_dma = 0;
> + bool use_irq = false;
> int status;
> u32 speed;
> u8 bpw;
> unsigned long flags;
> + u32 rdy_lv;
> + u32 val;
>
> reinit_completion(&sdd->xfer_completion);
>
> @@ -759,17 +772,46 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
> sdd->rx_dma.ch && sdd->tx_dma.ch) {
> use_dma = 1;
>
> - } else if (xfer->len > fifo_len) {
> + } else if (xfer->len >= fifo_len) {
I don't fully understand this. If len equals to fifo_len, everything
would fit into FIFO so no need for all this?
> tx_buf = xfer->tx_buf;
> rx_buf = xfer->rx_buf;
> origin_len = xfer->len;
> -
> target_len = xfer->len;
> - if (xfer->len > fifo_len)
> - xfer->len = fifo_len;
> + xfer->len = fifo_len - 1;
> }
>
> do {
> + /* transfer size is greater than 32, change to IRQ mode */
> + if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
> + use_irq = true;
> +
> + if (use_irq) {
> + reinit_completion(&sdd->xfer_completion);
> +
> + rdy_lv = xfer->len;
Style is:
/*
*
> + /* Setup RDY_FIFO trigger Level
> + * RDY_LVL =
> + * fifo_lvl up to 64 byte -> N bytes
> + * 128 byte -> RDY_LVL * 2 bytes
> + * 256 byte -> RDY_LVL * 4 bytes
I don't understand it. Based on this equation for 256 bytes,
RDY_LVL = RDY_LVL * 4?
Didn't you mean xfer->len?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
@ 2023-05-05 9:47 ` Krzysztof Kozlowski
0 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Kozlowski @ 2023-05-05 9:47 UTC (permalink / raw)
To: Jaewon Kim, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On 02/05/2023 08:28, Jaewon Kim wrote:
> Support interrupt based pio mode to optimize cpu usage.
> When transmitting data size is larget than 32 bytes, operates with
> interrupt based pio mode.
>
> By using the FIFORDY INT, an interrupt can be triggered when
> the desired size of data has been received. Using this, we can support
> interrupt based pio mode.
>
> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
> ---
> drivers/spi/spi-s3c64xx.c | 66 ++++++++++++++++++++++++++++++++++-----
> 1 file changed, 58 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 2a8304678df9..323c6da9730b 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -58,6 +58,8 @@
> #define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
> #define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
> #define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
> +#define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11)
> +#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11
> #define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3)
> #define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
> #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
> @@ -114,6 +116,8 @@
>
> #define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
>
> +#define S3C64XX_SPI_POLLING_SIZE 32
> +
> #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
> #define is_polling(x) (x->cntrlr_info->polling)
>
> @@ -552,7 +556,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
> }
>
> static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
> - struct spi_transfer *xfer)
> + struct spi_transfer *xfer, bool use_irq)
> {
> void __iomem *regs = sdd->regs;
> unsigned long val;
> @@ -573,6 +577,12 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
> if (RX_FIFO_LVL(status, sdd) < xfer->len)
> usleep_range(time_us / 2, time_us);
>
> + if (use_irq) {
> + val = msecs_to_jiffies(ms);
> + if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
> + return -EIO;
> + }
> +
> val = msecs_to_loops(ms);
> do {
> status = readl(regs + S3C64XX_SPI_STATUS);
> @@ -735,10 +745,13 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
> void *rx_buf = NULL;
> int target_len = 0, origin_len = 0;
> int use_dma = 0;
> + bool use_irq = false;
> int status;
> u32 speed;
> u8 bpw;
> unsigned long flags;
> + u32 rdy_lv;
> + u32 val;
>
> reinit_completion(&sdd->xfer_completion);
>
> @@ -759,17 +772,46 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
> sdd->rx_dma.ch && sdd->tx_dma.ch) {
> use_dma = 1;
>
> - } else if (xfer->len > fifo_len) {
> + } else if (xfer->len >= fifo_len) {
I don't fully understand this. If len equals to fifo_len, everything
would fit into FIFO so no need for all this?
> tx_buf = xfer->tx_buf;
> rx_buf = xfer->rx_buf;
> origin_len = xfer->len;
> -
> target_len = xfer->len;
> - if (xfer->len > fifo_len)
> - xfer->len = fifo_len;
> + xfer->len = fifo_len - 1;
> }
>
> do {
> + /* transfer size is greater than 32, change to IRQ mode */
> + if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
> + use_irq = true;
> +
> + if (use_irq) {
> + reinit_completion(&sdd->xfer_completion);
> +
> + rdy_lv = xfer->len;
Style is:
/*
*
> + /* Setup RDY_FIFO trigger Level
> + * RDY_LVL =
> + * fifo_lvl up to 64 byte -> N bytes
> + * 128 byte -> RDY_LVL * 2 bytes
> + * 256 byte -> RDY_LVL * 4 bytes
I don't understand it. Based on this equation for 256 bytes,
RDY_LVL = RDY_LVL * 4?
Didn't you mean xfer->len?
Best regards,
Krzysztof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
2023-05-05 9:47 ` Krzysztof Kozlowski
@ 2023-05-08 1:42 ` Jaewon Kim
-1 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-08 1:42 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On 23. 5. 5. 18:47, Krzysztof Kozlowski wrote:
> On 02/05/2023 08:28, Jaewon Kim wrote:
>> Support interrupt based pio mode to optimize cpu usage.
>> When transmitting data size is larget than 32 bytes, operates with
>> interrupt based pio mode.
>>
>> By using the FIFORDY INT, an interrupt can be triggered when
>> the desired size of data has been received. Using this, we can support
>> interrupt based pio mode.
>>
>> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
>> ---
>> drivers/spi/spi-s3c64xx.c | 66 ++++++++++++++++++++++++++++++++++-----
>> 1 file changed, 58 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
>> index 2a8304678df9..323c6da9730b 100644
>> --- a/drivers/spi/spi-s3c64xx.c
>> +++ b/drivers/spi/spi-s3c64xx.c
>> @@ -58,6 +58,8 @@
>> #define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
>> #define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
>> #define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
>> +#define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11)
>> +#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11
>> #define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3)
>> #define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
>> #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
>> @@ -114,6 +116,8 @@
>>
>> #define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
>>
>> +#define S3C64XX_SPI_POLLING_SIZE 32
>> +
>> #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
>> #define is_polling(x) (x->cntrlr_info->polling)
>>
>> @@ -552,7 +556,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
>> }
>>
>> static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
>> - struct spi_transfer *xfer)
>> + struct spi_transfer *xfer, bool use_irq)
>> {
>> void __iomem *regs = sdd->regs;
>> unsigned long val;
>> @@ -573,6 +577,12 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
>> if (RX_FIFO_LVL(status, sdd) < xfer->len)
>> usleep_range(time_us / 2, time_us);
>>
>> + if (use_irq) {
>> + val = msecs_to_jiffies(ms);
>> + if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
>> + return -EIO;
>> + }
>> +
>> val = msecs_to_loops(ms);
>> do {
>> status = readl(regs + S3C64XX_SPI_STATUS);
>> @@ -735,10 +745,13 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
>> void *rx_buf = NULL;
>> int target_len = 0, origin_len = 0;
>> int use_dma = 0;
>> + bool use_irq = false;
>> int status;
>> u32 speed;
>> u8 bpw;
>> unsigned long flags;
>> + u32 rdy_lv;
>> + u32 val;
>>
>> reinit_completion(&sdd->xfer_completion);
>>
>> @@ -759,17 +772,46 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
>> sdd->rx_dma.ch && sdd->tx_dma.ch) {
>> use_dma = 1;
>>
>> - } else if (xfer->len > fifo_len) {
>> + } else if (xfer->len >= fifo_len) {
> I don't fully understand this. If len equals to fifo_len, everything
> would fit into FIFO so no need for all this?
If the FIFO is filled with data, TX Overrun & RX Underrun interrupts
will occur.
In CPU polling, there is no such issue because data is read before an
interrupt occurs.
And, RDY_LVL has only 6 bits.(max. 63). we cannot set trigger level on
the FIFO max size.
>> tx_buf = xfer->tx_buf;
>> rx_buf = xfer->rx_buf;
>> origin_len = xfer->len;
>> -
>> target_len = xfer->len;
>> - if (xfer->len > fifo_len)
>> - xfer->len = fifo_len;
>> + xfer->len = fifo_len - 1;
>> }
>>
>> do {
>> + /* transfer size is greater than 32, change to IRQ mode */
>> + if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
>> + use_irq = true;
>> +
>> + if (use_irq) {
>> + reinit_completion(&sdd->xfer_completion);
>> +
>> + rdy_lv = xfer->len;
> Style is:
>
> /*
> *
>
>> + /* Setup RDY_FIFO trigger Level
>> + * RDY_LVL =
>> + * fifo_lvl up to 64 byte -> N bytes
>> + * 128 byte -> RDY_LVL * 2 bytes
>> + * 256 byte -> RDY_LVL * 4 bytes
> I don't understand it. Based on this equation for 256 bytes,
> RDY_LVL = RDY_LVL * 4?
> Didn't you mean xfer->len?
In v4, I will change it to the following
/*
* Trigger Level =
* (N = value of RDY_LVL field)
* fifo_lvl up to 64 byte -> N bytes
* 128 byte -> N * 2 bytes
* 256 byte -> N * 4 bytes
*/
>
>
> Best regards,
> Krzysztof
>
>
Thanks
Jaewon Kim
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
@ 2023-05-08 1:42 ` Jaewon Kim
0 siblings, 0 replies; 20+ messages in thread
From: Jaewon Kim @ 2023-05-08 1:42 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On 23. 5. 5. 18:47, Krzysztof Kozlowski wrote:
> On 02/05/2023 08:28, Jaewon Kim wrote:
>> Support interrupt based pio mode to optimize cpu usage.
>> When transmitting data size is larget than 32 bytes, operates with
>> interrupt based pio mode.
>>
>> By using the FIFORDY INT, an interrupt can be triggered when
>> the desired size of data has been received. Using this, we can support
>> interrupt based pio mode.
>>
>> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
>> ---
>> drivers/spi/spi-s3c64xx.c | 66 ++++++++++++++++++++++++++++++++++-----
>> 1 file changed, 58 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
>> index 2a8304678df9..323c6da9730b 100644
>> --- a/drivers/spi/spi-s3c64xx.c
>> +++ b/drivers/spi/spi-s3c64xx.c
>> @@ -58,6 +58,8 @@
>> #define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
>> #define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
>> #define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
>> +#define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11)
>> +#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11
>> #define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3)
>> #define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
>> #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
>> @@ -114,6 +116,8 @@
>>
>> #define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
>>
>> +#define S3C64XX_SPI_POLLING_SIZE 32
>> +
>> #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
>> #define is_polling(x) (x->cntrlr_info->polling)
>>
>> @@ -552,7 +556,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
>> }
>>
>> static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
>> - struct spi_transfer *xfer)
>> + struct spi_transfer *xfer, bool use_irq)
>> {
>> void __iomem *regs = sdd->regs;
>> unsigned long val;
>> @@ -573,6 +577,12 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
>> if (RX_FIFO_LVL(status, sdd) < xfer->len)
>> usleep_range(time_us / 2, time_us);
>>
>> + if (use_irq) {
>> + val = msecs_to_jiffies(ms);
>> + if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
>> + return -EIO;
>> + }
>> +
>> val = msecs_to_loops(ms);
>> do {
>> status = readl(regs + S3C64XX_SPI_STATUS);
>> @@ -735,10 +745,13 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
>> void *rx_buf = NULL;
>> int target_len = 0, origin_len = 0;
>> int use_dma = 0;
>> + bool use_irq = false;
>> int status;
>> u32 speed;
>> u8 bpw;
>> unsigned long flags;
>> + u32 rdy_lv;
>> + u32 val;
>>
>> reinit_completion(&sdd->xfer_completion);
>>
>> @@ -759,17 +772,46 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
>> sdd->rx_dma.ch && sdd->tx_dma.ch) {
>> use_dma = 1;
>>
>> - } else if (xfer->len > fifo_len) {
>> + } else if (xfer->len >= fifo_len) {
> I don't fully understand this. If len equals to fifo_len, everything
> would fit into FIFO so no need for all this?
If the FIFO is filled with data, TX Overrun & RX Underrun interrupts
will occur.
In CPU polling, there is no such issue because data is read before an
interrupt occurs.
And, RDY_LVL has only 6 bits.(max. 63). we cannot set trigger level on
the FIFO max size.
>> tx_buf = xfer->tx_buf;
>> rx_buf = xfer->rx_buf;
>> origin_len = xfer->len;
>> -
>> target_len = xfer->len;
>> - if (xfer->len > fifo_len)
>> - xfer->len = fifo_len;
>> + xfer->len = fifo_len - 1;
>> }
>>
>> do {
>> + /* transfer size is greater than 32, change to IRQ mode */
>> + if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
>> + use_irq = true;
>> +
>> + if (use_irq) {
>> + reinit_completion(&sdd->xfer_completion);
>> +
>> + rdy_lv = xfer->len;
> Style is:
>
> /*
> *
>
>> + /* Setup RDY_FIFO trigger Level
>> + * RDY_LVL =
>> + * fifo_lvl up to 64 byte -> N bytes
>> + * 128 byte -> RDY_LVL * 2 bytes
>> + * 256 byte -> RDY_LVL * 4 bytes
> I don't understand it. Based on this equation for 256 bytes,
> RDY_LVL = RDY_LVL * 4?
> Didn't you mean xfer->len?
In v4, I will change it to the following
/*
* Trigger Level =
* (N = value of RDY_LVL field)
* fifo_lvl up to 64 byte -> N bytes
* 128 byte -> N * 2 bytes
* 256 byte -> N * 4 bytes
*/
>
>
> Best regards,
> Krzysztof
>
>
Thanks
Jaewon Kim
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 0/3] Improve polling mode of s3c64xx driver
2023-05-02 6:28 ` Jaewon Kim
` (3 preceding siblings ...)
(?)
@ 2023-05-08 13:27 ` Mark Brown
-1 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2023-05-08 13:27 UTC (permalink / raw)
To: Krzysztof Kozlowski, Andi Shyti, Alim Akhtar, Jaewon Kim
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park
On Tue, 02 May 2023 15:28:10 +0900, Jaewon Kim wrote:
> Previously, polling mode was supported as quirk for SOC without DMA.
> In order to use it more flexibly, it is supported when there is
> no dmas property in devicetree, and the issue of using excessive CPU
> usage in polling mode is solved by adding sleep during transfer time and
> supporting interrupt mode.
>
> Changes in V3.
> - Fix patch commit message.
> - Change of_find_property() to of_property_present() with code cleanup
> - Remove cpu_relax() related patch.
> - Changes use_irq variable type to bool
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
Thanks!
[1/3] spi: s3c64xx: change polling mode to optional
commit: d1a7718ee8dbcc488d3243d52e19c755123e0024
[2/3] spi: s3c64xx: add sleep during transfer
commit: 3456674f54d3cfdedb28ce8a3db2b6f975392ac8
[3/3] spi: s3c64xx: support interrupt based pio mode
commit: 1ee806718d5ef7de31c6063c4493f3d6527c9427
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
2023-05-02 6:28 ` Jaewon Kim
(?)
(?)
@ 2023-05-09 13:03 ` Marek Szyprowski
2023-05-10 4:05 ` Jaewon Kim
-1 siblings, 1 reply; 20+ messages in thread
From: Marek Szyprowski @ 2023-05-09 13:03 UTC (permalink / raw)
To: Jaewon Kim, Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Łukasz Stelmach
On 02.05.2023 08:28, Jaewon Kim wrote:
> Support interrupt based pio mode to optimize cpu usage.
> When transmitting data size is larget than 32 bytes, operates with
> interrupt based pio mode.
>
> By using the FIFORDY INT, an interrupt can be triggered when
> the desired size of data has been received. Using this, we can support
> interrupt based pio mode.
>
> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
This patch landed recently in linux-next as commit 1ee806718d5e ("spi:
s3c64xx: support interrupt based pio mode"). Unfortunately it breaks
ethernet chip operation on Exynos3250 based Artik5 Development board. I
see the flood of the following messages:
[ 36.097739] ax88796c spi0.0: I/O Error: rx-1 tx-0 rx-f tx-p len-496
dma-1 res-(-5)
[ 36.100877] ax88796c spi0.0: RX residue: 248
[ 36.101383] ax88796c spi0.0: SPI transfer failed: -5
[ 36.101939] spi_master spi0: failed to transfer one message from queue
[ 36.102439] ax88796c spi0.0: axspi_read_rxq() failed: ret = -5
[ 36.107830] s3c64xx-spi 13920000.spi: Failed to get RX DMA channel
[ 36.148875] ax88796c spi0.0: I/O Error: rx-0 tx-1 rx-p tx-f len-4
dma-0 res-(-5)
[ 36.149517] ax88796c spi0.0: SPI transfer failed: -5
[ 36.150053] spi_master spi0: failed to transfer one message from queue
[ 36.150562] ax88796c spi0.0: axspi_read_reg() failed: ret = -5
[ 36.152175] s3c64xx-spi 13920000.spi: Failed to get RX DMA channel
[ 36.191651] ax88796c spi0.0: I/O Error: rx-0 tx-1 rx-p tx-f len-4
dma-0 res-(-5)
[ 36.192268] ax88796c spi0.0: SPI transfer failed: -5
...
I didn't analyze the details, but imho it looks like some kind of
mishandling of the corner case or switching between PIO and DMA mode. I
will check the details later.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
2023-05-09 13:03 ` Marek Szyprowski
@ 2023-05-10 4:05 ` Jaewon Kim
2023-05-10 6:54 ` Marek Szyprowski
0 siblings, 1 reply; 20+ messages in thread
From: Jaewon Kim @ 2023-05-10 4:05 UTC (permalink / raw)
To: Marek Szyprowski, Krzysztof Kozlowski, Andi Shyti, Mark Brown,
Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Łukasz Stelmach
Hello Marek
On 23. 5. 9. 22:03, Marek Szyprowski wrote:
> On 02.05.2023 08:28, Jaewon Kim wrote:
>> Support interrupt based pio mode to optimize cpu usage.
>> When transmitting data size is larget than 32 bytes, operates with
>> interrupt based pio mode.
>>
>> By using the FIFORDY INT, an interrupt can be triggered when
>> the desired size of data has been received. Using this, we can support
>> interrupt based pio mode.
>>
>> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
> This patch landed recently in linux-next as commit 1ee806718d5e ("spi:
> s3c64xx: support interrupt based pio mode"). Unfortunately it breaks
> ethernet chip operation on Exynos3250 based Artik5 Development board. I
> see the flood of the following messages:
>
> [ 36.097739] ax88796c spi0.0: I/O Error: rx-1 tx-0 rx-f tx-p len-496
> dma-1 res-(-5)
> [ 36.100877] ax88796c spi0.0: RX residue: 248
> [ 36.101383] ax88796c spi0.0: SPI transfer failed: -5
> [ 36.101939] spi_master spi0: failed to transfer one message from queue
> [ 36.102439] ax88796c spi0.0: axspi_read_rxq() failed: ret = -5
> [ 36.107830] s3c64xx-spi 13920000.spi: Failed to get RX DMA channel
> [ 36.148875] ax88796c spi0.0: I/O Error: rx-0 tx-1 rx-p tx-f len-4
> dma-0 res-(-5)
> [ 36.149517] ax88796c spi0.0: SPI transfer failed: -5
> [ 36.150053] spi_master spi0: failed to transfer one message from queue
> [ 36.150562] ax88796c spi0.0: axspi_read_reg() failed: ret = -5
> [ 36.152175] s3c64xx-spi 13920000.spi: Failed to get RX DMA channel
> [ 36.191651] ax88796c spi0.0: I/O Error: rx-0 tx-1 rx-p tx-f len-4
> dma-0 res-(-5)
> [ 36.192268] ax88796c spi0.0: SPI transfer failed: -5
>
> ...
>
> I didn't analyze the details, but imho it looks like some kind of
> mishandling of the corner case or switching between PIO and DMA mode. I
> will check the details later.
>
>
> Best regards
Thanks for testing the various cases.
The problem occurred when DMA mode and IRQ mode were enabled at the same
time.
In the above case, BUS_WIDTH register invaded.
Because, target length 496 were written to RX_RDY_LVL, but it exceeded
6-bits.
Could you test with below code??? If the problem is solved, I will send
a fix patch as soon as possible.
-----------------------------
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 238db29fc93b..a72e11e965c3 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -782,7 +782,7 @@ static int s3c64xx_spi_transfer_one(struct
spi_master *master,
do {
/* transfer size is greater than 32, change to IRQ mode */
- if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
+ if (!use_dma && (xfer->len > S3C64XX_SPI_POLLING_SIZE))
use_irq = true;
if (use_irq) {
-----------------------------
Best regards
Jaewon Kim
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode
2023-05-10 4:05 ` Jaewon Kim
@ 2023-05-10 6:54 ` Marek Szyprowski
0 siblings, 0 replies; 20+ messages in thread
From: Marek Szyprowski @ 2023-05-10 6:54 UTC (permalink / raw)
To: Jaewon Kim, Krzysztof Kozlowski, Andi Shyti, Mark Brown, Alim Akhtar
Cc: linux-spi, linux-samsung-soc, linux-arm-kernel, linux-kernel,
Chanho Park, Łukasz Stelmach
On 10.05.2023 06:05, Jaewon Kim wrote:
> Hello Marek
>
>
> On 23. 5. 9. 22:03, Marek Szyprowski wrote:
>> On 02.05.2023 08:28, Jaewon Kim wrote:
>>> Support interrupt based pio mode to optimize cpu usage.
>>> When transmitting data size is larget than 32 bytes, operates with
>>> interrupt based pio mode.
>>>
>>> By using the FIFORDY INT, an interrupt can be triggered when
>>> the desired size of data has been received. Using this, we can support
>>> interrupt based pio mode.
>>>
>>> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
>> This patch landed recently in linux-next as commit 1ee806718d5e ("spi:
>> s3c64xx: support interrupt based pio mode"). Unfortunately it breaks
>> ethernet chip operation on Exynos3250 based Artik5 Development board. I
>> see the flood of the following messages:
>>
>> [ 36.097739] ax88796c spi0.0: I/O Error: rx-1 tx-0 rx-f tx-p len-496
>> dma-1 res-(-5)
>> [ 36.100877] ax88796c spi0.0: RX residue: 248
>> [ 36.101383] ax88796c spi0.0: SPI transfer failed: -5
>> [ 36.101939] spi_master spi0: failed to transfer one message from queue
>> [ 36.102439] ax88796c spi0.0: axspi_read_rxq() failed: ret = -5
>> [ 36.107830] s3c64xx-spi 13920000.spi: Failed to get RX DMA channel
>> [ 36.148875] ax88796c spi0.0: I/O Error: rx-0 tx-1 rx-p tx-f len-4
>> dma-0 res-(-5)
>> [ 36.149517] ax88796c spi0.0: SPI transfer failed: -5
>> [ 36.150053] spi_master spi0: failed to transfer one message from queue
>> [ 36.150562] ax88796c spi0.0: axspi_read_reg() failed: ret = -5
>> [ 36.152175] s3c64xx-spi 13920000.spi: Failed to get RX DMA channel
>> [ 36.191651] ax88796c spi0.0: I/O Error: rx-0 tx-1 rx-p tx-f len-4
>> dma-0 res-(-5)
>> [ 36.192268] ax88796c spi0.0: SPI transfer failed: -5
>>
>> ...
>>
>> I didn't analyze the details, but imho it looks like some kind of
>> mishandling of the corner case or switching between PIO and DMA mode. I
>> will check the details later.
>>
>>
>> Best regards
>
> Thanks for testing the various cases.
>
> The problem occurred when DMA mode and IRQ mode were enabled at the same
> time.
>
>
> In the above case, BUS_WIDTH register invaded.
>
> Because, target length 496 were written to RX_RDY_LVL, but it exceeded
> 6-bits.
>
> Could you test with below code??? If the problem is solved, I will send
> a fix patch as soon as possible.
Thanks for quick response. Indeed, the proposed patch fixed the issue!
Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> -----------------------------
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 238db29fc93b..a72e11e965c3 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -782,7 +782,7 @@ static int s3c64xx_spi_transfer_one(struct
> spi_master *master,
>
> do {
> /* transfer size is greater than 32, change to IRQ mode */
> - if (xfer->len > S3C64XX_SPI_POLLING_SIZE)
> + if (!use_dma && (xfer->len > S3C64XX_SPI_POLLING_SIZE))
Parentheses around 'xfer->len > S3C64XX_SPI_POLLING_SIZE' are not needed.
> use_irq = true;
>
> if (use_irq) {
>
> -----------------------------
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2023-05-10 6:54 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <CGME20230502065025epcas2p16f5a02e6990d6f2b2257f001979ebcf9@epcas2p1.samsung.com>
2023-05-02 6:28 ` [PATCH v3 0/3] Improve polling mode of s3c64xx driver Jaewon Kim
2023-05-02 6:28 ` Jaewon Kim
[not found] ` <CGME20230502065025epcas2p4143c8ff3d44b7676ea8667c14618f2cd@epcas2p4.samsung.com>
2023-05-02 6:28 ` [PATCH v3 1/3] spi: s3c64xx: change polling mode to optional Jaewon Kim
2023-05-02 6:28 ` Jaewon Kim
2023-05-05 9:09 ` Krzysztof Kozlowski
2023-05-05 9:09 ` Krzysztof Kozlowski
[not found] ` <CGME20230502065025epcas2p11549db7400e6707c61bbb1cff1b22252@epcas2p1.samsung.com>
2023-05-02 6:28 ` [PATCH v3 2/3] spi: s3c64xx: add sleep during transfer Jaewon Kim
2023-05-02 6:28 ` Jaewon Kim
2023-05-05 9:09 ` Krzysztof Kozlowski
2023-05-05 9:09 ` Krzysztof Kozlowski
[not found] ` <CGME20230502065025epcas2p34507ffad60b32e091ff0efeced9bc12f@epcas2p3.samsung.com>
2023-05-02 6:28 ` [PATCH v3 3/3] spi: s3c64xx: support interrupt based pio mode Jaewon Kim
2023-05-02 6:28 ` Jaewon Kim
2023-05-05 9:47 ` Krzysztof Kozlowski
2023-05-05 9:47 ` Krzysztof Kozlowski
2023-05-08 1:42 ` Jaewon Kim
2023-05-08 1:42 ` Jaewon Kim
2023-05-09 13:03 ` Marek Szyprowski
2023-05-10 4:05 ` Jaewon Kim
2023-05-10 6:54 ` Marek Szyprowski
2023-05-08 13:27 ` [PATCH v3 0/3] Improve polling mode of s3c64xx driver Mark Brown
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.