Skip to content

Commit 2337824

Browse files
committed
Merge branch 'device-properties' into acpi-init
2 parents 9ffecb1 + 3f4232e commit 2337824

File tree

12 files changed

+753
-194
lines changed

12 files changed

+753
-194
lines changed

drivers/acpi/device_sysfs.c

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,106 @@
2626

2727
#include "internal.h"
2828

29+
static ssize_t acpi_object_path(acpi_handle handle, char *buf)
30+
{
31+
struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
32+
int result;
33+
34+
result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path);
35+
if (result)
36+
return result;
37+
38+
result = sprintf(buf, "%s\n", (char*)path.pointer);
39+
kfree(path.pointer);
40+
return result;
41+
}
42+
43+
struct acpi_data_node_attr {
44+
struct attribute attr;
45+
ssize_t (*show)(struct acpi_data_node *, char *);
46+
ssize_t (*store)(struct acpi_data_node *, const char *, size_t count);
47+
};
48+
49+
#define DATA_NODE_ATTR(_name) \
50+
static struct acpi_data_node_attr data_node_##_name = \
51+
__ATTR(_name, 0444, data_node_show_##_name, NULL)
52+
53+
static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
54+
{
55+
return acpi_object_path(dn->handle, buf);
56+
}
57+
58+
DATA_NODE_ATTR(path);
59+
60+
static struct attribute *acpi_data_node_default_attrs[] = {
61+
&data_node_path.attr,
62+
NULL
63+
};
64+
65+
#define to_data_node(k) container_of(k, struct acpi_data_node, kobj)
66+
#define to_attr(a) container_of(a, struct acpi_data_node_attr, attr)
67+
68+
static ssize_t acpi_data_node_attr_show(struct kobject *kobj,
69+
struct attribute *attr, char *buf)
70+
{
71+
struct acpi_data_node *dn = to_data_node(kobj);
72+
struct acpi_data_node_attr *dn_attr = to_attr(attr);
73+
74+
return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO;
75+
}
76+
77+
static const struct sysfs_ops acpi_data_node_sysfs_ops = {
78+
.show = acpi_data_node_attr_show,
79+
};
80+
81+
static void acpi_data_node_release(struct kobject *kobj)
82+
{
83+
struct acpi_data_node *dn = to_data_node(kobj);
84+
complete(&dn->kobj_done);
85+
}
86+
87+
static struct kobj_type acpi_data_node_ktype = {
88+
.sysfs_ops = &acpi_data_node_sysfs_ops,
89+
.default_attrs = acpi_data_node_default_attrs,
90+
.release = acpi_data_node_release,
91+
};
92+
93+
static void acpi_expose_nondev_subnodes(struct kobject *kobj,
94+
struct acpi_device_data *data)
95+
{
96+
struct list_head *list = &data->subnodes;
97+
struct acpi_data_node *dn;
98+
99+
if (list_empty(list))
100+
return;
101+
102+
list_for_each_entry(dn, list, sibling) {
103+
int ret;
104+
105+
init_completion(&dn->kobj_done);
106+
ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
107+
kobj, dn->name);
108+
if (ret)
109+
acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
110+
else
111+
acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
112+
}
113+
}
114+
115+
static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
116+
{
117+
struct list_head *list = &data->subnodes;
118+
struct acpi_data_node *dn;
119+
120+
if (list_empty(list))
121+
return;
122+
123+
list_for_each_entry_reverse(dn, list, sibling) {
124+
acpi_hide_nondev_subnodes(&dn->data);
125+
kobject_put(&dn->kobj);
126+
}
127+
}
128+
29129
/**
30130
* create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
31131
* @acpi_dev: ACPI device object.
@@ -323,20 +423,12 @@ static ssize_t acpi_device_adr_show(struct device *dev,
323423
}
324424
static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL);
325425

326-
static ssize_t
327-
acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
426+
static ssize_t acpi_device_path_show(struct device *dev,
427+
struct device_attribute *attr, char *buf)
428+
{
328429
struct acpi_device *acpi_dev = to_acpi_device(dev);
329-
struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
330-
int result;
331-
332-
result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
333-
if (result)
334-
goto end;
335430

336-
result = sprintf(buf, "%s\n", (char*)path.pointer);
337-
kfree(path.pointer);
338-
end:
339-
return result;
431+
return acpi_object_path(acpi_dev->handle, buf);
340432
}
341433
static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
342434

@@ -475,6 +567,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
475567
&dev_attr_real_power_state);
476568
}
477569

570+
acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data);
571+
478572
end:
479573
return result;
480574
}
@@ -485,6 +579,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
485579
*/
486580
void acpi_device_remove_files(struct acpi_device *dev)
487581
{
582+
acpi_hide_nondev_subnodes(&dev->data);
583+
488584
if (dev->flags.power_manageable) {
489585
device_remove_file(&dev->dev, &dev_attr_power_state);
490586
if (dev->power.flags.power_resources)

0 commit comments

Comments
 (0)