Messages in this thread | | | Date | Tue, 22 Nov 2022 09:18:48 +0100 | From | Michael Walle <> | Subject | Re: [PATCH v5 2/3] tty: serial: use uart_port_tx() helper |
| |
Am 2022-11-22 09:09, schrieb Michael Walle: > Hi, > > Am 2022-11-22 08:02, schrieb Jiri Slaby: >> On 21. 11. 22, 21:27, Michael Walle wrote: >>> This will break serial output for the userspace on my board >>> (arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt*dts). The >>> uart_port_tx() >>> helper will call __port->ops->stop_tx(__port) if >>> uart_circ_chars_pending() >>> returns 0. But the code above, doesn't do that. In fact, removing the >>> stop_tx() call in the helper macro, will fix the console output. >>> >>> Any ideas how to fix that? >> >> Hm, so ATMEL_US_TXRDY is removed from tx_done_mask in stop_tx, but not >> added back in start_tx. So the tx interrupt is never handled (the tx >> tasklet is not scheduled to send the queue chars) in >> atmel_handle_transmit(). >> >> Any chance, the below fixes it? >> >> diff --git a/drivers/tty/serial/atmel_serial.c >> b/drivers/tty/serial/atmel_serial.c >> index 11bf2466390e..395370e0c77b 100644 >> --- a/drivers/tty/serial/atmel_serial.c >> +++ b/drivers/tty/serial/atmel_serial.c >> @@ -596,6 +596,8 @@ static void atmel_start_tx(struct uart_port *port) >> /* re-enable PDC transmit */ >> atmel_uart_writel(port, ATMEL_PDC_PTCR, >> ATMEL_PDC_TXTEN); >> >> + atmel_port->tx_done_mask |= ATMEL_US_TXRDY; >> + >> /* Enable interrupts */ >> atmel_uart_writel(port, ATMEL_US_IER, >> atmel_port->tx_done_mask); >> >> >> thanks, > > Unfortunately, that doesn't help. Btw, some characters are transmitted: > > > [ 6.219356] Key type dns_resolver registered > [ 6.223679] Registering SWP/SWPB emulation handler > [ 6.247530] Loading compiled-in X.509 certificates > [ 6.288467] Freeing unused kernel image (initmem) memory: 1024K > [ 6.297789] Run /init as init process > WbSOROSOSOSOSOStarting linuxptp system clock synchronization: O > > -michael
But you made me look at atmel_stop_tx() and there is this:
/* * Disable the transmitter. * This is mandatory when DMA is used, otherwise the DMA buffer * is fully transmitted. */ atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
Removing that write, will also fix the problem. Could it be, that the transmit is still active (via DMA) but the driver will call tx_stop() and then stop the transmission in the background?
-michael
| |