26
26
27
27
#include "internal.h"
28
28
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
+
29
129
/**
30
130
* create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
31
131
* @acpi_dev: ACPI device object.
@@ -323,20 +423,12 @@ static ssize_t acpi_device_adr_show(struct device *dev,
323
423
}
324
424
static DEVICE_ATTR (adr , 0444 , acpi_device_adr_show , NULL) ;
325
425
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
+ {
328
429
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 ;
335
430
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 );
340
432
}
341
433
static DEVICE_ATTR (path , 0444 , acpi_device_path_show , NULL) ;
342
434
@@ -475,6 +567,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
475
567
& dev_attr_real_power_state );
476
568
}
477
569
570
+ acpi_expose_nondev_subnodes (& dev -> dev .kobj , & dev -> data );
571
+
478
572
end :
479
573
return result ;
480
574
}
@@ -485,6 +579,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
485
579
*/
486
580
void acpi_device_remove_files (struct acpi_device * dev )
487
581
{
582
+ acpi_hide_nondev_subnodes (& dev -> data );
583
+
488
584
if (dev -> flags .power_manageable ) {
489
585
device_remove_file (& dev -> dev , & dev_attr_power_state );
490
586
if (dev -> power .flags .power_resources )
0 commit comments