Skip to content

Commit 0bd83d2

Browse files
Tomasz BursztykaAnas Nashif
authored andcommitted
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 <[email protected]>
1 parent cd54dc6 commit 0bd83d2

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

drivers/spi/spi_context.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ extern "C" {
2222
struct spi_context {
2323
struct spi_config *config;
2424

25+
struct k_sem lock;
26+
2527
const struct spi_buf **current_tx;
2628
struct spi_buf **current_rx;
2729

@@ -31,12 +33,25 @@ struct spi_context {
3133
u32_t rx_len;
3234
};
3335

36+
#define SPI_CONTEXT_INIT_LOCK(_data, _ctx_name) \
37+
._ctx_name.lock = K_SEM_INITIALIZER(_data._ctx_name.lock, 0, 1)
38+
3439
static inline bool spi_context_configured(struct spi_context *ctx,
3540
struct spi_config *config)
3641
{
3742
return !!(ctx->config == config);
3843
}
3944

45+
static inline void spi_context_lock(struct spi_context *ctx)
46+
{
47+
k_sem_take(&ctx->lock, K_FOREVER);
48+
}
49+
50+
static inline void spi_context_release(struct spi_context *ctx)
51+
{
52+
k_sem_give(&ctx->lock);
53+
}
54+
4055
static inline void spi_context_cs_configure(struct spi_context *ctx)
4156
{
4257
if (ctx->config->cs) {

drivers/spi/spi_dw.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ static int spi_dw_transceive(struct device *dev,
259259
struct spi_dw_data *spi = dev->driver_data;
260260
u32_t rx_thsld = DW_SPI_RXFTLR_DFLT;
261261
u32_t imask = DW_SPI_IMR_UNMASK;
262+
int ret = 0;
262263

263264
SYS_LOG_DBG("%p, %p, %p", dev, tx_bufs, rx_bufs);
264265

@@ -268,9 +269,12 @@ static int spi_dw_transceive(struct device *dev,
268269
return -EBUSY;
269270
}
270271

272+
spi_context_lock(&spi->ctx);
273+
271274
/* Configure */
272-
if (spi_dw_configure(info, spi, config)) {
273-
return -EINVAL;
275+
ret = spi_dw_configure(info, spi, config);
276+
if (ret) {
277+
goto out;
274278
}
275279

276280
/* Set buffers info */
@@ -305,11 +309,12 @@ static int spi_dw_transceive(struct device *dev,
305309
k_sem_take(&spi->device_sync_sem, K_FOREVER);
306310

307311
if (spi->error) {
308-
spi->error = 0;
309-
return -EIO;
312+
ret = -EIO;
310313
}
314+
out:
315+
spi_context_release(&spi->ctx);
311316

312-
return 0;
317+
return ret;
313318
}
314319

315320
void spi_dw_isr(struct device *dev)
@@ -365,14 +370,18 @@ int spi_dw_init(struct device *dev)
365370

366371
SYS_LOG_DBG("Designware SPI driver initialized on device: %p", dev);
367372

373+
spi_context_release(&spi->ctx);
374+
368375
return 0;
369376
}
370377

371378

372379
#ifdef CONFIG_SPI_0
373380
void spi_config_0_irq(void);
374381

375-
struct spi_dw_data spi_dw_data_port_0;
382+
struct spi_dw_data spi_dw_data_port_0 = {
383+
SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_0, ctx),
384+
};
376385

377386
const struct spi_dw_config spi_dw_config_0 = {
378387
.regs = SPI_DW_PORT_0_REGS,
@@ -415,7 +424,9 @@ void spi_config_0_irq(void)
415424
#ifdef CONFIG_SPI_1
416425
void spi_config_1_irq(void);
417426

418-
struct spi_dw_data spi_dw_data_port_1;
427+
struct spi_dw_data spi_dw_data_port_1 = {
428+
SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_1, ctx),
429+
};
419430

420431
static const struct spi_dw_config spi_dw_config_1 = {
421432
.regs = SPI_DW_PORT_1_REGS,

0 commit comments

Comments
 (0)