From 2a88cb50f57cf010fc7d60b7e686f960417d6fd0 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 18 Mar 2025 10:52:57 +1000 Subject: [PATCH] spi: stm32: initialise according to `zephyr,pm-device-runtime-auto` Don't automatically enable device runtime PM on the SPI port just because `PM_DEVICE_RUNTIME` is enabled. Require the user to explicitly call `pm_device_runtime_enable` on the port, or add `zephyr,pm-device-runtime-auto` to the devicetree node. Through the usage of `pm_device_driver_init`, the default clock control and pinctrl handling can all be contained in `spi_stm32_pm_action`. Signed-off-by: Jordan Yates --- drivers/spi/spi_ll_stm32.c | 72 +++++++++++++++----------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index d4a722e9df1..b1891dea1fa 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -1403,7 +1403,24 @@ static inline bool spi_stm32_is_subghzspi(const struct device *dev) #endif /* st_stm32_spi_subghz */ } -#ifdef CONFIG_PM_DEVICE +static int spi_stm32_pinctrl_apply(const struct device *dev, uint8_t id) +{ + const struct spi_stm32_config *config = dev->config; + int err; + + if (spi_stm32_is_subghzspi(dev)) { + return 0; + } + + /* Move pins to requested state */ + err = pinctrl_apply_state(config->pcfg, id); + if ((id == PINCTRL_STATE_SLEEP) && (err == -ENOENT)) { + /* Sleep state is optional */ + err = 0; + } + return err; +} + static int spi_stm32_pm_action(const struct device *dev, enum pm_device_action action) { @@ -1411,17 +1428,13 @@ static int spi_stm32_pm_action(const struct device *dev, const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); int err; - switch (action) { case PM_DEVICE_ACTION_RESUME: - if (!spi_stm32_is_subghzspi(dev)) { - /* Set pins to active state */ - err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); - if (err < 0) { - return err; - } + /* Configure pins for active mode */ + err = spi_stm32_pinctrl_apply(dev, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; } - /* enable clock */ err = clock_control_on(clk, (clock_control_subsys_t)&config->pclken[0]); if (err != 0) { @@ -1436,22 +1449,12 @@ static int spi_stm32_pm_action(const struct device *dev, LOG_ERR("Could not disable SPI clock"); return err; } - - if (!spi_stm32_is_subghzspi(dev)) { - /* Move pins to sleep state */ - err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); - if ((err < 0) && (err != -ENOENT)) { - /* - * If returning -ENOENT, no pins where defined for sleep mode : - * Do not output on console (might sleep already) when going to - * sleep, - * "SPI pinctrl sleep state not available" - * and don't block PM suspend. - * Else return the error. - */ - return err; - } - } + /* Configure pins for sleep mode */ + return spi_stm32_pinctrl_apply(dev, PINCTRL_STATE_SLEEP); + case PM_DEVICE_ACTION_TURN_ON: + /* Configure pins for sleep mode */ + return spi_stm32_pinctrl_apply(dev, PINCTRL_STATE_SLEEP); + case PM_DEVICE_ACTION_TURN_OFF: break; default: return -ENOTSUP; @@ -1459,7 +1462,6 @@ static int spi_stm32_pm_action(const struct device *dev, return 0; } -#endif /* CONFIG_PM_DEVICE */ static int spi_stm32_init(const struct device *dev) { @@ -1472,13 +1474,6 @@ static int spi_stm32_init(const struct device *dev) return -ENODEV; } - err = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &cfg->pclken[0]); - if (err < 0) { - LOG_ERR("Could not enable SPI clock"); - return err; - } - if (IS_ENABLED(STM32_SPI_DOMAIN_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) { err = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t) &cfg->pclken[1], @@ -1489,15 +1484,6 @@ static int spi_stm32_init(const struct device *dev) } } - if (!spi_stm32_is_subghzspi(dev)) { - /* Configure dt provided device signals when available */ - err = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); - if (err < 0) { - LOG_ERR("SPI pinctrl setup failed (%d)", err); - return err; - } - } - #ifdef CONFIG_SPI_STM32_INTERRUPT cfg->irq_config(dev); #endif /* CONFIG_SPI_STM32_INTERRUPT */ @@ -1526,7 +1512,7 @@ static int spi_stm32_init(const struct device *dev) spi_context_unlock_unconditionally(&data->ctx); - return pm_device_runtime_enable(dev); + return pm_device_driver_init(dev, spi_stm32_pm_action); } #ifdef CONFIG_SPI_STM32_INTERRUPT