drivers: dma: siwx91x: replace pm_state with pm_device (udma and gpdma)

Removed unnecessary power management state lock calls since the DMA is
on a power domain that already handles state locking.
It will now managed directly pm_device which will active power_domain
and then block pm_state.

Signed-off-by: Martin Hoff <martin.hoff@silabs.com>
This commit is contained in:
Martin Hoff
2025-11-26 16:34:45 +01:00
committed by Benjamin Cabé
parent d5c45b10e5
commit aa315948dc
2 changed files with 32 additions and 41 deletions

View File

@@ -14,7 +14,7 @@
#include <zephyr/drivers/clock_control.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/types.h>
#include "rsi_rom_udma.h"
#include "rsi_rom_udma_wrapper.h"
@@ -63,16 +63,6 @@ struct dma_siwx91x_data {
*/
};
static void siwx91x_dma_pm_policy_state_lock_get(void)
{
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
static void siwx91x_dma_pm_policy_state_lock_put(void)
{
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
static enum dma_xfer_dir siwx91x_transfer_direction(uint32_t dir)
{
if (dir == MEMORY_TO_MEMORY) {
@@ -495,15 +485,14 @@ static int siwx91x_dma_start(const struct device *dev, uint32_t channel)
return -EINVAL;
}
/* Get the power management policy state lock */
if (!data->zephyr_channel_info[channel].channel_active) {
siwx91x_dma_pm_policy_state_lock_get();
pm_device_runtime_get(dev);
data->zephyr_channel_info[channel].channel_active = true;
}
if (RSI_UDMA_ChannelEnable(udma_handle, channel) != 0) {
if (data->zephyr_channel_info[channel].channel_active) {
siwx91x_dma_pm_policy_state_lock_put();
pm_device_runtime_put(dev);
data->zephyr_channel_info[channel].channel_active = false;
}
return -EINVAL;
@@ -534,7 +523,7 @@ static int siwx91x_dma_stop(const struct device *dev, uint32_t channel)
}
if (data->zephyr_channel_info[channel].channel_active) {
siwx91x_dma_pm_policy_state_lock_put();
pm_device_runtime_put(dev);
data->zephyr_channel_info[channel].channel_active = false;
}
@@ -680,16 +669,16 @@ static void siwx91x_dma_isr(const struct device *dev)
}
if (data->chan_info[channel].Cnt == data->chan_info[channel].Size) {
if (data->zephyr_channel_info[channel].channel_active) {
pm_device_runtime_put_async(dev, K_NO_WAIT);
data->zephyr_channel_info[channel].channel_active = false;
}
if (data->zephyr_channel_info[channel].dma_callback) {
/* Transfer complete, call user callback */
data->zephyr_channel_info[channel].dma_callback(
dev, data->zephyr_channel_info[channel].cb_data, channel, 0);
}
sys_write32(BIT(channel), (mem_addr_t)&cfg->reg->UDMA_DONE_STATUS_REG);
if (data->zephyr_channel_info[channel].channel_active) {
siwx91x_dma_pm_policy_state_lock_put();
data->zephyr_channel_info[channel].channel_active = false;
}
} else {
/* Call UDMA ROM IRQ handler. */
ROMAPI_UDMA_WRAPPER_API->uDMAx_IRQHandler(&udma_resources, udma_resources.desc,

View File

@@ -12,7 +12,7 @@
#include <zephyr/drivers/clock_control.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#include <zephyr/pm/device_runtime.h>
#include "rsi_gpdma.h"
#include "rsi_rom_gpdma.h"
@@ -43,6 +43,7 @@ struct siwx91x_gpdma_channel_info {
void *cb_data;
RSI_GPDMA_DESC_T *desc;
enum gpdma_xfer_dir xfer_direction;
bool channel_active;
};
struct siwx91x_gpdma_config {
@@ -62,16 +63,6 @@ struct siwx19x_gpdma_data {
uint8_t reload_compatible;
};
static void siwx91x_gpdma_pm_policy_state_lock_get(void)
{
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
static void siwx91x_gpdma_pm_policy_state_lock_put(void)
{
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
static bool siwx91x_gpdma_is_priority_valid(uint32_t channel_priority)
{
return (channel_priority >= GPDMA_MIN_PRIORITY && channel_priority <= GPDMA_MAX_PRIORITY);
@@ -408,19 +399,22 @@ static int siwx91x_gpdma_reload(const struct device *dev, uint32_t channel, uint
static int siwx91x_gpdma_start(const struct device *dev, uint32_t channel)
{
const struct siwx91x_gpdma_config *cfg = dev->config;
struct siwx19x_gpdma_data *data = dev->data;
if (channel >= data->dma_ctx.dma_channels) {
return -EINVAL;
}
if (!sys_test_bit((mem_addr_t)&cfg->reg->GLOBAL.DMA_CHNL_ENABLE_REG, channel)) {
siwx91x_gpdma_pm_policy_state_lock_get();
if (data->chan_info[channel].channel_active) {
pm_device_runtime_get(dev);
data->chan_info[channel].channel_active = true;
}
if (RSI_GPDMA_DMAChannelTrigger(&data->hal_ctx, channel)) {
siwx91x_gpdma_pm_policy_state_lock_put();
if (data->chan_info[channel].channel_active) {
pm_device_runtime_put(dev);
data->chan_info[channel].channel_active = false;
}
return -EINVAL;
}
@@ -429,7 +423,6 @@ static int siwx91x_gpdma_start(const struct device *dev, uint32_t channel)
static int siwx91x_gpdma_stop(const struct device *dev, uint32_t channel)
{
const struct siwx91x_gpdma_config *cfg = dev->config;
struct siwx19x_gpdma_data *data = dev->data;
k_spinlock_key_t key;
@@ -437,10 +430,6 @@ static int siwx91x_gpdma_stop(const struct device *dev, uint32_t channel)
return -EINVAL;
}
if (sys_test_bit((mem_addr_t)&cfg->reg->GLOBAL.DMA_CHNL_ENABLE_REG, channel)) {
siwx91x_gpdma_pm_policy_state_lock_put();
}
if (RSI_GPDMA_AbortChannel(&data->hal_ctx, channel)) {
return -EINVAL;
}
@@ -449,6 +438,11 @@ static int siwx91x_gpdma_stop(const struct device *dev, uint32_t channel)
siwx91x_gpdma_free_desc(data->desc_pool, data->chan_info[channel].desc);
k_spin_unlock(&data->desc_pool_lock, key);
if (data->chan_info[channel].channel_active) {
pm_device_runtime_put(dev);
data->chan_info[channel].channel_active = false;
}
return 0;
}
@@ -552,7 +546,10 @@ static void siwx91x_gpdma_isr(const struct device *dev)
if (channel_int_status & abort_mask) {
RSI_GPDMA_AbortChannel(&data->hal_ctx, channel);
cfg->reg->GLOBAL.INTERRUPT_STAT_REG = abort_mask;
siwx91x_gpdma_pm_policy_state_lock_put();
if (data->chan_info[channel].channel_active) {
pm_device_runtime_put_async(dev, K_NO_WAIT);
data->chan_info[channel].channel_active = false;
}
}
if (channel_int_status & desc_fetch_mask) {
@@ -569,11 +566,16 @@ static void siwx91x_gpdma_isr(const struct device *dev)
k_spin_unlock(&data->desc_pool_lock, key);
data->chan_info[channel].desc = NULL;
cfg->reg->GLOBAL.INTERRUPT_STAT_REG = done_mask;
if (data->chan_info[channel].channel_active) {
pm_device_runtime_put_async(dev, K_NO_WAIT);
data->chan_info[channel].channel_active = false;
}
if (data->chan_info[channel].cb) {
data->chan_info[channel].cb(dev, data->chan_info[channel].cb_data, channel,
0);
}
siwx91x_gpdma_pm_policy_state_lock_put();
}
}