aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/system.c
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2007-06-14 05:43:07 -0400
committerLen Brown <len.brown@intel.com>2007-07-22 02:42:45 -0400
commitd4c5f047ae2a33296774e41abc2ac5c89283f736 (patch)
tree49a2d39404d727756159751e9de3ffea2e728bbf /drivers/acpi/system.c
parentd7fff6f4d1ed1bc31577df887fefcb1541923367 (diff)
ACPI: Populate /sys/firmware/acpi/tables/
The file name is the signature, such as DSDT, and the contents are the binary table image. Some tables, such as the SSDT, can have multiple instances. If just one, the file is SSDT, but if 3 instances, for example, it will be SSDT1, SSDT2, SSDT3 All static tables (besides teh RSDP and RSDT themselves are exported. Dynamic tables, such as SSDT op-regions that are not declared in the RSDT, will be added in a subsequent patch. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/system.c')
-rw-r--r--drivers/acpi/system.c165
1 files changed, 144 insertions, 21 deletions
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 83a8d3097904..edee2806e37b 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system");
39 39
40#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
41#define ACPI_SYSTEM_DEVICE_NAME "System" 41#define ACPI_SYSTEM_DEVICE_NAME "System"
42#define ACPI_SYSTEM_FILE_INFO "info"
43#define ACPI_SYSTEM_FILE_EVENT "event"
44#define ACPI_SYSTEM_FILE_DSDT "dsdt"
45#define ACPI_SYSTEM_FILE_FADT "fadt"
46 42
47/* 43/*
48 * Make ACPICA version work as module param 44 * Make ACPICA version work as module param
49 */ 45 */
50static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { 46static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
47{
51 int result; 48 int result;
52 49
53 result = sprintf(buffer, "%x", ACPI_CA_VERSION); 50 result = sprintf(buffer, "%x", ACPI_CA_VERSION);
@@ -58,9 +55,126 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
58module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); 55module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
59 56
60/* -------------------------------------------------------------------------- 57/* --------------------------------------------------------------------------
58 FS Interface (/sys)
59 -------------------------------------------------------------------------- */
60static LIST_HEAD(acpi_table_attr_list);
61static struct kobject tables_kobj;
62
63struct acpi_table_attr {
64 struct bin_attribute attr;
65 char name[8];
66 int instance;
67 struct list_head node;
68};
69
70static ssize_t acpi_table_show(struct kobject *kobj,
71 struct bin_attribute *bin_attr, char *buf,
72 loff_t offset, size_t count)
73{
74 struct acpi_table_attr *table_attr =
75 container_of(bin_attr, struct acpi_table_attr, attr);
76 struct acpi_table_header *table_header = NULL;
77 acpi_status status;
78 ssize_t ret_count = count;
79
80 status =
81 acpi_get_table(table_attr->name, table_attr->instance,
82 &table_header);
83 if (ACPI_FAILURE(status))
84 return -ENODEV;
85
86 if (offset >= table_header->length) {
87 ret_count = 0;
88 goto end;
89 }
90
91 if (offset + ret_count > table_header->length)
92 ret_count = table_header->length - offset;
93
94 memcpy(buf, ((char *)table_header) + offset, ret_count);
95
96 end:
97 return ret_count;
98}
99
100static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
101 struct acpi_table_header *table_header)
102{
103 struct acpi_table_header *header = NULL;
104 struct acpi_table_attr *attr = NULL;
105
106 memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
107
108 list_for_each_entry(attr, &acpi_table_attr_list, node) {
109 if (!memcmp(table_header->signature, attr->name,
110 ACPI_NAME_SIZE))
111 if (table_attr->instance < attr->instance)
112 table_attr->instance = attr->instance;
113 }
114 table_attr->instance++;
115
116 if (table_attr->instance > 1 || (table_attr->instance == 1 &&
117 !acpi_get_table(table_header->
118 signature, 2,
119 &header)))
120 sprintf(table_attr->name + 4, "%d", table_attr->instance);
121
122 table_attr->attr.size = 0;
123 table_attr->attr.read = acpi_table_show;
124 table_attr->attr.attr.name = table_attr->name;
125 table_attr->attr.attr.mode = 0444;
126 table_attr->attr.attr.owner = THIS_MODULE;
127
128 return;
129}
130
131static int acpi_system_sysfs_init(void)
132{
133 struct acpi_table_attr *table_attr;
134 struct acpi_table_header *table_header = NULL;
135 int table_index = 0;
136 int result;
137
138 tables_kobj.parent = &acpi_subsys.kobj;
139 kobject_set_name(&tables_kobj, "tables");
140 result = kobject_register(&tables_kobj);
141 if (result)
142 return result;
143
144 do {
145 result = acpi_get_table_by_index(table_index, &table_header);
146 if (!result) {
147 table_index++;
148 table_attr = NULL;
149 table_attr =
150 kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
151 if (!table_attr)
152 return -ENOMEM;
153
154 acpi_table_attr_init(table_attr, table_header);
155 result =
156 sysfs_create_bin_file(&tables_kobj,
157 &table_attr->attr);
158 if (result) {
159 kfree(table_attr);
160 return result;
161 } else
162 list_add_tail(&table_attr->node,
163 &acpi_table_attr_list);
164 }
165 } while (!result);
166
167 return 0;
168}
169
170/* --------------------------------------------------------------------------
61 FS Interface (/proc) 171 FS Interface (/proc)
62 -------------------------------------------------------------------------- */ 172 -------------------------------------------------------------------------- */
63#ifdef CONFIG_ACPI_PROCFS 173#ifdef CONFIG_ACPI_PROCFS
174#define ACPI_SYSTEM_FILE_INFO "info"
175#define ACPI_SYSTEM_FILE_EVENT "event"
176#define ACPI_SYSTEM_FILE_DSDT "dsdt"
177#define ACPI_SYSTEM_FILE_FADT "fadt"
64 178
65static int acpi_system_read_info(struct seq_file *seq, void *offset) 179static int acpi_system_read_info(struct seq_file *seq, void *offset)
66{ 180{
@@ -80,7 +194,6 @@ static const struct file_operations acpi_system_info_ops = {
80 .llseek = seq_lseek, 194 .llseek = seq_lseek,
81 .release = single_release, 195 .release = single_release,
82}; 196};
83#endif
84 197
85static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, 198static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
86 loff_t *); 199 loff_t *);
@@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file,
97 struct acpi_table_header *dsdt = NULL; 210 struct acpi_table_header *dsdt = NULL;
98 ssize_t res; 211 ssize_t res;
99 212
100
101 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); 213 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
102 if (ACPI_FAILURE(status)) 214 if (ACPI_FAILURE(status))
103 return -ENODEV; 215 return -ENODEV;
104 216
105 res = simple_read_from_buffer(buffer, count, ppos, 217 res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
106 dsdt, dsdt->length);
107 218
108 return res; 219 return res;
109} 220}
@@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file,
123 struct acpi_table_header *fadt = NULL; 234 struct acpi_table_header *fadt = NULL;
124 ssize_t res; 235 ssize_t res;
125 236
126
127 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); 237 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
128 if (ACPI_FAILURE(status)) 238 if (ACPI_FAILURE(status))
129 return -ENODEV; 239 return -ENODEV;
130 240
131 res = simple_read_from_buffer(buffer, count, ppos, 241 res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
132 fadt, fadt->length);
133 242
134 return res; 243 return res;
135} 244}
136 245
137static int __init acpi_system_init(void) 246static int acpi_system_procfs_init(void)
138{ 247{
139 struct proc_dir_entry *entry; 248 struct proc_dir_entry *entry;
140 int error = 0; 249 int error = 0;
141 char *name; 250 char *name;
142 251
143
144 if (acpi_disabled)
145 return 0;
146
147#ifdef CONFIG_ACPI_PROCFS
148 /* 'info' [R] */ 252 /* 'info' [R] */
149 name = ACPI_SYSTEM_FILE_INFO; 253 name = ACPI_SYSTEM_FILE_INFO;
150 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); 254 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -153,7 +257,6 @@ static int __init acpi_system_init(void)
153 else { 257 else {
154 entry->proc_fops = &acpi_system_info_ops; 258 entry->proc_fops = &acpi_system_info_ops;
155 } 259 }
156#endif
157 260
158 /* 'dsdt' [R] */ 261 /* 'dsdt' [R] */
159 name = ACPI_SYSTEM_FILE_DSDT; 262 name = ACPI_SYSTEM_FILE_DSDT;
@@ -177,12 +280,32 @@ static int __init acpi_system_init(void)
177 Error: 280 Error:
178 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); 281 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
179 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); 282 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
180#ifdef CONFIG_ACPI_PROCFS
181 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); 283 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
182#endif
183 284
184 error = -EFAULT; 285 error = -EFAULT;
185 goto Done; 286 goto Done;
186} 287}
288#else
289static int acpi_system_procfs_init(void)
290{
291 return 0;
292}
293#endif
294
295static int __init acpi_system_init(void)
296{
297 int result = 0;
298
299 if (acpi_disabled)
300 return 0;
301
302 result = acpi_system_procfs_init();
303 if (result)
304 return result;
305
306 result = acpi_system_sysfs_init();
307
308 return result;
309}
187 310
188subsys_initcall(acpi_system_init); 311subsys_initcall(acpi_system_init);