2 * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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.
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.
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 * Modified for ReactOS and latest ACPICA
27 * Copyright (C)2009 Samuel Serapion
35 #define _COMPONENT ACPI_BUS_COMPONENT
36 ACPI_MODULE_NAME ("acpi_bus")
41 #define STRUCT_TO_INT(s) (*((int*)&s))
42 #define HAS_CHILDREN(d) ((d)->children.next != &((d)->children))
43 #define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children))
44 #define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node))
47 extern void acpi_pic_sci_set_trigger(unsigned int irq
, UINT16 trigger
);
49 typedef int (*acpi_bus_walk_callback
)(struct acpi_device
*, int, void*);
51 struct acpi_device
*acpi_root
;
52 KSPIN_LOCK acpi_bus_event_lock
;
53 LIST_HEAD(acpi_bus_event_list
);
54 //DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
55 KEVENT AcpiEventQueue
;
58 int ProcessorCount
, PowerDeviceCount
, PowerButtonCount
, FixedPowerButtonCount
;
59 int FixedSleepButtonCount
, SleepButtonCount
, ThermalZoneCount
;
62 acpi_device_register (
63 struct acpi_device
*device
,
64 struct acpi_device
*parent
)
69 return_VALUE(AE_BAD_PARAMETER
);
76 acpi_device_unregister (
77 struct acpi_device
*device
)
80 return_VALUE(AE_BAD_PARAMETER
);
83 put_device(&device
->dev
);
90 /* --------------------------------------------------------------------------
92 -------------------------------------------------------------------------- */
95 acpi_bus_data_handler (
99 DPRINT1("acpi_bus_data_handler not implemented\n");
108 acpi_bus_get_device (
110 struct acpi_device
**device
)
112 ACPI_STATUS status
= AE_OK
;
115 return_VALUE(AE_BAD_PARAMETER
);
117 /* TBD: Support fixed-feature devices */
119 status
= AcpiGetData(handle
, acpi_bus_data_handler
, (void**)device
);
120 if (ACPI_FAILURE(status
) || !*device
) {
121 DPRINT( "Error getting context for object [%p]\n",
123 return_VALUE(AE_NOT_FOUND
);
129 ACPI_STATUS
acpi_bus_get_status_handle(ACPI_HANDLE handle
,
130 unsigned long long *sta
)
134 status
= acpi_evaluate_integer(handle
, "_STA", NULL
, sta
);
135 if (ACPI_SUCCESS(status
))
138 if (status
== AE_NOT_FOUND
) {
139 *sta
= ACPI_STA_DEVICE_PRESENT
| ACPI_STA_DEVICE_ENABLED
|
140 ACPI_STA_DEVICE_UI
| ACPI_STA_DEVICE_FUNCTIONING
;
147 acpi_bus_get_status (
148 struct acpi_device
*device
)
151 unsigned long long sta
;
153 status
= acpi_bus_get_status_handle(device
->handle
, &sta
);
154 if (ACPI_FAILURE(status
))
157 STRUCT_TO_INT(device
->status
) = (int) sta
;
159 if (device
->status
.functional
&& !device
->status
.present
) {
160 ACPI_DEBUG_PRINT((ACPI_DB_INFO
, "Device [%s] status [%08x]: "
161 "functional but not present;\n",
163 (UINT32
) STRUCT_TO_INT(device
->status
)));
166 ACPI_DEBUG_PRINT((ACPI_DB_INFO
, "Device [%s] status [%08x]\n",
168 (UINT32
) STRUCT_TO_INT(device
->status
)));
172 void acpi_bus_private_data_handler(ACPI_HANDLE handle
,
178 int acpi_bus_get_private_data(ACPI_HANDLE handle
, void **data
)
180 ACPI_STATUS status
= AE_OK
;
185 status
= AcpiGetData(handle
, acpi_bus_private_data_handler
, data
);
186 if (ACPI_FAILURE(status
) || !*data
) {
187 DPRINT("No context for object [%p]\n", handle
);
193 /* --------------------------------------------------------------------------
195 -------------------------------------------------------------------------- */
203 ACPI_STATUS status
= 0;
204 struct acpi_device
*device
= NULL
;
205 unsigned long long psc
= 0;
207 result
= acpi_bus_get_device(handle
, &device
);
209 return_VALUE(result
);
211 *state
= ACPI_STATE_UNKNOWN
;
213 if (!device
->flags
.power_manageable
) {
214 /* TBD: Non-recursive algorithm for walking up hierarchy */
216 *state
= device
->parent
->power
.state
;
218 *state
= ACPI_STATE_D0
;
222 * Get the device's power state either directly (via _PSC) or
223 * indirectly (via power resources).
225 if (device
->power
.flags
.explicit_get
) {
226 status
= acpi_evaluate_integer(device
->handle
, "_PSC",
228 if (ACPI_FAILURE(status
))
229 return_VALUE(AE_NOT_FOUND
);
230 device
->power
.state
= (int) psc
;
232 else if (device
->power
.flags
.power_resources
) {
233 result
= acpi_power_get_inferred_state(device
);
235 return_VALUE(result
);
238 *state
= device
->power
.state
;
241 DPRINT("Device [%s] power state is D%d\n",
242 device
->pnp
.bus_id
, device
->power
.state
);
254 ACPI_STATUS status
= AE_OK
;
255 struct acpi_device
*device
= NULL
;
256 char object_name
[5] = {'_','P','S','0'+state
,'\0'};
259 result
= acpi_bus_get_device(handle
, &device
);
261 return_VALUE(result
);
263 if ((state
< ACPI_STATE_D0
) || (state
> ACPI_STATE_D3
))
264 return_VALUE(AE_BAD_PARAMETER
);
266 /* Make sure this is a valid target state */
268 if (!device
->flags
.power_manageable
) {
269 DPRINT1( "Device is not power manageable\n");
270 return_VALUE(AE_NOT_FOUND
);
273 * Get device's current power state
275 //if (!acpi_power_nocheck) {
277 * Maybe the incorrect power state is returned on the bogus
278 * bios, which is different with the real power state.
279 * For example: the bios returns D0 state and the real power
280 * state is D3. OS expects to set the device to D0 state. In
281 * such case if OS uses the power state returned by the BIOS,
282 * the device can't be transisted to the correct power state.
283 * So if the acpi_power_nocheck is set, it is unnecessary to
284 * get the power state by calling acpi_bus_get_power.
286 acpi_bus_get_power(device
->handle
, &device
->power
.state
);
289 if ((state
== device
->power
.state
) && !device
->flags
.force_power_state
) {
290 DPRINT1("Device is already at D%d\n", state
);
293 if (!device
->power
.states
[state
].flags
.valid
) {
294 DPRINT1( "Device does not support D%d\n", state
);
297 if (device
->parent
&& (state
< device
->parent
->power
.state
)) {
298 DPRINT1( "Cannot set device to a higher-powered state than parent\n");
305 * On transitions to a high-powered state we first apply power (via
306 * power resources) then evalute _PSx. Conversly for transitions to
307 * a lower-powered state.
309 if (state
< device
->power
.state
) {
310 if (device
->power
.flags
.power_resources
) {
311 result
= acpi_power_transition(device
, state
);
315 if (device
->power
.states
[state
].flags
.explicit_set
) {
316 status
= AcpiEvaluateObject(device
->handle
,
317 object_name
, NULL
, NULL
);
318 if (ACPI_FAILURE(status
)) {
319 result
= AE_NOT_FOUND
;
325 if (device
->power
.states
[state
].flags
.explicit_set
) {
326 status
= AcpiEvaluateObject(device
->handle
,
327 object_name
, NULL
, NULL
);
328 if (ACPI_FAILURE(status
)) {
329 result
= AE_NOT_FOUND
;
333 if (device
->power
.flags
.power_resources
) {
334 result
= acpi_power_transition(device
, state
);
342 DPRINT( "Error transitioning device [%s] to D%d\n",
343 device
->pnp
.bus_id
, state
);
345 DPRINT("Device [%s] transitioned to D%d\n",
346 device
->pnp
.bus_id
, state
);
351 BOOLEAN
acpi_bus_power_manageable(ACPI_HANDLE handle
)
353 struct acpi_device
*device
;
356 result
= acpi_bus_get_device(handle
, &device
);
357 return result
? 0 : device
->flags
.power_manageable
;
360 BOOLEAN
acpi_bus_can_wakeup(ACPI_HANDLE handle
)
362 struct acpi_device
*device
;
365 result
= acpi_bus_get_device(handle
, &device
);
366 return result
? 0 : device
->wakeup
.flags
.valid
;
370 acpi_bus_get_power_flags (
371 struct acpi_device
*device
)
373 ACPI_STATUS status
= 0;
374 ACPI_HANDLE handle
= 0;
381 * Power Management Flags
383 status
= AcpiGetHandle(device
->handle
, "_PSC", &handle
);
384 if (ACPI_SUCCESS(status
))
385 device
->power
.flags
.explicit_get
= 1;
386 status
= AcpiGetHandle(device
->handle
, "_IRC", &handle
);
387 if (ACPI_SUCCESS(status
))
388 device
->power
.flags
.inrush_current
= 1;
389 status
= AcpiGetHandle(device
->handle
, "_PRW", &handle
);
390 if (ACPI_SUCCESS(status
))
391 device
->flags
.wake_capable
= 1;
394 * Enumerate supported power management states
396 for (i
= ACPI_STATE_D0
; i
<= ACPI_STATE_D3
; i
++) {
397 struct acpi_device_power_state
*ps
= &device
->power
.states
[i
];
398 char object_name
[5] = {'_','P','R','0'+i
,'\0'};
400 /* Evaluate "_PRx" to se if power resources are referenced */
401 status
= acpi_evaluate_reference(device
->handle
, object_name
, NULL
,
403 if (ACPI_SUCCESS(status
) && ps
->resources
.count
) {
404 device
->power
.flags
.power_resources
= 1;
408 /* Evaluate "_PSx" to see if we can do explicit sets */
409 object_name
[2] = 'S';
410 status
= AcpiGetHandle(device
->handle
, object_name
, &handle
);
411 if (ACPI_SUCCESS(status
)) {
412 ps
->flags
.explicit_set
= 1;
416 /* State is valid if we have some power control */
417 if (ps
->resources
.count
|| ps
->flags
.explicit_set
)
420 ps
->power
= -1; /* Unknown - driver assigned */
421 ps
->latency
= -1; /* Unknown - driver assigned */
424 /* Set defaults for D0 and D3 states (always valid) */
425 device
->power
.states
[ACPI_STATE_D0
].flags
.valid
= 1;
426 device
->power
.states
[ACPI_STATE_D0
].power
= 100;
427 device
->power
.states
[ACPI_STATE_D3
].flags
.valid
= 1;
428 device
->power
.states
[ACPI_STATE_D3
].power
= 0;
430 device
->power
.state
= ACPI_STATE_UNKNOWN
;
435 /* --------------------------------------------------------------------------
436 Performance Management
437 -------------------------------------------------------------------------- */
440 acpi_bus_get_perf_flags (
441 struct acpi_device
*device
)
446 device
->performance
.state
= ACPI_STATE_UNKNOWN
;
452 /* --------------------------------------------------------------------------
454 -------------------------------------------------------------------------- */
458 acpi_bus_generate_event_dpc(PKDPC Dpc
,
459 PVOID DeferredContext
,
460 PVOID SystemArgument1
,
461 PVOID SystemArgument2
)
463 struct acpi_bus_event
*event
;
464 struct acpi_device
*device
= SystemArgument1
;
465 ULONG_PTR TypeData
= (ULONG_PTR
)SystemArgument2
;
468 event
= ExAllocatePoolWithTag(NonPagedPool
,sizeof(struct acpi_bus_event
), 'epcA');
472 sprintf(event
->device_class
, "%s", device
->pnp
.device_class
);
473 sprintf(event
->bus_id
, "%s", device
->pnp
.bus_id
);
474 event
->type
= (TypeData
& 0xFF000000) >> 24;
475 event
->data
= (TypeData
& 0x00FFFFFF);
477 KeAcquireSpinLock(&acpi_bus_event_lock
, &OldIrql
);
478 list_add_tail(&event
->node
, &acpi_bus_event_list
);
479 KeReleaseSpinLock(&acpi_bus_event_lock
, OldIrql
);
481 KeSetEvent(&AcpiEventQueue
, IO_NO_INCREMENT
, FALSE
);
485 acpi_bus_generate_event (
486 struct acpi_device
*device
,
490 ULONG_PTR TypeData
= 0;
492 DPRINT("acpi_bus_generate_event\n");
495 return_VALUE(AE_BAD_PARAMETER
);
497 /* drop event on the floor if no one's listening */
501 /* Data shouldn't even get near 24 bits */
502 ASSERT(!(data
& 0xFF000000));
505 TypeData
|= type
<< 24;
507 KeInsertQueueDpc(&event_dpc
, device
, (PVOID
)TypeData
);
513 acpi_bus_receive_event (
514 struct acpi_bus_event
*event
)
516 // unsigned long flags = 0;
517 struct acpi_bus_event
*entry
= NULL
;
520 //DECLARE_WAITQUEUE(wait, current);
522 DPRINT("acpi_bus_receive_event\n");
525 return AE_BAD_PARAMETER
;
528 KeWaitForSingleObject(&AcpiEventQueue
,
534 KeClearEvent(&AcpiEventQueue
);
536 if (list_empty(&acpi_bus_event_list
))
537 return_VALUE(AE_NOT_FOUND
);
539 // spin_lock_irqsave(&acpi_bus_event_lock, flags);
540 KeAcquireSpinLock(&acpi_bus_event_lock
, &OldIrql
);
541 entry
= list_entry(acpi_bus_event_list
.next
, struct acpi_bus_event
, node
);
543 list_del(&entry
->node
);
544 KeReleaseSpinLock(&acpi_bus_event_lock
, OldIrql
);
545 // spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
548 return_VALUE(AE_NOT_FOUND
);
550 memcpy(event
, entry
, sizeof(struct acpi_bus_event
));
552 ExFreePoolWithTag(entry
, 'epcA');
557 /* --------------------------------------------------------------------------
559 -------------------------------------------------------------------------- */
565 * Used to walk the ACPI Bus's device namespace. Can walk down (depth-first)
566 * or up. Able to parse starting at any node in the namespace. Note that a
567 * callback return value of -249 will terminate the walk.
569 * @start: starting point
570 * callback: function to call for every device encountered while parsing
571 * direction: direction to parse (up or down)
572 * @data: context for this search operation
576 struct acpi_device
*start
,
577 acpi_bus_walk_callback callback
,
583 struct acpi_device
*device
= NULL
;
585 if (!start
|| !callback
)
586 return AE_BAD_PARAMETER
;
593 * Parse a given subtree (specified by start) in the given direction.
594 * Walking 'up' simply means that we execute the callback on leaf
595 * devices prior to their parents (useful for things like removing
596 * or powering down a subtree).
601 if (direction
== WALK_DOWN
)
602 if (-249 == callback(device
, level
, data
))
607 if (HAS_CHILDREN(device
)) {
608 device
= NODE_TO_DEVICE(device
->children
.next
);
613 if (direction
== WALK_UP
)
614 if (-249 == callback(device
, level
, data
))
619 if (HAS_SIBLINGS(device
)) {
620 device
= NODE_TO_DEVICE(device
->node
.next
);
624 /* Scope Exhausted - Find Next */
626 while ((device
= device
->parent
)) {
628 if (HAS_SIBLINGS(device
)) {
629 device
= NODE_TO_DEVICE(device
->node
.next
);
635 if ((direction
== WALK_UP
) && (result
== 0))
636 callback(start
, level
, data
);
642 /* --------------------------------------------------------------------------
643 Notification Handling
644 -------------------------------------------------------------------------- */
647 acpi_bus_check_device (ACPI_HANDLE handle
)
649 struct acpi_device
*device
;
650 ACPI_STATUS status
= 0;
651 struct acpi_device_status old_status
;
653 if (acpi_bus_get_device(handle
, &device
))
658 old_status
= device
->status
;
661 * Make sure this device's parent is present before we go about
662 * messing with the device.
664 if (device
->parent
&& !device
->parent
->status
.present
) {
665 device
->status
= device
->parent
->status
;
669 status
= acpi_bus_get_status(device
);
670 if (ACPI_FAILURE(status
))
673 if (STRUCT_TO_INT(old_status
) == STRUCT_TO_INT(device
->status
))
678 * Device Insertion/Removal
680 if ((device
->status
.present
) && !(old_status
.present
)) {
681 DPRINT("Device insertion detected\n");
682 /* TBD: Handle device insertion */
684 else if (!(device
->status
.present
) && (old_status
.present
)) {
685 DPRINT("Device removal detected\n");
686 /* TBD: Handle device removal */
693 acpi_bus_check_scope (ACPI_HANDLE handle
)
696 acpi_bus_check_device(handle
);
699 * TBD: Enumerate child devices within this device's scope and
700 * run acpi_bus_check_device()'s on them.
708 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
716 struct acpi_device
*device
= NULL
;
717 struct acpi_driver
*driver
;
719 DPRINT1("Notification %#02x to handle %p\n", type
, handle
);
721 //blocking_notifier_call_chain(&acpi_bus_notify_list,
722 // type, (void *)handle);
724 acpi_bus_get_device(handle
, &device
);
728 case ACPI_NOTIFY_BUS_CHECK
:
729 DPRINT("Received BUS CHECK notification for device [%s]\n",
730 device
? device
->pnp
.bus_id
: "n/a");
731 acpi_bus_check_scope(handle
);
733 * TBD: We'll need to outsource certain events to non-ACPI
734 * drivers via the device manager (device.c).
738 case ACPI_NOTIFY_DEVICE_CHECK
:
739 DPRINT("Received DEVICE CHECK notification for device [%s]\n",
740 device
? device
->pnp
.bus_id
: "n/a");
741 acpi_bus_check_device(handle
);
743 * TBD: We'll need to outsource certain events to non-ACPI
744 * drivers via the device manager (device.c).
748 case ACPI_NOTIFY_DEVICE_WAKE
:
749 DPRINT("Received DEVICE WAKE notification for device [%s]\n",
750 device
? device
->pnp
.bus_id
: "n/a");
751 acpi_bus_check_device(handle
);
753 * TBD: We'll need to outsource certain events to non-ACPI
754 * drivers via the device manager (device.c).
758 case ACPI_NOTIFY_EJECT_REQUEST
:
759 DPRINT1("Received EJECT REQUEST notification for device [%s]\n",
760 device
? device
->pnp
.bus_id
: "n/a");
764 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT
:
765 DPRINT1("Received DEVICE CHECK LIGHT notification for device [%s]\n",
766 device
? device
->pnp
.bus_id
: "n/a");
767 /* TBD: Exactly what does 'light' mean? */
770 case ACPI_NOTIFY_FREQUENCY_MISMATCH
:
771 DPRINT1("Received FREQUENCY MISMATCH notification for device [%s]\n",
772 device
? device
->pnp
.bus_id
: "n/a");
776 case ACPI_NOTIFY_BUS_MODE_MISMATCH
:
777 DPRINT1("Received BUS MODE MISMATCH notification for device [%s]\n",
778 device
? device
->pnp
.bus_id
: "n/a");
782 case ACPI_NOTIFY_POWER_FAULT
:
783 DPRINT1("Received POWER FAULT notification for device [%s]\n",
784 device
? device
->pnp
.bus_id
: "n/a");
789 DPRINT1("Received unknown/unsupported notification [%08x] for device [%s]\n",
790 type
, device
? device
->pnp
.bus_id
: "n/a");
795 driver
= device
->driver
;
796 if (driver
&& driver
->ops
.notify
&&
797 (driver
->flags
& ACPI_DRIVER_ALL_NOTIFY_EVENTS
))
798 driver
->ops
.notify(device
, type
);
803 /* --------------------------------------------------------------------------
805 -------------------------------------------------------------------------- */
808 static LIST_HEAD(acpi_bus_drivers
);
809 //static DECLARE_MUTEX(acpi_bus_drivers_lock);
810 static FAST_MUTEX acpi_bus_drivers_lock
;
816 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
817 * matches the specified driver's criteria.
821 struct acpi_device
*device
,
822 struct acpi_driver
*driver
)
826 if (device
->flags
.hardware_id
)
827 if (strstr(driver
->ids
, device
->pnp
.hardware_id
))
830 if (device
->flags
.compatible_ids
) {
831 ACPI_PNP_DEVICE_ID_LIST
*cid_list
= device
->pnp
.cid_list
;
834 /* compare multiple _CID entries against driver ids */
835 for (i
= 0; i
< cid_list
->Count
; i
++)
837 if (strstr(driver
->ids
, cid_list
->Ids
[i
].String
))
850 * acpi_bus_driver_init
851 * --------------------
852 * Used to initialize a device via its device driver. Called whenever a
853 * driver is bound to a device. Invokes the driver's add() and start() ops.
856 acpi_bus_driver_init (
857 struct acpi_device
*device
,
858 struct acpi_driver
*driver
)
862 if (!device
|| !driver
)
863 return_VALUE(AE_BAD_PARAMETER
);
865 if (!driver
->ops
.add
)
868 result
= driver
->ops
.add(device
);
870 device
->driver
= NULL
;
871 //acpi_driver_data(device) = NULL;
872 return_VALUE(result
);
875 device
->driver
= driver
;
878 * TBD - Configuration Management: Assign resources to device based
879 * upon possible configuration and currently allocated resources.
882 if (driver
->ops
.start
) {
883 result
= driver
->ops
.start(device
);
884 if (result
&& driver
->ops
.remove
)
885 driver
->ops
.remove(device
, ACPI_BUS_REMOVAL_NORMAL
);
886 return_VALUE(result
);
889 DPRINT("Driver successfully bound to device\n");
891 if (driver
->ops
.scan
) {
892 driver
->ops
.scan(device
);
902 * Callback for acpi_bus_walk() used to find devices that match a specific
903 * driver's criteria and then attach the driver.
907 struct acpi_device
*device
,
912 struct acpi_driver
*driver
= NULL
;
914 if (!device
|| !data
)
915 return_VALUE(AE_BAD_PARAMETER
);
917 driver
= (struct acpi_driver
*) data
;
922 if (!device
->status
.present
)
923 return_VALUE(AE_NOT_FOUND
);
925 result
= acpi_bus_match(device
, driver
);
927 return_VALUE(result
);
929 DPRINT("Found driver [%s] for device [%s]\n",
930 driver
->name
, device
->pnp
.bus_id
);
932 result
= acpi_bus_driver_init(device
, driver
);
934 return_VALUE(result
);
936 down(&acpi_bus_drivers_lock
);
937 ++driver
->references
;
938 up(&acpi_bus_drivers_lock
);
947 * Callback for acpi_bus_walk() used to find devices that match a specific
948 * driver's criteria and unattach the driver.
952 struct acpi_device
*device
,
957 struct acpi_driver
*driver
= (struct acpi_driver
*) data
;
959 if (!device
|| !driver
)
960 return_VALUE(AE_BAD_PARAMETER
);
962 if (device
->driver
!= driver
)
965 if (!driver
->ops
.remove
)
968 result
= driver
->ops
.remove(device
, ACPI_BUS_REMOVAL_NORMAL
);
970 return_VALUE(result
);
972 device
->driver
= NULL
;
973 acpi_driver_data(device
) = NULL
;
975 down(&acpi_bus_drivers_lock
);
976 driver
->references
--;
977 up(&acpi_bus_drivers_lock
);
984 * acpi_bus_find_driver
985 * --------------------
986 * Parses the list of registered drivers looking for a driver applicable for
987 * the specified device.
990 acpi_bus_find_driver (
991 struct acpi_device
*device
)
993 int result
= AE_NOT_FOUND
;
994 struct list_head
*entry
= NULL
;
995 struct acpi_driver
*driver
= NULL
;
997 if (!device
|| device
->driver
)
998 return_VALUE(AE_BAD_PARAMETER
);
1000 down(&acpi_bus_drivers_lock
);
1002 list_for_each(entry
, &acpi_bus_drivers
) {
1004 driver
= list_entry(entry
, struct acpi_driver
, node
);
1006 if (acpi_bus_match(device
, driver
))
1009 result
= acpi_bus_driver_init(device
, driver
);
1011 ++driver
->references
;
1016 up(&acpi_bus_drivers_lock
);
1018 return_VALUE(result
);
1023 * acpi_bus_register_driver
1024 * ------------------------
1025 * Registers a driver with the ACPI bus. Searches the namespace for all
1026 * devices that match the driver's criteria and binds.
1029 acpi_bus_register_driver (
1030 struct acpi_driver
*driver
)
1033 return_VALUE(AE_BAD_PARAMETER
);
1035 //if (acpi_disabled)
1036 // return_VALUE(AE_NOT_FOUND);
1038 down(&acpi_bus_drivers_lock
);
1039 list_add_tail(&driver
->node
, &acpi_bus_drivers
);
1040 up(&acpi_bus_drivers_lock
);
1042 acpi_bus_walk(acpi_root
, acpi_bus_attach
,
1045 return_VALUE(driver
->references
);
1050 * acpi_bus_unregister_driver
1051 * --------------------------
1052 * Unregisters a driver with the ACPI bus. Searches the namespace for all
1053 * devices that match the driver's criteria and unbinds.
1056 acpi_bus_unregister_driver (
1057 struct acpi_driver
*driver
)
1062 acpi_bus_walk(acpi_root
, acpi_bus_unattach
, WALK_UP
, driver
);
1064 if (driver
->references
)
1067 down(&acpi_bus_drivers_lock
);
1068 list_del(&driver
->node
);
1069 up(&acpi_bus_drivers_lock
);
1075 /* --------------------------------------------------------------------------
1077 -------------------------------------------------------------------------- */
1080 acpi_bus_get_flags (
1081 struct acpi_device
*device
)
1083 ACPI_STATUS status
= AE_OK
;
1084 ACPI_HANDLE temp
= NULL
;
1086 /* Presence of _STA indicates 'dynamic_status' */
1087 status
= AcpiGetHandle(device
->handle
, "_STA", &temp
);
1088 if (ACPI_SUCCESS(status
))
1089 device
->flags
.dynamic_status
= 1;
1091 /* Presence of _CID indicates 'compatible_ids' */
1092 status
= AcpiGetHandle(device
->handle
, "_CID", &temp
);
1093 if (ACPI_SUCCESS(status
))
1094 device
->flags
.compatible_ids
= 1;
1096 /* Presence of _RMV indicates 'removable' */
1097 status
= AcpiGetHandle(device
->handle
, "_RMV", &temp
);
1098 if (ACPI_SUCCESS(status
))
1099 device
->flags
.removable
= 1;
1101 /* Presence of _EJD|_EJ0 indicates 'ejectable' */
1102 status
= AcpiGetHandle(device
->handle
, "_EJD", &temp
);
1103 if (ACPI_SUCCESS(status
))
1104 device
->flags
.ejectable
= 1;
1106 status
= AcpiGetHandle(device
->handle
, "_EJ0", &temp
);
1107 if (ACPI_SUCCESS(status
))
1108 device
->flags
.ejectable
= 1;
1111 /* Presence of _LCK indicates 'lockable' */
1112 status
= AcpiGetHandle(device
->handle
, "_LCK", &temp
);
1113 if (ACPI_SUCCESS(status
))
1114 device
->flags
.lockable
= 1;
1116 /* Presence of _PS0|_PR0 indicates 'power manageable' */
1117 status
= AcpiGetHandle(device
->handle
, "_PS0", &temp
);
1118 if (ACPI_FAILURE(status
))
1119 status
= AcpiGetHandle(device
->handle
, "_PR0", &temp
);
1120 if (ACPI_SUCCESS(status
))
1121 device
->flags
.power_manageable
= 1;
1123 /* TBD: Peformance management */
1131 struct acpi_device
**child
,
1132 struct acpi_device
*parent
,
1137 ACPI_STATUS status
= AE_OK
;
1138 struct acpi_device
*device
= NULL
;
1139 char bus_id
[5] = {'?',0};
1141 ACPI_DEVICE_INFO
*info
;
1144 ACPI_PNP_DEVICE_ID_LIST
*cid_list
= NULL
;
1146 acpi_unique_id static_uid_buffer
;
1149 return_VALUE(AE_BAD_PARAMETER
);
1151 device
= ExAllocatePoolWithTag(NonPagedPool
,sizeof(struct acpi_device
), 'DpcA');
1153 DPRINT1("Memory allocation error\n");
1156 memset(device
, 0, sizeof(struct acpi_device
));
1158 device
->handle
= handle
;
1159 device
->parent
= parent
;
1164 * The device's Bus ID is simply the object name.
1165 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
1168 case ACPI_BUS_TYPE_SYSTEM
:
1169 snprintf(device
->pnp
.bus_id
, sizeof(device
->pnp
.bus_id
), "%s", "ACPI");
1171 case ACPI_BUS_TYPE_POWER_BUTTONF
:
1172 case ACPI_BUS_TYPE_POWER_BUTTON
:
1173 snprintf(device
->pnp
.bus_id
, sizeof(device
->pnp
.bus_id
), "%s", "PWRF");
1175 case ACPI_BUS_TYPE_SLEEP_BUTTONF
:
1176 case ACPI_BUS_TYPE_SLEEP_BUTTON
:
1177 snprintf(device
->pnp
.bus_id
, sizeof(device
->pnp
.bus_id
), "%s", "SLPF");
1180 buffer
.Length
= sizeof(bus_id
);
1181 buffer
.Pointer
= bus_id
;
1182 AcpiGetName(handle
, ACPI_SINGLE_NAME
, &buffer
);
1185 /* Clean up trailing underscores (if any) */
1186 for (i
= 3; i
> 1; i
--) {
1187 if (bus_id
[i
] == '_')
1192 snprintf(device
->pnp
.bus_id
, sizeof(device
->pnp
.bus_id
), "%s", bus_id
);
1193 buffer
.Pointer
= NULL
;
1195 /* HACK: Skip HPET */
1196 if (strstr(device
->pnp
.bus_id
, "HPET"))
1198 DPRINT("Using HPET hack\n");
1209 * Get prior to calling acpi_bus_get_status() so we know whether
1210 * or not _STA is present. Note that we only look for object
1211 * handles -- cannot evaluate objects until we know the device is
1212 * present and properly initialized.
1214 result
= acpi_bus_get_flags(device
);
1221 * See if the device is present. We always assume that non-Device()
1222 * objects (e.g. thermal zones, power resources, processors, etc.) are
1223 * present, functioning, etc. (at least when parent object is present).
1224 * Note that _STA has a different meaning for some objects (e.g.
1225 * power resources) so we need to be careful how we use it.
1228 case ACPI_BUS_TYPE_DEVICE
:
1229 result
= acpi_bus_get_status(device
);
1234 STRUCT_TO_INT(device
->status
) = 0x0F;
1237 if (!device
->status
.present
) {
1245 * TBD: Synch with Core's enumeration/initialization process.
1249 * Hardware ID, Unique ID, & Bus Address
1250 * -------------------------------------
1253 case ACPI_BUS_TYPE_DEVICE
:
1254 status
= AcpiGetObjectInfo(handle
,&info
);
1255 if (ACPI_FAILURE(status
)) {
1256 ACPI_DEBUG_PRINT((ACPI_DB_ERROR
,
1257 "Error reading device info\n"));
1258 result
= AE_NOT_FOUND
;
1261 if (info
->Valid
& ACPI_VALID_HID
)
1262 hid
= info
->HardwareId
.String
;
1263 if (info
->Valid
& ACPI_VALID_UID
)
1264 uid
= info
->UniqueId
.String
;
1265 if (info
->Valid
& ACPI_VALID_CID
) {
1266 cid_list
= &info
->CompatibleIdList
;
1267 device
->pnp
.cid_list
= ExAllocatePoolWithTag(NonPagedPool
,cid_list
->ListSize
, 'DpcA');
1268 if (device
->pnp
.cid_list
)
1269 memcpy(device
->pnp
.cid_list
, cid_list
, cid_list
->ListSize
);
1271 DPRINT("Memory allocation error\n");
1273 if (info
->Valid
& ACPI_VALID_ADR
) {
1274 device
->pnp
.bus_address
= info
->Address
;
1275 device
->flags
.bus_address
= 1;
1278 case ACPI_BUS_TYPE_POWER
:
1279 hid
= ACPI_POWER_HID
;
1280 uid
= static_uid_buffer
;
1281 snprintf(uid
, sizeof(static_uid_buffer
), "%d", (PowerDeviceCount
++));
1283 case ACPI_BUS_TYPE_PROCESSOR
:
1284 hid
= ACPI_PROCESSOR_HID
;
1285 uid
= static_uid_buffer
;
1286 snprintf(uid
, sizeof(static_uid_buffer
), "_%d", (ProcessorCount
++));
1288 case ACPI_BUS_TYPE_SYSTEM
:
1289 hid
= ACPI_SYSTEM_HID
;
1291 case ACPI_BUS_TYPE_THERMAL
:
1292 hid
= ACPI_THERMAL_HID
;
1293 uid
= static_uid_buffer
;
1294 snprintf(uid
, sizeof(static_uid_buffer
), "%d", (ThermalZoneCount
++));
1296 case ACPI_BUS_TYPE_POWER_BUTTON
:
1297 hid
= ACPI_BUTTON_HID_POWER
;
1298 uid
= static_uid_buffer
;
1299 snprintf(uid
, sizeof(static_uid_buffer
), "%d", (PowerButtonCount
++));
1301 case ACPI_BUS_TYPE_POWER_BUTTONF
:
1302 hid
= ACPI_BUTTON_HID_POWERF
;
1303 uid
= static_uid_buffer
;
1304 snprintf(uid
, sizeof(static_uid_buffer
), "%d", (FixedPowerButtonCount
++));
1306 case ACPI_BUS_TYPE_SLEEP_BUTTON
:
1307 hid
= ACPI_BUTTON_HID_SLEEP
;
1308 uid
= static_uid_buffer
;
1309 snprintf(uid
, sizeof(static_uid_buffer
), "%d", (SleepButtonCount
++));
1311 case ACPI_BUS_TYPE_SLEEP_BUTTONF
:
1312 hid
= ACPI_BUTTON_HID_SLEEPF
;
1313 uid
= static_uid_buffer
;
1314 snprintf(uid
, sizeof(static_uid_buffer
), "%d", (FixedSleepButtonCount
++));
1321 * Fix for the system root bus device -- the only root-level device.
1323 if (((ACPI_HANDLE
)parent
== ACPI_ROOT_OBJECT
) && (type
== ACPI_BUS_TYPE_DEVICE
)) {
1325 snprintf(device
->pnp
.device_name
, sizeof(device
->pnp
.device_name
), "%s", ACPI_BUS_DEVICE_NAME
);
1326 snprintf(device
->pnp
.device_class
, sizeof(device
->pnp
.device_class
), "%s", ACPI_BUS_CLASS
);
1330 device
->pnp
.hardware_id
= ExAllocatePoolWithTag(NonPagedPool
, strlen(hid
) + 1, 'DpcA');
1331 if (device
->pnp
.hardware_id
) {
1332 snprintf(device
->pnp
.hardware_id
, strlen(hid
) + 1, "%s", hid
);
1333 device
->flags
.hardware_id
= 1;
1337 snprintf(device
->pnp
.unique_id
, sizeof(device
->pnp
.unique_id
), "%s", uid
);
1338 device
->flags
.unique_id
= 1;
1342 * If we called get_object_info, we now are finished with the buffer,
1343 * so we can free it.
1345 //if (buffer.Pointer)
1346 //AcpiOsFree(buffer.Pointer);
1352 if (device
->flags
.power_manageable
) {
1353 result
= acpi_bus_get_power_flags(device
);
1359 * Performance Management
1360 * ----------------------
1362 if (device
->flags
.performance_manageable
) {
1363 result
= acpi_bus_get_perf_flags(device
);
1371 * Attach this 'struct acpi_device' to the ACPI object. This makes
1372 * resolutions from handle->device very efficient. Note that we need
1373 * to be careful with fixed-feature devices as they all attach to the
1377 case ACPI_BUS_TYPE_POWER_BUTTON
:
1378 case ACPI_BUS_TYPE_POWER_BUTTONF
:
1379 case ACPI_BUS_TYPE_SLEEP_BUTTON
:
1380 case ACPI_BUS_TYPE_SLEEP_BUTTONF
:
1383 status
= AcpiAttachData(device
->handle
,
1384 acpi_bus_data_handler
, device
);
1387 if (ACPI_FAILURE(status
)) {
1388 ACPI_DEBUG_PRINT((ACPI_DB_ERROR
,
1389 "Error attaching device data\n"));
1390 result
= AE_NOT_FOUND
;
1397 * Link this device to its parent and siblings.
1399 INIT_LIST_HEAD(&device
->children
);
1400 if (!device
->parent
)
1401 INIT_LIST_HEAD(&device
->node
);
1403 list_add_tail(&device
->node
, &device
->parent
->children
);
1406 * Global Device Hierarchy:
1407 * ------------------------
1408 * Register this device with the global device hierarchy.
1410 acpi_device_register(device
, parent
);
1413 * Bind _ADR-Based Devices
1414 * -----------------------
1415 * If there's a a bus address (_ADR) then we utilize the parent's
1416 * 'bind' function (if exists) to bind the ACPI- and natively-
1417 * enumerated device representations.
1419 if (device
->flags
.bus_address
) {
1420 if (device
->parent
&& device
->parent
->ops
.bind
)
1421 device
->parent
->ops
.bind(device
);
1425 * Locate & Attach Driver
1426 * ----------------------
1427 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1428 * to see if there's a driver installed for this kind of device. Note
1429 * that drivers can install before or after a device is enumerated.
1431 * TBD: Assumes LDM provides driver hot-plug capability.
1433 if (device
->flags
.hardware_id
|| device
->flags
.compatible_ids
)
1434 acpi_bus_find_driver(device
);
1438 if (device
->pnp
.cid_list
) {
1439 ExFreePoolWithTag(device
->pnp
.cid_list
, 'DpcA');
1441 if (device
->pnp
.hardware_id
) {
1442 ExFreePoolWithTag(device
->pnp
.hardware_id
, 'DpcA');
1444 ExFreePoolWithTag(device
, 'DpcA');
1445 return_VALUE(result
);
1455 struct acpi_device
*device
,
1460 return_VALUE(AE_NOT_FOUND
);
1462 acpi_device_unregister(device
);
1464 if (device
->pnp
.cid_list
)
1465 ExFreePoolWithTag(device
->pnp
.cid_list
, 'DpcA');
1467 if (device
->pnp
.hardware_id
)
1468 ExFreePoolWithTag(device
->pnp
.hardware_id
, 'DpcA');
1471 ExFreePoolWithTag(device
, 'DpcA');
1479 struct acpi_device
*start
)
1481 ACPI_STATUS status
= AE_OK
;
1482 struct acpi_device
*parent
= NULL
;
1483 struct acpi_device
*child
= NULL
;
1484 ACPI_HANDLE phandle
= 0;
1485 ACPI_HANDLE chandle
= 0;
1486 ACPI_OBJECT_TYPE type
= 0;
1490 return_VALUE(AE_BAD_PARAMETER
);
1493 phandle
= start
->handle
;
1496 * Parse through the ACPI namespace, identify all 'devices', and
1497 * create a new 'struct acpi_device' for each.
1499 while ((level
> 0) && parent
) {
1501 status
= AcpiGetNextObject(ACPI_TYPE_ANY
, phandle
,
1505 * If this scope is exhausted then move our way back up.
1507 if (ACPI_FAILURE(status
)) {
1510 AcpiGetParent(phandle
, &phandle
);
1512 parent
= parent
->parent
;
1516 status
= AcpiGetType(chandle
, &type
);
1517 if (ACPI_FAILURE(status
))
1521 * If this is a scope object then parse it (depth-first).
1523 if (type
== ACPI_TYPE_LOCAL_SCOPE
) {
1531 * We're only interested in objects that we consider 'devices'.
1534 case ACPI_TYPE_DEVICE
:
1535 type
= ACPI_BUS_TYPE_DEVICE
;
1537 case ACPI_TYPE_PROCESSOR
:
1538 type
= ACPI_BUS_TYPE_PROCESSOR
;
1540 case ACPI_TYPE_THERMAL
:
1541 type
= ACPI_BUS_TYPE_THERMAL
;
1543 case ACPI_TYPE_POWER
:
1544 type
= ACPI_BUS_TYPE_POWER
;
1550 status
= acpi_bus_add(&child
, parent
, chandle
, type
);
1551 if (ACPI_FAILURE(status
))
1555 * If the device is present, enabled, and functioning then
1556 * parse its scope (depth-first). Note that we need to
1557 * represent absent devices to facilitate PnP notifications
1558 * -- but only the subtree head (not all of its children,
1559 * which will be enumerated when the parent is inserted).
1561 * TBD: Need notifications and other detection mechanisms
1562 * in place before we can fully implement this.
1564 if (child
->status
.present
) {
1565 status
= AcpiGetNextObject(ACPI_TYPE_ANY
, chandle
,
1567 if (ACPI_SUCCESS(status
)) {
1581 acpi_bus_scan_fixed (
1582 struct acpi_device
*root
)
1585 struct acpi_device
*device
= NULL
;
1588 return_VALUE(AE_NOT_FOUND
);
1590 /* If ACPI_FADT_POWER_BUTTON is set, then a control
1591 * method power button is present. Otherwise, a fixed
1592 * power button is present.
1594 if (AcpiGbl_FADT
.Flags
& ACPI_FADT_POWER_BUTTON
)
1595 result
= acpi_bus_add(&device
, acpi_root
,
1596 NULL
, ACPI_BUS_TYPE_POWER_BUTTON
);
1599 /* Enable the fixed power button so we get notified if it is pressed */
1600 AcpiWriteBitRegister(ACPI_BITREG_POWER_BUTTON_ENABLE
, 1);
1602 result
= acpi_bus_add(&device
, acpi_root
,
1603 NULL
, ACPI_BUS_TYPE_POWER_BUTTONF
);
1606 /* This one is a bit more complicated and we do it wrong
1607 * right now. If ACPI_FADT_SLEEP_BUTTON is set but no
1608 * device object is present then no sleep button is present, but
1609 * if the flags is clear and there is no device object then it is
1610 * a fixed sleep button. If the flag is set and there is a device object
1611 * the we have a control method button just like above.
1613 if (AcpiGbl_FADT
.Flags
& ACPI_FADT_SLEEP_BUTTON
)
1614 result
= acpi_bus_add(&device
, acpi_root
,
1615 NULL
, ACPI_BUS_TYPE_SLEEP_BUTTON
);
1618 /* Enable the fixed sleep button so we get notified if it is pressed */
1619 AcpiWriteBitRegister(ACPI_BITREG_SLEEP_BUTTON_ENABLE
, 1);
1621 result
= acpi_bus_add(&device
, acpi_root
,
1622 NULL
, ACPI_BUS_TYPE_SLEEP_BUTTONF
);
1625 return_VALUE(result
);
1629 /* --------------------------------------------------------------------------
1630 Initialization/Cleanup
1631 -------------------------------------------------------------------------- */
1634 acpi_bus_init (void)
1637 ACPI_STATUS status
= AE_OK
;
1639 DPRINT("acpi_bus_init\n");
1641 KeInitializeDpc(&event_dpc
, acpi_bus_generate_event_dpc
, NULL
);
1643 status
= AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION
);
1644 if (ACPI_FAILURE(status
)) {
1645 DPRINT1("Unable to start the ACPI Interpreter\n");
1650 * ACPI 2.0 requires the EC driver to be loaded and work before
1651 * the EC device is found in the namespace. This is accomplished
1652 * by looking for the ECDT table, and getting the EC parameters out
1655 //result = acpi_ec_ecdt_probe();
1656 /* Ignore result. Not having an ECDT is not fatal. */
1658 status
= AcpiInitializeObjects(ACPI_FULL_INITIALIZATION
);
1659 if (ACPI_FAILURE(status
)) {
1660 DPRINT1("Unable to initialize ACPI objects\n");
1665 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
1666 * is necessary to enable it as early as possible.
1668 //acpi_boot_ec_enable();
1670 /* Initialize sleep structures */
1671 //acpi_sleep_init();
1674 * Register the for all standard device notifications.
1676 status
= AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT
, ACPI_SYSTEM_NOTIFY
, acpi_bus_notify
, NULL
);
1677 if (ACPI_FAILURE(status
)) {
1678 DPRINT1("Unable to register for device notifications\n");
1679 result
= AE_NOT_FOUND
;
1684 * Create the root device in the bus's device tree
1686 result
= acpi_bus_add(&acpi_root
, NULL
, ACPI_ROOT_OBJECT
,
1687 ACPI_BUS_TYPE_SYSTEM
);
1693 * Enumerate devices in the ACPI namespace.
1695 result
= acpi_bus_scan_fixed(acpi_root
);
1697 DPRINT1("acpi_bus_scan_fixed failed\n");
1698 result
= acpi_bus_scan(acpi_root
);
1700 DPRINT1("acpi_bus_scan failed\n");
1704 /* Mimic structured exception handling */
1706 AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT
,
1707 ACPI_SYSTEM_NOTIFY
, acpi_bus_notify
);
1710 return_VALUE(AE_NOT_FOUND
);
1714 acpi_bus_exit (void)
1716 ACPI_STATUS status
= AE_OK
;
1718 DPRINT1("acpi_bus_exit\n");
1720 status
= AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT
,
1721 ACPI_SYSTEM_NOTIFY
, acpi_bus_notify
);
1722 if (ACPI_FAILURE(status
))
1723 DPRINT1("Error removing notify handler\n");
1725 #ifdef CONFIG_ACPI_PCI
1726 acpi_pci_root_exit();
1727 acpi_pci_link_exit();
1729 #ifdef CONFIG_ACPI_EC
1732 //acpi_power_exit();
1735 acpi_bus_remove(acpi_root
, ACPI_BUS_REMOVAL_NORMAL
);
1737 status
= AcpiTerminate();
1738 if (ACPI_FAILURE(status
))
1739 DPRINT1("Unable to terminate the ACPI Interpreter\n");
1741 DPRINT1("Interpreter disabled\n");
1752 DPRINT("acpi_init\n");
1754 DPRINT("Subsystem revision %08x\n",ACPI_CA_VERSION
);
1756 KeInitializeSpinLock(&acpi_bus_event_lock
);
1757 KeInitializeEvent(&AcpiEventQueue
, NotificationEvent
, FALSE
);
1758 ExInitializeFastMutex(&acpi_bus_drivers_lock
);
1760 result
= acpi_bus_init();
1763 //pci_mmcfg_late_init();
1764 //if (!(pm_flags & PM_APM))
1765 // pm_flags |= PM_ACPI;
1767 //DPRINT1("APM is already active, exiting\n");
1775 * If the laptop falls into the DMI check table, the power state check
1776 * will be disabled in the course of device power transistion.
1778 //dmi_check_system(power_nocheck_dmi_table);
1781 * Install drivers required for proper enumeration of the
1784 acpi_system_init(); /* ACPI System */
1785 acpi_power_init(); /* ACPI Bus Power Management */
1787 //acpi_ec_init(); /* ACPI Embedded Controller */
1788 #ifdef CONFIG_ACPI_PCI
1789 if (!acpi_pci_disabled
) {
1790 acpi_pci_link_init(); /* ACPI PCI Interrupt Link */
1791 acpi_pci_root_init(); /* ACPI PCI Root Bridge */
1797 //acpi_power_init();
1798 //acpi_system_init();
1799 //acpi_debug_init();
1800 //acpi_sleep_proc_init();
1801 //acpi_wakeup_device_init();
1810 DPRINT("acpi_exit\n");