Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * drivers/acpi/device_sysfs.c - ACPI device sysfs attributes and modalias.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2015, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/nls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static ssize_t acpi_object_path(acpi_handle handle, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	result = sprintf(buf, "%s\n", (char *)path.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	kfree(path.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) struct acpi_data_node_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	ssize_t (*show)(struct acpi_data_node *, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	ssize_t (*store)(struct acpi_data_node *, const char *, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define DATA_NODE_ATTR(_name)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	static struct acpi_data_node_attr data_node_##_name =	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		__ATTR(_name, 0444, data_node_show_##_name, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	return dn->handle ? acpi_object_path(dn->handle, buf) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) DATA_NODE_ATTR(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static struct attribute *acpi_data_node_default_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	&data_node_path.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define to_data_node(k) container_of(k, struct acpi_data_node, kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define to_attr(a) container_of(a, struct acpi_data_node_attr, attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static ssize_t acpi_data_node_attr_show(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 					struct attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct acpi_data_node *dn = to_data_node(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct acpi_data_node_attr *dn_attr = to_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static const struct sysfs_ops acpi_data_node_sysfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	.show	= acpi_data_node_attr_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static void acpi_data_node_release(struct kobject *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct acpi_data_node *dn = to_data_node(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	complete(&dn->kobj_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static struct kobj_type acpi_data_node_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	.sysfs_ops = &acpi_data_node_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	.default_attrs = acpi_data_node_default_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	.release = acpi_data_node_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static void acpi_expose_nondev_subnodes(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 					struct acpi_device_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct list_head *list = &data->subnodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct acpi_data_node *dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (list_empty(list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	list_for_each_entry(dn, list, sibling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		init_completion(&dn->kobj_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 					   kobj, "%s", dn->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		else if (dn->handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct list_head *list = &data->subnodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct acpi_data_node *dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (list_empty(list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	list_for_each_entry_reverse(dn, list, sibling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		acpi_hide_nondev_subnodes(&dn->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		kobject_put(&dn->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * @acpi_dev: ACPI device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * @modalias: Buffer to print into.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @size: Size of the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * Creates hid/cid(s) string needed for modalias and uevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * char *modalias: "acpi:IBM0001:ACPI0001"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * Return: 0: no _HID and no _CID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *         -EINVAL: output error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  *         -ENOMEM: output is truncated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			       int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct acpi_hardware_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	/* Avoid unnecessarily loading modules for non present devices. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (!acpi_device_is_present(acpi_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	 * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	 * device's list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	list_for_each_entry(id, &acpi_dev->pnp.ids, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		if (strcmp(id->id, ACPI_DT_NAMESPACE_HID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	len = snprintf(modalias, size, "acpi:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	size -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		count = snprintf(&modalias[len], size, "%s:", id->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		if (count >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		len += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		size -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	modalias[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * create_of_modalias - Creates DT compatible string for modalias and uevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * @acpi_dev: ACPI device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * @modalias: Buffer to print into.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * @size: Size of the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * Expose DT compatible modalias as of:NnameTCcompatible.  This function should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * ACPI/PNP IDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			      int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	const union acpi_object *of_compatible, *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	int len, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	int i, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	char *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	status = acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	/* DT strings are all in lower case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	for (c = buf.pointer; *c != '\0'; c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		*c = tolower(*c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	ACPI_FREE(buf.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	of_compatible = acpi_dev->data.of_compatible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (of_compatible->type == ACPI_TYPE_PACKAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		nval = of_compatible->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		obj = of_compatible->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	} else { /* Must be ACPI_TYPE_STRING. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		nval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		obj = of_compatible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	for (i = 0; i < nval; i++, obj++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		count = snprintf(&modalias[len], size, "C%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				 obj->string.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		if (count >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		len += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		size -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	modalias[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int __acpi_device_uevent_modalias(struct acpi_device *adev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				  struct kobj_uevent_env *env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (!adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (list_empty(&adev->pnp.ids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (add_uevent_var(env, "MODALIAS="))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	if (adev->data.of_compatible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		len = create_of_modalias(adev, &env->buf[env->buflen - 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 					 sizeof(env->buf) - env->buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		len = create_pnp_modalias(adev, &env->buf[env->buflen - 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 					  sizeof(env->buf) - env->buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	env->buflen += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  * acpi_device_uevent_modalias - uevent modalias for ACPI-enumerated devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * Create the uevent modalias field for ACPI-enumerated devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	int len, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (!adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (list_empty(&adev->pnp.ids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	len = create_pnp_modalias(adev, buf, size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	} else if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		buf[len++] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		size -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (!adev->data.of_compatible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	count = create_of_modalias(adev, buf + len, size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	if (count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	} else if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		len += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		buf[len++] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  * acpi_device_modalias - modalias sysfs attribute for ACPI-enumerated devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)  * Create the modalias sysfs attribute for ACPI-enumerated devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int acpi_device_modalias(struct device *dev, char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	return __acpi_device_modalias(acpi_companion_match(dev), buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) EXPORT_SYMBOL_GPL(acpi_device_modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return __acpi_device_modalias(to_acpi_device(dev), buf, 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static DEVICE_ATTR_RO(modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static ssize_t real_power_state_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 				     struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	struct acpi_device *adev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	ret = acpi_device_get_power(adev, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	return sprintf(buf, "%s\n", acpi_power_state_string(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static DEVICE_ATTR_RO(real_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static ssize_t power_state_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct acpi_device *adev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static DEVICE_ATTR_RO(power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) eject_store(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	    const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct acpi_device *acpi_device = to_acpi_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	acpi_object_type not_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!count || buf[0] != '1')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	    && !acpi_device->driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	status = acpi_get_type(acpi_device->handle, &not_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	get_device(&acpi_device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	put_device(&acpi_device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			  ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static DEVICE_ATTR_WO(eject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) hid_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static DEVICE_ATTR_RO(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static ssize_t uid_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static DEVICE_ATTR_RO(uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static ssize_t adr_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	if (acpi_dev->pnp.bus_address > U32_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		return sprintf(buf, "0x%016llx\n", acpi_dev->pnp.bus_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		return sprintf(buf, "0x%08llx\n", acpi_dev->pnp.bus_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static DEVICE_ATTR_RO(adr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static ssize_t path_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	return acpi_object_path(acpi_dev->handle, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static DEVICE_ATTR_RO(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* sysfs file that shows description text from the ACPI _STR method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static ssize_t description_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 				char *buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (acpi_dev->pnp.str_obj == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	 * The _STR object contains a Unicode identifier for a device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	 * We need to convert to utf-8 so it can be displayed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	result = utf16s_to_utf8s(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		(wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		acpi_dev->pnp.str_obj->buffer.length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		UTF16_LITTLE_ENDIAN, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	buf[result++] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static DEVICE_ATTR_RO(description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sun_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	 char *buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	unsigned long long sun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	return sprintf(buf, "%llu\n", sun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static DEVICE_ATTR_RO(sun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) hrv_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	 char *buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	unsigned long long hrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	status = acpi_evaluate_integer(acpi_dev->handle, "_HRV", NULL, &hrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	return sprintf(buf, "%llu\n", hrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static DEVICE_ATTR_RO(hrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static ssize_t status_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				char *buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	struct acpi_device *acpi_dev = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	unsigned long long sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	return sprintf(buf, "%llu\n", sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static DEVICE_ATTR_RO(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)  * acpi_device_setup_files - Create sysfs attributes of an ACPI device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)  * @dev: ACPI device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) int acpi_device_setup_files(struct acpi_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	 * Devices gotten from FADT don't have a "path" attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (dev->handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		result = device_create_file(&dev->dev, &dev_attr_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	if (!list_empty(&dev->pnp.ids)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		result = device_create_file(&dev->dev, &dev_attr_hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		result = device_create_file(&dev->dev, &dev_attr_modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	 * If device has _STR, 'description' file is created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	if (acpi_has_method(dev->handle, "_STR")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		status = acpi_evaluate_object(dev->handle, "_STR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 					NULL, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			buffer.pointer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		dev->pnp.str_obj = buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		result = device_create_file(&dev->dev, &dev_attr_description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	if (dev->pnp.type.bus_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		result = device_create_file(&dev->dev, &dev_attr_adr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if (dev->pnp.unique_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		result = device_create_file(&dev->dev, &dev_attr_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (acpi_has_method(dev->handle, "_SUN")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		result = device_create_file(&dev->dev, &dev_attr_sun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (acpi_has_method(dev->handle, "_HRV")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		result = device_create_file(&dev->dev, &dev_attr_hrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	if (acpi_has_method(dev->handle, "_STA")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		result = device_create_file(&dev->dev, &dev_attr_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	 * If device has _EJ0, 'eject' file is created that is used to trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	 * hot-removal function from userland.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	if (acpi_has_method(dev->handle, "_EJ0")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		result = device_create_file(&dev->dev, &dev_attr_eject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	if (dev->flags.power_manageable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		result = device_create_file(&dev->dev, &dev_attr_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		if (dev->power.flags.power_resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 			result = device_create_file(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 						    &dev_attr_real_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)  * acpi_device_remove_files - Remove sysfs attributes of an ACPI device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)  * @dev: ACPI device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) void acpi_device_remove_files(struct acpi_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	acpi_hide_nondev_subnodes(&dev->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (dev->flags.power_manageable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		device_remove_file(&dev->dev, &dev_attr_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		if (dev->power.flags.power_resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			device_remove_file(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 					   &dev_attr_real_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	 * If device has _STR, remove 'description' file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (acpi_has_method(dev->handle, "_STR")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		kfree(dev->pnp.str_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		device_remove_file(&dev->dev, &dev_attr_description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	 * If device has _EJ0, remove 'eject' file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	if (acpi_has_method(dev->handle, "_EJ0"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		device_remove_file(&dev->dev, &dev_attr_eject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	if (acpi_has_method(dev->handle, "_SUN"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		device_remove_file(&dev->dev, &dev_attr_sun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (acpi_has_method(dev->handle, "_HRV"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		device_remove_file(&dev->dev, &dev_attr_hrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	if (dev->pnp.unique_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		device_remove_file(&dev->dev, &dev_attr_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	if (dev->pnp.type.bus_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		device_remove_file(&dev->dev, &dev_attr_adr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	device_remove_file(&dev->dev, &dev_attr_modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	device_remove_file(&dev->dev, &dev_attr_hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	if (acpi_has_method(dev->handle, "_STA"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		device_remove_file(&dev->dev, &dev_attr_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (dev->handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		device_remove_file(&dev->dev, &dev_attr_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }