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:
parent
cd54dc66f2
commit
0bd83d21f2
2 changed files with 33 additions and 7 deletions
|
@ -22,6 +22,8 @@ extern "C" {
|
||||||
struct spi_context {
|
struct spi_context {
|
||||||
struct spi_config *config;
|
struct spi_config *config;
|
||||||
|
|
||||||
|
struct k_sem lock;
|
||||||
|
|
||||||
const struct spi_buf **current_tx;
|
const struct spi_buf **current_tx;
|
||||||
struct spi_buf **current_rx;
|
struct spi_buf **current_rx;
|
||||||
|
|
||||||
|
@ -31,12 +33,25 @@ struct spi_context {
|
||||||
u32_t rx_len;
|
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,
|
static inline bool spi_context_configured(struct spi_context *ctx,
|
||||||
struct spi_config *config)
|
struct spi_config *config)
|
||||||
{
|
{
|
||||||
return !!(ctx->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)
|
static inline void spi_context_cs_configure(struct spi_context *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->config->cs) {
|
if (ctx->config->cs) {
|
||||||
|
|
|
@ -259,6 +259,7 @@ static int spi_dw_transceive(struct device *dev,
|
||||||
struct spi_dw_data *spi = dev->driver_data;
|
struct spi_dw_data *spi = dev->driver_data;
|
||||||
u32_t rx_thsld = DW_SPI_RXFTLR_DFLT;
|
u32_t rx_thsld = DW_SPI_RXFTLR_DFLT;
|
||||||
u32_t imask = DW_SPI_IMR_UNMASK;
|
u32_t imask = DW_SPI_IMR_UNMASK;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
SYS_LOG_DBG("%p, %p, %p", dev, tx_bufs, rx_bufs);
|
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;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spi_context_lock(&spi->ctx);
|
||||||
|
|
||||||
/* Configure */
|
/* Configure */
|
||||||
if (spi_dw_configure(info, spi, config)) {
|
ret = spi_dw_configure(info, spi, config);
|
||||||
return -EINVAL;
|
if (ret) {
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set buffers info */
|
/* Set buffers info */
|
||||||
|
@ -305,11 +309,12 @@ static int spi_dw_transceive(struct device *dev,
|
||||||
k_sem_take(&spi->device_sync_sem, K_FOREVER);
|
k_sem_take(&spi->device_sync_sem, K_FOREVER);
|
||||||
|
|
||||||
if (spi->error) {
|
if (spi->error) {
|
||||||
spi->error = 0;
|
ret = -EIO;
|
||||||
return -EIO;
|
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
spi_context_release(&spi->ctx);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_dw_isr(struct device *dev)
|
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);
|
SYS_LOG_DBG("Designware SPI driver initialized on device: %p", dev);
|
||||||
|
|
||||||
|
spi_context_release(&spi->ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +379,9 @@ int spi_dw_init(struct device *dev)
|
||||||
#ifdef CONFIG_SPI_0
|
#ifdef CONFIG_SPI_0
|
||||||
void spi_config_0_irq(void);
|
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 = {
|
const struct spi_dw_config spi_dw_config_0 = {
|
||||||
.regs = SPI_DW_PORT_0_REGS,
|
.regs = SPI_DW_PORT_0_REGS,
|
||||||
|
@ -415,7 +424,9 @@ void spi_config_0_irq(void)
|
||||||
#ifdef CONFIG_SPI_1
|
#ifdef CONFIG_SPI_1
|
||||||
void spi_config_1_irq(void);
|
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 = {
|
static const struct spi_dw_config spi_dw_config_1 = {
|
||||||
.regs = SPI_DW_PORT_1_REGS,
|
.regs = SPI_DW_PORT_1_REGS,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue