bus.c revision cece92969762b8ed7930d4e23008b76b06411dee
1/*
2 *  acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
3 *
4 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 2 of the License, or (at
11 *  your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful, but
14 *  WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *  General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License along
19 *  with this program; if not, write to the Free Software Foundation, Inc.,
20 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/ioport.h>
28#include <linux/list.h>
29#include <linux/sched.h>
30#include <linux/pm.h>
31#include <linux/pm_legacy.h>
32#include <linux/device.h>
33#include <linux/proc_fs.h>
34#ifdef CONFIG_X86
35#include <asm/mpspec.h>
36#endif
37#include <acpi/acpi_bus.h>
38#include <acpi/acpi_drivers.h>
39
40#define _COMPONENT		ACPI_BUS_COMPONENT
41ACPI_MODULE_NAME("acpi_bus")
42#ifdef	CONFIG_X86
43extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
44#endif
45
46struct fadt_descriptor acpi_fadt;
47EXPORT_SYMBOL(acpi_fadt);
48
49struct acpi_device *acpi_root;
50struct proc_dir_entry *acpi_root_dir;
51EXPORT_SYMBOL(acpi_root_dir);
52
53#define STRUCT_TO_INT(s)	(*((int*)&s))
54
55/* --------------------------------------------------------------------------
56                                Device Management
57   -------------------------------------------------------------------------- */
58
59int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
60{
61	acpi_status status = AE_OK;
62
63	ACPI_FUNCTION_TRACE("acpi_bus_get_device");
64
65	if (!device)
66		return_VALUE(-EINVAL);
67
68	/* TBD: Support fixed-feature devices */
69
70	status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
71	if (ACPI_FAILURE(status) || !*device) {
72		ACPI_EXCEPTION((AE_INFO, status, "No context for object [%p]", handle));
73		return_VALUE(-ENODEV);
74	}
75
76	return_VALUE(0);
77}
78
79EXPORT_SYMBOL(acpi_bus_get_device);
80
81int acpi_bus_get_status(struct acpi_device *device)
82{
83	acpi_status status = AE_OK;
84	unsigned long sta = 0;
85
86	ACPI_FUNCTION_TRACE("acpi_bus_get_status");
87
88	if (!device)
89		return_VALUE(-EINVAL);
90
91	/*
92	 * Evaluate _STA if present.
93	 */
94	if (device->flags.dynamic_status) {
95		status =
96		    acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
97		if (ACPI_FAILURE(status))
98			return_VALUE(-ENODEV);
99		STRUCT_TO_INT(device->status) = (int)sta;
100	}
101
102	/*
103	 * Otherwise we assume the status of our parent (unless we don't
104	 * have one, in which case status is implied).
105	 */
106	else if (device->parent)
107		device->status = device->parent->status;
108	else
109		STRUCT_TO_INT(device->status) = 0x0F;
110
111	if (device->status.functional && !device->status.present) {
112		printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
113		       "functional but not present; setting present\n",
114		       device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
115		device->status.present = 1;
116	}
117
118	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
119			  device->pnp.bus_id,
120			  (u32) STRUCT_TO_INT(device->status)));
121
122	return_VALUE(0);
123}
124
125EXPORT_SYMBOL(acpi_bus_get_status);
126
127/* --------------------------------------------------------------------------
128                                 Power Management
129   -------------------------------------------------------------------------- */
130
131int acpi_bus_get_power(acpi_handle handle, int *state)
132{
133	int result = 0;
134	acpi_status status = 0;
135	struct acpi_device *device = NULL;
136	unsigned long psc = 0;
137
138	ACPI_FUNCTION_TRACE("acpi_bus_get_power");
139
140	result = acpi_bus_get_device(handle, &device);
141	if (result)
142		return_VALUE(result);
143
144	*state = ACPI_STATE_UNKNOWN;
145
146	if (!device->flags.power_manageable) {
147		/* TBD: Non-recursive algorithm for walking up hierarchy */
148		if (device->parent)
149			*state = device->parent->power.state;
150		else
151			*state = ACPI_STATE_D0;
152	} else {
153		/*
154		 * Get the device's power state either directly (via _PSC) or
155		 * indirectly (via power resources).
156		 */
157		if (device->power.flags.explicit_get) {
158			status = acpi_evaluate_integer(device->handle, "_PSC",
159						       NULL, &psc);
160			if (ACPI_FAILURE(status))
161				return_VALUE(-ENODEV);
162			device->power.state = (int)psc;
163		} else if (device->power.flags.power_resources) {
164			result = acpi_power_get_inferred_state(device);
165			if (result)
166				return_VALUE(result);
167		}
168
169		*state = device->power.state;
170	}
171
172	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
173			  device->pnp.bus_id, device->power.state));
174
175	return_VALUE(0);
176}
177
178EXPORT_SYMBOL(acpi_bus_get_power);
179
180int acpi_bus_set_power(acpi_handle handle, int state)
181{
182	int result = 0;
183	acpi_status status = AE_OK;
184	struct acpi_device *device = NULL;
185	char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
186
187	ACPI_FUNCTION_TRACE("acpi_bus_set_power");
188
189	result = acpi_bus_get_device(handle, &device);
190	if (result)
191		return_VALUE(result);
192
193	if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
194		return_VALUE(-EINVAL);
195
196	/* Make sure this is a valid target state */
197
198	if (!device->flags.power_manageable) {
199		printk(KERN_DEBUG "Device `[%s]is not power manageable",
200				device->kobj.name);
201		return_VALUE(-ENODEV);
202	}
203	/*
204	 * Get device's current power state if it's unknown
205	 * This means device power state isn't initialized or previous setting failed
206	 */
207	if (!device->flags.force_power_state) {
208		if (device->power.state == ACPI_STATE_UNKNOWN)
209			acpi_bus_get_power(device->handle, &device->power.state);
210		if (state == device->power.state) {
211			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
212					  state));
213			return_VALUE(0);
214		}
215	}
216	if (!device->power.states[state].flags.valid) {
217		printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
218		return_VALUE(-ENODEV);
219	}
220	if (device->parent && (state < device->parent->power.state)) {
221		printk(KERN_WARNING PREFIX
222			      "Cannot set device to a higher-powered"
223			      " state than parent\n");
224		return_VALUE(-ENODEV);
225	}
226
227	/*
228	 * Transition Power
229	 * ----------------
230	 * On transitions to a high-powered state we first apply power (via
231	 * power resources) then evalute _PSx.  Conversly for transitions to
232	 * a lower-powered state.
233	 */
234	if (state < device->power.state) {
235		if (device->power.flags.power_resources) {
236			result = acpi_power_transition(device, state);
237			if (result)
238				goto end;
239		}
240		if (device->power.states[state].flags.explicit_set) {
241			status = acpi_evaluate_object(device->handle,
242						      object_name, NULL, NULL);
243			if (ACPI_FAILURE(status)) {
244				result = -ENODEV;
245				goto end;
246			}
247		}
248	} else {
249		if (device->power.states[state].flags.explicit_set) {
250			status = acpi_evaluate_object(device->handle,
251						      object_name, NULL, NULL);
252			if (ACPI_FAILURE(status)) {
253				result = -ENODEV;
254				goto end;
255			}
256		}
257		if (device->power.flags.power_resources) {
258			result = acpi_power_transition(device, state);
259			if (result)
260				goto end;
261		}
262	}
263
264      end:
265	if (result)
266		printk(KERN_WARNING PREFIX
267			      "Transitioning device [%s] to D%d\n",
268			      device->pnp.bus_id, state);
269	else
270		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
271				  "Device [%s] transitioned to D%d\n",
272				  device->pnp.bus_id, state));
273
274	return_VALUE(result);
275}
276
277EXPORT_SYMBOL(acpi_bus_set_power);
278
279/* --------------------------------------------------------------------------
280                                Event Management
281   -------------------------------------------------------------------------- */
282
283static DEFINE_SPINLOCK(acpi_bus_event_lock);
284
285LIST_HEAD(acpi_bus_event_list);
286DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
287
288extern int event_is_open;
289
290int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
291{
292	struct acpi_bus_event *event = NULL;
293	unsigned long flags = 0;
294
295	ACPI_FUNCTION_TRACE("acpi_bus_generate_event");
296
297	if (!device)
298		return_VALUE(-EINVAL);
299
300	/* drop event on the floor if no one's listening */
301	if (!event_is_open)
302		return_VALUE(0);
303
304	event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
305	if (!event)
306		return_VALUE(-ENOMEM);
307
308	strcpy(event->device_class, device->pnp.device_class);
309	strcpy(event->bus_id, device->pnp.bus_id);
310	event->type = type;
311	event->data = data;
312
313	spin_lock_irqsave(&acpi_bus_event_lock, flags);
314	list_add_tail(&event->node, &acpi_bus_event_list);
315	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
316
317	wake_up_interruptible(&acpi_bus_event_queue);
318
319	return_VALUE(0);
320}
321
322EXPORT_SYMBOL(acpi_bus_generate_event);
323
324int acpi_bus_receive_event(struct acpi_bus_event *event)
325{
326	unsigned long flags = 0;
327	struct acpi_bus_event *entry = NULL;
328
329	DECLARE_WAITQUEUE(wait, current);
330
331	ACPI_FUNCTION_TRACE("acpi_bus_receive_event");
332
333	if (!event)
334		return_VALUE(-EINVAL);
335
336	if (list_empty(&acpi_bus_event_list)) {
337
338		set_current_state(TASK_INTERRUPTIBLE);
339		add_wait_queue(&acpi_bus_event_queue, &wait);
340
341		if (list_empty(&acpi_bus_event_list))
342			schedule();
343
344		remove_wait_queue(&acpi_bus_event_queue, &wait);
345		set_current_state(TASK_RUNNING);
346
347		if (signal_pending(current))
348			return_VALUE(-ERESTARTSYS);
349	}
350
351	spin_lock_irqsave(&acpi_bus_event_lock, flags);
352	entry =
353	    list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
354	if (entry)
355		list_del(&entry->node);
356	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
357
358	if (!entry)
359		return_VALUE(-ENODEV);
360
361	memcpy(event, entry, sizeof(struct acpi_bus_event));
362
363	kfree(entry);
364
365	return_VALUE(0);
366}
367
368EXPORT_SYMBOL(acpi_bus_receive_event);
369
370/* --------------------------------------------------------------------------
371                             Notification Handling
372   -------------------------------------------------------------------------- */
373
374static int
375acpi_bus_check_device(struct acpi_device *device, int *status_changed)
376{
377	acpi_status status = 0;
378	struct acpi_device_status old_status;
379
380	ACPI_FUNCTION_TRACE("acpi_bus_check_device");
381
382	if (!device)
383		return_VALUE(-EINVAL);
384
385	if (status_changed)
386		*status_changed = 0;
387
388	old_status = device->status;
389
390	/*
391	 * Make sure this device's parent is present before we go about
392	 * messing with the device.
393	 */
394	if (device->parent && !device->parent->status.present) {
395		device->status = device->parent->status;
396		if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) {
397			if (status_changed)
398				*status_changed = 1;
399		}
400		return_VALUE(0);
401	}
402
403	status = acpi_bus_get_status(device);
404	if (ACPI_FAILURE(status))
405		return_VALUE(-ENODEV);
406
407	if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
408		return_VALUE(0);
409
410	if (status_changed)
411		*status_changed = 1;
412
413	/*
414	 * Device Insertion/Removal
415	 */
416	if ((device->status.present) && !(old_status.present)) {
417		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
418		/* TBD: Handle device insertion */
419	} else if (!(device->status.present) && (old_status.present)) {
420		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
421		/* TBD: Handle device removal */
422	}
423
424	return_VALUE(0);
425}
426
427static int acpi_bus_check_scope(struct acpi_device *device)
428{
429	int result = 0;
430	int status_changed = 0;
431
432	ACPI_FUNCTION_TRACE("acpi_bus_check_scope");
433
434	if (!device)
435		return_VALUE(-EINVAL);
436
437	/* Status Change? */
438	result = acpi_bus_check_device(device, &status_changed);
439	if (result)
440		return_VALUE(result);
441
442	if (!status_changed)
443		return_VALUE(0);
444
445	/*
446	 * TBD: Enumerate child devices within this device's scope and
447	 *       run acpi_bus_check_device()'s on them.
448	 */
449
450	return_VALUE(0);
451}
452
453/**
454 * acpi_bus_notify
455 * ---------------
456 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
457 */
458static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
459{
460	int result = 0;
461	struct acpi_device *device = NULL;
462
463	ACPI_FUNCTION_TRACE("acpi_bus_notify");
464
465	if (acpi_bus_get_device(handle, &device))
466		return_VOID;
467
468	switch (type) {
469
470	case ACPI_NOTIFY_BUS_CHECK:
471		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
472				  "Received BUS CHECK notification for device [%s]\n",
473				  device->pnp.bus_id));
474		result = acpi_bus_check_scope(device);
475		/*
476		 * TBD: We'll need to outsource certain events to non-ACPI
477		 *      drivers via the device manager (device.c).
478		 */
479		break;
480
481	case ACPI_NOTIFY_DEVICE_CHECK:
482		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
483				  "Received DEVICE CHECK notification for device [%s]\n",
484				  device->pnp.bus_id));
485		result = acpi_bus_check_device(device, NULL);
486		/*
487		 * TBD: We'll need to outsource certain events to non-ACPI
488		 *      drivers via the device manager (device.c).
489		 */
490		break;
491
492	case ACPI_NOTIFY_DEVICE_WAKE:
493		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
494				  "Received DEVICE WAKE notification for device [%s]\n",
495				  device->pnp.bus_id));
496		/* TBD */
497		break;
498
499	case ACPI_NOTIFY_EJECT_REQUEST:
500		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
501				  "Received EJECT REQUEST notification for device [%s]\n",
502				  device->pnp.bus_id));
503		/* TBD */
504		break;
505
506	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
507		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
508				  "Received DEVICE CHECK LIGHT notification for device [%s]\n",
509				  device->pnp.bus_id));
510		/* TBD: Exactly what does 'light' mean? */
511		break;
512
513	case ACPI_NOTIFY_FREQUENCY_MISMATCH:
514		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
515				  "Received FREQUENCY MISMATCH notification for device [%s]\n",
516				  device->pnp.bus_id));
517		/* TBD */
518		break;
519
520	case ACPI_NOTIFY_BUS_MODE_MISMATCH:
521		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
522				  "Received BUS MODE MISMATCH notification for device [%s]\n",
523				  device->pnp.bus_id));
524		/* TBD */
525		break;
526
527	case ACPI_NOTIFY_POWER_FAULT:
528		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
529				  "Received POWER FAULT notification for device [%s]\n",
530				  device->pnp.bus_id));
531		/* TBD */
532		break;
533
534	default:
535		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
536				  "Received unknown/unsupported notification [%08x]\n",
537				  type));
538		break;
539	}
540
541	return_VOID;
542}
543
544/* --------------------------------------------------------------------------
545                             Initialization/Cleanup
546   -------------------------------------------------------------------------- */
547
548static int __init acpi_bus_init_irq(void)
549{
550	acpi_status status = AE_OK;
551	union acpi_object arg = { ACPI_TYPE_INTEGER };
552	struct acpi_object_list arg_list = { 1, &arg };
553	char *message = NULL;
554
555	ACPI_FUNCTION_TRACE("acpi_bus_init_irq");
556
557	/*
558	 * Let the system know what interrupt model we are using by
559	 * evaluating the \_PIC object, if exists.
560	 */
561
562	switch (acpi_irq_model) {
563	case ACPI_IRQ_MODEL_PIC:
564		message = "PIC";
565		break;
566	case ACPI_IRQ_MODEL_IOAPIC:
567		message = "IOAPIC";
568		break;
569	case ACPI_IRQ_MODEL_IOSAPIC:
570		message = "IOSAPIC";
571		break;
572	default:
573		printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
574		return_VALUE(-ENODEV);
575	}
576
577	printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
578
579	arg.integer.value = acpi_irq_model;
580
581	status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
582	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
583		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
584		return_VALUE(-ENODEV);
585	}
586
587	return_VALUE(0);
588}
589
590void __init acpi_early_init(void)
591{
592	acpi_status status = AE_OK;
593	struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
594
595	ACPI_FUNCTION_TRACE("acpi_early_init");
596
597	if (acpi_disabled)
598		return_VOID;
599
600	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
601
602	/* enable workarounds, unless strict ACPI spec. compliance */
603	if (!acpi_strict)
604		acpi_gbl_enable_interpreter_slack = TRUE;
605
606	status = acpi_initialize_subsystem();
607	if (ACPI_FAILURE(status)) {
608		printk(KERN_ERR PREFIX
609		       "Unable to initialize the ACPI Interpreter\n");
610		goto error0;
611	}
612
613	status = acpi_load_tables();
614	if (ACPI_FAILURE(status)) {
615		printk(KERN_ERR PREFIX
616		       "Unable to load the System Description Tables\n");
617		goto error0;
618	}
619
620	/*
621	 * Get a separate copy of the FADT for use by other drivers.
622	 */
623	status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer);
624	if (ACPI_FAILURE(status)) {
625		printk(KERN_ERR PREFIX "Unable to get the FADT\n");
626		goto error0;
627	}
628#ifdef CONFIG_X86
629	if (!acpi_ioapic) {
630		extern acpi_interrupt_flags acpi_sci_flags;
631
632		/* compatible (0) means level (3) */
633		if (acpi_sci_flags.trigger == 0)
634			acpi_sci_flags.trigger = 3;
635
636		/* Set PIC-mode SCI trigger type */
637		acpi_pic_sci_set_trigger(acpi_fadt.sci_int,
638					 acpi_sci_flags.trigger);
639	} else {
640		extern int acpi_sci_override_gsi;
641		/*
642		 * now that acpi_fadt is initialized,
643		 * update it with result from INT_SRC_OVR parsing
644		 */
645		acpi_fadt.sci_int = acpi_sci_override_gsi;
646	}
647#endif
648
649	status =
650	    acpi_enable_subsystem(~
651				  (ACPI_NO_HARDWARE_INIT |
652				   ACPI_NO_ACPI_ENABLE));
653	if (ACPI_FAILURE(status)) {
654		printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
655		goto error0;
656	}
657
658	return_VOID;
659
660      error0:
661	disable_acpi();
662	return_VOID;
663}
664
665static int __init acpi_bus_init(void)
666{
667	int result = 0;
668	acpi_status status = AE_OK;
669	extern acpi_status acpi_os_initialize1(void);
670
671	ACPI_FUNCTION_TRACE("acpi_bus_init");
672
673	status = acpi_os_initialize1();
674
675	status =
676	    acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
677	if (ACPI_FAILURE(status)) {
678		printk(KERN_ERR PREFIX
679		       "Unable to start the ACPI Interpreter\n");
680		goto error1;
681	}
682
683	if (ACPI_FAILURE(status)) {
684		printk(KERN_ERR PREFIX
685		       "Unable to initialize ACPI OS objects\n");
686		goto error1;
687	}
688#ifdef CONFIG_ACPI_EC
689	/*
690	 * ACPI 2.0 requires the EC driver to be loaded and work before
691	 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
692	 * is called).
693	 *
694	 * This is accomplished by looking for the ECDT table, and getting
695	 * the EC parameters out of that.
696	 */
697	status = acpi_ec_ecdt_probe();
698	/* Ignore result. Not having an ECDT is not fatal. */
699#endif
700
701	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
702	if (ACPI_FAILURE(status)) {
703		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
704		goto error1;
705	}
706
707	printk(KERN_INFO PREFIX "Interpreter enabled\n");
708
709	/*
710	 * Get the system interrupt model and evaluate \_PIC.
711	 */
712	result = acpi_bus_init_irq();
713	if (result)
714		goto error1;
715
716	/*
717	 * Register the for all standard device notifications.
718	 */
719	status =
720	    acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
721					&acpi_bus_notify, NULL);
722	if (ACPI_FAILURE(status)) {
723		printk(KERN_ERR PREFIX
724		       "Unable to register for device notifications\n");
725		goto error1;
726	}
727
728	/*
729	 * Create the top ACPI proc directory
730	 */
731	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
732
733	return_VALUE(0);
734
735	/* Mimic structured exception handling */
736      error1:
737	acpi_terminate();
738	return_VALUE(-ENODEV);
739}
740
741decl_subsys(acpi, NULL, NULL);
742
743static int __init acpi_init(void)
744{
745	int result = 0;
746
747	ACPI_FUNCTION_TRACE("acpi_init");
748
749	if (acpi_disabled) {
750		printk(KERN_INFO PREFIX "Interpreter disabled.\n");
751		return_VALUE(-ENODEV);
752	}
753
754	firmware_register(&acpi_subsys);
755
756	result = acpi_bus_init();
757
758	if (!result) {
759#ifdef CONFIG_PM_LEGACY
760		if (!PM_IS_ACTIVE())
761			pm_active = 1;
762		else {
763			printk(KERN_INFO PREFIX
764			       "APM is already active, exiting\n");
765			disable_acpi();
766			result = -ENODEV;
767		}
768#endif
769	} else
770		disable_acpi();
771
772	return_VALUE(result);
773}
774
775subsys_initcall(acpi_init);
776