drivers/rtc/sysfs.c

Source file repositories/reference/linux-study-clean/drivers/rtc/sysfs.c

File Facts

System
Linux kernel
Corpus path
drivers/rtc/sysfs.c
Extension
.c
Size
8474 bytes
Lines
352
Domain
Driver Families
Bucket
drivers/rtc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (*buf_ptr == '=') {
			buf_ptr++;
			push = 1;
		} else {
			adjust = 1;
		}
	}
	retval = kstrtos64(buf_ptr, 0, &alarm);
	if (retval)
		return retval;
	if (adjust)
		alarm += now;
	if (alarm > now || push) {
		/* Avoid accidentally clobbering active alarms; we can't
		 * entirely prevent that here, without even the minimal
		 * locking from the /dev/rtcN api.
		 */
		retval = rtc_read_alarm(rtc, &alm);
		if (retval < 0)
			return retval;
		if (alm.enabled) {
			if (push) {
				push = rtc_tm_to_time64(&alm.time);
				alarm += push;
			} else
				return -EBUSY;
		} else if (push)
			return -EINVAL;
		alm.enabled = 1;
	} else {
		alm.enabled = 0;

		/* Provide a valid future alarm time.  Linux isn't EFI,
		 * this time won't be ignored when disabling the alarm.
		 */
		alarm = now + 300;
	}
	rtc_time64_to_tm(alarm, &alm.time);

	retval = rtc_set_alarm(rtc, &alm);
	return (retval < 0) ? retval : n;
}
static DEVICE_ATTR_RW(wakealarm);

static ssize_t
offset_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	ssize_t retval;
	long offset;

	retval = rtc_read_offset(to_rtc_device(dev), &offset);
	if (retval)
		return retval;

	return sysfs_emit(buf, "%ld\n", offset);
}

static ssize_t
offset_store(struct device *dev, struct device_attribute *attr,
	     const char *buf, size_t n)
{
	ssize_t retval;
	long offset;

	retval = kstrtol(buf, 10, &offset);
	if (retval == 0)
		retval = rtc_set_offset(to_rtc_device(dev), offset);

	return (retval < 0) ? retval : n;
}
static DEVICE_ATTR_RW(offset);

static ssize_t
range_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "[%lld,%llu]\n", to_rtc_device(dev)->range_min,
			  to_rtc_device(dev)->range_max);
}
static DEVICE_ATTR_RO(range);

static struct attribute *rtc_attrs[] = {
	&dev_attr_name.attr,
	&dev_attr_date.attr,
	&dev_attr_time.attr,
	&dev_attr_since_epoch.attr,
	&dev_attr_max_user_freq.attr,
	&dev_attr_hctosys.attr,
	&dev_attr_wakealarm.attr,
	&dev_attr_offset.attr,
	&dev_attr_range.attr,

Annotation

Implementation Notes