Skip to content

Commit a7ba06b

Browse files
Jordan Yatesdleach02
authored andcommitted
flash: spi_nor: don't hard loop in wait_until_ready
Don't monopolise the CPU in `spi_nor_wait_until_ready`. For slow flash chips, operations can take minutes (Full chip erase on MX25R is listed as 120s typical, 240s max). Signed-off-by: Jordan Yates <[email protected]>
1 parent 88c4362 commit a7ba06b

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

drivers/flash/Kconfig.nor

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ config SPI_NOR_CS_WAIT_DELAY
5555
help
5656
This is the wait delay (in us) to allow for CS switching to take effect
5757

58+
config SPI_NOR_SLEEP_WHILE_WAITING_UNTIL_READY
59+
bool "Sleep while waiting for flash operations to complete"
60+
default y
61+
help
62+
Flash operations can take anywhere from 1ms to 240 seconds to
63+
complete. Enabling this option adds a delay between polls on the
64+
status register for slow operations. Disabling this option can
65+
result in significant flash savings if this driver is the only user
66+
of "k_sleep". This can be the case when building as a bootloader.
67+
5868
config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE
5969
int "Page size to use for FLASH_LAYOUT feature"
6070
default 65536

drivers/flash/spi_nor.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,19 @@ static int spi_nor_wait_until_ready(const struct device *dev)
402402
int ret;
403403
uint8_t reg;
404404

405-
do {
406-
ret = spi_nor_cmd_read(dev, SPI_NOR_CMD_RDSR, &reg, sizeof(reg));
407-
} while (!ret && (reg & SPI_NOR_WIP_BIT));
405+
ARG_UNUSED(poll_delay);
408406

407+
while (true) {
408+
ret = spi_nor_cmd_read(dev, SPI_NOR_CMD_RDSR, &reg, sizeof(reg));
409+
/* Exit on error or no longer WIP */
410+
if (ret || !(reg & SPI_NOR_WIP_BIT)) {
411+
break;
412+
}
413+
#ifdef CONFIG_SPI_NOR_SLEEP_WHILE_WAITING_UNTIL_READY
414+
/* Don't monopolise the CPU while waiting for ready */
415+
k_sleep(K_TICKS(1));
416+
#endif /* CONFIG_SPI_NOR_SLEEP_WHILE_WAITING_UNTIL_READY */
417+
}
409418
return ret;
410419
}
411420

0 commit comments

Comments
 (0)