drivers/spi: Add reentrance support to DW driver in a generic manner

Let's improve common SPI driver context by adding a lock and generic
function to get/release it.

It's statically initialized to save a bit of ROM.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2017-05-05 13:28:17 +02:00 committed by Anas Nashif
commit 0bd83d21f2
2 changed files with 33 additions and 7 deletions

View file

@ -22,6 +22,8 @@ extern "C" {
struct spi_context {
struct spi_config *config;
struct k_sem lock;
const struct spi_buf **current_tx;
struct spi_buf **current_rx;
@ -31,12 +33,25 @@ struct spi_context {
u32_t rx_len;
};
#define SPI_CONTEXT_INIT_LOCK(_data, _ctx_name) \
._ctx_name.lock = K_SEM_INITIALIZER(_data._ctx_name.lock, 0, 1)
static inline bool spi_context_configured(struct spi_context *ctx,
struct spi_config *config)
{
return !!(ctx->config == config);
}
static inline void spi_context_lock(struct spi_context *ctx)
{
k_sem_take(&ctx->lock, K_FOREVER);
}
static inline void spi_context_release(struct spi_context *ctx)
{
k_sem_give(&ctx->lock);
}
static inline void spi_context_cs_configure(struct spi_context *ctx)
{
if (ctx->config->cs) {

View file

@ -259,6 +259,7 @@ static int spi_dw_transceive(struct device *dev,
struct spi_dw_data *spi = dev->driver_data;
u32_t rx_thsld = DW_SPI_RXFTLR_DFLT;
u32_t imask = DW_SPI_IMR_UNMASK;
int ret = 0;
SYS_LOG_DBG("%p, %p, %p", dev, tx_bufs, rx_bufs);
@ -268,9 +269,12 @@ static int spi_dw_transceive(struct device *dev,
return -EBUSY;
}
spi_context_lock(&spi->ctx);
/* Configure */
if (spi_dw_configure(info, spi, config)) {
return -EINVAL;
ret = spi_dw_configure(info, spi, config);
if (ret) {
goto out;
}
/* Set buffers info */
@ -305,11 +309,12 @@ static int spi_dw_transceive(struct device *dev,
k_sem_take(&spi->device_sync_sem, K_FOREVER);
if (spi->error) {
spi->error = 0;
return -EIO;
ret = -EIO;
}
out:
spi_context_release(&spi->ctx);
return 0;
return ret;
}
void spi_dw_isr(struct device *dev)
@ -365,6 +370,8 @@ int spi_dw_init(struct device *dev)
SYS_LOG_DBG("Designware SPI driver initialized on device: %p", dev);
spi_context_release(&spi->ctx);
return 0;
}
@ -372,7 +379,9 @@ int spi_dw_init(struct device *dev)
#ifdef CONFIG_SPI_0
void spi_config_0_irq(void);
struct spi_dw_data spi_dw_data_port_0;
struct spi_dw_data spi_dw_data_port_0 = {
SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_0, ctx),
};
const struct spi_dw_config spi_dw_config_0 = {
.regs = SPI_DW_PORT_0_REGS,
@ -415,7 +424,9 @@ void spi_config_0_irq(void)
#ifdef CONFIG_SPI_1
void spi_config_1_irq(void);
struct spi_dw_data spi_dw_data_port_1;
struct spi_dw_data spi_dw_data_port_1 = {
SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_1, ctx),
};
static const struct spi_dw_config spi_dw_config_1 = {
.regs = SPI_DW_PORT_1_REGS,