Skip to content

Conversation

@SeppoTakalo
Copy link
Contributor

@SeppoTakalo SeppoTakalo commented Sep 25, 2025

This driver wraps an existing UART device and adds DTR (Data Terminal Ready) output for a runtime power management.
When the UART is powered off, DTR is deasserted.
When the UART is powered on, DTR is asserted.

This allows remote end to shut down the UART when DTR is deasserted.

@zephyrbot zephyrbot added area: UART Universal Asynchronous Receiver-Transmitter area: Devicetree labels Sep 25, 2025
@SeppoTakalo
Copy link
Contributor Author

Refactored the driver a bit.

  • uart_dtr_work_handler() split to two separate functions, power on and power-off.
  • UART interrupt API removed, that was untested and just a dummy template from Copilot.

Only the asynchronous API has been properly used against a real UART driver (nrfx-uarte).

Copy link
Contributor

@mbolivar mbolivar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a new zephyr,uart-dt

@@ -0,0 +1,16 @@
description: UART DTR Wrapper Driver
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The binding is a bit too unclear to merge as-is in my opinion especially since this is clearly a binding meant to be introduced purely to allocate a struct device. The description doesn't make it clear that it's for power management, etc... did you consider any alternative approaches here? I'm kind of skeptical about this approach even though I do agree with your goal and would like to help get this PR merged.

@SeppoTakalo
Copy link
Contributor Author

I have now simplified the driver and removed all the logic that should have been in the upper layer.

So this driver is now nothing else than a wrapper that adds a DTR GPIO output to an existing UART.

&uart1 {	zephyr,pm-device-runtime-auto;	uart_dtr: uart-dtr {	compatible = "zephyr,uart-dtr";	dtr-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;	status = "okay";	zephyr,pm-device-runtime-auto;	modem: modem {	/* The child device that might turn the UART device on or off */	};	}; }; 

So now the DTR pin follows the power state of the UART.
It is the upper layers responsibility to stop RX&TX before powering down.

@SeppoTakalo
Copy link
Contributor Author

SeppoTakalo commented Oct 9, 2025

Why do we need a new zephyr,uart-dt

I don't understand this question. There is no zephyr,uart-dt currently.
Most UART devices don't have a DTR pin and adding one without changing anything in the UART API might benefit some use cases.

This is not uncommon, for example one popular modem has this:
image

And we are now implementing the same functionality in our Serial Modem application.

@SeppoTakalo SeppoTakalo changed the title drivers: serial: Implement serial wrapper to add DTR drivers: serial: Implement serial wrapper to add DTR output Oct 9, 2025
@SeppoTakalo SeppoTakalo requested a review from mbolivar October 9, 2025 13:45
@mbolivar
Copy link
Contributor

mbolivar commented Oct 9, 2025

Why do we need a new zephyr,uart-dt

I don't understand this question.

The question is about why we need the new binding at all

There is no zephyr,uart-dt currently.

right, and from looking at this, I think I would like to keep it that way for the reasons I explained in my comment.

Most UART devices don't have a DTR pin and adding one without changing anything in the UART API might benefit some use cases.

We don't typically add an entire child node and generic binding to cover a single pin.

This driver wraps an existing UART device and adds DTR (Data Terminal Ready) GPIO output for a runtime power management. When the UART is powered off, DTR is deasserted. When the UART is powered on, DTR is asserted. This allows remote end to shut down the UART when DTR is deasserted. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
@SeppoTakalo
Copy link
Contributor Author

Updated the documentation to show the use case for this driver:

 DTR output for a UART. This driver wraps an existing UART device and adds DTR (Data Terminal Ready) functionality which follows the runtime power state. When UART is powered, the DTR signal is asserted (logical high), and when the UART is powered down, the DTR signal is de-asserted (logical low). This allows a remote end to detect whether the UART is powered or not and manage its own power state accordingly. The driver acts as a child node of the actual UART. The application should use the DTR UART device which will manage the DTR signal and forward all UART operations to the parent UART. Example where DTR state follows the runtime power state of another device that uses UART: &uart1 { zephyr,pm-device-runtime-auto; dtr_uart: dtr_uart { compatible = "zephyr,uart-dtr"; dtr-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; zephyr,pm-device-runtime-auto; modem: modem { /* Can be any device that uses UART and supports PM_DEVICE_RUNTIME */ zephyr,pm-device-runtime-auto; }; }; }; In the example above, zephyr,pm-device-runtime-auto is used to enable runtime power management for devices when they are initialized. DTR GPIO is typically active low but this depends on the HW design. 

After being open for almost a month, still no-one has suggested any alternatives.
And even though the idea is opposed, this is not the first driver that wraps around existing physical driver to add functionality.

Other examples:

@SeppoTakalo
Copy link
Contributor Author

@dcpleung please review and provide your feedback.

@SeppoTakalo
Copy link
Contributor Author

I'll close this in favor of alternative solution in #98145

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

6 participants