|
8 | 8 | #include <zephyr/drivers/spi/rtio.h> |
9 | 9 | #include <zephyr/cache.h> |
10 | 10 | #include <zephyr/pm/device.h> |
| 11 | +#include <zephyr/pm/device_runtime.h> |
11 | 12 | #include <zephyr/drivers/pinctrl.h> |
12 | 13 | #include <zephyr/mem_mgmt/mem_attr.h> |
13 | 14 | #include <soc.h> |
@@ -90,6 +91,8 @@ static inline void finalize_spi_transaction(const struct device *dev, bool deact |
90 | 91 | if (NRF_SPIM_IS_320MHZ_SPIM(reg) && !(dev_data->ctx.config->operation & SPI_HOLD_ON_CS)) { |
91 | 92 | nrfy_spim_disable(reg); |
92 | 93 | } |
| 94 | + |
| 95 | + pm_device_runtime_put_async(dev, K_NO_WAIT); |
93 | 96 | } |
94 | 97 |
|
95 | 98 | static inline uint32_t get_nrf_spim_frequency(uint32_t frequency) |
@@ -460,6 +463,7 @@ static int transceive(const struct device *dev, |
460 | 463 | void *reg = dev_config->spim.p_reg; |
461 | 464 | int error; |
462 | 465 |
|
| 466 | + pm_device_runtime_get(dev); |
463 | 467 | spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); |
464 | 468 |
|
465 | 469 | error = configure(dev, spi_cfg); |
@@ -571,56 +575,49 @@ static const struct spi_driver_api spi_nrfx_driver_api = { |
571 | 575 | .release = spi_nrfx_release, |
572 | 576 | }; |
573 | 577 |
|
574 | | -#ifdef CONFIG_PM_DEVICE |
575 | | -static int spim_nrfx_pm_action(const struct device *dev, |
576 | | - enum pm_device_action action) |
| 578 | +static void spim_resume(const struct device *dev) |
577 | 579 | { |
578 | | - int ret = 0; |
579 | | - struct spi_nrfx_data *dev_data = dev->data; |
580 | 580 | const struct spi_nrfx_config *dev_config = dev->config; |
581 | 581 |
|
582 | | - switch (action) { |
583 | | - case PM_DEVICE_ACTION_RESUME: |
584 | | - ret = pinctrl_apply_state(dev_config->pcfg, |
585 | | - PINCTRL_STATE_DEFAULT); |
586 | | - if (ret < 0) { |
587 | | - return ret; |
588 | | - } |
589 | | - /* nrfx_spim_init() will be called at configuration before |
590 | | - * the next transfer. |
591 | | - */ |
| 582 | + (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); |
| 583 | + /* nrfx_spim_init() will be called at configuration before |
| 584 | + * the next transfer. |
| 585 | + */ |
592 | 586 |
|
593 | 587 | #ifdef CONFIG_SOC_NRF54H20_GPD |
594 | | - nrf_gpd_retain_pins_set(dev_config->pcfg, false); |
| 588 | + nrf_gpd_retain_pins_set(dev_config->pcfg, false); |
595 | 589 | #endif |
| 590 | +} |
596 | 591 |
|
597 | | - break; |
| 592 | +static void spim_suspend(const struct device *dev) |
| 593 | +{ |
| 594 | + const struct spi_nrfx_config *dev_config = dev->config; |
| 595 | + struct spi_nrfx_data *dev_data = dev->data; |
598 | 596 |
|
599 | | - case PM_DEVICE_ACTION_SUSPEND: |
600 | | - if (dev_data->initialized) { |
601 | | - nrfx_spim_uninit(&dev_config->spim); |
602 | | - dev_data->initialized = false; |
603 | | - } |
| 597 | + if (dev_data->initialized) { |
| 598 | + nrfx_spim_uninit(&dev_config->spim); |
| 599 | + dev_data->initialized = false; |
| 600 | + } |
604 | 601 |
|
605 | 602 | #ifdef CONFIG_SOC_NRF54H20_GPD |
606 | | - nrf_gpd_retain_pins_set(dev_config->pcfg, true); |
| 603 | + nrf_gpd_retain_pins_set(dev_config->pcfg, true); |
607 | 604 | #endif |
608 | 605 |
|
609 | | - ret = pinctrl_apply_state(dev_config->pcfg, |
610 | | - PINCTRL_STATE_SLEEP); |
611 | | - if (ret < 0) { |
612 | | - return ret; |
613 | | - } |
614 | | - break; |
| 606 | + (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); |
| 607 | +} |
615 | 608 |
|
616 | | - default: |
617 | | - ret = -ENOTSUP; |
| 609 | +static int spim_nrfx_pm_action(const struct device *dev, enum pm_device_action action) |
| 610 | +{ |
| 611 | + if (action == PM_DEVICE_ACTION_RESUME) { |
| 612 | + spim_resume(dev); |
| 613 | + } else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) { |
| 614 | + spim_suspend(dev); |
| 615 | + } else { |
| 616 | + return -ENOTSUP; |
618 | 617 | } |
619 | 618 |
|
620 | | - return ret; |
| 619 | + return 0; |
621 | 620 | } |
622 | | -#endif /* CONFIG_PM_DEVICE */ |
623 | | - |
624 | 621 |
|
625 | 622 | static int spi_nrfx_init(const struct device *dev) |
626 | 623 | { |
@@ -655,10 +652,12 @@ static int spi_nrfx_init(const struct device *dev) |
655 | 652 | spi_context_unlock_unconditionally(&dev_data->ctx); |
656 | 653 |
|
657 | 654 | #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 |
658 | | - return anomaly_58_workaround_init(dev); |
659 | | -#else |
660 | | - return 0; |
| 655 | + err = anomaly_58_workaround_init(dev); |
| 656 | + if (err < 0) { |
| 657 | + return err; |
| 658 | + } |
661 | 659 | #endif |
| 660 | + return pm_device_driver_init(dev, spim_nrfx_pm_action); |
662 | 661 | } |
663 | 662 | /* |
664 | 663 | * We use NODELABEL here because the nrfx API requires us to call |
|
0 commit comments