Skip to content

Commit

Permalink
flash: spi_nor: remove SPI_NOR_IDLE_IN_DPD
Browse files Browse the repository at this point in the history
Remove `SPI_NOR_IDLE_IN_DPD` to simplify the possible transition states
in the `spi_nor` driver. This option was originally added 5 years ago
when device runtime PM was in a much less mature state.

I do not believe having a separate power management implementation for
this one in-tree driver is in the interests of the project.

The behaviour of `SPI_NOR_IDLE_IN_DPD` leads to extremly suboptimal
behaviour in use cases where multiple small reads are performed
sequentially, see #69588.

Removal of this option does not break the behaviour of any existing
applications, only increases current consumption in idle by ~10uA until
device runtime PM is enabled.

Signed-off-by: Jordan Yates <[email protected]>
  • Loading branch information
JordanYates authored and nashif committed Aug 27, 2024
1 parent 77cbd27 commit 6487a2a
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 55 deletions.
12 changes: 0 additions & 12 deletions drivers/flash/Kconfig.nor
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,4 @@ config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE
(32768), the sector size (4096), or any non-zero multiple of the
sector size.

config SPI_NOR_IDLE_IN_DPD
bool "Use Deep Power-Down mode when flash is not being accessed."
help
Where supported deep power-down mode can reduce current draw
to as little as 0.1% of standby current. However it takes
some milliseconds to enter and exit from this mode.

Select this option for applications where device power
management is not enabled, the flash remains inactive for
long periods, and when used the impact of waiting for mode
enter and exit delays is acceptable.

endif # SPI_NOR
37 changes: 4 additions & 33 deletions drivers/flash/spi_nor.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,10 @@ LOG_MODULE_REGISTER(spi_nor, CONFIG_FLASH_LOG_LEVEL);
* * Some devices support a Deep Power-Down mode which reduces current
* to as little as 0.1% of standby.
*
* The power reduction from DPD is sufficient to warrant allowing its
* use even in cases where Zephyr's device power management is not
* available. This is selected through the SPI_NOR_IDLE_IN_DPD
* Kconfig option.
*
* When mapped to the Zephyr Device Power Management states:
* * PM_DEVICE_STATE_ACTIVE covers both active and standby modes;
* * PM_DEVICE_STATE_SUSPENDED, and PM_DEVICE_STATE_OFF all correspond to
* deep-power-down mode.
* * PM_DEVICE_STATE_SUSPENDED corresponds to deep-power-down mode;
* * PM_DEVICE_STATE_OFF covers the powered off state;
*/

#define SPI_NOR_MAX_ADDR_WIDTH 4
Expand Down Expand Up @@ -552,35 +547,19 @@ static int exit_dpd(const struct device *const dev)
return ret;
}

/* Everything necessary to acquire owning access to the device.
*
* This means taking the lock and, if necessary, waking the device
* from deep power-down mode.
*/
/* Everything necessary to acquire owning access to the device. */
static void acquire_device(const struct device *dev)
{
if (IS_ENABLED(CONFIG_MULTITHREADING)) {
struct spi_nor_data *const driver_data = dev->data;

k_sem_take(&driver_data->sem, K_FOREVER);
}

if (IS_ENABLED(CONFIG_SPI_NOR_IDLE_IN_DPD)) {
exit_dpd(dev);
}
}

/* Everything necessary to release access to the device.
*
* This means (optionally) putting the device into deep power-down
* mode, and releasing the lock.
*/
/* Everything necessary to release access to the device. */
static void release_device(const struct device *dev)
{
if (IS_ENABLED(CONFIG_SPI_NOR_IDLE_IN_DPD)) {
enter_dpd(dev);
}

if (IS_ENABLED(CONFIG_MULTITHREADING)) {
struct spi_nor_data *const driver_data = dev->data;

Expand Down Expand Up @@ -1439,11 +1418,6 @@ static int spi_nor_pm_control(const struct device *dev, enum pm_device_action ac
int rc = 0;

switch (action) {
#ifdef CONFIG_SPI_NOR_IDLE_IN_DPD
case PM_DEVICE_ACTION_SUSPEND:
case PM_DEVICE_ACTION_RESUME:
break;
#else
case PM_DEVICE_ACTION_SUSPEND:
acquire_device(dev);
rc = enter_dpd(dev);
Expand All @@ -1454,11 +1428,9 @@ static int spi_nor_pm_control(const struct device *dev, enum pm_device_action ac
rc = exit_dpd(dev);
release_device(dev);
break;
#endif /* CONFIG_SPI_NOR_IDLE_IN_DPD */
case PM_DEVICE_ACTION_TURN_ON:
/* Coming out of power off */
rc = spi_nor_configure(dev);
#ifndef CONFIG_SPI_NOR_IDLE_IN_DPD
if (rc == 0) {
/* Move to DPD, the correct device state
* for PM_DEVICE_STATE_SUSPENDED
Expand All @@ -1467,7 +1439,6 @@ static int spi_nor_pm_control(const struct device *dev, enum pm_device_action ac
rc = enter_dpd(dev);
release_device(dev);
}
#endif /* CONFIG_SPI_NOR_IDLE_IN_DPD */
break;
case PM_DEVICE_ACTION_TURN_OFF:
break;
Expand Down
10 changes: 0 additions & 10 deletions samples/drivers/spi_flash/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,3 @@ tests:
- "Attempting to write 4 bytes"
- "Data read matches data written. Good!!"
depends_on: spi
sample.drivers.spi.flash_dpd:
tags:
- spi
- flash
filter: dt_compat_enabled("jedec,spi-nor")
platform_exclude: hifive_unmatched
build_only: true
extra_configs:
- CONFIG_SPI_NOR_IDLE_IN_DPD=y
depends_on: spi

0 comments on commit 6487a2a

Please sign in to comment.