drivers/virtio/virtio_rtc_class.c

Source file repositories/reference/linux-study-clean/drivers/virtio/virtio_rtc_class.c

File Facts

System
Linux kernel
Corpus path
drivers/virtio/virtio_rtc_class.c
Extension
.c
Size
6484 bytes
Lines
263
Domain
Driver Families
Bucket
drivers/virtio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct viortc_class {
	struct viortc_dev *viortc;
	struct rtc_device *rtc;
	u16 vio_clk_id;
	bool stopped;
};

/**
 * viortc_class_get_locked() - get RTC class wrapper, if ops allowed
 * @dev: virtio device
 *
 * Gets the RTC class wrapper from the virtio device, if it is available and
 * ops are allowed.
 *
 * Context: Caller must hold rtc_lock().
 * Return: RTC class wrapper if available and ops allowed, ERR_PTR otherwise.
 */
static struct viortc_class *viortc_class_get_locked(struct device *dev)
{
	struct viortc_class *viortc_class;

	viortc_class = viortc_class_from_dev(dev);
	if (IS_ERR(viortc_class))
		return viortc_class;

	if (viortc_class->stopped)
		return ERR_PTR(-EBUSY);

	return viortc_class;
}

/**
 * viortc_class_read_time() - RTC class op read_time
 * @dev: virtio device
 * @tm: read time
 *
 * Context: Process context.
 * Return: Zero on success, negative error code otherwise.
 */
static int viortc_class_read_time(struct device *dev, struct rtc_time *tm)
{
	struct viortc_class *viortc_class;
	time64_t sec;
	int ret;
	u64 ns;

	viortc_class = viortc_class_get_locked(dev);
	if (IS_ERR(viortc_class))
		return PTR_ERR(viortc_class);

	ret = viortc_read(viortc_class->viortc, viortc_class->vio_clk_id, &ns);
	if (ret)
		return ret;

	sec = div_u64(ns, NSEC_PER_SEC);

	rtc_time64_to_tm(sec, tm);

	return 0;
}

/**
 * viortc_class_read_alarm() - RTC class op read_alarm
 * @dev: virtio device
 * @alrm: alarm read out
 *
 * Context: Process context.
 * Return: Zero on success, negative error code otherwise.
 */
static int viortc_class_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct viortc_class *viortc_class;
	time64_t alarm_time_sec;
	u64 alarm_time_ns;
	bool enabled;
	int ret;

	viortc_class = viortc_class_get_locked(dev);
	if (IS_ERR(viortc_class))
		return PTR_ERR(viortc_class);

	ret = viortc_read_alarm(viortc_class->viortc, viortc_class->vio_clk_id,
				&alarm_time_ns, &enabled);
	if (ret)
		return ret;

	alarm_time_sec = div_u64(alarm_time_ns, NSEC_PER_SEC);
	rtc_time64_to_tm(alarm_time_sec, &alrm->time);

	alrm->enabled = enabled;

Annotation

Implementation Notes