Skip to content

Commit

Permalink
drivers: serial: Disable interrupts in SCIF driver
Browse files Browse the repository at this point in the history
SCIF uses interrups by LEVEL and TX interrupt is fired if FIFO is not
full. In this case interrupt is faired immediately after exit from ISR.
Disable interrupts in SCIF driver after DMA operation finished. We
don't need enabled interrupts if nothing to transmit.

Signed-off-by: Dmytro Semenets <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Volodymyr Babchuk <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
  • Loading branch information
dsemenets committed Mar 28, 2024
1 parent 14d3700 commit 8d17e9d
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/serial/uart_scif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@ static void uart_scif_dma_replace_buffer(const struct device *dev)
return;
}

uart_scif_write_16(dev, SCSCR, uart_scif_read_16(dev, SCSCR) | SCSCR_RE | SCSCR_RIE);

/* Request next buffer */
scif_async_evt_rx_buf_request(data);
}
Expand Down Expand Up @@ -1126,6 +1128,8 @@ static int uart_scif_async_tx_abort(const struct device *dev)
{
struct uart_scif_data *data = dev->data;

/* Turn off TX Interrupts to prevent hung in ISR */
uart_scif_write_16(dev, SCSCR, uart_scif_read_16(dev, SCSCR) & ~(SCSCR_TIE));
(void)k_work_cancel_delayable(&data->dma_tx.timeout_work);
return 0;
}
Expand Down Expand Up @@ -1228,6 +1232,8 @@ static void dma_tx_callback(const struct device *dev, void *user_data,
if (!dma_get_status(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &stat)) {
data->dma_tx.counter = data->dma_tx.buffer_length - stat.pending_length;
}
/* Turn off TX Interrupts to prevent hung in ISR */
uart_scif_write_16(uart_dev, SCSCR, uart_scif_read_16(uart_dev, SCSCR) & ~(SCSCR_TIE));
scif_async_evt_tx_done(data);
K_SPINLOCK(&data->dma_tx.lock) {
data->dma_tx.buffer_length = 0;
Expand All @@ -1240,6 +1246,9 @@ static void dma_rx_callback(const struct device *dev, void *user_data,
const struct device *uart_dev = user_data;
struct uart_scif_data *data = uart_dev->data;

/* Turn off RX Interrupts to prevent hung in ISR */
uart_scif_write_16(uart_dev, SCSCR, uart_scif_read_16(uart_dev, SCSCR) & ~(SCSCR_RIE));

(void)k_work_cancel_delayable(&data->dma_rx.timeout_work);
if (status < 0) {
scif_async_evt_rx_err(data, status);
Expand Down

0 comments on commit 8d17e9d

Please sign in to comment.