From c2913ad0255d779df2a395eec64fcc7a4ed91e2c Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Wed, 10 May 2017 14:13:59 +0200 Subject: [PATCH] drivers/spi: Handle ressource locking and release in DW driver Again this is made as generic as possible through driver's spi_context API. Signed-off-by: Tomasz Bursztyka --- drivers/spi/spi_context.h | 15 ++++++++++++++- drivers/spi/spi_dw.c | 10 ++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_context.h b/drivers/spi/spi_context.h index 773d870864f..a0039b68cd2 100644 --- a/drivers/spi/spi_context.h +++ b/drivers/spi/spi_context.h @@ -64,6 +64,10 @@ static inline void spi_context_lock(struct spi_context *ctx, static inline void spi_context_release(struct spi_context *ctx, int status) { + if (!status && (ctx->config->operation & SPI_LOCK_ON)) { + return; + } + #ifdef CONFIG_POLL if (!ctx->asynchronous || status) { k_sem_give(&ctx->lock); @@ -73,6 +77,13 @@ static inline void spi_context_release(struct spi_context *ctx, int status) #endif } +static inline void spi_context_unlock_unconditionally(struct spi_context *ctx) +{ + if (!k_sem_count_get(&ctx->lock)) { + k_sem_give(&ctx->lock); + } +} + static inline void spi_context_wait_for_completion(struct spi_context *ctx) { #ifdef CONFIG_POLL @@ -94,7 +105,9 @@ static inline void spi_context_complete(struct spi_context *ctx, int status) k_poll_signal(ctx->signal, status); } - k_sem_give(&ctx->lock); + if (!(ctx->config->operation & SPI_LOCK_ON)) { + k_sem_give(&ctx->lock); + } } #else k_sem_give(&ctx->sync); diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index f313c9448ee..e65d1f2272f 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -339,6 +339,16 @@ static int spi_dw_transceive_async(struct spi_config *config, static int spi_dw_release(struct spi_config *config) { + const struct spi_dw_config *info = config->dev->config->config_info; + struct spi_dw_data *spi = config->dev->driver_data; + + if (!spi_context_configured(&spi->ctx, config) || + test_bit_ssienr(info->regs) || test_bit_sr_busy(info->regs)) { + return -EBUSY; + } + + spi_context_unlock_unconditionally(&spi->ctx); + return 0; }