system.c 15.8 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 28
/*
 *  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>
#include <linux/init.h>
29
#include <linux/string.h>
L
Linus Torvalds 已提交
30 31 32 33 34
#include <asm/uaccess.h>

#include <acpi/acpi_drivers.h>

#define _COMPONENT		ACPI_SYSTEM_COMPONENT
35
ACPI_MODULE_NAME("system");
Z
Zhang Rui 已提交
36

L
Linus Torvalds 已提交
37 38 39
#define ACPI_SYSTEM_CLASS		"system"
#define ACPI_SYSTEM_DEVICE_NAME		"System"

40
u32 acpi_irq_handled;
41
u32 acpi_irq_not_handled;
42

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

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

	return result;
}

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

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

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;
79 80 81 82 83 84
	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);
85 86

	status =
87
	    acpi_get_table(name, table_attr->instance,
88 89 90 91
			   &table_header);
	if (ACPI_FAILURE(status))
		return -ENODEV;

92 93
	return memory_read_from_buffer(buf, count, &offset,
					table_header, table_header->length);
94 95 96 97 98 99 100 101
}

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;

102 103 104 105 106
	if (table_header->signature[0] != '\0')
		memcpy(table_attr->name, table_header->signature,
			ACPI_NAME_SIZE);
	else
		memcpy(table_attr->name, "NULL", 4);
107 108

	list_for_each_entry(attr, &acpi_table_attr_list, node) {
109
		if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
110 111 112 113 114 115
			if (table_attr->instance < attr->instance)
				table_attr->instance = attr->instance;
	}
	table_attr->instance++;

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

	table_attr->attr.size = 0;
	table_attr->attr.read = acpi_table_show;
	table_attr->attr.attr.name = table_attr->name;
	table_attr->attr.attr.mode = 0444;

	return;
}

129 130 131 132 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
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;
}

163 164 165 166 167 168 169
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;

170 171
	tables_kobj = kobject_create_and_add("tables", acpi_kobj);
	if (!tables_kobj)
172 173 174 175 176
		goto err;

	dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
	if (!dynamic_tables_kobj)
		goto err_dynamic_tables;
177 178 179 180 181 182 183 184 185 186 187 188 189

	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 =
190
			    sysfs_create_bin_file(tables_kobj,
191 192 193 194 195 196 197 198 199
						  &table_attr->attr);
			if (result) {
				kfree(table_attr);
				return result;
			} else
				list_add_tail(&table_attr->node,
					      &acpi_table_attr_list);
		}
	} while (!result);
200
	kobject_uevent(tables_kobj, KOBJ_ADD);
201 202 203 204 205 206 207 208
	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;
209 210
}

211 212 213 214 215 216 217
/*
 * 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 */
218 219 220
#define COUNT_SCI_NOT 2	/* acpi_irq_not_handled */
#define COUNT_ERROR 3	/* other */
#define NUM_COUNTERS_EXTRA 4
221

222 223 224 225 226 227
struct event_counter {
	u32 count;
	u32 flags;
};

static struct event_counter *all_counters;
228 229 230 231 232 233 234 235 236 237 238 239
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)
{
240
	struct event_counter *tmp = all_counters;
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265

	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)
266
		all_counters[gpe_number].count++;
267
	else
268 269
		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
					count++;
270 271 272 273 274 275 276 277 278 279

	return;
}

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

	if (event_number < ACPI_NUM_FIXED_EVENTS)
280
		all_counters[num_gpes + event_number].count++;
281
	else
282 283
		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
				count++;
284 285 286 287

	return;
}

288 289 290 291 292 293 294 295
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) {
296
		result = acpi_get_gpe_device(index, handle);
297 298 299 300 301 302 303 304 305 306 307 308 309 310
		if (result) {
			ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
				"Invalid GPE 0x%x\n", index));
			goto end;
		}
		result = acpi_get_gpe_status(*handle, index,
						ACPI_NOT_ISR, status);
	} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
		result = acpi_get_event_status(index - num_gpes, status);

end:
	return result;
}

311 312 313
static ssize_t counter_show(struct kobject *kobj,
	struct kobj_attribute *attr, char *buf)
{
314 315 316 317 318 319 320
	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 =
321
		acpi_irq_handled;
322 323
	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
		acpi_irq_not_handled;
324
	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
325 326
		acpi_gpe_count;

327 328 329 330 331 332 333 334 335 336
	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;

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

end:
	size += sprintf(buf + size, "\n");
	return result ? result : size;
349 350 351 352 353
}

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

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

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

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

385 386 387
	if (index < num_gpes) {
		if (!strcmp(buf, "disable\n") &&
				(status & ACPI_EVENT_FLAG_ENABLED))
388
			result = acpi_disable_gpe(handle, index);
389 390
		else if (!strcmp(buf, "enable\n") &&
				!(status & ACPI_EVENT_FLAG_ENABLED))
391
			result = acpi_enable_gpe(handle, index);
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
		else if (!strcmp(buf, "clear\n") &&
				(status & ACPI_EVENT_FLAG_SET))
			result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
		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);
410
	} else
411
		all_counters[index].count = strtoul(buf, NULL, 0);
412

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

void acpi_irq_stats_init(void)
{
	int i;

	if (all_counters)
		return;

426
	num_gpes = acpi_current_gpe_count;
427 428 429 430 431 432 433
	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;

434 435
	all_counters = kzalloc(sizeof(struct event_counter) * (num_counters),
				GFP_KERNEL);
436 437 438 439 440 441 442 443 444
	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) {
445
		char buffer[12];
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
		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");
464 465
		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT)
			sprintf(buffer, "sci_not");
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
		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);

		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 已提交
485 486
	if (!sysfs_create_group(acpi_kobj, &interrupt_stats_attr_group))
		return;
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

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 已提交
502 503 504
/* --------------------------------------------------------------------------
                              FS Interface (/proc)
   -------------------------------------------------------------------------- */
Z
Zhang Rui 已提交
505
#ifdef CONFIG_ACPI_PROCFS
506 507 508 509
#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 已提交
510

L
Len Brown 已提交
511
static int acpi_system_read_info(struct seq_file *seq, void *offset)
L
Linus Torvalds 已提交
512 513 514
{

	seq_printf(seq, "version:                 %x\n", ACPI_CA_VERSION);
515
	return 0;
L
Linus Torvalds 已提交
516 517 518 519 520 521 522
}

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

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

L
Len Brown 已提交
531 532
static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
				     loff_t *);
L
Linus Torvalds 已提交
533

534
static const struct file_operations acpi_system_dsdt_ops = {
535
	.owner = THIS_MODULE,
L
Len Brown 已提交
536
	.read = acpi_system_read_dsdt,
L
Linus Torvalds 已提交
537 538 539
};

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

547
	status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
L
Linus Torvalds 已提交
548
	if (ACPI_FAILURE(status))
549
		return -ENODEV;
L
Linus Torvalds 已提交
550

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

553
	return res;
L
Linus Torvalds 已提交
554 555
}

L
Len Brown 已提交
556 557
static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
				     loff_t *);
L
Linus Torvalds 已提交
558

559
static const struct file_operations acpi_system_fadt_ops = {
560
	.owner = THIS_MODULE,
L
Len Brown 已提交
561
	.read = acpi_system_read_fadt,
L
Linus Torvalds 已提交
562 563 564
};

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

572
	status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
L
Linus Torvalds 已提交
573
	if (ACPI_FAILURE(status))
574
		return -ENODEV;
L
Linus Torvalds 已提交
575

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

578
	return res;
L
Linus Torvalds 已提交
579 580
}

581
static int acpi_system_procfs_init(void)
L
Linus Torvalds 已提交
582
{
L
Len Brown 已提交
583
	struct proc_dir_entry *entry;
L
Linus Torvalds 已提交
584 585 586
	int error = 0;

	/* 'info' [R] */
587 588
	entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir,
			    &acpi_system_info_ops);
L
Linus Torvalds 已提交
589 590 591 592
	if (!entry)
		goto Error;

	/* 'dsdt' [R] */
593 594 595
	entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir,
			    &acpi_system_dsdt_ops);
	if (!entry)
L
Linus Torvalds 已提交
596 597 598
		goto Error;

	/* 'fadt' [R] */
599 600 601
	entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir,
			    &acpi_system_fadt_ops);
	if (!entry)
L
Linus Torvalds 已提交
602 603
		goto Error;

L
Len Brown 已提交
604
      Done:
605
	return error;
L
Linus Torvalds 已提交
606

L
Len Brown 已提交
607
      Error:
L
Linus Torvalds 已提交
608 609 610 611 612 613 614
	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;
}
615 616 617 618 619 620 621
#else
static int acpi_system_procfs_init(void)
{
	return 0;
}
#endif

622
int __init acpi_system_init(void)
623
{
624
	int result;
625 626 627 628 629 630 631 632 633

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

	result = acpi_system_sysfs_init();

	return result;
}