From b9838475accedbd09a9127719d20aaf580a0fc75 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 5 May 2017 13:42:44 +0200 Subject: [PATCH] drivers/spi: Handle synchronous calls in a generic manner in DW driver All SPI drivers have this same way to handle synchronous call, thus let's generalize it in struct spi_context, with a relevant API and apply the change into SPI DW driver. spi_context API will prove to be useful once asynchronous call will be handled as well, through the same completion functions used now only for synchronous call. It will be transparent for the driver. Signed-off-by: Tomasz Bursztyka --- drivers/spi/spi_context.h | 14 ++++++++++++++ drivers/spi/spi_dw.c | 8 ++++---- drivers/spi/spi_dw.h | 1 - 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi_context.h b/drivers/spi/spi_context.h index d2075ca4596..96d39ab0e9e 100644 --- a/drivers/spi/spi_context.h +++ b/drivers/spi/spi_context.h @@ -23,6 +23,7 @@ struct spi_context { struct spi_config *config; struct k_sem lock; + struct k_sem sync; const struct spi_buf **current_tx; struct spi_buf **current_rx; @@ -36,6 +37,9 @@ struct spi_context { #define SPI_CONTEXT_INIT_LOCK(_data, _ctx_name) \ ._ctx_name.lock = K_SEM_INITIALIZER(_data._ctx_name.lock, 0, 1) +#define SPI_CONTEXT_INIT_SYNC(_data, _ctx_name) \ + ._ctx_name.sync = K_SEM_INITIALIZER(_data._ctx_name.sync, 0, UINT_MAX) + static inline bool spi_context_configured(struct spi_context *ctx, struct spi_config *config) { @@ -52,6 +56,16 @@ static inline void spi_context_release(struct spi_context *ctx) k_sem_give(&ctx->lock); } +static inline void spi_context_wait_for_completion(struct spi_context *ctx) +{ + k_sem_take(&ctx->sync, K_FOREVER); +} + +static inline void spi_context_complete(struct spi_context *ctx) +{ + k_sem_give(&ctx->sync); +} + static inline void spi_context_cs_configure(struct spi_context *ctx) { if (ctx->config->cs) { diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index e1e539eb244..68b24530641 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -75,7 +75,7 @@ out: SYS_LOG_DBG("SPI transaction completed %s error", error ? "with" : "without"); - k_sem_give(&spi->device_sync_sem); + spi_context_complete(&spi->ctx); } static void push_data(struct device *dev) @@ -306,7 +306,7 @@ static int spi_dw_transceive(struct device *dev, /* Enable the controller */ set_bit_ssienr(info->regs); - k_sem_take(&spi->device_sync_sem, K_FOREVER); + spi_context_wait_for_completion(&spi->ctx); if (spi->error) { ret = -EIO; @@ -362,8 +362,6 @@ int spi_dw_init(struct device *dev) info->config_func(); - k_sem_init(&spi->device_sync_sem, 0, UINT_MAX); - /* Masking interrupt and making sure controller is disabled */ write_imr(DW_SPI_IMR_MASK, info->regs); clear_bit_ssienr(info->regs); @@ -381,6 +379,7 @@ void spi_config_0_irq(void); struct spi_dw_data spi_dw_data_port_0 = { SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_0, ctx), + SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_0, ctx), }; const struct spi_dw_config spi_dw_config_0 = { @@ -426,6 +425,7 @@ void spi_config_1_irq(void); struct spi_dw_data spi_dw_data_port_1 = { SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_1, ctx), + SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_1, ctx), }; static const struct spi_dw_config spi_dw_config_1 = { diff --git a/drivers/spi/spi_dw.h b/drivers/spi/spi_dw.h index 795368426a6..e5cd4852d7f 100644 --- a/drivers/spi/spi_dw.h +++ b/drivers/spi/spi_dw.h @@ -51,7 +51,6 @@ struct spi_dw_data { #ifdef CONFIG_SPI_DW_CLOCK_GATE struct device *clock; #endif /* CONFIG_SPI_DW_CLOCK_GATE */ - struct k_sem device_sync_sem; struct spi_context ctx; u8_t error; u8_t dfs; /* dfs in bytes: 1,2 or 4 */