bus.c revision 9dc130fccb874f2959ef313d7922d306dc6d4f75
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 <linux/pci.h>
39#include <acpi/acpi_bus.h>
40#include <acpi/acpi_drivers.h>
41#include <linux/dmi.h>
42
43#include "internal.h"
44
45#define _COMPONENT		ACPI_BUS_COMPONENT
46ACPI_MODULE_NAME("bus");
47
48struct acpi_device *acpi_root;
49struct proc_dir_entry *acpi_root_dir;
50EXPORT_SYMBOL(acpi_root_dir);
51
52#define STRUCT_TO_INT(s)	(*((int*)&s))
53
54static int set_power_nocheck(const struct dmi_system_id *id)
55{
56	printk(KERN_NOTICE PREFIX "%s detected - "
57		"disable power check in power transistion\n", id->ident);
58	acpi_power_nocheck = 1;
59	return 0;
60}
61static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
62	{
63	set_power_nocheck, "HP Pavilion 05", {
64	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
65	DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
66	DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
67	{},
68};
69
70
71/* --------------------------------------------------------------------------
72                                Device Management
73   -------------------------------------------------------------------------- */
74
75int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
76{
77	acpi_status status = AE_OK;
78
79
80	if (!device)
81		return -EINVAL;
82
83	/* TBD: Support fixed-feature devices */
84
85	status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
86	if (ACPI_FAILURE(status) || !*device) {
87		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
88				  handle));
89		return -ENODEV;
90	}
91
92	return 0;
93}
94
95EXPORT_SYMBOL(acpi_bus_get_device);
96
97acpi_status acpi_bus_get_status_handle(acpi_handle handle,
98				       unsigned long long *sta)
99{
100	acpi_status status;
101
102	status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
103	if (ACPI_SUCCESS(status))
104		return AE_OK;
105
106	if (status == AE_NOT_FOUND) {
107		*sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
108		       ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
109		return AE_OK;
110	}
111	return status;
112}
113
114int acpi_bus_get_status(struct acpi_device *device)
115{
116	acpi_status status;
117	unsigned long long sta;
118
119	status = acpi_bus_get_status_handle(device->handle, &sta);
120	if (ACPI_FAILURE(status))
121		return -ENODEV;
122
123	STRUCT_TO_INT(device->status) = (int) sta;
124
125	if (device->status.functional && !device->status.present) {
126		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
127		       "functional but not present;\n",
128			device->pnp.bus_id,
129			(u32) STRUCT_TO_INT(device->status)));
130	}
131
132	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
133			  device->pnp.bus_id,
134			  (u32) STRUCT_TO_INT(device->status)));
135	return 0;
136}
137EXPORT_SYMBOL(acpi_bus_get_status);
138
139void acpi_bus_private_data_handler(acpi_handle handle,
140				   void *context)
141{
142	return;
143}
144EXPORT_SYMBOL(acpi_bus_private_data_handler);
145
146int acpi_bus_get_private_data(acpi_handle handle, void **data)
147{
148	acpi_status status = AE_OK;
149
150	if (!*data)
151		return -EINVAL;
152
153	status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
154	if (ACPI_FAILURE(status) || !*data) {
155		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
156				handle));
157		return -ENODEV;
158	}
159
160	return 0;
161}
162EXPORT_SYMBOL(acpi_bus_get_private_data);
163
164/* --------------------------------------------------------------------------
165                                 Power Management
166   -------------------------------------------------------------------------- */
167
168int acpi_bus_get_power(acpi_handle handle, int *state)
169{
170	int result = 0;
171	acpi_status status = 0;
172	struct acpi_device *device = NULL;
173	unsigned long long psc = 0;
174
175
176	result = acpi_bus_get_device(handle, &device);
177	if (result)
178		return result;
179
180	*state = ACPI_STATE_UNKNOWN;
181
182	if (!device->flags.power_manageable) {
183		/* TBD: Non-recursive algorithm for walking up hierarchy */
184		if (device->parent)
185			*state = device->parent->power.state;
186		else
187			*state = ACPI_STATE_D0;
188	} else {
189		/*
190		 * Get the device's power state either directly (via _PSC) or
191		 * indirectly (via power resources).
192		 */
193		if (device->power.flags.explicit_get) {
194			status = acpi_evaluate_integer(device->handle, "_PSC",
195						       NULL, &psc);
196			if (ACPI_FAILURE(status))
197				return -ENODEV;
198			device->power.state = (int)psc;
199		} else if (device->power.flags.power_resources) {
200			result = acpi_power_get_inferred_state(device);
201			if (result)
202				return result;
203		}
204
205		*state = device->power.state;
206	}
207
208	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
209			  device->pnp.bus_id, device->power.state));
210
211	return 0;
212}
213
214EXPORT_SYMBOL(acpi_bus_get_power);
215
216int acpi_bus_set_power(acpi_handle handle, int state)
217{
218	int result = 0;
219	acpi_status status = AE_OK;
220	struct acpi_device *device = NULL;
221	char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
222
223
224	result = acpi_bus_get_device(handle, &device);
225	if (result)
226		return result;
227
228	if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
229		return -EINVAL;
230
231	/* Make sure this is a valid target state */
232
233	if (!device->flags.power_manageable) {
234		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
235				kobject_name(&device->dev.kobj)));
236		return -ENODEV;
237	}
238	/*
239	 * Get device's current power state
240	 */
241	if (!acpi_power_nocheck) {
242		/*
243		 * Maybe the incorrect power state is returned on the bogus
244		 * bios, which is different with the real power state.
245		 * For example: the bios returns D0 state and the real power
246		 * state is D3. OS expects to set the device to D0 state. In
247		 * such case if OS uses the power state returned by the BIOS,
248		 * the device can't be transisted to the correct power state.
249		 * So if the acpi_power_nocheck is set, it is unnecessary to
250		 * get the power state by calling acpi_bus_get_power.
251		 */
252		acpi_bus_get_power(device->handle, &device->power.state);
253	}
254	if ((state == device->power.state) && !device->flags.force_power_state) {
255		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
256				  state));
257		return 0;
258	}
259
260	if (!device->power.states[state].flags.valid) {
261		printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
262		return -ENODEV;
263	}
264	if (device->parent && (state < device->parent->power.state)) {
265		printk(KERN_WARNING PREFIX
266			      "Cannot set device to a higher-powered"
267			      " state than parent\n");
268		return -ENODEV;
269	}
270
271	/*
272	 * Transition Power
273	 * ----------------
274	 * On transitions to a high-powered state we first apply power (via
275	 * power resources) then evalute _PSx.  Conversly for transitions to
276	 * a lower-powered state.
277	 */
278	if (state < device->power.state) {
279		if (device->power.flags.power_resources) {
280			result = acpi_power_transition(device, state);
281			if (result)
282				goto end;
283		}
284		if (device->power.states[state].flags.explicit_set) {
285			status = acpi_evaluate_object(device->handle,
286						      object_name, NULL, NULL);
287			if (ACPI_FAILURE(status)) {
288				result = -ENODEV;
289				goto end;
290			}
291		}
292	} else {
293		if (device->power.states[state].flags.explicit_set) {
294			status = acpi_evaluate_object(device->handle,
295						      object_name, NULL, NULL);
296			if (ACPI_FAILURE(status)) {
297				result = -ENODEV;
298				goto end;
299			}
300		}
301		if (device->power.flags.power_resources) {
302			result = acpi_power_transition(device, state);
303			if (result)
304				goto end;
305		}
306	}
307
308      end:
309	if (result)
310		printk(KERN_WARNING PREFIX
311			      "Device [%s] failed to transition to D%d\n",
312			      device->pnp.bus_id, state);
313	else {
314		device->power.state = state;
315		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
316				  "Device [%s] transitioned to D%d\n",
317				  device->pnp.bus_id, state));
318	}
319
320	return result;
321}
322
323EXPORT_SYMBOL(acpi_bus_set_power);
324
325bool acpi_bus_power_manageable(acpi_handle handle)
326{
327	struct acpi_device *device;
328	int result;
329
330	result = acpi_bus_get_device(handle, &device);
331	return result ? false : device->flags.power_manageable;
332}
333
334EXPORT_SYMBOL(acpi_bus_power_manageable);
335
336bool acpi_bus_can_wakeup(acpi_handle handle)
337{
338	struct acpi_device *device;
339	int result;
340
341	result = acpi_bus_get_device(handle, &device);
342	return result ? false : device->wakeup.flags.valid;
343}
344
345EXPORT_SYMBOL(acpi_bus_can_wakeup);
346
347static void acpi_print_osc_error(acpi_handle handle,
348	struct acpi_osc_context *context, char *error)
349{
350	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER};
351	int i;
352
353	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))
354		printk(KERN_DEBUG "%s\n", error);
355	else {
356		printk(KERN_DEBUG "%s:%s\n", (char *)buffer.pointer, error);
357		kfree(buffer.pointer);
358	}
359	printk(KERN_DEBUG"_OSC request data:");
360	for (i = 0; i < context->cap.length; i += sizeof(u32))
361		printk("%x ", *((u32 *)(context->cap.pointer + i)));
362	printk("\n");
363}
364
365static u8 hex_val(unsigned char c)
366{
367	return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
368}
369
370static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
371{
372	int i;
373	static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
374		24, 26, 28, 30, 32, 34};
375
376	if (strlen(str) != 36)
377		return AE_BAD_PARAMETER;
378	for (i = 0; i < 36; i++) {
379		if (i == 8 || i == 13 || i == 18 || i == 23) {
380			if (str[i] != '-')
381				return AE_BAD_PARAMETER;
382		} else if (!isxdigit(str[i]))
383			return AE_BAD_PARAMETER;
384	}
385	for (i = 0; i < 16; i++) {
386		uuid[i] = hex_val(str[opc_map_to_uuid[i]]) << 4;
387		uuid[i] |= hex_val(str[opc_map_to_uuid[i] + 1]);
388	}
389	return AE_OK;
390}
391
392acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
393{
394	acpi_status status;
395	struct acpi_object_list input;
396	union acpi_object in_params[4];
397	union acpi_object *out_obj;
398	u8 uuid[16];
399	u32 errors;
400	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
401
402	if (!context)
403		return AE_ERROR;
404	if (ACPI_FAILURE(acpi_str_to_uuid(context->uuid_str, uuid)))
405		return AE_ERROR;
406	context->ret.length = ACPI_ALLOCATE_BUFFER;
407	context->ret.pointer = NULL;
408
409	/* Setting up input parameters */
410	input.count = 4;
411	input.pointer = in_params;
412	in_params[0].type 		= ACPI_TYPE_BUFFER;
413	in_params[0].buffer.length 	= 16;
414	in_params[0].buffer.pointer	= uuid;
415	in_params[1].type 		= ACPI_TYPE_INTEGER;
416	in_params[1].integer.value 	= context->rev;
417	in_params[2].type 		= ACPI_TYPE_INTEGER;
418	in_params[2].integer.value	= context->cap.length/sizeof(u32);
419	in_params[3].type		= ACPI_TYPE_BUFFER;
420	in_params[3].buffer.length 	= context->cap.length;
421	in_params[3].buffer.pointer 	= context->cap.pointer;
422
423	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
424	if (ACPI_FAILURE(status))
425		return status;
426
427	if (!output.length)
428		return AE_NULL_OBJECT;
429
430	out_obj = output.pointer;
431	if (out_obj->type != ACPI_TYPE_BUFFER
432		|| out_obj->buffer.length != context->cap.length) {
433		acpi_print_osc_error(handle, context,
434			"_OSC evaluation returned wrong type");
435		status = AE_TYPE;
436		goto out_kfree;
437	}
438	/* Need to ignore the bit0 in result code */
439	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
440	if (errors) {
441		if (errors & OSC_REQUEST_ERROR)
442			acpi_print_osc_error(handle, context,
443				"_OSC request failed");
444		if (errors & OSC_INVALID_UUID_ERROR)
445			acpi_print_osc_error(handle, context,
446				"_OSC invalid UUID");
447		if (errors & OSC_INVALID_REVISION_ERROR)
448			acpi_print_osc_error(handle, context,
449				"_OSC invalid revision");
450		if (errors & OSC_CAPABILITIES_MASK_ERROR) {
451			if (((u32 *)context->cap.pointer)[OSC_QUERY_TYPE]
452			    & OSC_QUERY_ENABLE)
453				goto out_success;
454			status = AE_SUPPORT;
455			goto out_kfree;
456		}
457		status = AE_ERROR;
458		goto out_kfree;
459	}
460out_success:
461	context->ret.length = out_obj->buffer.length;
462	context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL);
463	if (!context->ret.pointer) {
464		status =  AE_NO_MEMORY;
465		goto out_kfree;
466	}
467	memcpy(context->ret.pointer, out_obj->buffer.pointer,
468		context->ret.length);
469	status =  AE_OK;
470
471out_kfree:
472	kfree(output.pointer);
473	if (status != AE_OK)
474		context->ret.pointer = NULL;
475	return status;
476}
477EXPORT_SYMBOL(acpi_run_osc);
478
479static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
480static void acpi_bus_osc_support(void)
481{
482	u32 capbuf[2];
483	struct acpi_osc_context context = {
484		.uuid_str = sb_uuid_str,
485		.rev = 1,
486		.cap.length = 8,
487		.cap.pointer = capbuf,
488	};
489	acpi_handle handle;
490
491	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
492	capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
493#ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
494	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
495#endif
496	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
497		return;
498	if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
499		kfree(context.ret.pointer);
500	/* do we need to check the returned cap? Sounds no */
501}
502
503/* --------------------------------------------------------------------------
504                                Event Management
505   -------------------------------------------------------------------------- */
506
507#ifdef CONFIG_ACPI_PROC_EVENT
508static DEFINE_SPINLOCK(acpi_bus_event_lock);
509
510LIST_HEAD(acpi_bus_event_list);
511DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
512
513extern int event_is_open;
514
515int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
516{
517	struct acpi_bus_event *event;
518	unsigned long flags = 0;
519
520	/* drop event on the floor if no one's listening */
521	if (!event_is_open)
522		return 0;
523
524	event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
525	if (!event)
526		return -ENOMEM;
527
528	strcpy(event->device_class, device_class);
529	strcpy(event->bus_id, bus_id);
530	event->type = type;
531	event->data = data;
532
533	spin_lock_irqsave(&acpi_bus_event_lock, flags);
534	list_add_tail(&event->node, &acpi_bus_event_list);
535	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
536
537	wake_up_interruptible(&acpi_bus_event_queue);
538
539	return 0;
540
541}
542
543EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
544
545int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
546{
547	if (!device)
548		return -EINVAL;
549	return acpi_bus_generate_proc_event4(device->pnp.device_class,
550					     device->pnp.bus_id, type, data);
551}
552
553EXPORT_SYMBOL(acpi_bus_generate_proc_event);
554
555int acpi_bus_receive_event(struct acpi_bus_event *event)
556{
557	unsigned long flags = 0;
558	struct acpi_bus_event *entry = NULL;
559
560	DECLARE_WAITQUEUE(wait, current);
561
562
563	if (!event)
564		return -EINVAL;
565
566	if (list_empty(&acpi_bus_event_list)) {
567
568		set_current_state(TASK_INTERRUPTIBLE);
569		add_wait_queue(&acpi_bus_event_queue, &wait);
570
571		if (list_empty(&acpi_bus_event_list))
572			schedule();
573
574		remove_wait_queue(&acpi_bus_event_queue, &wait);
575		set_current_state(TASK_RUNNING);
576
577		if (signal_pending(current))
578			return -ERESTARTSYS;
579	}
580
581	spin_lock_irqsave(&acpi_bus_event_lock, flags);
582	if (!list_empty(&acpi_bus_event_list)) {
583		entry = list_entry(acpi_bus_event_list.next,
584				   struct acpi_bus_event, node);
585		list_del(&entry->node);
586	}
587	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
588
589	if (!entry)
590		return -ENODEV;
591
592	memcpy(event, entry, sizeof(struct acpi_bus_event));
593
594	kfree(entry);
595
596	return 0;
597}
598
599#endif	/* CONFIG_ACPI_PROC_EVENT */
600
601/* --------------------------------------------------------------------------
602                             Notification Handling
603   -------------------------------------------------------------------------- */
604
605static void acpi_bus_check_device(acpi_handle handle)
606{
607	struct acpi_device *device;
608	acpi_status status;
609	struct acpi_device_status old_status;
610
611	if (acpi_bus_get_device(handle, &device))
612		return;
613	if (!device)
614		return;
615
616	old_status = device->status;
617
618	/*
619	 * Make sure this device's parent is present before we go about
620	 * messing with the device.
621	 */
622	if (device->parent && !device->parent->status.present) {
623		device->status = device->parent->status;
624		return;
625	}
626
627	status = acpi_bus_get_status(device);
628	if (ACPI_FAILURE(status))
629		return;
630
631	if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
632		return;
633
634	/*
635	 * Device Insertion/Removal
636	 */
637	if ((device->status.present) && !(old_status.present)) {
638		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
639		/* TBD: Handle device insertion */
640	} else if (!(device->status.present) && (old_status.present)) {
641		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
642		/* TBD: Handle device removal */
643	}
644}
645
646static void acpi_bus_check_scope(acpi_handle handle)
647{
648	/* Status Change? */
649	acpi_bus_check_device(handle);
650
651	/*
652	 * TBD: Enumerate child devices within this device's scope and
653	 *       run acpi_bus_check_device()'s on them.
654	 */
655}
656
657static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
658int register_acpi_bus_notifier(struct notifier_block *nb)
659{
660	return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
661}
662EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
663
664void unregister_acpi_bus_notifier(struct notifier_block *nb)
665{
666	blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
667}
668EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
669
670/**
671 * acpi_bus_notify
672 * ---------------
673 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
674 */
675static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
676{
677	struct acpi_device *device = NULL;
678	struct acpi_driver *driver;
679
680	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n",
681			  type, handle));
682
683	blocking_notifier_call_chain(&acpi_bus_notify_list,
684		type, (void *)handle);
685
686	switch (type) {
687
688	case ACPI_NOTIFY_BUS_CHECK:
689		acpi_bus_check_scope(handle);
690		/*
691		 * TBD: We'll need to outsource certain events to non-ACPI
692		 *      drivers via the device manager (device.c).
693		 */
694		break;
695
696	case ACPI_NOTIFY_DEVICE_CHECK:
697		acpi_bus_check_device(handle);
698		/*
699		 * TBD: We'll need to outsource certain events to non-ACPI
700		 *      drivers via the device manager (device.c).
701		 */
702		break;
703
704	case ACPI_NOTIFY_DEVICE_WAKE:
705		/* TBD */
706		break;
707
708	case ACPI_NOTIFY_EJECT_REQUEST:
709		/* TBD */
710		break;
711
712	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
713		/* TBD: Exactly what does 'light' mean? */
714		break;
715
716	case ACPI_NOTIFY_FREQUENCY_MISMATCH:
717		/* TBD */
718		break;
719
720	case ACPI_NOTIFY_BUS_MODE_MISMATCH:
721		/* TBD */
722		break;
723
724	case ACPI_NOTIFY_POWER_FAULT:
725		/* TBD */
726		break;
727
728	default:
729		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
730				  "Received unknown/unsupported notification [%08x]\n",
731				  type));
732		break;
733	}
734
735	acpi_bus_get_device(handle, &device);
736	if (device) {
737		driver = device->driver;
738		if (driver && driver->ops.notify &&
739		    (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
740			driver->ops.notify(device, type);
741	}
742}
743
744/* --------------------------------------------------------------------------
745                             Initialization/Cleanup
746   -------------------------------------------------------------------------- */
747
748static int __init acpi_bus_init_irq(void)
749{
750	acpi_status status = AE_OK;
751	union acpi_object arg = { ACPI_TYPE_INTEGER };
752	struct acpi_object_list arg_list = { 1, &arg };
753	char *message = NULL;
754
755
756	/*
757	 * Let the system know what interrupt model we are using by
758	 * evaluating the \_PIC object, if exists.
759	 */
760
761	switch (acpi_irq_model) {
762	case ACPI_IRQ_MODEL_PIC:
763		message = "PIC";
764		break;
765	case ACPI_IRQ_MODEL_IOAPIC:
766		message = "IOAPIC";
767		break;
768	case ACPI_IRQ_MODEL_IOSAPIC:
769		message = "IOSAPIC";
770		break;
771	case ACPI_IRQ_MODEL_PLATFORM:
772		message = "platform specific model";
773		break;
774	default:
775		printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
776		return -ENODEV;
777	}
778
779	printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
780
781	arg.integer.value = acpi_irq_model;
782
783	status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
784	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
785		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
786		return -ENODEV;
787	}
788
789	return 0;
790}
791
792u8 acpi_gbl_permanent_mmap;
793
794
795void __init acpi_early_init(void)
796{
797	acpi_status status = AE_OK;
798
799	if (acpi_disabled)
800		return;
801
802	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
803
804	/* enable workarounds, unless strict ACPI spec. compliance */
805	if (!acpi_strict)
806		acpi_gbl_enable_interpreter_slack = TRUE;
807
808	acpi_gbl_permanent_mmap = 1;
809
810	status = acpi_reallocate_root_table();
811	if (ACPI_FAILURE(status)) {
812		printk(KERN_ERR PREFIX
813		       "Unable to reallocate ACPI tables\n");
814		goto error0;
815	}
816
817	status = acpi_initialize_subsystem();
818	if (ACPI_FAILURE(status)) {
819		printk(KERN_ERR PREFIX
820		       "Unable to initialize the ACPI Interpreter\n");
821		goto error0;
822	}
823
824	status = acpi_load_tables();
825	if (ACPI_FAILURE(status)) {
826		printk(KERN_ERR PREFIX
827		       "Unable to load the System Description Tables\n");
828		goto error0;
829	}
830
831#ifdef CONFIG_X86
832	if (!acpi_ioapic) {
833		/* compatible (0) means level (3) */
834		if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
835			acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
836			acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
837		}
838		/* Set PIC-mode SCI trigger type */
839		acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
840					 (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
841	} else {
842		/*
843		 * now that acpi_gbl_FADT is initialized,
844		 * update it with result from INT_SRC_OVR parsing
845		 */
846		acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
847	}
848#endif
849
850	status =
851	    acpi_enable_subsystem(~
852				  (ACPI_NO_HARDWARE_INIT |
853				   ACPI_NO_ACPI_ENABLE));
854	if (ACPI_FAILURE(status)) {
855		printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
856		goto error0;
857	}
858
859	return;
860
861      error0:
862	disable_acpi();
863	return;
864}
865
866static int __init acpi_bus_init(void)
867{
868	int result = 0;
869	acpi_status status = AE_OK;
870	extern acpi_status acpi_os_initialize1(void);
871
872	acpi_os_initialize1();
873
874	status =
875	    acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
876	if (ACPI_FAILURE(status)) {
877		printk(KERN_ERR PREFIX
878		       "Unable to start the ACPI Interpreter\n");
879		goto error1;
880	}
881
882	/*
883	 * ACPI 2.0 requires the EC driver to be loaded and work before
884	 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
885	 * is called).
886	 *
887	 * This is accomplished by looking for the ECDT table, and getting
888	 * the EC parameters out of that.
889	 */
890	status = acpi_ec_ecdt_probe();
891	/* Ignore result. Not having an ECDT is not fatal. */
892
893	acpi_bus_osc_support();
894
895	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
896	if (ACPI_FAILURE(status)) {
897		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
898		goto error1;
899	}
900
901	/*
902	 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
903	 * is necessary to enable it as early as possible.
904	 */
905	acpi_boot_ec_enable();
906
907	printk(KERN_INFO PREFIX "Interpreter enabled\n");
908
909	/* Initialize sleep structures */
910	acpi_sleep_init();
911
912	/*
913	 * Get the system interrupt model and evaluate \_PIC.
914	 */
915	result = acpi_bus_init_irq();
916	if (result)
917		goto error1;
918
919	/*
920	 * Register the for all standard device notifications.
921	 */
922	status =
923	    acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
924					&acpi_bus_notify, NULL);
925	if (ACPI_FAILURE(status)) {
926		printk(KERN_ERR PREFIX
927		       "Unable to register for device notifications\n");
928		goto error1;
929	}
930
931	/*
932	 * Create the top ACPI proc directory
933	 */
934	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
935
936	return 0;
937
938	/* Mimic structured exception handling */
939      error1:
940	acpi_terminate();
941	return -ENODEV;
942}
943
944struct kobject *acpi_kobj;
945
946static int __init acpi_init(void)
947{
948	int result = 0;
949
950
951	if (acpi_disabled) {
952		printk(KERN_INFO PREFIX "Interpreter disabled.\n");
953		return -ENODEV;
954	}
955
956	acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
957	if (!acpi_kobj) {
958		printk(KERN_WARNING "%s: kset create error\n", __func__);
959		acpi_kobj = NULL;
960	}
961
962	init_acpi_device_notify();
963	result = acpi_bus_init();
964
965	if (!result) {
966		pci_mmcfg_late_init();
967		if (!(pm_flags & PM_APM))
968			pm_flags |= PM_ACPI;
969		else {
970			printk(KERN_INFO PREFIX
971			       "APM is already active, exiting\n");
972			disable_acpi();
973			result = -ENODEV;
974		}
975	} else
976		disable_acpi();
977
978	if (acpi_disabled)
979		return result;
980
981	/*
982	 * If the laptop falls into the DMI check table, the power state check
983	 * will be disabled in the course of device power transistion.
984	 */
985	dmi_check_system(power_nocheck_dmi_table);
986
987	acpi_scan_init();
988	acpi_ec_init();
989	acpi_power_init();
990	acpi_system_init();
991	acpi_debug_init();
992	acpi_sleep_proc_init();
993	acpi_wakeup_device_init();
994	return result;
995}
996
997subsys_initcall(acpi_init);
998