mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
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: Théo Lebrun <theo.lebrun@bootlin.com> Link: https://lore.kernel.org/r/20240423-cdns-qspi-mbly-v4-3-3d2a7b535ad0@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
1f257b92e6
commit
c188739637
@ -120,6 +120,7 @@ struct cqspi_driver_platdata {
|
||||
/* Operation timeout value */
|
||||
#define CQSPI_TIMEOUT_MS 500
|
||||
#define CQSPI_READ_TIMEOUT_MS 10
|
||||
#define CQSPI_BUSYWAIT_TIMEOUT_US 500
|
||||
|
||||
/* Runtime_pm autosuspend delay */
|
||||
#define CQSPI_AUTOSUSPEND_TIMEOUT 2000
|
||||
@ -298,13 +299,27 @@ struct cqspi_driver_platdata {
|
||||
|
||||
#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;
|
||||
|
||||
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,
|
||||
(((clr ? ~val : val) & mask) == mask),
|
||||
10, CQSPI_TIMEOUT_MS * 1000);
|
||||
10, timeout_us);
|
||||
}
|
||||
|
||||
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)
|
||||
writel(reg, reg_base + CQSPI_REG_CMDCTRL);
|
||||
|
||||
/* Polling for completion. */
|
||||
ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_CMDCTRL,
|
||||
CQSPI_REG_CMDCTRL_INPROGRESS_MASK, 1);
|
||||
ret = cqspi_wait_for_bit(cqspi->ddata, reg_base + CQSPI_REG_CMDCTRL,
|
||||
CQSPI_REG_CMDCTRL_INPROGRESS_MASK, 1, true);
|
||||
if (ret) {
|
||||
dev_err(&cqspi->pdev->dev,
|
||||
"Flash command execution timed out.\n");
|
||||
@ -790,8 +805,8 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
|
||||
}
|
||||
|
||||
/* Check indirect done status */
|
||||
ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
|
||||
CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
|
||||
ret = cqspi_wait_for_bit(cqspi->ddata, reg_base + CQSPI_REG_INDIRECTRD,
|
||||
CQSPI_REG_INDIRECTRD_DONE_MASK, 0, true);
|
||||
if (ret) {
|
||||
dev_err(dev, "Indirect read completion error (%i)\n", ret);
|
||||
goto failrd;
|
||||
@ -1091,8 +1106,8 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
|
||||
}
|
||||
|
||||
/* Check indirect done status */
|
||||
ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTWR,
|
||||
CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
|
||||
ret = cqspi_wait_for_bit(cqspi->ddata, reg_base + CQSPI_REG_INDIRECTWR,
|
||||
CQSPI_REG_INDIRECTWR_DONE_MASK, 0, false);
|
||||
if (ret) {
|
||||
dev_err(dev, "Indirect write completion error (%i)\n", ret);
|
||||
goto failwr;
|
||||
|
Loading…
Reference in New Issue
Block a user