drivers: spi: Use timeout for transfer completion
Instead of waiting forever for the SPI transfer to complete, let's use a timeout value and bail out if elapsed. The timeout value logic is, xfer_len/frequency + tolerance Tolerance value can be modified using a Kconfig symbol, CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE. It defaults to 200ms. Fixes: #33192 Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
This commit is contained in:
parent
a95457a984
commit
fa2d1ea422
|
@ -31,6 +31,12 @@ config SPI_INIT_PRIORITY
|
|||
help
|
||||
Device driver initialization priority.
|
||||
|
||||
config SPI_COMPLETION_TIMEOUT_TOLERANCE
|
||||
int "Completion timeout tolerance (ms)"
|
||||
default 200
|
||||
help
|
||||
The tolerance value in ms for the SPI completion timeout logic.
|
||||
|
||||
module = SPI
|
||||
module-str = spi
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
|
|
@ -112,13 +112,25 @@ static inline void spi_context_release(struct spi_context *ctx, int status)
|
|||
static inline int spi_context_wait_for_completion(struct spi_context *ctx)
|
||||
{
|
||||
int status = 0;
|
||||
uint32_t timeout_ms;
|
||||
|
||||
timeout_ms = MAX(ctx->tx_len, ctx->rx_len) * 8 * 1000 /
|
||||
ctx->config->frequency;
|
||||
timeout_ms += CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE;
|
||||
|
||||
#ifdef CONFIG_SPI_ASYNC
|
||||
if (!ctx->asynchronous) {
|
||||
k_sem_take(&ctx->sync, K_FOREVER);
|
||||
if (k_sem_take(&ctx->sync, K_MSEC(timeout_ms))) {
|
||||
LOG_ERR("Timeout waiting for transfer complete");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
status = ctx->sync_status;
|
||||
}
|
||||
#else
|
||||
k_sem_take(&ctx->sync, K_FOREVER);
|
||||
if (k_sem_take(&ctx->sync, K_MSEC(timeout_ms))) {
|
||||
LOG_ERR("Timeout waiting for transfer complete");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
status = ctx->sync_status;
|
||||
#endif /* CONFIG_SPI_ASYNC */
|
||||
|
||||
|
|
Loading…
Reference in a new issue