Skip to content

Commit d46d5c8

Browse files
committed
Merge tag 'tty-7.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH: "Here are some small tty/vt and serial driver fixes for 7.0-rc5. Included in here are: - 8250 driver fixes for reported problems - serial core lockup fix - uartlite driver bugfix - vt save/restore bugfix All of these have been in linux-next for over a week with no reported problems" * tag 'tty-7.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: vt: save/restore unicode screen buffer for alternate screen serial: 8250_dw: Ensure BUSY is deasserted serial: 8250: Add late synchronize_irq() to shutdown to handle DW UART BUSY serial: 8250_dw: Rework IIR_NO_INT handling to stop interrupt storm serial: 8250_dw: Rework dw8250_handle_irq() locking and IIR handling serial: 8250: Add serial8250_handle_irq_locked() serial: 8250_dw: Avoid unnecessary LCR writes serial: 8250: Protect LCR write in shutdown serial: 8250_pci: add support for the AX99100 serial: core: fix infinite loop in handle_tx() for PORT_UNKNOWN serial: uartlite: fix PM runtime usage count underflow on probe serial: 8250: always disable IRQ during THRE test serial: 8250: Fix TX deadlock when using DMA
2 parents c612261 + 5eb6083 commit d46d5c8

10 files changed

Lines changed: 352 additions & 92 deletions

File tree

drivers/tty/serial/8250/8250.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,9 @@ static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
175175
return value;
176176
}
177177

178+
void serial8250_clear_fifos(struct uart_8250_port *p);
178179
void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
180+
void serial8250_fifo_wait_for_lsr_thre(struct uart_8250_port *up, unsigned int count);
179181

180182
void serial8250_rpm_get(struct uart_8250_port *p);
181183
void serial8250_rpm_put(struct uart_8250_port *p);
@@ -400,6 +402,26 @@ static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
400402

401403
return dma && dma->tx_running;
402404
}
405+
406+
static inline void serial8250_tx_dma_pause(struct uart_8250_port *p)
407+
{
408+
struct uart_8250_dma *dma = p->dma;
409+
410+
if (!dma->tx_running)
411+
return;
412+
413+
dmaengine_pause(dma->txchan);
414+
}
415+
416+
static inline void serial8250_tx_dma_resume(struct uart_8250_port *p)
417+
{
418+
struct uart_8250_dma *dma = p->dma;
419+
420+
if (!dma->tx_running)
421+
return;
422+
423+
dmaengine_resume(dma->txchan);
424+
}
403425
#else
404426
static inline int serial8250_tx_dma(struct uart_8250_port *p)
405427
{
@@ -421,6 +443,9 @@ static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
421443
{
422444
return false;
423445
}
446+
447+
static inline void serial8250_tx_dma_pause(struct uart_8250_port *p) { }
448+
static inline void serial8250_tx_dma_resume(struct uart_8250_port *p) { }
424449
#endif
425450

426451
static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)

drivers/tty/serial/8250/8250_dma.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,22 @@ void serial8250_tx_dma_flush(struct uart_8250_port *p)
162162
*/
163163
dma->tx_size = 0;
164164

165+
/*
166+
* We can't use `dmaengine_terminate_sync` because `uart_flush_buffer` is
167+
* holding the uart port spinlock.
168+
*/
165169
dmaengine_terminate_async(dma->txchan);
170+
171+
/*
172+
* The callback might or might not run. If it doesn't run, we need to ensure
173+
* that `tx_running` is cleared so that we can schedule new transactions.
174+
* If it does run, then the zombie callback will clear `tx_running` again
175+
* and perform a no-op since `tx_size` was cleared above.
176+
*
177+
* In either case, we ASSUME the DMA transaction will terminate before we
178+
* issue a new `serial8250_tx_dma`.
179+
*/
180+
dma->tx_running = 0;
166181
}
167182

168183
int serial8250_rx_dma(struct uart_8250_port *p)

0 commit comments

Comments
 (0)