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

Reply via email to