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