system.c 16.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 *  acpi_system.c - ACPI System Driver ($Revision: 63 $)
 *
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
28
#include <linux/slab.h>
L
Linus Torvalds 已提交
29
#include <linux/init.h>
30
#include <linux/string.h>
L
Linus Torvalds 已提交
31 32 33 34
#include <asm/uaccess.h>

#include <acpi/acpi_drivers.h>

35 36
#define PREFIX "ACPI: "

L
Linus Torvalds 已提交
37
#define _COMPONENT		ACPI_SYSTEM_COMPONENT
38
ACPI_MODULE_NAME("system");
Z
Zhang Rui 已提交
39

L
Linus Torvalds 已提交
40 41 42
#define ACPI_SYSTEM_CLASS		"system"
#define ACPI_SYSTEM_DEVICE_NAME		"System"

43
u32 acpi_irq_handled;
44
u32 acpi_irq_not_handled;
45

Z
Zhang Rui 已提交
46 47 48
/*
 * Make ACPICA version work as module param
 */
49 50
static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
{
Z
Zhang Rui 已提交
51 52 53 54 55 56 57 58 59
	int result;

	result = sprintf(buffer, "%x", ACPI_CA_VERSION);

	return result;
}

module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);

60 61 62 63
/* --------------------------------------------------------------------------
                              FS Interface (/sys)
   -------------------------------------------------------------------------- */
static LIST_HEAD(acpi_table_attr_list);
64
static struct kobject *tables_kobj;
65
static struct kobject *dynamic_tables_kobj;
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

struct acpi_table_attr {
	struct bin_attribute attr;
	char name[8];
	int instance;
	struct list_head node;
};

static ssize_t acpi_table_show(struct kobject *kobj,
			       struct bin_attribute *bin_attr, char *buf,
			       loff_t offset, size_t count)
{
	struct acpi_table_attr *table_attr =
	    container_of(bin_attr, struct acpi_table_attr, attr);
	struct acpi_table_header *table_header = NULL;
	acpi_status status;
82 83 84 85 86 87
	char name[ACPI_NAME_SIZE];

	if (strncmp(table_attr->name, "NULL", 4))
		memcpy(name, table_attr->name, ACPI_NAME_SIZE);
	else
		memcpy(name, "\0\0\0\0", 4);
88 89

	status =
90
	    acpi_get_table(name, table_attr->instance,
91 92 93 94
			   &table_header);
	if (ACPI_FAILURE(status))
		return -ENODEV;

95 96
	return memory_read_from_buffer(buf, count, &offset,
					table_header, table_header->length);
97 98 99 100 101 102 103 104
}

static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
				 struct acpi_table_header *table_header)
{
	struct acpi_table_header *header = NULL;
	struct acpi_table_attr *attr = NULL;

105
	sysfs_attr_init(&table_attr->attr.attr);
106 107 108 109 110
	if (table_header->signature[0] != '\0')
		memcpy(table_attr->name, table_header->signature,
			ACPI_NAME_SIZE);
	else
		memcpy(table_attr->name, "NULL", 4);
111 112

	list_for_each_entry(attr, &acpi_table_attr_list, node) {
113
		if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
114 115 116 117 118 119
			if (table_attr->instance < attr->instance)
				table_attr->instance = attr->instance;
	}
	table_attr->instance++;

	if (table_attr->instance > 1 || (table_attr->instance == 1 &&
120 121 122 123
					!acpi_get_table
					(table_header->signature, 2, &header)))
		sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
			table_attr->instance);
124 125 126 127

	table_attr->attr.size = 0;
	table_attr->attr.read = acpi_table_show;
	table_attr->attr.attr.name = table_attr->name;
128
	table_attr->attr.attr.mode = 0400;
129 130 131 132

	return;
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
static acpi_status
acpi_sysfs_table_handler(u32 event, void *table, void *context)
{
	struct acpi_table_attr *table_attr;

	switch (event) {
	case ACPI_TABLE_EVENT_LOAD:
		table_attr =
			kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
		if (!table_attr)
			return AE_NO_MEMORY;

		acpi_table_attr_init(table_attr, table);
		if (sysfs_create_bin_file(dynamic_tables_kobj,
					&table_attr->attr)) {
			kfree(table_attr);
			return AE_ERROR;
		} else
			list_add_tail(&table_attr->node,
					&acpi_table_attr_list);
		break;
	case ACPI_TABLE_EVENT_UNLOAD:
		/*
		 * we do not need to do anything right now
		 * because the table is not deleted from the
		 * global table list when unloading it.
		 */
		break;
	default:
		return AE_BAD_PARAMETER;
	}
	return AE_OK;
}

167 168 169 170 171 172 173
static int acpi_system_sysfs_init(void)
{
	struct acpi_table_attr *table_attr;
	struct acpi_table_header *table_header = NULL;
	int table_index = 0;
	int result;

174 175
	tables_kobj = kobject_create_and_add("tables", acpi_kobj);
	if (!tables_kobj)
176 177 178 179 180
		goto err;

	dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
	if (!dynamic_tables_kobj)
		goto err_dynamic_tables;
181 182 183 184 185 186 187 188 189 190 191 192 193

	do {
		result = acpi_get_table_by_index(table_index, &table_header);
		if (!result) {
			table_index++;
			table_attr = NULL;
			table_attr =
			    kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
			if (!table_attr)
				return -ENOMEM;

			acpi_table_attr_init(table_attr, table_header);
			result =
194
			    sysfs_create_bin_file(tables_kobj,
195 196 197 198 199 200 201 202 203
						  &table_attr->attr);
			if (result) {
				kfree(table_attr);
				return result;
			} else
				list_add_tail(&table_attr->node,
					      &acpi_table_attr_list);
		}
	} while (!result);
204
	kobject_uevent(tables_kobj, KOBJ_ADD);
205 206 207 208 209 210 211 212
	kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
	result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);

	return result == AE_OK ? 0 : -EINVAL;
err_dynamic_tables:
	kobject_put(tables_kobj);
err:
	return -ENOMEM;
213 214
}

215 216 217 218 219 220 221
/*
 * Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/
 * See Documentation/ABI/testing/sysfs-firmware-acpi
 */

#define COUNT_GPE 0
#define COUNT_SCI 1	/* acpi_irq_handled */
222 223 224
#define COUNT_SCI_NOT 2	/* acpi_irq_not_handled */
#define COUNT_ERROR 3	/* other */
#define NUM_COUNTERS_EXTRA 4
225

226 227 228 229 230 231
struct event_counter {
	u32 count;
	u32 flags;
};

static struct event_counter *all_counters;
232 233 234 235 236 237 238 239 240 241 242 243
static u32 num_gpes;
static u32 num_counters;
static struct attribute **all_attrs;
static u32 acpi_gpe_count;

static struct attribute_group interrupt_stats_attr_group = {
	.name = "interrupts",
};
static struct kobj_attribute *counter_attrs;

static void delete_gpe_attr_array(void)
{
244
	struct event_counter *tmp = all_counters;
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269

	all_counters = NULL;
	kfree(tmp);

	if (counter_attrs) {
		int i;

		for (i = 0; i < num_gpes; i++)
			kfree(counter_attrs[i].attr.name);

		kfree(counter_attrs);
	}
	kfree(all_attrs);

	return;
}

void acpi_os_gpe_count(u32 gpe_number)
{
	acpi_gpe_count++;

	if (!all_counters)
		return;

	if (gpe_number < num_gpes)
270
		all_counters[gpe_number].count++;
271
	else
272 273
		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
					count++;
274 275 276 277 278 279 280 281 282 283

	return;
}

void acpi_os_fixed_event_count(u32 event_number)
{
	if (!all_counters)
		return;

	if (event_number < ACPI_NUM_FIXED_EVENTS)
284
		all_counters[num_gpes + event_number].count++;
285
	else
286 287
		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
				count++;
288 289 290 291

	return;
}

292 293 294 295 296 297 298 299
static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
{
	int result = 0;

	if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
		goto end;

	if (index < num_gpes) {
300
		result = acpi_get_gpe_device(index, handle);
301 302 303 304 305
		if (result) {
			ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
				"Invalid GPE 0x%x\n", index));
			goto end;
		}
306
		result = acpi_get_gpe_status(*handle, index, status);
307 308 309 310 311 312 313
	} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
		result = acpi_get_event_status(index - num_gpes, status);

end:
	return result;
}

314 315 316
static ssize_t counter_show(struct kobject *kobj,
	struct kobj_attribute *attr, char *buf)
{
317 318 319 320 321 322 323
	int index = attr - counter_attrs;
	int size;
	acpi_handle handle;
	acpi_event_status status;
	int result = 0;

	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
324
		acpi_irq_handled;
325 326
	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
		acpi_irq_not_handled;
327
	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
328 329
		acpi_gpe_count;

330 331 332 333 334 335 336 337 338 339
	size = sprintf(buf, "%8d", all_counters[index].count);

	/* "gpe_all" or "sci" */
	if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
		goto end;

	result = get_status(index, &status, &handle);
	if (result)
		goto end;

340 341
	if (!(status & ACPI_EVENT_FLAG_HANDLE))
		size += sprintf(buf + size, "	invalid");
342
	else if (status & ACPI_EVENT_FLAG_ENABLED)
343 344 345
		size += sprintf(buf + size, "	enabled");
	else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
		size += sprintf(buf + size, "	wake_enabled");
346
	else
347
		size += sprintf(buf + size, "	disabled");
348 349 350 351

end:
	size += sprintf(buf + size, "\n");
	return result ? result : size;
352 353 354 355 356
}

/*
 * counter_set() sets the specified counter.
 * setting the total "sci" file to any value clears all counters.
357
 * enable/disable/clear a gpe/fixed event in user space.
358 359 360 361 362
 */
static ssize_t counter_set(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t size)
{
	int index = attr - counter_attrs;
363 364 365
	acpi_event_status status;
	acpi_handle handle;
	int result = 0;
366 367 368 369

	if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) {
		int i;
		for (i = 0; i < num_counters; ++i)
370
			all_counters[i].count = 0;
371 372
		acpi_gpe_count = 0;
		acpi_irq_handled = 0;
373
		acpi_irq_not_handled = 0;
374 375 376 377 378 379 380 381
		goto end;
	}

	/* show the event status for both GPEs and Fixed Events */
	result = get_status(index, &status, &handle);
	if (result)
		goto end;

382
	if (!(status & ACPI_EVENT_FLAG_HANDLE)) {
383 384
		printk(KERN_WARNING PREFIX
			"Can not change Invalid GPE/Fixed Event status\n");
385 386
		return -EINVAL;
	}
387

388 389 390
	if (index < num_gpes) {
		if (!strcmp(buf, "disable\n") &&
				(status & ACPI_EVENT_FLAG_ENABLED))
391
			result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE);
392 393
		else if (!strcmp(buf, "enable\n") &&
				!(status & ACPI_EVENT_FLAG_ENABLED))
394
			result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE);
395 396
		else if (!strcmp(buf, "clear\n") &&
				(status & ACPI_EVENT_FLAG_SET))
397
			result = acpi_clear_gpe(handle, index);
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
		else
			all_counters[index].count = strtoul(buf, NULL, 0);
	} else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
		int event = index - num_gpes;
		if (!strcmp(buf, "disable\n") &&
				(status & ACPI_EVENT_FLAG_ENABLED))
			result = acpi_disable_event(event, ACPI_NOT_ISR);
		else if (!strcmp(buf, "enable\n") &&
				!(status & ACPI_EVENT_FLAG_ENABLED))
			result = acpi_enable_event(event, ACPI_NOT_ISR);
		else if (!strcmp(buf, "clear\n") &&
				(status & ACPI_EVENT_FLAG_SET))
			result = acpi_clear_event(event);
		else
			all_counters[index].count = strtoul(buf, NULL, 0);
413
	} else
414
		all_counters[index].count = strtoul(buf, NULL, 0);
415

416 417 418 419
	if (ACPI_FAILURE(result))
		result = -EINVAL;
end:
	return result ? result : size;
420 421 422 423 424 425 426 427 428
}

void acpi_irq_stats_init(void)
{
	int i;

	if (all_counters)
		return;

429
	num_gpes = acpi_current_gpe_count;
430 431 432 433 434 435 436
	num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA;

	all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1),
			GFP_KERNEL);
	if (all_attrs == NULL)
		return;

437 438
	all_counters = kzalloc(sizeof(struct event_counter) * (num_counters),
				GFP_KERNEL);
439 440 441 442 443 444 445 446 447
	if (all_counters == NULL)
		goto fail;

	counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
			GFP_KERNEL);
	if (counter_attrs == NULL)
		goto fail;

	for (i = 0; i < num_counters; ++i) {
448
		char buffer[12];
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
		char *name;

		if (i < num_gpes)
			sprintf(buffer, "gpe%02X", i);
		else if (i == num_gpes + ACPI_EVENT_PMTIMER)
			sprintf(buffer, "ff_pmtimer");
		else if (i == num_gpes + ACPI_EVENT_GLOBAL)
			sprintf(buffer, "ff_gbl_lock");
		else if (i == num_gpes + ACPI_EVENT_POWER_BUTTON)
			sprintf(buffer, "ff_pwr_btn");
		else if (i == num_gpes + ACPI_EVENT_SLEEP_BUTTON)
			sprintf(buffer, "ff_slp_btn");
		else if (i == num_gpes + ACPI_EVENT_RTC)
			sprintf(buffer, "ff_rt_clk");
		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE)
			sprintf(buffer, "gpe_all");
		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
			sprintf(buffer, "sci");
467 468
		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT)
			sprintf(buffer, "sci_not");
469 470 471 472 473 474 475 476 477 478
		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
			sprintf(buffer, "error");
		else
			sprintf(buffer, "bug%02X", i);

		name = kzalloc(strlen(buffer) + 1, GFP_KERNEL);
		if (name == NULL)
			goto fail;
		strncpy(name, buffer, strlen(buffer) + 1);

479
		sysfs_attr_init(&counter_attrs[i].attr);
480 481 482 483 484 485 486 487 488
		counter_attrs[i].attr.name = name;
		counter_attrs[i].attr.mode = 0644;
		counter_attrs[i].show = counter_show;
		counter_attrs[i].store = counter_set;

		all_attrs[i] = &counter_attrs[i].attr;
	}

	interrupt_stats_attr_group.attrs = all_attrs;
L
Len Brown 已提交
489 490
	if (!sysfs_create_group(acpi_kobj, &interrupt_stats_attr_group))
		return;
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505

fail:
	delete_gpe_attr_array();
	return;
}

static void __exit interrupt_stats_exit(void)
{
	sysfs_remove_group(acpi_kobj, &interrupt_stats_attr_group);

	delete_gpe_attr_array();

	return;
}

L
Linus Torvalds 已提交
506 507 508
/* --------------------------------------------------------------------------
                              FS Interface (/proc)
   -------------------------------------------------------------------------- */
Z
Zhang Rui 已提交
509
#ifdef CONFIG_ACPI_PROCFS
510 511 512 513
#define ACPI_SYSTEM_FILE_INFO		"info"
#define ACPI_SYSTEM_FILE_EVENT		"event"
#define ACPI_SYSTEM_FILE_DSDT		"dsdt"
#define ACPI_SYSTEM_FILE_FADT		"fadt"
L
Linus Torvalds 已提交
514

L
Len Brown 已提交
515
static int acpi_system_read_info(struct seq_file *seq, void *offset)
L
Linus Torvalds 已提交
516 517 518
{

	seq_printf(seq, "version:                 %x\n", ACPI_CA_VERSION);
519
	return 0;
L
Linus Torvalds 已提交
520 521 522 523 524 525 526
}

static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, acpi_system_read_info, PDE(inode)->data);
}

527
static const struct file_operations acpi_system_info_ops = {
528
	.owner = THIS_MODULE,
L
Len Brown 已提交
529 530 531 532
	.open = acpi_system_info_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
L
Linus Torvalds 已提交
533 534
};

L
Len Brown 已提交
535 536
static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
				     loff_t *);
L
Linus Torvalds 已提交
537

538
static const struct file_operations acpi_system_dsdt_ops = {
539
	.owner = THIS_MODULE,
L
Len Brown 已提交
540
	.read = acpi_system_read_dsdt,
L
Linus Torvalds 已提交
541 542 543
};

static ssize_t
L
Len Brown 已提交
544 545
acpi_system_read_dsdt(struct file *file,
		      char __user * buffer, size_t count, loff_t * ppos)
L
Linus Torvalds 已提交
546
{
L
Len Brown 已提交
547
	acpi_status status = AE_OK;
548
	struct acpi_table_header *dsdt = NULL;
L
Len Brown 已提交
549
	ssize_t res;
L
Linus Torvalds 已提交
550

551
	status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
L
Linus Torvalds 已提交
552
	if (ACPI_FAILURE(status))
553
		return -ENODEV;
L
Linus Torvalds 已提交
554

555
	res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
L
Linus Torvalds 已提交
556

557
	return res;
L
Linus Torvalds 已提交
558 559
}

L
Len Brown 已提交
560 561
static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
				     loff_t *);
L
Linus Torvalds 已提交
562

563
static const struct file_operations acpi_system_fadt_ops = {
564
	.owner = THIS_MODULE,
L
Len Brown 已提交
565
	.read = acpi_system_read_fadt,
L
Linus Torvalds 已提交
566 567 568
};

static ssize_t
L
Len Brown 已提交
569 570
acpi_system_read_fadt(struct file *file,
		      char __user * buffer, size_t count, loff_t * ppos)
L
Linus Torvalds 已提交
571
{
L
Len Brown 已提交
572
	acpi_status status = AE_OK;
573
	struct acpi_table_header *fadt = NULL;
L
Len Brown 已提交
574
	ssize_t res;
L
Linus Torvalds 已提交
575

576
	status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
L
Linus Torvalds 已提交
577
	if (ACPI_FAILURE(status))
578
		return -ENODEV;
L
Linus Torvalds 已提交
579

580
	res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
L
Linus Torvalds 已提交
581

582
	return res;
L
Linus Torvalds 已提交
583 584
}

585
static int acpi_system_procfs_init(void)
L
Linus Torvalds 已提交
586
{
L
Len Brown 已提交
587
	struct proc_dir_entry *entry;
L
Linus Torvalds 已提交
588 589 590
	int error = 0;

	/* 'info' [R] */
591 592
	entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir,
			    &acpi_system_info_ops);
L
Linus Torvalds 已提交
593 594 595 596
	if (!entry)
		goto Error;

	/* 'dsdt' [R] */
597 598 599
	entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir,
			    &acpi_system_dsdt_ops);
	if (!entry)
L
Linus Torvalds 已提交
600 601 602
		goto Error;

	/* 'fadt' [R] */
603 604 605
	entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir,
			    &acpi_system_fadt_ops);
	if (!entry)
L
Linus Torvalds 已提交
606 607
		goto Error;

L
Len Brown 已提交
608
      Done:
609
	return error;
L
Linus Torvalds 已提交
610

L
Len Brown 已提交
611
      Error:
L
Linus Torvalds 已提交
612 613 614 615 616 617 618
	remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
	remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
	remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);

	error = -EFAULT;
	goto Done;
}
619 620 621 622 623 624 625
#else
static int acpi_system_procfs_init(void)
{
	return 0;
}
#endif

626
int __init acpi_system_init(void)
627
{
628
	int result;
629 630 631 632 633 634 635 636 637

	result = acpi_system_procfs_init();
	if (result)
		return result;

	result = acpi_system_sysfs_init();

	return result;
}