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 <jordan@embeint.com>
This commit is contained in:
Jordan Yates 2025-03-18 10:52:57 +10:00 committed by Chris Friedt
parent d8f87a6d09
commit 2a88cb50f5

View File

@ -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