Hi Hung-Chun,
On 2026-10-14T19:06:28, Hung-Chun Tseng <[email protected]> wrote:
> virtio: rtc: Add virtio RTC driver
>
> Add a driver for the virtio RTC device (virtio device ID 17), which
> QEMU provides as virtio-rtc-pci and virtio-rtc-device since v11.1.0.
>
> The device exposes its clocks through a request virtqueue. As the
> virtqueue must not be used before the virtio uclass sets DRIVER_OK,
> which happens after probe(), the first read looks for the clock: it
> asks for the number of clocks with VIRTIO_RTC_REQ_CFG and picks the
> first one whose VIRTIO_RTC_REQ_CLOCK_CAP type is UTC, smeared UTC or
> maybe-smeared UTC. Reading the time sends a VIRTIO_RTC_REQ_READ for
> that clock and converts the nanoseconds since the epoch with
> rtc_to_tm(). The clocks are read-only, so there is no set operation,
> and the optional alarm feature is not negotiated.
>
> VIRTIO_RTC defaults to y when VIRTIO and DM_RTC are enabled, like
> VIRTIO_RNG does for DM_RNG.
>
> Signed-off-by: Hung-Chun Tseng <[email protected]>
>
> drivers/virtio/Kconfig | 9 ++
> drivers/virtio/Makefile | 1 +
> drivers/virtio/virtio-uclass.c | 1 +
> drivers/virtio/virtio_rtc.c | 213
> +++++++++++++++++++++++++++++++++++++++++
> include/virtio.h | 4 +-
> 5 files changed, 227 insertions(+), 1 deletion(-)
> On sandbox, where VIRTIO_RTC now defaults to y,
> "ut dm rtc*" and "ut dm virtio*" pass.
Just to clarify, the sandbox virtio transport only exposes a
VIRTIO_ID_BLOCK device (see uc_priv->device in
drivers/virtio/virtio_sandbox.c), so neither of those actually probes
virtio_rtc — they only confirm the driver builds. Please mention that
in the commit message. A sandbox test along the lines of
test/dm/virtio_rng.c would be good as a follow-up.
> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> @@ -84,4 +84,13 @@ config VIRTIO_9P
> +config VIRTIO_RTC
> + bool "virtio RTC driver"
> + depends on DM_RTC
> + depends on VIRTIO
> + default y
> + help
> + This is the virtual RTC driver. It reads the UTC clock of a
> + virtio RTC device. It can be used with QEMU based targets.
Please can you expand the help text - something like "This enables the
virtio RTC driver, which reads the UTC clock exposed by a virtio RTC
device (QEMU v11.1.0 or later provides virtio-rtc-pci and
virtio-rtc-device). The clocks are read-only, so the time cannot be
set."
> diff --git a/drivers/virtio/virtio_rtc.c b/drivers/virtio/virtio_rtc.c
> @@ -0,0 +1,213 @@
> +static int virtio_rtc_get(struct udevice *dev, struct rtc_time *time)
> +{
> + struct virtio_rtc_priv *priv = dev_get_priv(dev);
> + struct virtio_rtc_req_clock req = {
> + .head.msg_type = cpu_to_le16(VIRTIO_RTC_REQ_READ),
> + };
> + struct virtio_rtc_resp_read resp = {};
> + u64 now;
> + int ret;
> +
> + /*
> + * The virtqueue must not be used before DRIVER_OK, which the virtio
> + * uclass sets only after probe(), so look for the clock on first use.
> + */
> + if (!priv->clock_found) {
> + ret = virtio_rtc_find_utc_clock(dev);
> + if (ret)
> + return ret;
> + }
If the first find fails (e.g. a device with only TAI or MONOTONIC
clocks), clock_found stays false and every subsequent 'date' re-walks
every clock. Since the clock set is fixed for the life of the device,
please cache the failure too - e.g. a state enum or a cached error
code — so the second call returns immediately.
Regards,
Simon