drivers/acpi/acpi_tad.c

Source file repositories/reference/linux-study-clean/drivers/acpi/acpi_tad.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/acpi_tad.c
Extension
.c
Size
21583 bytes
Lines
903
Domain
Driver Families
Bucket
drivers/acpi
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 acpi_tad_driver_data {
	u32 capabilities;
};

struct acpi_tad_rt {
	u16 year;  /* 1900 - 9999 */
	u8 month;  /* 1 - 12 */
	u8 day;    /* 1 - 31 */
	u8 hour;   /* 0 - 23 */
	u8 minute; /* 0 - 59 */
	u8 second; /* 0 - 59 */
	u8 valid;  /* 0 (failed) or 1 (success) for reads, 0 for writes */
	u16 msec;  /* 1 - 1000 */
	s16 tz;    /* -1440 to 1440 or 2047 (unspecified) */
	u8 daylight;
	u8 padding[3]; /* must be 0 */
} __packed;

static bool acpi_tad_rt_is_invalid(struct acpi_tad_rt *rt)
{
	return rt->year < 1900 || rt->year > 9999 ||
	    rt->month < 1 || rt->month > 12 ||
	    rt->hour > 23 || rt->minute > 59 || rt->second > 59 ||
	    rt->tz < -1440 ||
	    (rt->tz > 1440 && rt->tz != ACPI_TAD_TZ_UNSPEC) ||
	    rt->daylight > 3;
}

static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
{
	acpi_handle handle = ACPI_HANDLE(dev);
	union acpi_object args[] = {
		{ .type = ACPI_TYPE_BUFFER, },
	};
	struct acpi_object_list arg_list = {
		.pointer = args,
		.count = ARRAY_SIZE(args),
	};
	unsigned long long retval;
	acpi_status status;

	if (acpi_tad_rt_is_invalid(rt))
		return -EINVAL;

	rt->valid = 0;
	rt->msec = 0;
	memset(rt->padding, 0, 3);

	args[0].buffer.pointer = (u8 *)rt;
	args[0].buffer.length = sizeof(*rt);

	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval);
	if (ACPI_FAILURE(status) || retval)
		return -EIO;

	return 0;
}

static int acpi_tad_evaluate_grt(struct device *dev, struct acpi_tad_rt *rt)
{
	acpi_handle handle = ACPI_HANDLE(dev);
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
	union acpi_object *out_obj;
	struct acpi_tad_rt *data;
	acpi_status status;
	int ret = -EIO;

	status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
	if (ACPI_FAILURE(status))
		goto out_free;

	out_obj = output.pointer;
	if (out_obj->type != ACPI_TYPE_BUFFER)
		goto out_free;

	if (out_obj->buffer.length != sizeof(*rt))
		goto out_free;

	data = (struct acpi_tad_rt *)(out_obj->buffer.pointer);
	if (!data->valid)
		goto out_free;

	memcpy(rt, data, sizeof(*rt));
	ret = 0;

out_free:

Annotation

Implementation Notes