diff --git a/drivers/dma/dma_nxp_edma.c b/drivers/dma/dma_nxp_edma.c index 7d4f6e8b44958ab..449720edabc808a 100644 --- a/drivers/dma/dma_nxp_edma.c +++ b/drivers/dma/dma_nxp_edma.c @@ -270,11 +270,11 @@ static int edma_config(const struct device *dev, uint32_t chan_id, chan->cyclic_buffer = false; } - /* change channel's state to CONFIGURED */ - ret = channel_change_state(chan, CHAN_STATE_CONFIGURED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to CONFIGURED", chan_id); - return ret; + /* check if transition to CONFIGURED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_CONFIGURED)) { + LOG_ERR("chan %d transition from %d to CONFIGURED not allowed", + chan_id, chan->state); + return -EPERM; } ret = get_transfer_type(dma_cfg->channel_direction, &transfer_type); @@ -335,6 +335,8 @@ static int edma_config(const struct device *dev, uint32_t chan_id, /* dump register status - for debugging purposes */ edma_dump_channel_registers(data, chan_id); + chan->state = CHAN_STATE_CONFIGURED; + return 0; } @@ -389,7 +391,6 @@ static int edma_suspend(const struct device *dev, uint32_t chan_id) struct edma_data *data; const struct edma_config *cfg; struct edma_channel *chan; - int ret; data = dev->data; cfg = dev->config; @@ -403,11 +404,11 @@ static int edma_suspend(const struct device *dev, uint32_t chan_id) edma_dump_channel_registers(data, chan_id); - /* change channel's state to SUSPENDED */ - ret = channel_change_state(chan, CHAN_STATE_SUSPENDED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to SUSPENDED", chan_id); - return ret; + /* check if transition to SUSPENDED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_SUSPENDED)) { + LOG_ERR("chan %d transition from %d to SUSPENDED not allowed", + chan_id, chan->state); + return -EPERM; } LOG_DBG("suspending channel %u", chan_id); @@ -416,6 +417,8 @@ static int edma_suspend(const struct device *dev, uint32_t chan_id) EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, 0, EDMA_TCD_CH_CSR_ERQ_MASK); + chan->state = CHAN_STATE_SUSPENDED; + return 0; } @@ -439,11 +442,11 @@ static int edma_stop(const struct device *dev, uint32_t chan_id) prev_state = chan->state; - /* change channel's state to STOPPED */ - ret = channel_change_state(chan, CHAN_STATE_STOPPED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to STOPPED", chan_id); - return ret; + /* check if transition to STOPPED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_STOPPED)) { + LOG_ERR("chan %d transition from %d to STOPPED not allowed", + chan_id, chan->state); + return -EPERM; } LOG_DBG("stopping channel %u", chan_id); @@ -482,6 +485,8 @@ static int edma_stop(const struct device *dev, uint32_t chan_id) edma_dump_channel_registers(data, chan_id); + chan->state = CHAN_STATE_STOPPED; + return 0; } @@ -490,7 +495,6 @@ static int edma_start(const struct device *dev, uint32_t chan_id) struct edma_data *data; const struct edma_config *cfg; struct edma_channel *chan; - int ret; data = dev->data; cfg = dev->config; @@ -502,11 +506,11 @@ static int edma_start(const struct device *dev, uint32_t chan_id) return -EINVAL; } - /* change channel's state to STARTED */ - ret = channel_change_state(chan, CHAN_STATE_STARTED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to STARTED", chan_id); - return ret; + /* check if transition to STARTED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_STARTED)) { + LOG_ERR("chan %d transition from %d to STARTED not allowed", + chan_id, chan->state); + return -EPERM; } LOG_DBG("starting channel %u", chan_id); @@ -517,6 +521,8 @@ static int edma_start(const struct device *dev, uint32_t chan_id) EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, EDMA_TCD_CH_CSR_ERQ_MASK, 0); + chan->state = CHAN_STATE_STARTED; + return 0; } diff --git a/drivers/dma/dma_nxp_edma.h b/drivers/dma/dma_nxp_edma.h index f45740d981d2150..287657dd87fb87d 100644 --- a/drivers/dma/dma_nxp_edma.h +++ b/drivers/dma/dma_nxp_edma.h @@ -221,52 +221,47 @@ struct edma_config { bool contiguous_channels; }; -static inline int channel_change_state(struct edma_channel *chan, - enum channel_state next) +static inline bool channel_allows_transition(struct edma_channel *chan, + enum channel_state next) { enum channel_state prev = chan->state; - LOG_DBG("attempting to change state from %d to %d for channel %d", prev, next, chan->id); - /* validate transition */ switch (prev) { case CHAN_STATE_INIT: if (next != CHAN_STATE_CONFIGURED) { - return -EPERM; + return false; } break; case CHAN_STATE_CONFIGURED: if (next != CHAN_STATE_STARTED && next != CHAN_STATE_CONFIGURED) { - return -EPERM; + return false; } break; case CHAN_STATE_STARTED: if (next != CHAN_STATE_STOPPED && next != CHAN_STATE_SUSPENDED) { - return -EPERM; + return false; } break; case CHAN_STATE_STOPPED: if (next != CHAN_STATE_CONFIGURED) { - return -EPERM; + return false; } break; case CHAN_STATE_SUSPENDED: if (next != CHAN_STATE_STARTED && next != CHAN_STATE_STOPPED) { - return -EPERM; + return false; } break; default: LOG_ERR("invalid channel previous state: %d", prev); - return -EINVAL; + return false; } - /* transition OK, proceed */ - chan->state = next; - - return 0; + return true; } static inline int get_transfer_type(enum dma_channel_direction dir, uint32_t *type)