- patches.kernel.org/revert-removal-of-ACPI-procfs-entries.patch:
[opensuse:kernel-source.git] / patches.kernel.org / revert-removal-of-ACPI-procfs-entries.patch
1 From: Tomas Cech <sleep_walker@suse.cz>
2 Date: Wed, 12 Sep 2012 16:22:11 +0200
3 Subject: Revert removal of ACPI procfs entries
4 Patch-mainline: never
5 References: bnc#777283
6
7 Revert changes made by 47f5c892b06797336a34f1096b4b617623aa1960.
8 We need to keep our API.
9
10 ---
11  drivers/acpi/Kconfig    |   12 +++
12  drivers/acpi/Makefile   |    3 +-
13  drivers/acpi/bus.c      |    2 +
14  drivers/acpi/debug.c    |  227 +++++++++++++++++++++++++++++++++++++++++++++++
15  drivers/acpi/internal.h |    7 ++
16  drivers/acpi/proc.c     |   70 +++++++++++++++
17  drivers/acpi/system.c   |  170 +++++++++++++++++++++++++++++++++++
18  7 files changed, 490 insertions(+), 1 deletions(-)
19  create mode 100644 drivers/acpi/debug.c
20  create mode 100644 drivers/acpi/system.c
21
22 Acked-by: Petr Tesarik <ptesarik@suse.cz>
23
24 diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
25 index 5c8f7b0..9717640 100644
26 --- a/drivers/acpi/Kconfig
27 +++ b/drivers/acpi/Kconfig
28 @@ -50,7 +50,19 @@ config ACPI_PROCFS
29           For backwards compatibility, this option allows
30           deprecated /proc/acpi/ files to exist, even when
31           they have been replaced by functions in /sys.
32 +         The deprecated files (and their replacements) include:
33  
34 +         /proc/acpi/sleep (/sys/power/state)
35 +         /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
36 +         /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
37 +         /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
38 +         /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
39 +         /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level)
40 +         /proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*)
41 +         /proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/
42 +               cpufreq/*)
43 +         /proc/acpi/processor/*/throttling (/sys/class/thermal/
44 +               cooling_device*/*)
45           This option has no effect on /proc/acpi/ files
46           and functions which do not yet exist in /sys.
47  
48 diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
49 index 1e835cc..224089b 100644
50 --- a/drivers/acpi/Makefile
51 +++ b/drivers/acpi/Makefile
52 @@ -37,8 +37,9 @@ acpi-y                                += ec.o
53  acpi-$(CONFIG_ACPI_DOCK)       += dock.o
54  acpi-y                         += pci_root.o pci_link.o pci_irq.o pci_bind.o
55  acpi-y                         += power.o
56 -acpi-y                         += event.o
57 +acpi-y                         += system.o event.o
58  acpi-y                         += sysfs.o
59 +acpi-$(CONFIG_ACPI_DEBUG)      += debug.o
60  acpi-$(CONFIG_DEBUG_FS)                += debugfs.o
61  acpi-$(CONFIG_ACPI_NUMA)       += numa.o
62  acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
63 diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
64 index 437ddbf..2758a44 100644
65 --- a/drivers/acpi/bus.c
66 +++ b/drivers/acpi/bus.c
67 @@ -1040,6 +1040,8 @@ static int __init acpi_init(void)
68         pci_mmcfg_late_init();
69         acpi_scan_init();
70         acpi_ec_init();
71 +       acpi_system_init();
72 +       acpi_debug_init();
73         acpi_debugfs_init();
74         acpi_sleep_proc_init();
75         acpi_wakeup_device_init();
76 diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
77 new file mode 100644
78 index 0000000..f82240d
79 --- /dev/null
80 +++ b/drivers/acpi/debug.c
81 @@ -0,0 +1,227 @@
82 +/*
83 + * debug.c - ACPI debug interface to userspace.
84 + */
85 +
86 +#include <linux/proc_fs.h>
87 +#include <linux/seq_file.h>
88 +#include <linux/init.h>
89 +#include <linux/module.h>
90 +#include <linux/kernel.h>
91 +#include <linux/moduleparam.h>
92 +#include <linux/debugfs.h>
93 +#include <linux/slab.h>
94 +#include <asm/uaccess.h>
95 +#include <acpi/acpi_drivers.h>
96 +
97 +#define _COMPONENT             ACPI_SYSTEM_COMPONENT
98 +ACPI_MODULE_NAME("debug");
99 +
100 +struct acpi_dlayer {
101 +       const char *name;
102 +       unsigned long value;
103 +};
104 +struct acpi_dlevel {
105 +       const char *name;
106 +       unsigned long value;
107 +};
108 +#define ACPI_DEBUG_INIT(v)     { .name = #v, .value = v }
109 +
110 +static const struct acpi_dlayer acpi_debug_layers[] = {
111 +       ACPI_DEBUG_INIT(ACPI_UTILITIES),
112 +       ACPI_DEBUG_INIT(ACPI_HARDWARE),
113 +       ACPI_DEBUG_INIT(ACPI_EVENTS),
114 +       ACPI_DEBUG_INIT(ACPI_TABLES),
115 +       ACPI_DEBUG_INIT(ACPI_NAMESPACE),
116 +       ACPI_DEBUG_INIT(ACPI_PARSER),
117 +       ACPI_DEBUG_INIT(ACPI_DISPATCHER),
118 +       ACPI_DEBUG_INIT(ACPI_EXECUTER),
119 +       ACPI_DEBUG_INIT(ACPI_RESOURCES),
120 +       ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
121 +       ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
122 +       ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
123 +       ACPI_DEBUG_INIT(ACPI_COMPILER),
124 +       ACPI_DEBUG_INIT(ACPI_TOOLS),
125 +
126 +       ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT),
127 +       ACPI_DEBUG_INIT(ACPI_AC_COMPONENT),
128 +       ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT),
129 +       ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT),
130 +       ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT),
131 +       ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT),
132 +       ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT),
133 +       ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT),
134 +       ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT),
135 +       ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT),
136 +       ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT),
137 +       ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT),
138 +       ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT),
139 +       ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT),
140 +};
141 +
142 +static const struct acpi_dlevel acpi_debug_levels[] = {
143 +       ACPI_DEBUG_INIT(ACPI_LV_INIT),
144 +       ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
145 +       ACPI_DEBUG_INIT(ACPI_LV_INFO),
146 +
147 +       ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
148 +       ACPI_DEBUG_INIT(ACPI_LV_PARSE),
149 +       ACPI_DEBUG_INIT(ACPI_LV_LOAD),
150 +       ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
151 +       ACPI_DEBUG_INIT(ACPI_LV_EXEC),
152 +       ACPI_DEBUG_INIT(ACPI_LV_NAMES),
153 +       ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
154 +       ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
155 +       ACPI_DEBUG_INIT(ACPI_LV_TABLES),
156 +       ACPI_DEBUG_INIT(ACPI_LV_VALUES),
157 +       ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
158 +       ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
159 +       ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
160 +       ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),
161 +
162 +       ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
163 +       ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
164 +       ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),
165 +
166 +       ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
167 +       ACPI_DEBUG_INIT(ACPI_LV_THREADS),
168 +       ACPI_DEBUG_INIT(ACPI_LV_IO),
169 +       ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),
170 +
171 +       ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
172 +       ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
173 +       ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
174 +       ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
175 +};
176 +
177 +/* --------------------------------------------------------------------------
178 +                              FS Interface (/proc)
179 +   -------------------------------------------------------------------------- */
180 +#ifdef CONFIG_ACPI_PROCFS
181 +#define ACPI_SYSTEM_FILE_DEBUG_LAYER   "debug_layer"
182 +#define ACPI_SYSTEM_FILE_DEBUG_LEVEL           "debug_level"
183 +
184 +static int acpi_system_debug_proc_show(struct seq_file *m, void *v)
185 +{
186 +       unsigned int i;
187 +
188 +       seq_printf(m, "%-25s\tHex        SET\n", "Description");
189 +
190 +       switch ((unsigned long)m->private) {
191 +       case 0:
192 +               for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
193 +                       seq_printf(m, "%-25s\t0x%08lX [%c]\n",
194 +                                    acpi_debug_layers[i].name,
195 +                                    acpi_debug_layers[i].value,
196 +                                    (acpi_dbg_layer & acpi_debug_layers[i].
197 +                                     value) ? '*' : ' ');
198 +               }
199 +               seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
200 +                            ACPI_ALL_DRIVERS,
201 +                            (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
202 +                            ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
203 +                                                      ACPI_ALL_DRIVERS) ==
204 +                            0 ? ' ' : '-');
205 +               seq_printf(m,
206 +                            "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
207 +                            acpi_dbg_layer);
208 +               break;
209 +       case 1:
210 +               for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
211 +                       seq_printf(m, "%-25s\t0x%08lX [%c]\n",
212 +                                    acpi_debug_levels[i].name,
213 +                                    acpi_debug_levels[i].value,
214 +                                    (acpi_dbg_level & acpi_debug_levels[i].
215 +                                     value) ? '*' : ' ');
216 +               }
217 +               seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n",
218 +                            acpi_dbg_level);
219 +               break;
220 +       }
221 +       return 0;
222 +}
223 +
224 +static int acpi_system_debug_proc_open(struct inode *inode, struct file *file)
225 +{
226 +       return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data);
227 +}
228 +
229 +static ssize_t acpi_system_debug_proc_write(struct file *file,
230 +                       const char __user * buffer,
231 +                       size_t count, loff_t *pos)
232 +{
233 +       char debug_string[12] = { '\0' };
234 +
235 +
236 +       if (count > sizeof(debug_string) - 1)
237 +               return -EINVAL;
238 +
239 +       if (copy_from_user(debug_string, buffer, count))
240 +               return -EFAULT;
241 +
242 +       debug_string[count] = '\0';
243 +
244 +       switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) {
245 +       case 0:
246 +               acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0);
247 +               break;
248 +       case 1:
249 +               acpi_dbg_level = simple_strtoul(debug_string, NULL, 0);
250 +               break;
251 +       default:
252 +               return -EINVAL;
253 +       }
254 +
255 +       return count;
256 +}
257 +
258 +static const struct file_operations acpi_system_debug_proc_fops = {
259 +       .owner          = THIS_MODULE,
260 +       .open           = acpi_system_debug_proc_open,
261 +       .read           = seq_read,
262 +       .llseek         = seq_lseek,
263 +       .release        = single_release,
264 +       .write          = acpi_system_debug_proc_write,
265 +};
266 +#endif
267 +
268 +int __init acpi_procfs_init(void)
269 +{
270 +#ifdef CONFIG_ACPI_PROCFS
271 +       struct proc_dir_entry *entry;
272 +       int error = 0;
273 +       char *name;
274 +
275 +       /* 'debug_layer' [R/W] */
276 +       name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
277 +       entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR,
278 +                                acpi_root_dir, &acpi_system_debug_proc_fops,
279 +                                (void *)0);
280 +       if (!entry)
281 +               goto Error;
282 +
283 +       /* 'debug_level' [R/W] */
284 +       name = ACPI_SYSTEM_FILE_DEBUG_LEVEL;
285 +       entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR,
286 +                                acpi_root_dir, &acpi_system_debug_proc_fops,
287 +                                (void *)1);
288 +       if (!entry)
289 +               goto Error;
290 +
291 +      Done:
292 +       return error;
293 +
294 +      Error:
295 +       remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir);
296 +       remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
297 +       error = -ENODEV;
298 +       goto Done;
299 +#else
300 +       return 0;
301 +#endif
302 +}
303 +
304 +int __init acpi_debug_init(void)
305 +{
306 +       acpi_procfs_init();
307 +       return 0;
308 +}
309 diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
310 index ca75b9c..9143cc0 100644
311 --- a/drivers/acpi/internal.h
312 +++ b/drivers/acpi/internal.h
313 @@ -25,8 +25,15 @@
314  
315  int init_acpi_device_notify(void);
316  int acpi_scan_init(void);
317 +int acpi_system_init(void);
318  int acpi_sysfs_init(void);
319  
320 +#ifdef CONFIG_ACPI_DEBUG
321 +int acpi_debug_init(void);
322 +#else
323 +static inline int acpi_debug_init(void) { return 0; }
324 +#endif
325 +
326  #ifdef CONFIG_DEBUG_FS
327  extern struct dentry *acpi_debugfs_dir;
328  int acpi_debugfs_init(void);
329 diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
330 index f5f9869..064cc64 100644
331 --- a/drivers/acpi/proc.c
332 +++ b/drivers/acpi/proc.c
333 @@ -17,11 +17,64 @@
334  
335  /*
336   * this file provides support for:
337 + * /proc/acpi/sleep
338   * /proc/acpi/alarm
339   * /proc/acpi/wakeup
340   */
341  
342  ACPI_MODULE_NAME("sleep")
343 +#ifdef CONFIG_ACPI_PROCFS
344 +static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
345 +{
346 +       int i;
347 +
348 +       for (i = 0; i <= ACPI_STATE_S5; i++) {
349 +               if (sleep_states[i]) {
350 +                       seq_printf(seq, "S%d ", i);
351 +               }
352 +       }
353 +
354 +       seq_puts(seq, "\n");
355 +
356 +       return 0;
357 +}
358 +
359 +static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
360 +{
361 +       return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
362 +}
363 +
364 +static ssize_t
365 +acpi_system_write_sleep(struct file *file,
366 +                       const char __user * buffer, size_t count, loff_t * ppos)
367 +{
368 +       char str[12];
369 +       u32 state = 0;
370 +       int error = 0;
371 +
372 +       if (count > sizeof(str) - 1)
373 +               goto Done;
374 +       memset(str, 0, sizeof(str));
375 +       if (copy_from_user(str, buffer, count))
376 +               return -EFAULT;
377 +
378 +       /* Check for S4 bios request */
379 +       if (!strcmp(str, "4b")) {
380 +               error = acpi_suspend(4);
381 +               goto Done;
382 +       }
383 +       state = simple_strtoul(str, NULL, 0);
384 +#ifdef CONFIG_HIBERNATION
385 +       if (state == 4) {
386 +               error = hibernate();
387 +               goto Done;
388 +       }
389 +#endif
390 +       error = acpi_suspend(state);
391 +      Done:
392 +       return error ? error : count;
393 +}
394 +#endif                         /* CONFIG_ACPI_PROCFS */
395  
396  #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86)
397  /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
398 @@ -393,6 +446,17 @@ static const struct file_operations acpi_system_wakeup_device_fops = {
399         .release = single_release,
400  };
401  
402 +#ifdef CONFIG_ACPI_PROCFS
403 +static const struct file_operations acpi_system_sleep_fops = {
404 +       .owner = THIS_MODULE,
405 +       .open = acpi_system_sleep_open_fs,
406 +       .read = seq_read,
407 +       .write = acpi_system_write_sleep,
408 +       .llseek = seq_lseek,
409 +       .release = single_release,
410 +};
411 +#endif                         /* CONFIG_ACPI_PROCFS */
412 +
413  #ifdef HAVE_ACPI_LEGACY_ALARM
414  static const struct file_operations acpi_system_alarm_fops = {
415         .owner = THIS_MODULE,
416 @@ -414,6 +478,12 @@ static u32 rtc_handler(void *context)
417  
418  int __init acpi_sleep_proc_init(void)
419  {
420 +#ifdef CONFIG_ACPI_PROCFS
421 +       /* 'sleep' [R/W] */
422 +       proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
423 +                   acpi_root_dir, &acpi_system_sleep_fops);
424 +#endif                         /* CONFIG_ACPI_PROCFS */
425 +
426  #ifdef HAVE_ACPI_LEGACY_ALARM
427         /* 'alarm' [R/W] */
428         proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR,
429 diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
430 new file mode 100644
431 index 0000000..d70481f
432 --- /dev/null
433 +++ b/drivers/acpi/system.c
434 @@ -0,0 +1,170 @@
435 +/*
436 + *  acpi_system.c - ACPI System Driver ($Revision: 63 $)
437 + *
438 + *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
439 + *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
440 + *
441 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
442 + *
443 + *  This program is free software; you can redistribute it and/or modify
444 + *  it under the terms of the GNU General Public License as published by
445 + *  the Free Software Foundation; either version 2 of the License, or (at
446 + *  your option) any later version.
447 + *
448 + *  This program is distributed in the hope that it will be useful, but
449 + *  WITHOUT ANY WARRANTY; without even the implied warranty of
450 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
451 + *  General Public License for more details.
452 + *
453 + *  You should have received a copy of the GNU General Public License along
454 + *  with this program; if not, write to the Free Software Foundation, Inc.,
455 + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
456 + *
457 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
458 + */
459 +
460 +#include <linux/proc_fs.h>
461 +#include <linux/seq_file.h>
462 +#include <linux/slab.h>
463 +#include <linux/init.h>
464 +#include <linux/string.h>
465 +#include <asm/uaccess.h>
466 +
467 +#include <acpi/acpi_drivers.h>
468 +
469 +#define PREFIX "ACPI: "
470 +
471 +#define _COMPONENT             ACPI_SYSTEM_COMPONENT
472 +ACPI_MODULE_NAME("system");
473 +
474 +#define ACPI_SYSTEM_CLASS              "system"
475 +#define ACPI_SYSTEM_DEVICE_NAME                "System"
476 +
477 +/* --------------------------------------------------------------------------
478 +                              FS Interface (/proc)
479 +   -------------------------------------------------------------------------- */
480 +#ifdef CONFIG_ACPI_PROCFS
481 +#define ACPI_SYSTEM_FILE_INFO          "info"
482 +#define ACPI_SYSTEM_FILE_EVENT         "event"
483 +#define ACPI_SYSTEM_FILE_DSDT          "dsdt"
484 +#define ACPI_SYSTEM_FILE_FADT          "fadt"
485 +
486 +static int acpi_system_read_info(struct seq_file *seq, void *offset)
487 +{
488 +
489 +       seq_printf(seq, "version:                 %x\n", ACPI_CA_VERSION);
490 +       return 0;
491 +}
492 +
493 +static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
494 +{
495 +       return single_open(file, acpi_system_read_info, PDE(inode)->data);
496 +}
497 +
498 +static const struct file_operations acpi_system_info_ops = {
499 +       .owner = THIS_MODULE,
500 +       .open = acpi_system_info_open_fs,
501 +       .read = seq_read,
502 +       .llseek = seq_lseek,
503 +       .release = single_release,
504 +};
505 +
506 +static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
507 +                                    loff_t *);
508 +
509 +static const struct file_operations acpi_system_dsdt_ops = {
510 +       .owner = THIS_MODULE,
511 +       .read = acpi_system_read_dsdt,
512 +};
513 +
514 +static ssize_t
515 +acpi_system_read_dsdt(struct file *file,
516 +                     char __user * buffer, size_t count, loff_t * ppos)
517 +{
518 +       acpi_status status = AE_OK;
519 +       struct acpi_table_header *dsdt = NULL;
520 +       ssize_t res;
521 +
522 +       status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
523 +       if (ACPI_FAILURE(status))
524 +               return -ENODEV;
525 +
526 +       res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
527 +
528 +       return res;
529 +}
530 +
531 +static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
532 +                                    loff_t *);
533 +
534 +static const struct file_operations acpi_system_fadt_ops = {
535 +       .owner = THIS_MODULE,
536 +       .read = acpi_system_read_fadt,
537 +};
538 +
539 +static ssize_t
540 +acpi_system_read_fadt(struct file *file,
541 +                     char __user * buffer, size_t count, loff_t * ppos)
542 +{
543 +       acpi_status status = AE_OK;
544 +       struct acpi_table_header *fadt = NULL;
545 +       ssize_t res;
546 +
547 +       status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
548 +       if (ACPI_FAILURE(status))
549 +               return -ENODEV;
550 +
551 +       res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
552 +
553 +       return res;
554 +}
555 +
556 +static int acpi_system_procfs_init(void)
557 +{
558 +       struct proc_dir_entry *entry;
559 +       int error = 0;
560 +
561 +       /* 'info' [R] */
562 +       entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir,
563 +                           &acpi_system_info_ops);
564 +       if (!entry)
565 +               goto Error;
566 +
567 +       /* 'dsdt' [R] */
568 +       entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir,
569 +                           &acpi_system_dsdt_ops);
570 +       if (!entry)
571 +               goto Error;
572 +
573 +       /* 'fadt' [R] */
574 +       entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir,
575 +                           &acpi_system_fadt_ops);
576 +       if (!entry)
577 +               goto Error;
578 +
579 +      Done:
580 +       return error;
581 +
582 +      Error:
583 +       remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
584 +       remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
585 +       remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
586 +
587 +       error = -EFAULT;
588 +       goto Done;
589 +}
590 +#else
591 +static int acpi_system_procfs_init(void)
592 +{
593 +       return 0;
594 +}
595 +#endif
596 +
597 +int __init acpi_system_init(void)
598 +{
599 +       int result;
600 +
601 +       result = acpi_system_procfs_init();
602 +
603 +       return result;
604 +}
605 -- 
606 1.7.7
607