Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

virtio_rtc: Add RTC class driver

Expose the virtio-rtc UTC-like clock as an RTC clock to userspace - if it
is present, and if it does not step on leap seconds. The RTC class enables
the virtio-rtc device to resume the system from sleep states on RTC alarm.

Support RTC alarm if the virtio-rtc alarm feature is present. The
virtio-rtc device signals an alarm by marking an alarmq buffer as used.

Peculiarities
-------------

A virtio-rtc clock is a bit special for an RTC clock in that

- the clock may step (also backwards) autonomously at any time and

- the device, and its notification mechanism, will be reset during boot or
resume from sleep.

The virtio-rtc device avoids that the driver might miss an alarm. The
device signals an alarm whenever the clock has reached or passed the alarm
time, and also when the device is reset (on boot or resume from sleep), if
the alarm time is in the past.

Open Issue
----------

The CLOCK_BOOTTIME_ALARM will use the RTC clock to wake up from sleep, and
implicitly assumes that no RTC clock steps will occur during sleep. The RTC
class driver does not know whether the current alarm is a real-time alarm
or a boot-time alarm.

Perhaps this might be handled by the driver also setting a virtio-rtc
monotonic alarm (which uses a clock similar to CLOCK_BOOTTIME_ALARM). The
virtio-rtc monotonic alarm would just be used to wake up in case it was a
CLOCK_BOOTTIME_ALARM alarm.

Otherwise, the behavior should not differ from other RTC class drivers.

Signed-off-by: Peter Hilber <quic_philber@quicinc.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Message-Id: <20250509160734.1772-5-quic_philber@quicinc.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Peter Hilber and committed by
Michael S. Tsirkin
9d4f22fd e2ef1675

+934 -11
+19 -3
drivers/virtio/Kconfig
··· 195 195 help 196 196 This driver provides current time from a Virtio RTC device. The driver 197 197 provides the time through one or more clocks. The Virtio RTC PTP 198 - clocks must be enabled to expose the clocks to userspace. 198 + clocks and/or the Real Time Clock driver for Virtio RTC must be 199 + enabled to expose the clocks to userspace. 199 200 200 201 To compile this code as a module, choose M here: the module will be 201 202 called virtio_rtc. ··· 205 204 206 205 if VIRTIO_RTC 207 206 208 - comment "WARNING: Consider enabling VIRTIO_RTC_PTP." 209 - depends on !VIRTIO_RTC_PTP 207 + comment "WARNING: Consider enabling VIRTIO_RTC_PTP and/or VIRTIO_RTC_CLASS." 208 + depends on !VIRTIO_RTC_PTP && !VIRTIO_RTC_CLASS 210 209 211 210 comment "Enable PTP_1588_CLOCK in order to enable VIRTIO_RTC_PTP." 212 211 depends on PTP_1588_CLOCK=n ··· 232 231 cross-timestamp is available through the PTP clock driver precise 233 232 cross-timestamp ioctl (PTP_SYS_OFFSET_PRECISE2 aka 234 233 PTP_SYS_OFFSET_PRECISE). 234 + 235 + If unsure, say Y. 236 + 237 + comment "Enable RTC_CLASS in order to enable VIRTIO_RTC_CLASS." 238 + depends on RTC_CLASS=n 239 + 240 + config VIRTIO_RTC_CLASS 241 + bool "Real Time Clock driver for Virtio RTC" 242 + default y 243 + depends on RTC_CLASS 244 + help 245 + This exposes the Virtio RTC UTC-like clock as a Linux Real Time Clock. 246 + It only has an effect if the Virtio RTC device has a UTC-like clock 247 + which smears leap seconds to avoid steps. The Real Time Clock is 248 + read-only, and may support setting an alarm. 235 249 236 250 If unsure, say Y. 237 251
+1
drivers/virtio/Makefile
··· 18 18 virtio_rtc-y := virtio_rtc_driver.o 19 19 virtio_rtc-$(CONFIG_VIRTIO_RTC_PTP) += virtio_rtc_ptp.o 20 20 virtio_rtc-$(CONFIG_VIRTIO_RTC_ARM) += virtio_rtc_arm.o 21 + virtio_rtc-$(CONFIG_VIRTIO_RTC_CLASS) += virtio_rtc_class.o
+262
drivers/virtio/virtio_rtc_class.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * virtio_rtc RTC class driver 4 + * 5 + * Copyright (C) 2023 OpenSynergy GmbH 6 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 7 + */ 8 + 9 + #include <linux/math64.h> 10 + #include <linux/overflow.h> 11 + #include <linux/rtc.h> 12 + #include <linux/time64.h> 13 + 14 + #include <uapi/linux/virtio_rtc.h> 15 + 16 + #include "virtio_rtc_internal.h" 17 + 18 + /** 19 + * struct viortc_class - RTC class wrapper 20 + * @viortc: virtio_rtc device data 21 + * @rtc: RTC device 22 + * @vio_clk_id: virtio_rtc clock id 23 + * @stopped: Whether RTC ops are disallowed. Access protected by rtc_lock(). 24 + */ 25 + struct viortc_class { 26 + struct viortc_dev *viortc; 27 + struct rtc_device *rtc; 28 + u16 vio_clk_id; 29 + bool stopped; 30 + }; 31 + 32 + /** 33 + * viortc_class_get_locked() - get RTC class wrapper, if ops allowed 34 + * @dev: virtio device 35 + * 36 + * Gets the RTC class wrapper from the virtio device, if it is available and 37 + * ops are allowed. 38 + * 39 + * Context: Caller must hold rtc_lock(). 40 + * Return: RTC class wrapper if available and ops allowed, ERR_PTR otherwise. 41 + */ 42 + static struct viortc_class *viortc_class_get_locked(struct device *dev) 43 + { 44 + struct viortc_class *viortc_class; 45 + 46 + viortc_class = viortc_class_from_dev(dev); 47 + if (IS_ERR(viortc_class)) 48 + return viortc_class; 49 + 50 + if (viortc_class->stopped) 51 + return ERR_PTR(-EBUSY); 52 + 53 + return viortc_class; 54 + } 55 + 56 + /** 57 + * viortc_class_read_time() - RTC class op read_time 58 + * @dev: virtio device 59 + * @tm: read time 60 + * 61 + * Context: Process context. 62 + * Return: Zero on success, negative error code otherwise. 63 + */ 64 + static int viortc_class_read_time(struct device *dev, struct rtc_time *tm) 65 + { 66 + struct viortc_class *viortc_class; 67 + time64_t sec; 68 + int ret; 69 + u64 ns; 70 + 71 + viortc_class = viortc_class_get_locked(dev); 72 + if (IS_ERR(viortc_class)) 73 + return PTR_ERR(viortc_class); 74 + 75 + ret = viortc_read(viortc_class->viortc, viortc_class->vio_clk_id, &ns); 76 + if (ret) 77 + return ret; 78 + 79 + sec = div_u64(ns, NSEC_PER_SEC); 80 + 81 + rtc_time64_to_tm(sec, tm); 82 + 83 + return 0; 84 + } 85 + 86 + /** 87 + * viortc_class_read_alarm() - RTC class op read_alarm 88 + * @dev: virtio device 89 + * @alrm: alarm read out 90 + * 91 + * Context: Process context. 92 + * Return: Zero on success, negative error code otherwise. 93 + */ 94 + static int viortc_class_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 95 + { 96 + struct viortc_class *viortc_class; 97 + time64_t alarm_time_sec; 98 + u64 alarm_time_ns; 99 + bool enabled; 100 + int ret; 101 + 102 + viortc_class = viortc_class_get_locked(dev); 103 + if (IS_ERR(viortc_class)) 104 + return PTR_ERR(viortc_class); 105 + 106 + ret = viortc_read_alarm(viortc_class->viortc, viortc_class->vio_clk_id, 107 + &alarm_time_ns, &enabled); 108 + if (ret) 109 + return ret; 110 + 111 + alarm_time_sec = div_u64(alarm_time_ns, NSEC_PER_SEC); 112 + rtc_time64_to_tm(alarm_time_sec, &alrm->time); 113 + 114 + alrm->enabled = enabled; 115 + 116 + return 0; 117 + } 118 + 119 + /** 120 + * viortc_class_set_alarm() - RTC class op set_alarm 121 + * @dev: virtio device 122 + * @alrm: alarm to set 123 + * 124 + * Context: Process context. 125 + * Return: Zero on success, negative error code otherwise. 126 + */ 127 + static int viortc_class_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 128 + { 129 + struct viortc_class *viortc_class; 130 + time64_t alarm_time_sec; 131 + u64 alarm_time_ns; 132 + 133 + viortc_class = viortc_class_get_locked(dev); 134 + if (IS_ERR(viortc_class)) 135 + return PTR_ERR(viortc_class); 136 + 137 + alarm_time_sec = rtc_tm_to_time64(&alrm->time); 138 + 139 + if (alarm_time_sec < 0) 140 + return -EINVAL; 141 + 142 + if (check_mul_overflow((u64)alarm_time_sec, (u64)NSEC_PER_SEC, 143 + &alarm_time_ns)) 144 + return -EINVAL; 145 + 146 + return viortc_set_alarm(viortc_class->viortc, viortc_class->vio_clk_id, 147 + alarm_time_ns, alrm->enabled); 148 + } 149 + 150 + /** 151 + * viortc_class_alarm_irq_enable() - RTC class op alarm_irq_enable 152 + * @dev: virtio device 153 + * @enabled: enable or disable alarm IRQ 154 + * 155 + * Context: Process context. 156 + * Return: Zero on success, negative error code otherwise. 157 + */ 158 + static int viortc_class_alarm_irq_enable(struct device *dev, 159 + unsigned int enabled) 160 + { 161 + struct viortc_class *viortc_class; 162 + 163 + viortc_class = viortc_class_get_locked(dev); 164 + if (IS_ERR(viortc_class)) 165 + return PTR_ERR(viortc_class); 166 + 167 + return viortc_set_alarm_enabled(viortc_class->viortc, 168 + viortc_class->vio_clk_id, enabled); 169 + } 170 + 171 + static const struct rtc_class_ops viortc_class_ops = { 172 + .read_time = viortc_class_read_time, 173 + .read_alarm = viortc_class_read_alarm, 174 + .set_alarm = viortc_class_set_alarm, 175 + .alarm_irq_enable = viortc_class_alarm_irq_enable, 176 + }; 177 + 178 + /** 179 + * viortc_class_alarm() - propagate alarm notification as alarm interrupt 180 + * @viortc_class: RTC class wrapper 181 + * @vio_clk_id: virtio_rtc clock id 182 + * 183 + * Context: Any context. 184 + */ 185 + void viortc_class_alarm(struct viortc_class *viortc_class, u16 vio_clk_id) 186 + { 187 + if (vio_clk_id != viortc_class->vio_clk_id) { 188 + dev_warn_ratelimited(&viortc_class->rtc->dev, 189 + "ignoring alarm for clock id %d, expected id %d\n", 190 + vio_clk_id, viortc_class->vio_clk_id); 191 + return; 192 + } 193 + 194 + rtc_update_irq(viortc_class->rtc, 1, RTC_AF | RTC_IRQF); 195 + } 196 + 197 + /** 198 + * viortc_class_stop() - disallow RTC class ops 199 + * @viortc_class: RTC class wrapper 200 + * 201 + * Context: Process context. Caller must NOT hold rtc_lock(). 202 + */ 203 + void viortc_class_stop(struct viortc_class *viortc_class) 204 + { 205 + rtc_lock(viortc_class->rtc); 206 + 207 + viortc_class->stopped = true; 208 + 209 + rtc_unlock(viortc_class->rtc); 210 + } 211 + 212 + /** 213 + * viortc_class_register() - register RTC class device 214 + * @viortc_class: RTC class wrapper 215 + * 216 + * Context: Process context. 217 + * Return: Zero on success, negative error code otherwise. 218 + */ 219 + int viortc_class_register(struct viortc_class *viortc_class) 220 + { 221 + return devm_rtc_register_device(viortc_class->rtc); 222 + } 223 + 224 + /** 225 + * viortc_class_init() - init RTC class wrapper and device 226 + * @viortc: device data 227 + * @vio_clk_id: virtio_rtc clock id 228 + * @have_alarm: have alarm feature 229 + * @parent_dev: virtio device 230 + * 231 + * Context: Process context. 232 + * Return: RTC class wrapper on success, ERR_PTR otherwise. 233 + */ 234 + struct viortc_class *viortc_class_init(struct viortc_dev *viortc, 235 + u16 vio_clk_id, bool have_alarm, 236 + struct device *parent_dev) 237 + { 238 + struct viortc_class *viortc_class; 239 + struct rtc_device *rtc; 240 + 241 + viortc_class = 242 + devm_kzalloc(parent_dev, sizeof(*viortc_class), GFP_KERNEL); 243 + if (!viortc_class) 244 + return ERR_PTR(-ENOMEM); 245 + 246 + rtc = devm_rtc_allocate_device(parent_dev); 247 + if (IS_ERR(rtc)) 248 + return ERR_CAST(rtc); 249 + 250 + viortc_class->viortc = viortc; 251 + viortc_class->rtc = rtc; 252 + viortc_class->vio_clk_id = vio_clk_id; 253 + 254 + if (!have_alarm) 255 + clear_bit(RTC_FEATURE_ALARM, rtc->features); 256 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 257 + 258 + rtc->ops = &viortc_class_ops; 259 + rtc->range_max = div_u64(U64_MAX, NSEC_PER_SEC); 260 + 261 + return viortc_class; 262 + }
+513 -7
drivers/virtio/virtio_rtc_driver.c
··· 18 18 19 19 #include "virtio_rtc_internal.h" 20 20 21 + #define VIORTC_ALARMQ_BUF_CAP sizeof(union virtio_rtc_notif_alarmq) 22 + 21 23 /* virtqueue order */ 22 24 enum { 23 25 VIORTC_REQUESTQ, 26 + VIORTC_ALARMQ, 24 27 VIORTC_MAX_NR_QUEUES, 25 28 }; 26 29 ··· 40 37 /** 41 38 * struct viortc_dev - virtio_rtc device data 42 39 * @vdev: virtio device 40 + * @viortc_class: RTC class wrapper for UTC-like clock, NULL if not available 43 41 * @vqs: virtqueues 44 42 * @clocks_to_unregister: Clock references, which are only used during device 45 43 * removal. 46 44 * For other uses, there would be a race between device 47 45 * creation and setting the pointers here. 46 + * @alarmq_bufs: alarmq buffers list 47 + * @num_alarmq_bufs: # of alarmq buffers 48 48 * @num_clocks: # of virtio_rtc clocks 49 49 */ 50 50 struct viortc_dev { 51 51 struct virtio_device *vdev; 52 + struct viortc_class *viortc_class; 52 53 struct viortc_vq vqs[VIORTC_MAX_NR_QUEUES]; 53 54 struct viortc_ptp_clock **clocks_to_unregister; 55 + void **alarmq_bufs; 56 + unsigned int num_alarmq_bufs; 54 57 u16 num_clocks; 55 58 }; 56 59 ··· 86 77 unsigned int resp_cap; 87 78 unsigned int resp_actual_size; 88 79 }; 80 + 81 + /** 82 + * viortc_class_from_dev() - Get RTC class object from virtio device. 83 + * @dev: virtio device 84 + * 85 + * Context: Any context. 86 + * Return: RTC class object if available, ERR_PTR otherwise. 87 + */ 88 + struct viortc_class *viortc_class_from_dev(struct device *dev) 89 + { 90 + struct virtio_device *vdev; 91 + struct viortc_dev *viortc; 92 + 93 + vdev = container_of(dev, typeof(*vdev), dev); 94 + viortc = vdev->priv; 95 + 96 + return viortc->viortc_class ?: ERR_PTR(-ENODEV); 97 + } 98 + 99 + /** 100 + * viortc_alarms_supported() - Whether device and driver support alarms. 101 + * @vdev: virtio device 102 + * 103 + * NB: Device and driver may not support alarms for the same clocks. 104 + * 105 + * Context: Any context. 106 + * Return: True if both device and driver can support alarms. 107 + */ 108 + static bool viortc_alarms_supported(struct virtio_device *vdev) 109 + { 110 + return IS_ENABLED(CONFIG_VIRTIO_RTC_CLASS) && 111 + virtio_has_feature(vdev, VIRTIO_RTC_F_ALARM); 112 + } 113 + 114 + /** 115 + * viortc_feed_vq() - Make a device write-only buffer available. 116 + * @viortc: device data 117 + * @vq: notification virtqueue 118 + * @buf: buffer 119 + * @buf_len: buffer capacity in bytes 120 + * @data: token, identifying buffer 121 + * 122 + * Context: Caller must prevent concurrent access to vq. 123 + * Return: Zero on success, negative error code otherwise. 124 + */ 125 + static int viortc_feed_vq(struct viortc_dev *viortc, struct virtqueue *vq, 126 + void *buf, unsigned int buf_len, void *data) 127 + { 128 + struct scatterlist sg; 129 + 130 + sg_init_one(&sg, buf, buf_len); 131 + 132 + return virtqueue_add_inbuf(vq, &sg, 1, data, GFP_ATOMIC); 133 + } 89 134 90 135 /** 91 136 * viortc_msg_init() - Allocate and initialize requestq message. ··· 297 234 static void viortc_cb_requestq(struct virtqueue *vq) 298 235 { 299 236 viortc_do_cb(vq, viortc_requestq_hdlr); 237 + } 238 + 239 + /** 240 + * viortc_alarmq_hdlr() - process an alarmq used buffer 241 + * @token: token identifying the buffer 242 + * @len: bytes written by device 243 + * @vq: virtqueue 244 + * @viortc_vq: device specific data for virtqueue 245 + * @viortc: device data 246 + * 247 + * Processes a VIRTIO_RTC_NOTIF_ALARM notification by calling the RTC class 248 + * driver. Makes the buffer available again. 249 + * 250 + * Context: virtqueue callback 251 + */ 252 + static void viortc_alarmq_hdlr(void *token, unsigned int len, 253 + struct virtqueue *vq, 254 + struct viortc_vq *viortc_vq, 255 + struct viortc_dev *viortc) 256 + { 257 + struct virtio_rtc_notif_alarm *notif = token; 258 + struct virtio_rtc_notif_head *head = token; 259 + unsigned long flags; 260 + u16 clock_id; 261 + bool notify; 262 + 263 + if (len < sizeof(*head)) { 264 + dev_err_ratelimited(&viortc->vdev->dev, 265 + "%s: ignoring notification with short header\n", 266 + __func__); 267 + goto feed_vq; 268 + } 269 + 270 + if (virtio_le_to_cpu(head->msg_type) != VIRTIO_RTC_NOTIF_ALARM) { 271 + dev_err_ratelimited(&viortc->vdev->dev, 272 + "%s: ignoring unknown notification type 0x%x\n", 273 + __func__, virtio_le_to_cpu(head->msg_type)); 274 + goto feed_vq; 275 + } 276 + 277 + if (len < sizeof(*notif)) { 278 + dev_err_ratelimited(&viortc->vdev->dev, 279 + "%s: ignoring too small alarm notification\n", 280 + __func__); 281 + goto feed_vq; 282 + } 283 + 284 + clock_id = virtio_le_to_cpu(notif->clock_id); 285 + 286 + if (!viortc->viortc_class) 287 + dev_warn_ratelimited(&viortc->vdev->dev, 288 + "ignoring alarm, no RTC class device available\n"); 289 + else 290 + viortc_class_alarm(viortc->viortc_class, clock_id); 291 + 292 + feed_vq: 293 + spin_lock_irqsave(&viortc_vq->lock, flags); 294 + 295 + if (viortc_feed_vq(viortc, vq, notif, VIORTC_ALARMQ_BUF_CAP, token)) 296 + dev_warn(&viortc->vdev->dev, 297 + "%s: failed to re-expose input buffer\n", __func__); 298 + 299 + notify = virtqueue_kick_prepare(vq); 300 + 301 + spin_unlock_irqrestore(&viortc_vq->lock, flags); 302 + 303 + if (notify) 304 + virtqueue_notify(vq); 305 + } 306 + 307 + /** 308 + * viortc_cb_alarmq() - callback for alarmq 309 + * @vq: virtqueue 310 + * 311 + * Context: virtqueue callback 312 + */ 313 + static void viortc_cb_alarmq(struct virtqueue *vq) 314 + { 315 + viortc_do_cb(vq, viortc_alarmq_hdlr); 300 316 } 301 317 302 318 /** ··· 703 561 * @vio_clk_id: virtio_rtc clock id 704 562 * @type: virtio_rtc clock type 705 563 * @leap_second_smearing: virtio_rtc smearing variant 564 + * @flags: struct virtio_rtc_resp_clock_cap.flags 706 565 * 707 566 * Context: Process context. 708 567 * Return: Zero on success, negative error code otherwise. 709 568 */ 710 569 static int viortc_clock_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 *type, 711 - u8 *leap_second_smearing) 570 + u8 *leap_second_smearing, u8 *flags) 712 571 { 713 572 VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_CLOCK_CAP, 714 573 struct virtio_rtc_req_clock_cap, ··· 732 589 733 590 VIORTC_MSG_READ(hdl, type, type); 734 591 VIORTC_MSG_READ(hdl, leap_second_smearing, leap_second_smearing); 592 + VIORTC_MSG_READ(hdl, flags, flags); 735 593 736 594 out_release: 737 595 viortc_msg_release(VIORTC_MSG(hdl)); ··· 783 639 return ret; 784 640 } 785 641 642 + /** 643 + * viortc_read_alarm() - VIRTIO_RTC_REQ_READ_ALARM wrapper 644 + * @viortc: device data 645 + * @vio_clk_id: virtio_rtc clock id 646 + * @alarm_time: alarm time in ns 647 + * @enabled: whether alarm is enabled 648 + * 649 + * Context: Process context. 650 + * Return: Zero on success, negative error code otherwise. 651 + */ 652 + int viortc_read_alarm(struct viortc_dev *viortc, u16 vio_clk_id, 653 + u64 *alarm_time, bool *enabled) 654 + { 655 + VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_READ_ALARM, 656 + struct virtio_rtc_req_read_alarm, 657 + struct virtio_rtc_resp_read_alarm); 658 + u8 flags; 659 + int ret; 660 + 661 + ret = VIORTC_MSG_INIT(hdl, viortc); 662 + if (ret) 663 + return ret; 664 + 665 + VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id); 666 + 667 + ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl), 668 + 0); 669 + if (ret) { 670 + dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__, 671 + ret); 672 + goto out_release; 673 + } 674 + 675 + VIORTC_MSG_READ(hdl, alarm_time, alarm_time); 676 + VIORTC_MSG_READ(hdl, flags, &flags); 677 + 678 + *enabled = !!(flags & VIRTIO_RTC_FLAG_ALARM_ENABLED); 679 + 680 + out_release: 681 + viortc_msg_release(VIORTC_MSG(hdl)); 682 + 683 + return ret; 684 + } 685 + 686 + /** 687 + * viortc_set_alarm() - VIRTIO_RTC_REQ_SET_ALARM wrapper 688 + * @viortc: device data 689 + * @vio_clk_id: virtio_rtc clock id 690 + * @alarm_time: alarm time in ns 691 + * @alarm_enable: enable or disable alarm 692 + * 693 + * Context: Process context. 694 + * Return: Zero on success, negative error code otherwise. 695 + */ 696 + int viortc_set_alarm(struct viortc_dev *viortc, u16 vio_clk_id, u64 alarm_time, 697 + bool alarm_enable) 698 + { 699 + VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_SET_ALARM, 700 + struct virtio_rtc_req_set_alarm, 701 + struct virtio_rtc_resp_set_alarm); 702 + u8 flags = 0; 703 + int ret; 704 + 705 + ret = VIORTC_MSG_INIT(hdl, viortc); 706 + if (ret) 707 + return ret; 708 + 709 + if (alarm_enable) 710 + flags |= VIRTIO_RTC_FLAG_ALARM_ENABLED; 711 + 712 + VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id); 713 + VIORTC_MSG_WRITE(hdl, alarm_time, &alarm_time); 714 + VIORTC_MSG_WRITE(hdl, flags, &flags); 715 + 716 + ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl), 717 + 0); 718 + if (ret) { 719 + dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__, 720 + ret); 721 + goto out_release; 722 + } 723 + 724 + out_release: 725 + viortc_msg_release(VIORTC_MSG(hdl)); 726 + 727 + return ret; 728 + } 729 + 730 + /** 731 + * viortc_set_alarm_enabled() - VIRTIO_RTC_REQ_SET_ALARM_ENABLED wrapper 732 + * @viortc: device data 733 + * @vio_clk_id: virtio_rtc clock id 734 + * @alarm_enable: enable or disable alarm 735 + * 736 + * Context: Process context. 737 + * Return: Zero on success, negative error code otherwise. 738 + */ 739 + int viortc_set_alarm_enabled(struct viortc_dev *viortc, u16 vio_clk_id, 740 + bool alarm_enable) 741 + { 742 + VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_SET_ALARM_ENABLED, 743 + struct virtio_rtc_req_set_alarm_enabled, 744 + struct virtio_rtc_resp_set_alarm_enabled); 745 + u8 flags = 0; 746 + int ret; 747 + 748 + ret = VIORTC_MSG_INIT(hdl, viortc); 749 + if (ret) 750 + return ret; 751 + 752 + if (alarm_enable) 753 + flags |= VIRTIO_RTC_FLAG_ALARM_ENABLED; 754 + 755 + VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id); 756 + VIORTC_MSG_WRITE(hdl, flags, &flags); 757 + 758 + ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl), 759 + 0); 760 + if (ret) { 761 + dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__, 762 + ret); 763 + goto out_release; 764 + } 765 + 766 + out_release: 767 + viortc_msg_release(VIORTC_MSG(hdl)); 768 + 769 + return ret; 770 + } 771 + 786 772 /* 787 773 * init, deinit 788 774 */ 775 + 776 + /** 777 + * viortc_init_rtc_class_clock() - init and register a RTC class device 778 + * @viortc: device data 779 + * @vio_clk_id: virtio_rtc clock id 780 + * @clock_type: virtio_rtc clock type 781 + * @flags: struct virtio_rtc_resp_clock_cap.flags 782 + * 783 + * The clock must be a UTC-like clock. 784 + * 785 + * Context: Process context. 786 + * Return: Positive if registered, zero if not supported by configuration, 787 + * negative error code otherwise. 788 + */ 789 + static int viortc_init_rtc_class_clock(struct viortc_dev *viortc, 790 + u16 vio_clk_id, u8 clock_type, u8 flags) 791 + { 792 + struct virtio_device *vdev = viortc->vdev; 793 + struct viortc_class *viortc_class; 794 + struct device *dev = &vdev->dev; 795 + bool have_alarm; 796 + 797 + if (clock_type != VIRTIO_RTC_CLOCK_UTC_SMEARED) { 798 + dev_info(dev, 799 + "not creating RTC class device for clock %d, which may step on leap seconds\n", 800 + vio_clk_id); 801 + return 0; 802 + } 803 + 804 + if (viortc->viortc_class) { 805 + dev_warn_once(dev, 806 + "multiple UTC-like clocks are present, but creating only one RTC class device\n"); 807 + return 0; 808 + } 809 + 810 + have_alarm = viortc_alarms_supported(vdev) && 811 + !!(flags & VIRTIO_RTC_FLAG_ALARM_CAP); 812 + 813 + viortc_class = viortc_class_init(viortc, vio_clk_id, have_alarm, dev); 814 + if (IS_ERR(viortc_class)) 815 + return PTR_ERR(viortc_class); 816 + 817 + viortc->viortc_class = viortc_class; 818 + 819 + if (have_alarm) 820 + devm_device_init_wakeup(dev); 821 + 822 + return viortc_class_register(viortc_class) ?: 1; 823 + } 789 824 790 825 /** 791 826 * viortc_init_ptp_clock() - init and register PTP clock ··· 1005 682 * @viortc: device data 1006 683 * @vio_clk_id: virtio_rtc clock id 1007 684 * 1008 - * Initializes PHC to represent virtio_rtc clock. 685 + * Initializes PHC and/or RTC class device to represent virtio_rtc clock. 1009 686 * 1010 687 * Context: Process context. 1011 688 * Return: Zero on success, negative error code otherwise. 1012 689 */ 1013 690 static int viortc_init_clock(struct viortc_dev *viortc, u16 vio_clk_id) 1014 691 { 1015 - u8 clock_type, leap_second_smearing; 692 + u8 clock_type, leap_second_smearing, flags; 1016 693 bool is_exposed = false; 1017 694 int ret; 1018 695 1019 696 ret = viortc_clock_cap(viortc, vio_clk_id, &clock_type, 1020 - &leap_second_smearing); 697 + &leap_second_smearing, &flags); 1021 698 if (ret) 1022 699 return ret; 700 + 701 + if (IS_ENABLED(CONFIG_VIRTIO_RTC_CLASS) && 702 + (clock_type == VIRTIO_RTC_CLOCK_UTC || 703 + clock_type == VIRTIO_RTC_CLOCK_UTC_SMEARED || 704 + clock_type == VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED)) { 705 + ret = viortc_init_rtc_class_clock(viortc, vio_clk_id, 706 + clock_type, flags); 707 + if (ret < 0) 708 + return ret; 709 + if (ret > 0) 710 + is_exposed = true; 711 + } 1023 712 1024 713 if (IS_ENABLED(CONFIG_VIRTIO_RTC_PTP)) { 1025 714 ret = viortc_init_ptp_clock(viortc, vio_clk_id, clock_type, ··· 1051 716 } 1052 717 1053 718 /** 1054 - * viortc_clocks_deinit() - unregister PHCs 719 + * viortc_clocks_deinit() - unregister PHCs, stop RTC ops 1055 720 * @viortc: device data 1056 721 */ 1057 722 static void viortc_clocks_deinit(struct viortc_dev *viortc) ··· 1069 734 1070 735 WARN_ON(viortc_ptp_unregister(vio_ptp, &viortc->vdev->dev)); 1071 736 } 737 + 738 + if (viortc->viortc_class) 739 + viortc_class_stop(viortc->viortc_class); 1072 740 } 1073 741 1074 742 /** ··· 1119 781 } 1120 782 1121 783 /** 784 + * viortc_populate_vq() - populate alarmq with device-writable buffers 785 + * @viortc: device data 786 + * @viortc_vq: device specific data for virtqueue 787 + * @buf_cap: device-writable buffer size in bytes 788 + * @lock: lock queue during accesses 789 + * 790 + * Populates the alarmq with pre-allocated buffers. 791 + * 792 + * The caller is responsible for kicking the device. 793 + * 794 + * Context: Process context. 795 + * Return: Zero on success, negative error code otherwise. 796 + */ 797 + static int viortc_populate_vq(struct viortc_dev *viortc, 798 + struct viortc_vq *viortc_vq, u32 buf_cap, 799 + bool lock) 800 + { 801 + unsigned int num_elems, i; 802 + struct virtqueue *vq; 803 + unsigned long flags; 804 + void *buf; 805 + int ret; 806 + 807 + num_elems = viortc->num_alarmq_bufs; 808 + vq = viortc_vq->vq; 809 + 810 + for (i = 0; i < num_elems; i++) { 811 + buf = viortc->alarmq_bufs[i]; 812 + 813 + if (lock) { 814 + spin_lock_irqsave(&viortc_vq->lock, flags); 815 + 816 + ret = viortc_feed_vq(viortc, vq, buf, buf_cap, buf); 817 + 818 + spin_unlock_irqrestore(&viortc_vq->lock, flags); 819 + } else { 820 + ret = viortc_feed_vq(viortc, vq, buf, buf_cap, buf); 821 + } 822 + 823 + if (ret) 824 + return ret; 825 + } 826 + 827 + return 0; 828 + } 829 + 830 + /** 831 + * viortc_alloc_vq_bufs() - allocate alarmq buffers 832 + * @viortc: device data 833 + * @num_elems: # of buffers 834 + * @buf_cap: per-buffer device-writable bytes 835 + * 836 + * Context: Process context. 837 + * Return: Zero on success, negative error code otherwise. 838 + */ 839 + static int viortc_alloc_vq_bufs(struct viortc_dev *viortc, 840 + unsigned int num_elems, u32 buf_cap) 841 + { 842 + struct device *dev = &viortc->vdev->dev; 843 + void **buf_list; 844 + unsigned int i; 845 + void *buf; 846 + 847 + buf_list = devm_kcalloc(dev, num_elems, sizeof(*buf_list), GFP_KERNEL); 848 + if (!buf_list) 849 + return -ENOMEM; 850 + 851 + viortc->alarmq_bufs = buf_list; 852 + viortc->num_alarmq_bufs = num_elems; 853 + 854 + for (i = 0; i < num_elems; i++) { 855 + buf = devm_kzalloc(dev, buf_cap, GFP_KERNEL); 856 + if (!buf) 857 + return -ENOMEM; 858 + 859 + buf_list[i] = buf; 860 + } 861 + 862 + return 0; 863 + } 864 + 865 + /** 1122 866 * viortc_init_vqs() - init virtqueues 1123 867 * @viortc: device data 1124 868 * ··· 1214 794 struct virtqueue *vqs[VIORTC_MAX_NR_QUEUES]; 1215 795 struct virtqueue_info vqs_info[] = { 1216 796 { "requestq", viortc_cb_requestq }, 797 + { "alarmq", viortc_cb_alarmq }, 1217 798 }; 1218 799 struct virtio_device *vdev = viortc->vdev; 800 + unsigned int num_elems; 1219 801 int nr_queues, ret; 802 + bool have_alarms; 1220 803 1221 - nr_queues = VIORTC_REQUESTQ + 1; 804 + have_alarms = viortc_alarms_supported(vdev); 805 + 806 + if (have_alarms) 807 + nr_queues = VIORTC_ALARMQ + 1; 808 + else 809 + nr_queues = VIORTC_REQUESTQ + 1; 1222 810 1223 811 ret = virtio_find_vqs(vdev, nr_queues, vqs, vqs_info, NULL); 1224 812 if (ret) ··· 1234 806 1235 807 viortc->vqs[VIORTC_REQUESTQ].vq = vqs[VIORTC_REQUESTQ]; 1236 808 spin_lock_init(&viortc->vqs[VIORTC_REQUESTQ].lock); 809 + 810 + if (have_alarms) { 811 + viortc->vqs[VIORTC_ALARMQ].vq = vqs[VIORTC_ALARMQ]; 812 + spin_lock_init(&viortc->vqs[VIORTC_ALARMQ].lock); 813 + 814 + num_elems = virtqueue_get_vring_size(vqs[VIORTC_ALARMQ]); 815 + if (num_elems == 0) 816 + return -ENOSPC; 817 + 818 + if (!viortc->alarmq_bufs) { 819 + ret = viortc_alloc_vq_bufs(viortc, num_elems, 820 + VIORTC_ALARMQ_BUF_CAP); 821 + if (ret) 822 + return ret; 823 + } else { 824 + viortc->num_alarmq_bufs = 825 + min(num_elems, viortc->num_alarmq_bufs); 826 + } 827 + } 1237 828 1238 829 return 0; 1239 830 } ··· 1266 819 */ 1267 820 static int viortc_probe(struct virtio_device *vdev) 1268 821 { 822 + struct viortc_vq *alarm_viortc_vq; 823 + struct virtqueue *alarm_vq; 1269 824 struct viortc_dev *viortc; 825 + unsigned long flags; 826 + bool notify; 1270 827 int ret; 1271 828 1272 829 viortc = devm_kzalloc(&vdev->dev, sizeof(*viortc), GFP_KERNEL); ··· 1290 839 if (ret) 1291 840 goto err_reset_vdev; 1292 841 842 + if (viortc_alarms_supported(vdev)) { 843 + alarm_viortc_vq = &viortc->vqs[VIORTC_ALARMQ]; 844 + alarm_vq = alarm_viortc_vq->vq; 845 + 846 + ret = viortc_populate_vq(viortc, alarm_viortc_vq, 847 + VIORTC_ALARMQ_BUF_CAP, true); 848 + if (ret) 849 + goto err_deinit_clocks; 850 + 851 + spin_lock_irqsave(&alarm_viortc_vq->lock, flags); 852 + notify = virtqueue_kick_prepare(alarm_vq); 853 + spin_unlock_irqrestore(&alarm_viortc_vq->lock, flags); 854 + 855 + if (notify && !virtqueue_notify(alarm_vq)) { 856 + ret = -EIO; 857 + goto err_deinit_clocks; 858 + } 859 + } 860 + 1293 861 return 0; 862 + 863 + err_deinit_clocks: 864 + viortc_clocks_deinit(viortc); 1294 865 1295 866 err_reset_vdev: 1296 867 virtio_reset_device(vdev); ··· 1348 875 static int viortc_restore(struct virtio_device *dev) 1349 876 { 1350 877 struct viortc_dev *viortc = dev->priv; 878 + struct viortc_vq *alarm_viortc_vq; 879 + struct virtqueue *alarm_vq; 880 + bool notify = false; 881 + int ret; 1351 882 1352 - return viortc_init_vqs(viortc); 883 + ret = viortc_init_vqs(viortc); 884 + if (ret) 885 + return ret; 886 + 887 + alarm_viortc_vq = &viortc->vqs[VIORTC_ALARMQ]; 888 + alarm_vq = alarm_viortc_vq->vq; 889 + 890 + if (viortc_alarms_supported(dev)) { 891 + ret = viortc_populate_vq(viortc, alarm_viortc_vq, 892 + VIORTC_ALARMQ_BUF_CAP, false); 893 + if (ret) 894 + return ret; 895 + 896 + notify = virtqueue_kick_prepare(alarm_vq); 897 + } 898 + 899 + virtio_device_ready(dev); 900 + 901 + if (notify && !virtqueue_notify(alarm_vq)) 902 + ret = -EIO; 903 + 904 + return ret; 1353 905 } 906 + 907 + static unsigned int features[] = { 908 + #if IS_ENABLED(CONFIG_VIRTIO_RTC_CLASS) 909 + VIRTIO_RTC_F_ALARM, 910 + #endif 911 + }; 1354 912 1355 913 static struct virtio_device_id id_table[] = { 1356 914 { VIRTIO_ID_CLOCK, VIRTIO_DEV_ANY_ID }, ··· 1391 887 1392 888 static struct virtio_driver virtio_rtc_drv = { 1393 889 .driver.name = KBUILD_MODNAME, 890 + .feature_table = features, 891 + .feature_table_size = ARRAY_SIZE(features), 1394 892 .id_table = id_table, 1395 893 .probe = viortc_probe, 1396 894 .remove = viortc_remove,
+52
drivers/virtio/virtio_rtc_internal.h
··· 9 9 #ifndef _VIRTIO_RTC_INTERNAL_H_ 10 10 #define _VIRTIO_RTC_INTERNAL_H_ 11 11 12 + #include <linux/device.h> 13 + #include <linux/err.h> 12 14 #include <linux/ptp_clock_kernel.h> 13 15 #include <linux/types.h> 14 16 ··· 23 21 u64 *reading, u64 *cycles); 24 22 int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter, 25 23 bool *supported); 24 + int viortc_read_alarm(struct viortc_dev *viortc, u16 vio_clk_id, 25 + u64 *alarm_time, bool *enabled); 26 + int viortc_set_alarm(struct viortc_dev *viortc, u16 vio_clk_id, u64 alarm_time, 27 + bool alarm_enable); 28 + int viortc_set_alarm_enabled(struct viortc_dev *viortc, u16 vio_clk_id, 29 + bool alarm_enable); 30 + 31 + struct viortc_class; 32 + 33 + struct viortc_class *viortc_class_from_dev(struct device *dev); 26 34 27 35 /* PTP IFs */ 28 36 ··· 78 66 * Return: Zero on success, negative error code otherwise. 79 67 */ 80 68 int viortc_hw_xtstamp_params(u8 *hw_counter, enum clocksource_ids *cs_id); 69 + 70 + /* RTC class IFs */ 71 + 72 + #if IS_ENABLED(CONFIG_VIRTIO_RTC_CLASS) 73 + 74 + void viortc_class_alarm(struct viortc_class *viortc_class, u16 vio_clk_id); 75 + 76 + void viortc_class_stop(struct viortc_class *viortc_class); 77 + 78 + int viortc_class_register(struct viortc_class *viortc_class); 79 + 80 + struct viortc_class *viortc_class_init(struct viortc_dev *viortc, 81 + u16 vio_clk_id, bool have_alarm, 82 + struct device *parent_dev); 83 + 84 + #else /* CONFIG_VIRTIO_RTC_CLASS */ 85 + 86 + static inline void viortc_class_alarm(struct viortc_class *viortc_class, 87 + u16 vio_clk_id) 88 + { 89 + } 90 + 91 + static inline void viortc_class_stop(struct viortc_class *viortc_class) 92 + { 93 + } 94 + 95 + static inline int viortc_class_register(struct viortc_class *viortc_class) 96 + { 97 + return -ENODEV; 98 + } 99 + 100 + static inline struct viortc_class *viortc_class_init(struct viortc_dev *viortc, 101 + u16 vio_clk_id, 102 + bool have_alarm, 103 + struct device *parent_dev) 104 + { 105 + return ERR_PTR(-ENODEV); 106 + } 107 + 108 + #endif /* CONFIG_VIRTIO_RTC_CLASS */ 81 109 82 110 #endif /* _VIRTIO_RTC_INTERNAL_H_ */
+87 -1
include/uapi/linux/virtio_rtc.h
··· 9 9 10 10 #include <linux/types.h> 11 11 12 + /* alarm feature */ 13 + #define VIRTIO_RTC_F_ALARM 0 14 + 12 15 /* read request message types */ 13 16 14 17 #define VIRTIO_RTC_REQ_READ 0x0001 ··· 22 19 #define VIRTIO_RTC_REQ_CFG 0x1000 23 20 #define VIRTIO_RTC_REQ_CLOCK_CAP 0x1001 24 21 #define VIRTIO_RTC_REQ_CROSS_CAP 0x1002 22 + #define VIRTIO_RTC_REQ_READ_ALARM 0x1003 23 + #define VIRTIO_RTC_REQ_SET_ALARM 0x1004 24 + #define VIRTIO_RTC_REQ_SET_ALARM_ENABLED 0x1005 25 + 26 + /* alarmq message types */ 27 + 28 + #define VIRTIO_RTC_NOTIF_ALARM 0x2000 25 29 26 30 /* Message headers */ 27 31 ··· 47 37 #define VIRTIO_RTC_S_EIO 5 48 38 __u8 status; 49 39 __u8 reserved[7]; 40 + }; 41 + 42 + /** common notification header */ 43 + struct virtio_rtc_notif_head { 44 + __le16 msg_type; 45 + __u8 reserved[6]; 50 46 }; 51 47 52 48 /* read requests */ ··· 127 111 #define VIRTIO_RTC_SMEAR_NOON_LINEAR 1 128 112 #define VIRTIO_RTC_SMEAR_UTC_SLS 2 129 113 __u8 leap_second_smearing; 130 - __u8 reserved[6]; 114 + #define VIRTIO_RTC_FLAG_ALARM_CAP (1 << 0) 115 + __u8 flags; 116 + __u8 reserved[5]; 131 117 }; 132 118 133 119 /* VIRTIO_RTC_REQ_CROSS_CAP message */ ··· 148 130 __u8 reserved[7]; 149 131 }; 150 132 133 + /* VIRTIO_RTC_REQ_READ_ALARM message */ 134 + 135 + struct virtio_rtc_req_read_alarm { 136 + struct virtio_rtc_req_head head; 137 + __le16 clock_id; 138 + __u8 reserved[6]; 139 + }; 140 + 141 + struct virtio_rtc_resp_read_alarm { 142 + struct virtio_rtc_resp_head head; 143 + __le64 alarm_time; 144 + #define VIRTIO_RTC_FLAG_ALARM_ENABLED (1 << 0) 145 + __u8 flags; 146 + __u8 reserved[7]; 147 + }; 148 + 149 + /* VIRTIO_RTC_REQ_SET_ALARM message */ 150 + 151 + struct virtio_rtc_req_set_alarm { 152 + struct virtio_rtc_req_head head; 153 + __le64 alarm_time; 154 + __le16 clock_id; 155 + /* flag VIRTIO_RTC_FLAG_ALARM_ENABLED */ 156 + __u8 flags; 157 + __u8 reserved[5]; 158 + }; 159 + 160 + struct virtio_rtc_resp_set_alarm { 161 + struct virtio_rtc_resp_head head; 162 + /* no response params */ 163 + }; 164 + 165 + /* VIRTIO_RTC_REQ_SET_ALARM_ENABLED message */ 166 + 167 + struct virtio_rtc_req_set_alarm_enabled { 168 + struct virtio_rtc_req_head head; 169 + __le16 clock_id; 170 + /* flag VIRTIO_RTC_ALARM_ENABLED */ 171 + __u8 flags; 172 + __u8 reserved[5]; 173 + }; 174 + 175 + struct virtio_rtc_resp_set_alarm_enabled { 176 + struct virtio_rtc_resp_head head; 177 + /* no response params */ 178 + }; 179 + 151 180 /** Union of request types for requestq */ 152 181 union virtio_rtc_req_requestq { 153 182 struct virtio_rtc_req_read read; ··· 202 137 struct virtio_rtc_req_cfg cfg; 203 138 struct virtio_rtc_req_clock_cap clock_cap; 204 139 struct virtio_rtc_req_cross_cap cross_cap; 140 + struct virtio_rtc_req_read_alarm read_alarm; 141 + struct virtio_rtc_req_set_alarm set_alarm; 142 + struct virtio_rtc_req_set_alarm_enabled set_alarm_enabled; 205 143 }; 206 144 207 145 /** Union of response types for requestq */ ··· 214 146 struct virtio_rtc_resp_cfg cfg; 215 147 struct virtio_rtc_resp_clock_cap clock_cap; 216 148 struct virtio_rtc_resp_cross_cap cross_cap; 149 + struct virtio_rtc_resp_read_alarm read_alarm; 150 + struct virtio_rtc_resp_set_alarm set_alarm; 151 + struct virtio_rtc_resp_set_alarm_enabled set_alarm_enabled; 152 + }; 153 + 154 + /* alarmq notifications */ 155 + 156 + /* VIRTIO_RTC_NOTIF_ALARM notification */ 157 + 158 + struct virtio_rtc_notif_alarm { 159 + struct virtio_rtc_notif_head head; 160 + __le16 clock_id; 161 + __u8 reserved[6]; 162 + }; 163 + 164 + /** Union of notification types for alarmq */ 165 + union virtio_rtc_notif_alarmq { 166 + struct virtio_rtc_notif_alarm alarm; 217 167 }; 218 168 219 169 #endif /* _LINUX_VIRTIO_RTC_H */