drivers/platform/chrome/chromeos_acpi.c

Source file repositories/reference/linux-study-clean/drivers/platform/chrome/chromeos_acpi.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/chrome/chromeos_acpi.c
Extension
.c
Size
8346 bytes
Lines
287
Domain
Driver Families
Bucket
drivers/platform
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * ChromeOS specific ACPI extensions
 *
 * Copyright 2022 Google LLC
 *
 * This driver attaches to the ChromeOS ACPI device and then exports the
 * values reported by the ACPI in a sysfs directory. All values are
 * presented in the string form (numbers as decimal values) and can be
 * accessed as the contents of the appropriate read only files in the
 * sysfs directory tree.
 */
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>

#define ACPI_ATTR_NAME_LEN 4

#define DEV_ATTR(_var, _name)					\
	static struct device_attribute dev_attr_##_var =	\
		__ATTR(_name, 0444, chromeos_first_level_attr_show, NULL);

#define GPIO_ATTR_GROUP(_group, _name, _num)						\
	static umode_t attr_is_visible_gpio_##_num(struct kobject *kobj,		\
						   struct attribute *attr, int n)	\
	{										\
		if (_num < chromeos_acpi_gpio_groups)					\
			return attr->mode;						\
		return 0;								\
	}										\
	static ssize_t chromeos_attr_show_gpio_##_num(struct device *dev,		\
						      struct device_attribute *attr,	\
						      char *buf)			\
	{										\
		char name[ACPI_ATTR_NAME_LEN + 1];					\
		int ret, num;								\
											\
		ret = parse_attr_name(attr->attr.name, name, &num);			\
		if (ret)								\
			return ret;							\
		return chromeos_acpi_evaluate_method(dev, _num, num, name, buf);	\
	}										\
	static struct device_attribute dev_attr_0_##_group =				\
		__ATTR(GPIO.0, 0444, chromeos_attr_show_gpio_##_num, NULL);		\
	static struct device_attribute dev_attr_1_##_group =				\
		__ATTR(GPIO.1, 0444, chromeos_attr_show_gpio_##_num, NULL);		\
	static struct device_attribute dev_attr_2_##_group =				\
		__ATTR(GPIO.2, 0444, chromeos_attr_show_gpio_##_num, NULL);		\
	static struct device_attribute dev_attr_3_##_group =				\
		__ATTR(GPIO.3, 0444, chromeos_attr_show_gpio_##_num, NULL);		\
											\
	static struct attribute *attrs_##_group[] = {					\
		&dev_attr_0_##_group.attr,						\
		&dev_attr_1_##_group.attr,						\
		&dev_attr_2_##_group.attr,						\
		&dev_attr_3_##_group.attr,						\
		NULL									\
	};										\
	static const struct attribute_group attr_group_##_group = {			\
		.name = _name,								\
		.is_visible = attr_is_visible_gpio_##_num,				\
		.attrs = attrs_##_group,						\
	};

static unsigned int chromeos_acpi_gpio_groups;

/* Parse the ACPI package and return the data related to that attribute */
static int chromeos_acpi_handle_package(struct device *dev, union acpi_object *obj,
					int pkg_num, int sub_pkg_num, char *name, char *buf)
{
	union acpi_object *element = obj->package.elements;

	if (pkg_num >= obj->package.count)
		return -EINVAL;
	element += pkg_num;

	if (element->type == ACPI_TYPE_PACKAGE) {
		if (sub_pkg_num >= element->package.count)
			return -EINVAL;
		/* select sub element inside this package */
		element = element->package.elements;
		element += sub_pkg_num;
	}

	switch (element->type) {
	case ACPI_TYPE_INTEGER:
		return sysfs_emit(buf, "%d\n", (int)element->integer.value);
	case ACPI_TYPE_STRING:

Annotation

Implementation Notes