api/spi: Add a dedicated Kconfig option for asynchronous mode enablement

Instead of using CONFIG_POLL, which is not directly related to SPI and
is a kernel option, let's have SPI_ASYNC instead. When enabled, it will
select POLL automatically.

Fixes #5839

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2018-01-29 22:12:50 +01:00 committed by Carles Cufí
commit da42c0077c
7 changed files with 33 additions and 25 deletions

View file

@ -24,6 +24,13 @@ config SPI_LEGACY_API
Driver and user API implements/use the legacy SPI API.
If unselected, the new API will be used (default).
config SPI_ASYNC
bool "Enable Asynchronous call support"
default n
select POLL
help
This option enables the asynchronous API calls.
config SPI_INIT_PRIORITY
int "Init priority"
default 70

View file

@ -26,10 +26,10 @@ struct spi_context {
struct k_sem sync;
int sync_status;
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
struct k_poll_signal *signal;
bool asynchronous;
#endif
#endif /* CONFIG_SPI_ASYNC */
const struct spi_buf *current_tx;
size_t tx_count;
const struct spi_buf *current_rx;
@ -59,10 +59,10 @@ static inline void spi_context_lock(struct spi_context *ctx,
{
k_sem_take(&ctx->lock, K_FOREVER);
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
ctx->asynchronous = asynchronous;
ctx->signal = signal;
#endif
#endif /* CONFIG_SPI_ASYNC */
}
static inline void spi_context_release(struct spi_context *ctx, int status)
@ -71,13 +71,13 @@ static inline void spi_context_release(struct spi_context *ctx, int status)
return;
}
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
if (!ctx->asynchronous || status) {
k_sem_give(&ctx->lock);
}
#else
k_sem_give(&ctx->lock);
#endif
#endif /* CONFIG_SPI_ASYNC */
}
static inline void spi_context_unlock_unconditionally(struct spi_context *ctx)
@ -90,7 +90,7 @@ static inline void spi_context_unlock_unconditionally(struct spi_context *ctx)
static inline int spi_context_wait_for_completion(struct spi_context *ctx)
{
int status = 0;
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
if (!ctx->asynchronous) {
k_sem_take(&ctx->sync, K_FOREVER);
status = ctx->sync_status;
@ -98,13 +98,13 @@ static inline int spi_context_wait_for_completion(struct spi_context *ctx)
#else
k_sem_take(&ctx->sync, K_FOREVER);
status = ctx->sync_status;
#endif
#endif /* CONFIG_SPI_ASYNC */
return status;
}
static inline void spi_context_complete(struct spi_context *ctx, int status)
{
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
if (!ctx->asynchronous) {
ctx->sync_status = status;
k_sem_give(&ctx->sync);
@ -120,7 +120,7 @@ static inline void spi_context_complete(struct spi_context *ctx, int status)
#else
ctx->sync_status = status;
k_sem_give(&ctx->sync);
#endif
#endif /* CONFIG_SPI_ASYNC */
}
static inline void spi_context_cs_configure(struct spi_context *ctx)

View file

@ -321,7 +321,7 @@ static int spi_dw_transceive(struct device *dev,
return transceive(dev, config, tx_bufs, rx_bufs, false, NULL);
}
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
static int spi_dw_transceive_async(struct device *dev,
const struct spi_config *config,
const struct spi_buf_set *tx_bufs,
@ -332,7 +332,7 @@ static int spi_dw_transceive_async(struct device *dev,
return transceive(dev, config, tx_bufs, rx_bufs, true, async);
}
#endif /* CONFIG_POLL */
#endif /* CONFIG_SPI_ASYNC */
static int spi_dw_release(struct device *dev, const struct spi_config *config)
{
@ -382,9 +382,9 @@ out:
static const struct spi_driver_api dw_spi_api = {
.transceive = spi_dw_transceive,
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
.transceive_async = spi_dw_transceive_async,
#endif
#endif /* CONFIG_SPI_ASYNC */
.release = spi_dw_release,
};

View file

@ -429,7 +429,7 @@ static int spi_stm32_transceive(struct device *dev,
return transceive(dev, config, tx_bufs, rx_bufs, false, NULL);
}
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
static int spi_stm32_transceive_async(struct device *dev,
const struct spi_config *config,
const struct spi_buf_set *tx_bufs,
@ -438,11 +438,11 @@ static int spi_stm32_transceive_async(struct device *dev,
{
return transceive(dev, config, tx_bufs, rx_bufs, true, async);
}
#endif /* CONFIG_POLL */
#endif /* CONFIG_SPI_ASYNC */
static const struct spi_driver_api api_funcs = {
.transceive = spi_stm32_transceive,
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
.transceive_async = spi_stm32_transceive_async,
#endif
.release = spi_stm32_release,

View file

@ -400,7 +400,7 @@ done:
return err;
}
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
static int spi_sam0_transceive_async(struct device *dev,
const struct spi_config *config,
const struct spi_buf_set *tx_bufs,
@ -409,7 +409,7 @@ static int spi_sam0_transceive_async(struct device *dev,
{
return -ENOTSUP;
}
#endif
#endif /* CONFIG_SPI_ASYNC */
static int spi_sam0_release(struct device *dev,
const struct spi_config *config)
@ -449,7 +449,7 @@ static int spi_sam0_init(struct device *dev)
static const struct spi_driver_api spi_sam0_driver_api = {
.transceive = spi_sam0_transceive,
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
.transceive_async = spi_sam0_transceive_async,
#endif
.release = spi_sam0_release,

View file

@ -231,9 +231,9 @@ typedef int (*spi_api_release)(struct device *dev,
*/
struct spi_driver_api {
spi_api_io transceive;
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
spi_api_io_async transceive_async;
#endif
#endif /* CONFIG_SPI_ASYNC */
spi_api_release release;
};
@ -302,7 +302,7 @@ static inline int spi_write(struct device *dev,
return spi_transceive(dev, config, tx_bufs, NULL);
}
#ifdef CONFIG_POLL
#ifdef CONFIG_SPI_ASYNC
/**
* @brief Read/write the specified amount of data from the SPI driver.
*
@ -377,7 +377,7 @@ static inline int spi_write_async(struct device *dev,
{
return spi_transceive_async(dev, config, tx_bufs, NULL, async);
}
#endif /* CONFIG_POLL */
#endif /* CONFIG_SPI_ASYNC */
/**
* @brief Release the SPI device locked on by the current config

View file

@ -3,5 +3,6 @@ CONFIG_BOOT_BANNER=y
CONFIG_BUILD_TIMESTAMP=y
CONFIG_SYS_LOG=y
CONFIG_SPI=y
CONFIG_SPI_ASYNC=y
CONFIG_SYS_LOG_SPI_LEVEL=1
CONFIG_POLL=y