Skip to content

Commit f115e9f

Browse files
mjchen0fabiobaltieri
authored andcommitted
drivers: spi_mcux_flexcomm: fix calls to pm_policy_device_power_lock_put()
Some error cases, and the asynchronous dma case, were not calling pm_policy_device_power_lock_put() at the right time. Signed-off-by: Mike J. Chen <[email protected]>
1 parent addf568 commit f115e9f

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/spi/spi_mcux_flexcomm.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ static void spi_mcux_transfer_next_packet(const struct device *dev)
147147
LOG_ERR("Transfer could not start");
148148
spi_context_cs_control(&data->ctx, false);
149149
spi_context_complete(&data->ctx, dev, -EIO);
150+
pm_policy_device_power_lock_put(dev);
150151
}
151152
}
152153

@@ -338,12 +339,14 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg,
338339
data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_RX_DONE_FLAG;
339340
spi_context_cs_control(&data->ctx, false);
340341
spi_context_complete(&data->ctx, spi_dev, 0);
342+
pm_policy_device_power_lock_put(dev);
341343
} else {
342344
LOG_ERR("DMA callback channel %d is not valid.",
343345
channel);
344346
data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_ERROR_FLAG;
345347
spi_context_cs_control(&data->ctx, false);
346348
spi_context_complete(&data->ctx, spi_dev, -EIO);
349+
pm_policy_device_power_lock_put(dev);
347350
}
348351
}
349352
}
@@ -683,6 +686,10 @@ static int transceive_dma(const struct device *dev,
683686
spi_context_update_rx(&data->ctx, data->word_size_bytes, data->transfer_len);
684687
spi_context_cs_control(&data->ctx, false);
685688
spi_context_complete(&data->ctx, dev, 0);
689+
/* If asynchronous was true, set to false since transfer is done and we
690+
* want to release the power lock below.
691+
*/
692+
asynchronous = false;
686693
} else {
687694
/* Enable DMATX/RX. */
688695
base->FIFOCFG |= SPI_FIFOCFG_DMARX_MASK | SPI_FIFOCFG_DMATX_MASK;
@@ -693,12 +700,21 @@ static int transceive_dma(const struct device *dev,
693700
}
694701
}
695702

703+
/* if asynchronous is true, spi_context_wait_for_completion() just returns 0
704+
* and spi_context_release() is a noop
705+
*/
696706
ret = spi_context_wait_for_completion(&data->ctx);
697707

698708
out:
699709
spi_context_release(&data->ctx, ret);
700710

701-
pm_policy_device_power_lock_put(dev);
711+
if (!asynchronous || (ret != 0)) {
712+
/* Only release the power lock if synchronous, or if an error occurred.
713+
* For asynchronous case, the power_lock is released in
714+
* when the transfer is done in the dma completion callback
715+
*/
716+
pm_policy_device_power_lock_put(dev);
717+
}
702718

703719
return ret;
704720
}

0 commit comments

Comments
 (0)