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 <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
0bd83d21f2
commit
b9838475ac
3 changed files with 18 additions and 5 deletions
|
@ -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) {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue