Commit graph zephyr/drivers/serial
Author SHA1 Message Date
Guðni Már Gilbert
344987da05 drivers: serial: nrfx: Avoid expanding disabled UARTE instances
IF_ENABLED expands UART_NRF_UARTE_DEVICE before discarding declarations
for disabled instances. Select the declaration macro before invoking it
to avoid this work.

For blinky on nrf54l15dk/nrf54l15/cpuapp, uncached compilation of
uart_nrfx_uarte.c drops from approximately 4.7 s to 1.3 s.

Assisted-by: Codex:GPT-6
Signed-off-by: Guðni Már Gilbert <gudni.m.g@gmail.com>
2026-10-29 19:45:51 -04:00
Richard Mc Sweeney
6d9efb6f5c drivers: serial: infineon: park UART TX across DS
cyhal only parks the pad when it knows the TX pin exists. Passing NC
left it floating for the whole sleep. Resolve it from the mux table.

Assisted-by: Copilot:claude-opus-5
Signed-off-by: Richard Mc Sweeney <Richard.McSweeney@infineon.com>
2026-10-29 19:44:17 -04:00
Richard Mc Sweeney
4ee6b9285d drivers: serial: infineon: block poll_out properly
cyhal_uart_putc() returns once the byte is in the FIFO, so poll_out
returned early and a draining shifter made the SCB veto DeepSleep.
This now blocks until the byte is shifted out.

Assisted-by: Copilot:claude-opus-5
Signed-off-by: Richard Mc Sweeney <Richard.McSweeney@infineon.com>
2026-10-29 19:44:17 -04:00
Benjamin Cabé
f2dd511715 drivers: serial: uart_mcux_lpsci: clear RX overrun in interrupt mode
The LPSCI stores no data while S1[OR] is set and only uart_err_check()
cleared it, so interrupt-driven RX stalled after an overrun. Clear OR
in the ISR after the callback and enable the overrun interrupt, as
uart_mcux_lpuart does. Not tested on hardware.

Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-10-29 19:43:41 -04:00
Gail Rojas
fda1a4f338 drivers: serial: msp432p4xx: fix ISR masking UART interrupt
The ISR read the enabled interrupt status and passed it to
disableInterrupt at the end of every callback invocation. This
silently disabled whichever UART interrupt had just fired, causing
the shell and any other interrupt-driven consumer to stop receiving
input after the first event.

Remove the disable call. The TX interrupt flag is level-sensitive and
stays set while the transmit buffer is empty; the registered callback
is responsible for disabling TX interrupts once it has no more data
to send.

Signed-off-by: Gail Rojas <gailroco@gmail.com>
Assisted-by: Claude
2026-10-29 19:43:08 -04:00
Gail Rojas
3138fb03ec drivers: serial: msp432p4xx: fix fifo_fill transmit flag check
The function checked the transmit-complete flag after writing each
byte rather than the transmit-ready flag before. Transmit-complete
fires after the shift register empties, not when the buffer is ready
to accept a new byte, so the old check had the wrong contract and
dropped bytes under load.

Check the transmit-ready flag before writing and extract it into a
local variable so the loop condition stays within the 80-column limit.

Signed-off-by: Gail Rojas <gailroco@gmail.com>
Assisted-by: Claude
2026-10-29 19:43:08 -04:00
Gail Rojas
bc946378eb drivers: serial: msp432p4xx: fix poll_in when no byte is waiting
The function read from the receive buffer unconditionally and returned
0 even when no byte had arrived, giving callers stale or uninitialized
data. Check the receive interrupt flag before reading and return -1
immediately if the buffer is empty, matching the poll_in contract
required by the Zephyr UART API.

Signed-off-by: Gail Rojas <gailroco@gmail.com>
Assisted-by: Claude
2026-10-29 19:43:08 -04:00
Anas Nashif
ecee79e1ac drivers: serial: rts5912: use portable IRQ pending API
Replace direct NVIC_*PendingIRQ()/NVIC_EnableIRQ()/NVIC_DisableIRQ()
calls with k_irq_clear_pending()/k_irq_set_pending()/k_irq_is_pending() and
irq_enable()/irq_disable(), dropping the driver's dependency on
cmsis_core.h where nothing else needed it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-10-29 15:38:34 -04:00
Otavio Salvador
e0a30bafe0 drivers: serial: native_tty: stop on a hung-up port
poll() reports a hung-up or failed tty as ready, so the interrupt
emulation thread called the UART callback forever while every read
failed: unplugging a USB serial adapter left the application spinning.

native_tty_poll_bottom(), the host side of the poll, now returns EIO on
POLLHUP and POLLERR, EBADF on POLLNVAL and the host's errno when poll()
itself fails, all as NSI_ERRNO_MID_* values, and the thread exits the
process naming the port and the error, as opening it does when it is
missing.

A poll() interrupted by a signal is not an error: it reports no data, and
the thread polls again on its next iteration.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
2026-10-28 22:54:49 -04:00
Emin Ates
eee99ff35d drivers: serial: silabs: fix EUSART data bits with parity
The EUSART driver incorrectly increments the configured data width
when parity is enabled. Silicon Labs EUSART hardware configures data
bits and parity independently.

As a result, 7-bit configurations with parity use 8 data bits, while
8-bit configurations with parity use 9 data bits.

Remove the parity-dependent adjustment and map the requested UART
data width directly to the EUSART hardware configuration.

Signed-off-by: Emin Ates <m.emin.ates@hotmail.com>
2026-10-28 22:51:13 -04:00
Andrew Davis
8676d14d60 drivers: serial: stellaris: Use modern DT_INST_FOREACH helper
This driver was defining each instance using KConfig, we now have
DT_INST_FOREACH helpers to define multiple instances. Update to
this to allow arbitrary instance counts.

This then allows us to drop the KConfig symbols that once were
used for the above. But we do need to keep part of them around
in the SoC dir as these also set the power enable bits for these
devices. This could most likely be also updated to some form
of automatic PM handling, but for now just keep things simple.

Signed-off-by: Andrew Davis <afd@ti.com>
2026-10-28 22:43:55 -04:00
minyuan xue
ce2921bd48 drivers: uart: add ameba uart driver support
Add realtek ameba uart driver.

Signed-off-by: minyuan xue <minyuan_xue@realsil.com.cn>
2026-10-28 22:26:35 -04:00
Michal Chromec
07345ca8ec drivers: serial: mcux_flexcomm: reduce DMA RX buffer switch gap
In the async RX DMA completion callback, dma_reload() and dma_start()
were called after three user-visible callbacks (UART_RX_RDY,
UART_RX_BUF_RELEASED, UART_RX_BUF_REQUEST). During this window the
DMA was idle and only the RX FIFO protected against data loss.

Reorder the callback so that dma_reload() and dma_start() are called
immediately after the driver state is updated, before any user
callbacks are issued. Bytes arriving during the callbacks are then
captured by DMA rather than stalling in the RX FIFO.

Signed-off-by: Michal Chromec <michal.chromec@nxp.com>
2026-10-28 20:17:07 -04:00
Afonso Oliveira
d0f94fa7cc drivers: serial: add Nekko Shakti UART polling support
Include the UART needed for console output on the Erbium board. Its
original Shakti integration uses 32-bit MMIO accesses at eight-byte
register intervals, while the generic Shakti driver uses four-byte
intervals and mixed access widths.

Use openhwgroup,shakti-uart-v1 to identify the original register layout,
with interrupt enable at 0x30 and receive threshold at 0x40. The later
Erbium UART has a different interrupt register layout. Link the public
register documentation for the supported revision in the binding [1].

Follow the documented transmit flow: wait for space in the FIFO and
write the character. The functional emulator [2] also enqueues data on
the TX write, without additional configuration-register writes.

Provide polling input/output, receive error reporting and fixed 8N1
initialization. Calculate the baud divisor at build time from devicetree
clock-frequency and current-speed. Reject zero baud rates and divisors
outside 1..65535 with build assertions. Keep the divisor in the constant
device configuration and program it once at initialization. Use the
device MMIO API and add the serial Kconfig and CMake integration.

Validate polling transmit and receive with actual input on the public
et-platform functional emulator at 836a4ab600e93. Interrupt-driven,
asynchronous and runtime line-configuration APIs remain unsupported.

[1] 325b32b7ef/doc/uart.md
[2] 836a4ab600/sw-sysemu/devices/shakti_uart.h

Signed-off-by: Afonso Oliveira <afonso.oliveira707@gmail.com>
Assisted-by: Codex:GPT-6
2026-10-28 20:14:43 -04:00
Fin Maaß
00e80416aa drivers: serial: sifive: only report enabled interrupts as pending
The ip register reports the watermark conditions regardless of the ie
register, so with the TX FIFO empty and the TX interrupt disabled
uart_irq_is_pending() kept returning 1 and callbacks that loop until
nothing is pending never terminated. Mask ip with ie.

Fixes the test_uart_pending case of tests/drivers/uart/uart_basic_api,
run on qemu_riscv32_xip.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
2026-10-21 13:46:12 +02:00
Benjamin Cabé
c124f43e72 drivers: serial: mcux_lpuart: wait for TX room with interrupts enabled
mcux_lpuart_poll_out() waited for the transmit data register to be empty
with interrupts locked, which holds them off for up to a character time.
It now waits with interrupts enabled, and locks them only to check again
and write the character.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
2026-10-21 11:47:22 +02:00
Dominika Kubicz
d4ea79f99e drivers: serial: uart_emul: initialize locals defensively
Initialize rx_buf, rx_buf_len, rx_buf_offset, rx_buf_data_len, rx_en,
written, and rx_stopping at declaration. These are always assigned
 before use on every path, but static analysis cannot prove this
 through the K_SPINLOCK for-loop construct, producing false-positive
 uninitialized-read warnings (MISRA C:2012 Rule 9.1).

No functional change.

Signed-off-by: Dominika Kubicz <dominika.kubicz@gmail.com>
2026-10-21 11:46:43 +02:00
Sylvio Alves
20230563c3 drivers: serial: esp32_usb: recover in fifo after bus reset
A USB bus reset leaves data already in the USB Serial/JTAG IN
FIFO uncommitted: the FIFO is not marked free and the data is
never sent. The host resets the bus several times while
enumerating, so output written before or during enumeration can
stall TX for good while RX keeps working. Whether it hits depends
on boot timing.

Flush the IN FIFO in poll_out() when it is not writable. In
interrupt mode, arm the EP1 IN token interrupt on each bus reset
and flush on the first token, once the host is reading.

Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
2026-10-21 11:44:29 +02:00
Fin Maaß
6ad602ad30 drivers: serial: sifive: drop sys_clk_freq from the config struct
SIFIVE_PERIPHERAL_CLOCK_FREQUENCY is the same for every instance, so
use it directly when computing the baud rate divisor instead of
storing a copy in each device config.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
2026-10-20 17:45:31 +02:00
Aksel Skauge Mellbye
f764977314 drivers: serial: silabs_usart: Hold TX PM lock until TXC
For interrupt-driven transfers, PM must be locked until data has
been fully shifted out. Postpone releasing the PM lock until TXC
is reported.

Split handling of TXBL and TXC such that TXBL maps to the user-facing
callback, while TXC is only used internally in the driver. Only handle
TXC and RXOF in the async ISR when an async transfer is active, so the
interrupt-driven API receives them otherwise.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-20 17:42:59 +02:00
Aksel Skauge Mellbye
26859d9e21 drivers: serial: silabs: Request next RX buffer before DMA completes
If the first RX buffer was filled as soon as the DMA started, the DMA
callback could report UART_RX_DISABLED before rx_enable() emitted
UART_RX_BUF_REQUEST, so the request arrived for a disabled receiver.

Lock interrupts from enabling the RX interrupts until the buffer request
has been emitted, so the DMA completion is handled after the request and
can use a buffer provided in response to it. This also keeps an RX
overflow interrupt from disabling RX before the DMA is started.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-20 17:42:59 +02:00
Aksel Skauge Mellbye
27f2a1cdff drivers: serial: silabs: Enable RX interrupts before starting DMA
RX could complete in the DMA callback before rx_enable() enabled the
RX overflow and timeout interrupts, leaving them enabled while RX was
disabled.

Enable the interrupts before starting the DMA, and disable them again
if the DMA fails to start.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-20 17:42:59 +02:00
Aksel Skauge Mellbye
bd8209bd01 drivers: serial: silabs: Disable RX interrupts when DMA stops RX
When the RX DMA buffer was filled and no next buffer was provided, the
DMA callback stopped RX and reported UART_RX_DISABLED, but left the RXOF
and TCMP1 interrupts enabled. A later overrun or receive timeout then
raised async events for a receiver that was already disabled.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-20 17:42:59 +02:00
Arkadiusz Grzelka
dda08cc854 drivers: serial: uart_bt: rate-limit the unsubscribed drop warning
LOG_WRN_ONCE() keeps one flag per call site, so the warning in
uart_bt_fifo_fill() fires once per boot for all instances. Output
dropped in a later period without a subscriber goes unreported.

Use LOG_WRN_RATELIMIT() so the warning repeats, at most once per
CONFIG_LOG_RATELIMIT_INTERVAL_MS.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Arkadiusz Grzelka <arkadiusz.grzelka@arivemb.com>
2026-10-19 10:24:44 +02:00
Benjamin Cabé
f93698d20c drivers: serial: mcux_lpuart: RX timeout from a kernel timer
Run the RX timeout from a k_timer, in interrupt context like the idle
line and DMA events that also flush received data, instead of a
delayable work item on the system work queue. This avoids a work queue
thread wakeup for each burst of received data.

Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-10-16 13:17:16 +02:00
Luis Casas
a657098407 drivers: serial: mcux_lpuart: fix single-wire implementation
The LPUART driver for NXP devices did not support
the single-wire mode for the UART peripheral.
This has been fixed by switching the TXDIR bit to TX mode upon entry of
function: mcux_lpuart_poll_out() and switching it back to RX mode
at the end of the function when single-wire mode is selected.

Signed-off-by: Luis Casas <luis.casas@nxp.com>
2026-10-15 14:07:28 +02:00
Aksel Skauge Mellbye
1718448d76 drivers: serial: silabs_eusart: Respect exclusive API callbacks
With CONFIG_UART_EXCLUSIVE_API_CALLBACKS, setting the callback of one
API must remove the callback of the other.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-15 00:56:39 +02:00
Aksel Skauge Mellbye
987ce41b10 drivers: serial: silabs_eusart: Fix transceiver state after sleep
The transceiver must be manually shut down prior to going to
deep sleep, otherwise the state will be inconsistent on wakeup.

Register a PM notifier to disable and reenable the transceiver.

In the future, this should be implemented as a power management
TURN_ON/TURN_OFF callback called from a power domain driver.
Since no such driver exists yet for Series 2, deal with it ad-hoc
from the UART driver itself.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-15 00:56:39 +02:00
Aksel Skauge Mellbye
0ced80f808 drivers: serial: silabs_eusart: Hold TX PM lock until TXC
For interrupt-driven transfers, PM must be locked until data has
been fully shifted out. Postpone releasing the PM lock until TXC
is reported.

Split handling of TXFL and TXC such that TXFL maps to the user-facing
callback, while TXC is only used internally in the driver.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-15 00:56:39 +02:00
Aksel Skauge Mellbye
a3b6a878c7 drivers: serial: silabs_eusart: Limit async ISR to active transfers
The interrupt-driven and async APIs share TXC and RXOF. When the
driver had DMA channels, the ISR handled every enabled TXC and RXOF as
an async event, producing spurious UART_TX_DONE and UART_RX_STOPPED
events.

Handle RXTO and RXOF as async events only while async RX is enabled,
and TXC only while an async TX is outstanding.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-15 00:56:39 +02:00
Aksel Skauge Mellbye
d12e410071 drivers: serial: silabs_eusart: Disable RX interrupts when DMA stops RX
When the RX DMA buffer was filled and no next buffer was provided, the
DMA callback stopped RX and reported UART_RX_DISABLED, but left the RXOF
and RXTO interrupts enabled. A later overrun or receive timeout then
raised async events for a receiver that was already disabled.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2026-10-15 00:56:39 +02:00
Benjamin Cabé
ff00e022f7 drivers: serial: uart_emul: initialize config from devicetree
The emulated UART never initialized its struct uart_config, so
uart_config_get() returned an all-zero configuration until
uart_configure() was called: a baudrate of 0, no parity,
UART_CFG_STOP_BITS_0_5, UART_CFG_DATA_BITS_5 and no flow control. The
current-speed, parity, stop-bits, data-bits and hw-flow-control
properties that the binding inherits from uart-controller.yaml were
ignored.

Users doing a get/modify/set of the configuration then write that bogus
framing back. For instance, modem_cellular_baudrate_update() in the
modem_cellular driver only changes the baudrate, so with the emulator it
configures 5 data bits and 0.5 stop bits, and the original baudrate it
saves for later restoration is 0.

Initialize the configuration from devicetree, as other UART drivers do,
and fall back to 115200 baud, 8 data bits, no parity, 1 stop bit and no
flow control for absent properties. Nodes setting current-speed = <0>
still report a baudrate of 0.

Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-10-14 08:43:52 +02:00
Arkadiusz Grzelka
912e94ae9a drivers: serial: uart_bt: don't stall writer while unsubscribed
Output written while no peer is subscribed, boot output included, is
buffered for the first peer that subscribes. Once the buffer is full,
an interrupt-driven writer such as the shell stalls: only tx_work frees
buffer space, and it does not run until a peer subscribes.

Keep the buffering, with RTT semantics: while nobody is subscribed, a
full buffer drops new output and the writer never waits.
uart_bt_fifo_fill() reports all of it written and uart_bt_irq_tx_ready()
stays ready.

Also check the return value of every work submit and schedule call.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Arkadiusz Grzelka <devitwise@gmail.com>
2026-10-14 08:40:04 +02:00
The.Thanh Nguyen
2db58d5c86 drivers: uart: fix UART RA SCI B issue when enable ASYNC mode
Fix an issue that when global configs: CONFIG_UART_INTERRUPT_DRIVEN
and CONFIG_UART_ASYNC_API are enabled simultaneously, the channel
which running interrupt driven mode hit the issue that the hardware
interrupt flags will be never cleared.

Signed-off-by: The.Thanh Nguyen <the.nguyen.yf@renesas.com>
2026-10-13 17:07:45 +02:00
Pisit Sawangvonganan
8eaf92f312 drivers: {sensor, serial, spi, tee, usb, usb_c}: fix typo
Utilize a code spell-checking tool to scan for and correct spelling errors
in all files within:
- `drivers/sensor`
- `drivers/serial`
- `drivers/spi`
- `drivers/tee`
- `drivers/usb`
- `drivers/usb_c`

Assisted-by: Claude:claude-sonnet-5-5 codespell
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
2026-10-13 17:06:54 +02:00
Benjamin Cabé
c2ebaa8636 drivers: serial: mcux_lpuart: keep async DMA buffers cache coherent
The async API hands caller buffers to the eDMA without any cache
maintenance, so on a core with a data cache TX sends stale data and RX
reports stale bytes unless the buffers sit in DTCM or non-cacheable
memory. Boards placing zephyr,sram in OCRAM, such as vmu_rt1170, are
affected.

Flush TX buffers before starting the DMA, clean and invalidate RX
buffers when they are handed to the DMA, and again for each range
reported in UART_RX_RDY. Select CACHE_MANAGEMENT so the cache API is
backed whenever a data cache is present.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
2026-10-12 23:28:49 +02:00
YunHung Hua
e2dd5346bb drivers: serial: stm32: keep the UART running when configure fails
uart_stm32_configure() disables the USART, applies the new parameters
and returns -ENOTSUP if the baud rate is rejected. The USART is left
disabled with the new framing already applied, so on a console UART
the next poll_out() waits forever for TXE.

Set the baud rate before any other field, and check its range before
writing any register, so a rejected configuration leaves the registers
untouched. configure() then only re-enables the USART and the previous
configuration keeps working.

Fixes #121176

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: YunHung Hua <oliverhua.us@gmail.com>
2026-10-08 15:10:26 +02:00
YunHung Hua
d0fd0a9a5b drivers: serial: stm32: reject baud rates beyond the BRR range
On the USART path, uart_stm32_set_baudrate() only rejects a USARTDIV
below 16. BRR is 16 bits wide and LL_USART_SetBaudRate() writes the
divider truncated to uint16_t, so a rate whose divider exceeds 0xFFFF
is programmed as a faster rate and the call still returns 0: 1200 baud
from an 84 MHz clock needs a divider of 70000, which is written as 4464
(18817 baud). Reject those rates as well.

Fixes #121176

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: YunHung Hua <oliverhua.us@gmail.com>
2026-10-08 15:10:26 +02:00
Sylvio Alves
c609f62453 drivers: serial: esp32: flush pending rx bytes before stopping
UHCI hands received bytes to the DMA only when a packet ends, on
length or after an idle period. rx_disable() stopped the DMA
right away, so bytes still held by UHCI were lost.

Make rx_disable() asynchronous: mask the RX FIFO interrupt, lower
the UART idle threshold and enable the idle EOF, then finish the
stop from a dedicated work item a few character times later. The
EOF moves the pending bytes into the buffer and sets the count
from the descriptor. While the stop is pending, the DMA
completion and the timeout work leave the buffer to the stop
work, and a pending stop is cancelled when the DMA runs out of
buffers first.

Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
2026-10-06 07:26:27 +02:00
Sylvio Alves
5638b9eb06 drivers: serial: esp32: reset the rx fifo on async rx enable
Bytes received while async RX was off stay in the RX FIFO and are
delivered at the start of the next buffer. Reset the RX FIFO in
rx_enable() before the RX interrupts are armed again.

Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
2026-10-06 07:26:27 +02:00
Sylvio Alves
b2a66457d2 drivers: serial: esp32: report tx_done once the fifo drains
UART_TX_DONE was raised from the DMA completion, while the tail of
the buffer was still in the TX FIFO. A caller acting on TX_DONE,
for example by disabling RX or suspending the device, cut the
transfer short.

Arm the UART TX_DONE interrupt when the DMA completes and report
the event from the ISR once the transmitter is idle. Release the
TX state before the callback so a chained uart_tx() is accepted,
and reject a new transfer while the FIFO drains. On abort, flush
the TX FIFO and drop the drain PM lock along with the TX state,
and clear the state when a transfer fails to start.

Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
2026-10-06 07:26:27 +02:00
Jinming Zhao
8d56d85b28 arch, drivers: fix mismatched IRQ lock pairs
Pair the ARC range operations' arch_irq_lock() with arch_irq_unlock()
to avoid decrementing an outer SMP global lock. Use local IRQ locking
for the all-cache operations too; shared SLC locking is unchanged.
Pair irq_lock() with irq_unlock() in the ESP32 USB serial callback to
balance its SMP global lock state.

Signed-off-by: Jinming Zhao <jinmzhao@qti.qualcomm.com>
2026-10-06 07:23:42 +02:00
Benjamin Cabé
ca7db037fc drivers: serial: infineon: fix pm_action build with PERI_CLOCK_V2
The PM_DEVICE_ACTION_TURN_ON handler assigns the clock divider through
data->clock, which does not exist with PERI_CLOCK_V2, so every
PM_DEVICE build fails on kit_t2g_c2d6m_lite. Skip it there as
ifx_cat1_uart_init() does: ifx_cat1_uart_configure() assigns the
divider through the clock control driver.

Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-10-03 09:39:53 +02:00
JiaXiang Liang
5b2953bef2 drivers: serial: esp32: fix async RX DMA accounting
The RX completion combined the EOF descriptor length with rx_offset,
which double-reported bytes after a finite idle timeout. The GDMA
driver also invokes the RX callback for non-EOF descriptor blocks.
Ignore block callbacks, derive an absolute buffer position from the
EOF descriptor, and protect callbacks and timeout work when RX is
rearmed.

Retain FIFO interrupt counting for RX disable before the open DMA
descriptor has written back its received length. Clamp the count to
the buffer and report only bytes beyond rx_offset. Clear a pending FIFO
interrupt when EOF has already consumed its bytes, so it cannot increment
the next buffer's counter.

Validate initial and successor RX buffer lengths against the UHCI
packet threshold, and clear RX state when DMA setup fails.

Signed-off-by: JiaXiang Liang <moonbite233@gmail.com>
Assisted-by: Codex:gpt-6
2026-10-02 08:32:18 -05:00
JiaXiang Liang
ad57e7b86f drivers: serial: esp32: disarm async RX interrupts when RX stops
An async RX buffer can be released without a successor while RXFIFO
level interrupts remain enabled. A byte left in the FIFO then keeps
the UART ISR running and starves the system timer.

Use the shared RX disable helper to mask interrupts at both async stop
points. Keep the PM lock release in the async paths, as interrupt-driven
RX does not hold that lock. Drop completion and timeout work after the
RX buffer has been released.

Signed-off-by: JiaXiang Liang <moonbite233@gmail.com>
Assisted-by: Codex:gpt-6
2026-10-02 08:32:18 -05:00
Benjamin Cabé
084daaa11d drivers: serial: sf32lb: fix uninitialized irq key on busy exit
uart_async_sf32lb_rx_disable() and uart_async_sf32lb_tx_abort() jump to
their shared unlock label when the DMA channel is busy, which is before
irq_lock() has run, so irq_unlock() writes an uninitialized value to
PRIMASK. Return -EBUSY directly, as the other async entry points
already do on the same check.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
2026-10-02 08:22:17 -05:00
Bill Waters
118157466f drivers: serial: uart_infineon_pdl: cache uart_config only on success
ifx_cat1_uart_configure() stored the requested uart_config into
data->cfg at the top of the function, before ifx_cat1_uart_set_baud()
ran. When the requested rate is unachievable -- for example 9600 baud on
an SCB clocked from an 8-bit peripheral divider group, where the divider
needed overflows the register -- set_baud() fails and configure()
returns -ENOTSUP, but data->cfg has already been overwritten with the
rejected configuration.

Every subsequent uart_config_get() then returns the bad config, and each
per-test re-init re-applies and re-fails it, cascading a single rejected
reconfigure across an entire suite (observed as drivers.uart.async_api
failing on kit_psc3m5_evk after test_read_abort switches to 9600 baud).

Cache data->cfg only after set_baud() succeeds, so a rejected
reconfigure leaves the previously-applied configuration intact.

Verified on kit_psc3m5_evk/psc3m5fds2afq1 with an SCB on an 8-bit divider
group: uart_configure(9600) is rejected (-ENOTSUP) and uart_config_get()
now returns the prior 115200 config instead of the rejected 9600.

Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
2026-09-30 20:09:13 +02:00
Merin George
acf1f9c489 drivers: uart: infineon: Fix IRQ-driven API hang and zero-length assert
The PDL asserts on zero-length FIFO reads and writes, which the UART
API allows; return 0 for them.

uart_irq_is_pending() and uart_irq_tx_ready() read the latched
interrupt status, which the PDL clears only after the callback
returns, so a callback looping on uart_irq_is_pending() never
returned. Use the RX and TX FIFO levels instead.

Tested with hci_uart on cyw920829m2evk_02/cyw20829b0lkml.

Assisted-by: Copilot:claude-opus-5.5

Signed-off-by: Merin George <merin.george@infineon.com>
2026-09-30 20:08:22 +02:00
Pisit Sawangvonganan
885363d738 drivers: serial: infineon: use local pointers for async state
The async API, its DMA callbacks and event helpers repeat the full
data->async.dma_rx.<member> and data->async.dma_tx.<member> chains on
every access. The long, repetitive statements make the code hard to
read.

Take a local pointer to the stream (dma_tx, dma_rx) and to the async
context (async) at the top of each function that uses them, and rejoin
the statements that now fit on one line.

No functional change.

Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
2026-09-30 19:42:56 +02:00
Pisit Sawangvonganan
bb6aac85a1 drivers: serial: infineon: make UART lookup tables static
data_bits_lut and stop_bits_lut are only used inside
uart_infineon_pdl.c. Give them internal linkage so they are no longer
exported as global symbols.

Also remove parity_lut. It was never referenced, because the parity
conversion already uses a switch statement.

Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
2026-09-30 19:42:56 +02:00