LPUART disable doesn't release RX buffer

I am using the LPUART and running into an issue when the UART is disabled. The LPUART doesn't notify the user callback that the buffer can be released. In my case, I am using the modem_backend_uart_async with Zephyr's cellular modem driver. The modem_backend_uart_async will internally mark its RX buffer as used on a UART_RX_BUF_REQUESTand clear that on a UART_RX_BUF_RELEASED. With the LPUART driver, when disable is called, the current RX buffer is not released, which causes modem_backend_uart_async to not clear the used flag for that buffer.

This seems to be caused by how the LPUART driver always requests the next buffer when it enters the RX_TO_IDLE state, but never calls to release it.

If I apply the following patch to force a UART_RX_BUF_RELEASED on a disable, I no longer see the issue, and the modem_backend_uart_async is fully able to stop:

--- a/drivers/serial/uart_nrf_sw_lpuart.c
+++ b/drivers/serial/uart_nrf_sw_lpuart.c

@@ -768,6 +770,20 @@ static int api_rx_disable(const struct device *dev)

return -EFAULT;
}

+ if (data->rx_state == RX_IDLE) {
+ struct uart_event event = {
+ .type = UART_RX_BUF_RELEASED,
+ .data = {
+ .rx_buf = {
+ .buf = data->rx_buf,
+ }
+ }
+ };
+
+ data->rx_buf = NULL;
+ user_callback(dev, &event);
+ }
+
data->rx_state = RX_TO_OFF;

err = uart_rx_disable(data->uart);

Is this an issue of the LPUART driver or is the intention to have the user (modem_backend_uart_async in this case) know that all the RX buffers are free on the UART_RX_DISABLED event. 

nrfConnect 2.6.1 SDK running on a nrf5340. 

Related