Commit c1887396 authored by Théo Lebrun's avatar Théo Lebrun Committed by Mark Brown

spi: cadence-qspi: add early busywait to cqspi_wait_for_bit()

Call readl_relaxed_poll_timeout() with no sleep at the start of
cqspi_wait_for_bit(). If its short timeout expires, a sleeping
readl_relaxed_poll_timeout() call takes the relay.

The reason is to avoid hrtimer interrupts on the system. All read
operations are expected to take less than 100µs.
Signed-off-by: default avatarThéo Lebrun <theo.lebrun@bootlin.com>
Link: https://lore.kernel.org/r/20240423-cdns-qspi-mbly-v4-3-3d2a7b535ad0@bootlin.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1f257b92
...@@ -120,6 +120,7 @@ struct cqspi_driver_platdata { ...@@ -120,6 +120,7 @@ struct cqspi_driver_platdata {
/* Operation timeout value */ /* Operation timeout value */
#define CQSPI_TIMEOUT_MS 500 #define CQSPI_TIMEOUT_MS 500
#define CQSPI_READ_TIMEOUT_MS 10 #define CQSPI_READ_TIMEOUT_MS 10
#define CQSPI_BUSYWAIT_TIMEOUT_US 500
/* Runtime_pm autosuspend delay */ /* Runtime_pm autosuspend delay */
#define CQSPI_AUTOSUSPEND_TIMEOUT 2000 #define CQSPI_AUTOSUSPEND_TIMEOUT 2000
...@@ -298,13 +299,27 @@ struct cqspi_driver_platdata { ...@@ -298,13 +299,27 @@ struct cqspi_driver_platdata {
#define CQSPI_REG_VERSAL_DMA_VAL 0x602 #define CQSPI_REG_VERSAL_DMA_VAL 0x602
static int cqspi_wait_for_bit(void __iomem *reg, const u32 mask, bool clr) static int cqspi_wait_for_bit(const struct cqspi_driver_platdata *ddata,
void __iomem *reg, const u32 mask, bool clr,
bool busywait)
{ {
u64 timeout_us = CQSPI_TIMEOUT_MS * USEC_PER_MSEC;
u32 val; u32 val;
if (busywait) {
int ret = readl_relaxed_poll_timeout(reg, val,
(((clr ? ~val : val) & mask) == mask),
0, CQSPI_BUSYWAIT_TIMEOUT_US);
if (ret != -ETIMEDOUT)
return ret;
timeout_us -= CQSPI_BUSYWAIT_TIMEOUT_US;
}
return readl_relaxed_poll_timeout(reg, val, return readl_relaxed_poll_timeout(reg, val,
(((clr ? ~val : val) & mask) == mask), (((clr ? ~val : val) & mask) == mask),
10, CQSPI_TIMEOUT_MS * 1000); 10, timeout_us);
} }
static bool cqspi_is_idle(struct cqspi_st *cqspi) static bool cqspi_is_idle(struct cqspi_st *cqspi)
...@@ -434,8 +449,8 @@ static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg) ...@@ -434,8 +449,8 @@ static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg)
writel(reg, reg_base + CQSPI_REG_CMDCTRL); writel(reg, reg_base + CQSPI_REG_CMDCTRL);
/* Polling for completion. */ /* Polling for completion. */
ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_CMDCTRL, ret = cqspi_wait_for_bit(cqspi->ddata, reg_base + CQSPI_REG_CMDCTRL,
CQSPI_REG_CMDCTRL_INPROGRESS_MASK, 1); CQSPI_REG_CMDCTRL_INPROGRESS_MASK, 1, true);
if (ret) { if (ret) {
dev_err(&cqspi->pdev->dev, dev_err(&cqspi->pdev->dev,
"Flash command execution timed out.\n"); "Flash command execution timed out.\n");
...@@ -790,8 +805,8 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, ...@@ -790,8 +805,8 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
} }
/* Check indirect done status */ /* Check indirect done status */
ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD, ret = cqspi_wait_for_bit(cqspi->ddata, reg_base + CQSPI_REG_INDIRECTRD,
CQSPI_REG_INDIRECTRD_DONE_MASK, 0); CQSPI_REG_INDIRECTRD_DONE_MASK, 0, true);
if (ret) { if (ret) {
dev_err(dev, "Indirect read completion error (%i)\n", ret); dev_err(dev, "Indirect read completion error (%i)\n", ret);
goto failrd; goto failrd;
...@@ -1091,8 +1106,8 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata, ...@@ -1091,8 +1106,8 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
} }
/* Check indirect done status */ /* Check indirect done status */
ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTWR, ret = cqspi_wait_for_bit(cqspi->ddata, reg_base + CQSPI_REG_INDIRECTWR,
CQSPI_REG_INDIRECTWR_DONE_MASK, 0); CQSPI_REG_INDIRECTWR_DONE_MASK, 0, false);
if (ret) { if (ret) {
dev_err(dev, "Indirect write completion error (%i)\n", ret); dev_err(dev, "Indirect write completion error (%i)\n", ret);
goto failwr; goto failwr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment