Skip to content

Commit 86af9bc

Browse files
teburdstephanosio
authored andcommitted
spi: SAM add spin lock around all tx/rx/txrx funcs
The fast tx/rx/txrx functions will leave the SPI bus in an inoperable state if interrupted, potentially spinning forever waiting on some data. Wrapping these operations in what amounts to a critical section using spin locks to avoid the issue. Signed-off-by: Tom Burdick <[email protected]>
1 parent bcee4ed commit 86af9bc

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

drivers/spi/spi_sam.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ static void spi_sam_finish(Spi *regs)
180180
/* Fast path that transmits a buf */
181181
static void spi_sam_fast_tx(Spi *regs, const struct spi_buf *tx_buf)
182182
{
183+
struct k_spinlock lock;
184+
k_spinlock_key_t key = k_spin_lock(&lock);
185+
183186
const uint8_t *p = tx_buf->buf;
184187
const uint8_t *pend = (uint8_t *)tx_buf->buf + tx_buf->len;
185188
uint8_t ch;
@@ -194,11 +197,16 @@ static void spi_sam_fast_tx(Spi *regs, const struct spi_buf *tx_buf)
194197
}
195198

196199
spi_sam_finish(regs);
200+
201+
k_spin_unlock(&lock, key);
197202
}
198203

199204
/* Fast path that reads into a buf */
200205
static void spi_sam_fast_rx(Spi *regs, const struct spi_buf *rx_buf)
201206
{
207+
struct k_spinlock lock;
208+
k_spinlock_key_t key = k_spin_lock(&lock);
209+
202210
uint8_t *rx = rx_buf->buf;
203211
int len = rx_buf->len;
204212

@@ -234,6 +242,8 @@ static void spi_sam_fast_rx(Spi *regs, const struct spi_buf *rx_buf)
234242
*rx = (uint8_t)regs->SPI_RDR;
235243

236244
spi_sam_finish(regs);
245+
246+
k_spin_unlock(&lock, key);
237247
}
238248

239249
#ifdef CONFIG_SPI_SAM_DMA
@@ -383,6 +393,9 @@ static void spi_sam_fast_txrx(Spi *regs,
383393
const struct spi_buf *tx_buf,
384394
const struct spi_buf *rx_buf)
385395
{
396+
struct k_spinlock lock;
397+
k_spinlock_key_t key = k_spin_lock(&lock);
398+
386399
const uint8_t *tx = tx_buf->buf;
387400
const uint8_t *txend = (uint8_t *)tx_buf->buf + tx_buf->len;
388401
uint8_t *rx = rx_buf->buf;
@@ -431,6 +444,8 @@ static void spi_sam_fast_txrx(Spi *regs,
431444
*rx = (uint8_t)regs->SPI_RDR;
432445

433446
spi_sam_finish(regs);
447+
448+
k_spin_unlock(&lock, key);
434449
}
435450

436451
static inline void spi_sam_rx(const struct device *dev,

0 commit comments

Comments
 (0)