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
34 #include <acpi_drivers.h>
40 #define _COMPONENT ACPI_BUS_COMPONENT
41 ACPI_MODULE_NAME ("acpi_bus")
46 #define STRUCT_TO_INT(s) (*((int*)&s))
47 #define HAS_CHILDREN(d) ((d)->children.next != &((d)->children))
48 #define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children))
49 #define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node))
51 extern int event_is_open
;
52 extern void acpi_pic_sci_set_trigger(unsigned int irq
, UINT16 trigger
);
54 typedef int (*acpi_bus_walk_callback
)(struct acpi_device
*, int, void*);
56 struct acpi_device
*acpi_root
;
57 KSPIN_LOCK acpi_bus_event_lock
;
58 LIST_HEAD(acpi_bus_event_list
);
59 //DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
63 acpi_device_register (
64 struct acpi_device
*device
,
65 struct acpi_device
*parent
)
70 return_VALUE(AE_BAD_PARAMETER
);
77 acpi_device_unregister (
78 struct acpi_device
*device
)
81 return_VALUE(AE_BAD_PARAMETER
);
84 put_device(&device
->dev
);
91 /* --------------------------------------------------------------------------
93 -------------------------------------------------------------------------- */
96 acpi_bus_data_handler (
100 DPRINT1("acpi_bus_data_handler not implemented");
109 acpi_bus_get_device (
111 struct acpi_device
**device
)
113 ACPI_STATUS status
= AE_OK
;
116 return_VALUE(AE_BAD_PARAMETER
);
118 /* TBD: Support fixed-feature devices */
120 status
= AcpiGetData(handle
, acpi_bus_data_handler
, (void**)device
);
121 if (ACPI_FAILURE(status
) || !*device
) {
122 DPRINT( "Error getting context for object [%p]\n",
124 return_VALUE(AE_NOT_FOUND
);
130 ACPI_STATUS
acpi_bus_get_status_handle(ACPI_HANDLE handle
,
131 unsigned long long *sta
)
135 status
= acpi_evaluate_integer(handle
, "_STA", NULL
, sta
);
136 if (ACPI_SUCCESS(status
))
139 if (status
== AE_NOT_FOUND
) {
140 *sta
= ACPI_STA_DEVICE_PRESENT
| ACPI_STA_DEVICE_ENABLED
|
141 ACPI_STA_DEVICE_UI
| ACPI_STA_DEVICE_FUNCTIONING
;
148 acpi_bus_get_status (
149 struct acpi_device
*device
)
152 unsigned long long sta
;
154 status
= acpi_bus_get_status_handle(device
->handle
, &sta
);
155 if (ACPI_FAILURE(status
))
158 STRUCT_TO_INT(device
->status
) = (int) sta
;
160 if (device
->status
.functional
&& !device
->status
.present
) {
161 ACPI_DEBUG_PRINT((ACPI_DB_INFO
, "Device [%s] status [%08x]: "
162 "functional but not present;\n",
164 (UINT32
) STRUCT_TO_INT(device
->status
)));
167 ACPI_DEBUG_PRINT((ACPI_DB_INFO
, "Device [%s] status [%08x]\n",
169 (UINT32
) STRUCT_TO_INT(device
->status
)));
173 void acpi_bus_private_data_handler(ACPI_HANDLE handle
,
179 int acpi_bus_get_private_data(ACPI_HANDLE handle
, void **data
)
181 ACPI_STATUS status
= AE_OK
;
186 status
= AcpiGetData(handle
, acpi_bus_private_data_handler
, data
);
187 if (ACPI_FAILURE(status
) || !*data
) {
188 DPRINT("No context for object [%p]\n", handle
);
194 /* --------------------------------------------------------------------------
196 -------------------------------------------------------------------------- */
204 ACPI_STATUS status
= 0;
205 struct acpi_device
*device
= NULL
;
206 unsigned long long psc
= 0;
208 result
= acpi_bus_get_device(handle
, &device
);
210 return_VALUE(result
);
212 *state
= ACPI_STATE_UNKNOWN
;
214 if (!device
->flags
.power_manageable
) {
215 /* TBD: Non-recursive algorithm for walking up hierarchy */
217 *state
= device
->parent
->power
.state
;
219 *state
= ACPI_STATE_D0
;
223 * Get the device's power state either directly (via _PSC) or
224 * indirectly (via power resources).
226 if (device
->power
.flags
.explicit_get
) {
227 status
= acpi_evaluate_integer(device
->handle
, "_PSC",
229 if (ACPI_FAILURE(status
))
230 return_VALUE(AE_NOT_FOUND
);
231 device
->power
.state
= (int) psc
;
233 else if (device
->power
.flags
.power_resources
) {
234 result
= acpi_power_get_inferred_state(device
);
236 return_VALUE(result
);
239 *state
= device
->power
.state
;
242 DPRINT("Device [%s] power state is D%d\n",
243 device
->pnp
.bus_id
, device
->power
.state
);
255 ACPI_STATUS status
= AE_OK
;
256 struct acpi_device
*device
= NULL
;
257 char object_name
[5] = {'_','P','S','0'+state
,'\0'};
260 result
= acpi_bus_get_device(handle
, &device
);
262 return_VALUE(result
);
264 if ((state
< ACPI_STATE_D0
) || (state
> ACPI_STATE_D3
))
265 return_VALUE(AE_BAD_PARAMETER
);
267 /* Make sure this is a valid target state */
269 if (!device
->flags
.power_manageable
) {
270 DPRINT1( "Device is not power manageable\n");
271 return_VALUE(AE_NOT_FOUND
);
274 * Get device's current power state
276 //if (!acpi_power_nocheck) {
278 * Maybe the incorrect power state is returned on the bogus
279 * bios, which is different with the real power state.
280 * For example: the bios returns D0 state and the real power
281 * state is D3. OS expects to set the device to D0 state. In
282 * such case if OS uses the power state returned by the BIOS,
283 * the device can't be transisted to the correct power state.
284 * So if the acpi_power_nocheck is set, it is unnecessary to
285 * get the power state by calling acpi_bus_get_power.
287 acpi_bus_get_power(device
->handle
, &device
->power
.state
);
290 if ((state
== device
->power
.state
) && !device
->flags
.force_power_state
) {
291 DPRINT1("Device is already at D%d\n", state
);
294 if (!device
->power
.states
[state
].flags
.valid
) {
295 DPRINT1( "Device does not support D%d\n", state
);
298 if (device
->parent
&& (state
< device
->parent
->power
.state
)) {
299 DPRINT1( "Cannot set device to a higher-powered state than parent\n");
306 * On transitions to a high-powered state we first apply power (via
307 * power resources) then evalute _PSx. Conversly for transitions to
308 * a lower-powered state.
310 if (state
< device
->power
.state
) {
311 if (device
->power
.flags
.power_resources
) {
312 result
= acpi_power_transition(device
, state
);
316 if (device
->power
.states
[state
].flags
.explicit_set
) {
317 status
= AcpiEvaluateObject(device
->handle
,
318 object_name
, NULL
, NULL
);
319 if (ACPI_FAILURE(status
)) {
320 result
= AE_NOT_FOUND
;
326 if (device
->power
.states
[state
].flags
.explicit_set
) {
327 status
= AcpiEvaluateObject(device
->handle
,
328 object_name
, NULL
, NULL
);
329 if (ACPI_FAILURE(status
)) {
330 result
= AE_NOT_FOUND
;
334 if (device
->power
.flags
.power_resources
) {
335 result
= acpi_power_transition(device
, state
);
343 DPRINT( "Error transitioning device [%s] to D%d\n",
344 device
->pnp
.bus_id
, state
);
346 DPRINT("Device [%s] transitioned to D%d\n",
347 device
->pnp
.bus_id
, state
);
352 BOOLEAN
acpi_bus_power_manageable(ACPI_HANDLE handle
)
354 struct acpi_device
*device
;
357 result
= acpi_bus_get_device(handle
, &device
);
358 return result
? 0 : device
->flags
.power_manageable
;
361 BOOLEAN
acpi_bus_can_wakeup(ACPI_HANDLE handle
)
363 struct acpi_device
*device
;
366 result
= acpi_bus_get_device(handle
, &device
);
367 return result
? 0 : device
->wakeup
.flags
.valid
;
371 acpi_bus_get_power_flags (
372 struct acpi_device
*device
)
374 ACPI_STATUS status
= 0;
375 ACPI_HANDLE handle
= 0;
382 * Power Management Flags
384 status
= AcpiGetHandle(device
->handle
, "_PSC", &handle
);
385 if (ACPI_SUCCESS(status
))
386 device
->power
.flags
.explicit_get
= 1;
387 status
= AcpiGetHandle(device
->handle
, "_IRC", &handle
);
388 if (ACPI_SUCCESS(status
))
389 device
->power
.flags
.inrush_current
= 1;
390 status
= AcpiGetHandle(device
->handle
, "_PRW", &handle
);
391 if (ACPI_SUCCESS(status
))
392 device
->flags
.wake_capable
= 1;
395 * Enumerate supported power management states
397 for (i
= ACPI_STATE_D0
; i
<= ACPI_STATE_D3
; i
++) {
398 struct acpi_device_power_state
*ps
= &device
->power
.states
[i
];
399 char object_name
[5] = {'_','P','R','0'+i
,'\0'};
401 /* Evaluate "_PRx" to se if power resources are referenced */
402 acpi_evaluate_reference(device
->handle
, object_name
, NULL
,
404 if (ps
->resources
.count
) {
405 device
->power
.flags
.power_resources
= 1;
409 /* Evaluate "_PSx" to see if we can do explicit sets */
410 object_name
[2] = 'S';
411 status
= AcpiGetHandle(device
->handle
, object_name
, &handle
);
412 if (ACPI_SUCCESS(status
)) {
413 ps
->flags
.explicit_set
= 1;
417 /* State is valid if we have some power control */
418 if (ps
->resources
.count
|| ps
->flags
.explicit_set
)
421 ps
->power
= -1; /* Unknown - driver assigned */
422 ps
->latency
= -1; /* Unknown - driver assigned */
425 /* Set defaults for D0 and D3 states (always valid) */
426 device
->power
.states
[ACPI_STATE_D0
].flags
.valid
= 1;
427 device
->power
.states
[ACPI_STATE_D0
].power
= 100;
428 device
->power
.states
[ACPI_STATE_D3
].flags
.valid
= 1;
429 device
->power
.states
[ACPI_STATE_D3
].power
= 0;
431 device
->power
.state
= ACPI_STATE_UNKNOWN
;
436 /* --------------------------------------------------------------------------
437 Performance Management
438 -------------------------------------------------------------------------- */
441 acpi_bus_get_perf_flags (
442 struct acpi_device
*device
)
447 device
->performance
.state
= ACPI_STATE_UNKNOWN
;
453 /* --------------------------------------------------------------------------
455 -------------------------------------------------------------------------- */
459 acpi_bus_generate_event (
460 struct acpi_device
*device
,
464 struct acpi_bus_event
*event
= NULL
;
465 //unsigned long flags = 0;
467 DPRINT1("acpi_bus_generate_event");
470 return_VALUE(AE_BAD_PARAMETER
);
472 /* drop event on the floor if no one's listening */
473 //if (!event_is_open)
476 event
= ExAllocatePool(NonPagedPool
,sizeof(struct acpi_bus_event
));
480 sprintf(event
->device_class
, "%s", device
->pnp
.device_class
);
481 sprintf(event
->bus_id
, "%s", device
->pnp
.bus_id
);
485 //spin_lock_irqsave(&acpi_bus_event_lock, flags);
486 list_add_tail(&event
->node
, &acpi_bus_event_list
);
487 //spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
489 //wake_up_interruptible(&acpi_bus_event_queue);
495 acpi_bus_receive_event (
496 struct acpi_bus_event
*event
)
498 //unsigned long flags = 0;
499 //struct acpi_bus_event *entry = NULL;
501 //DECLARE_WAITQUEUE(wait, current);
503 DPRINT1("acpi_bus_receive_event");
506 // return AE_BAD_PARAMETER;
508 //if (list_empty(&acpi_bus_event_list)) {
510 // set_current_state(TASK_INTERRUPTIBLE);
511 // add_wait_queue(&acpi_bus_event_queue, &wait);
513 // if (list_empty(&acpi_bus_event_list))
516 // remove_wait_queue(&acpi_bus_event_queue, &wait);
517 // set_current_state(TASK_RUNNING);
519 // if (signal_pending(current))
520 // return_VALUE(-ERESTARTSYS);
523 //spin_lock_irqsave(&acpi_bus_event_lock, flags);
524 //entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
526 // list_del(&entry->node);
527 //spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
530 // return_VALUE(AE_NOT_FOUND);
532 //memcpy(event, entry, sizeof(struct acpi_bus_event));
540 /* --------------------------------------------------------------------------
542 -------------------------------------------------------------------------- */
548 * Used to walk the ACPI Bus's device namespace. Can walk down (depth-first)
549 * or up. Able to parse starting at any node in the namespace. Note that a
550 * callback return value of -249 will terminate the walk.
552 * @start: starting point
553 * callback: function to call for every device encountered while parsing
554 * direction: direction to parse (up or down)
555 * @data: context for this search operation
559 struct acpi_device
*start
,
560 acpi_bus_walk_callback callback
,
566 struct acpi_device
*device
= NULL
;
568 if (!start
|| !callback
)
569 return AE_BAD_PARAMETER
;
576 * Parse a given subtree (specified by start) in the given direction.
577 * Walking 'up' simply means that we execute the callback on leaf
578 * devices prior to their parents (useful for things like removing
579 * or powering down a subtree).
584 if (direction
== WALK_DOWN
)
585 if (-249 == callback(device
, level
, data
))
590 if (HAS_CHILDREN(device
)) {
591 device
= NODE_TO_DEVICE(device
->children
.next
);
596 if (direction
== WALK_UP
)
597 if (-249 == callback(device
, level
, data
))
602 if (HAS_SIBLINGS(device
)) {
603 device
= NODE_TO_DEVICE(device
->node
.next
);
607 /* Scope Exhausted - Find Next */
609 while ((device
= device
->parent
)) {
611 if (HAS_SIBLINGS(device
)) {
612 device
= NODE_TO_DEVICE(device
->node
.next
);
618 if ((direction
== WALK_UP
) && (result
== 0))
619 callback(start
, level
, data
);
625 /* --------------------------------------------------------------------------
626 Notification Handling
627 -------------------------------------------------------------------------- */
630 acpi_bus_check_device (ACPI_HANDLE handle
)
632 struct acpi_device
*device
;
633 ACPI_STATUS status
= 0;
634 struct acpi_device_status old_status
;
636 if (acpi_bus_get_device(handle
, &device
))
641 old_status
= device
->status
;
644 * Make sure this device's parent is present before we go about
645 * messing with the device.
647 if (device
->parent
&& !device
->parent
->status
.present
) {
648 device
->status
= device
->parent
->status
;
652 status
= acpi_bus_get_status(device
);
653 if (ACPI_FAILURE(status
))
656 if (STRUCT_TO_INT(old_status
) == STRUCT_TO_INT(device
->status
))
661 * Device Insertion/Removal
663 if ((device
->status
.present
) && !(old_status
.present
)) {
664 DPRINT("Device insertion detected\n");
665 /* TBD: Handle device insertion */
667 else if (!(device
->status
.present
) && (old_status
.present
)) {
668 DPRINT("Device removal detected\n");
669 /* TBD: Handle device removal */
676 acpi_bus_check_scope (ACPI_HANDLE handle
)
679 acpi_bus_check_device(handle
);
682 * TBD: Enumerate child devices within this device's scope and
683 * run acpi_bus_check_device()'s on them.
691 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
699 struct acpi_device
*device
= NULL
;
700 struct acpi_driver
*driver
;
702 DPRINT1("Notification %#02x to handle %p\n", type
, handle
);
704 //blocking_notifier_call_chain(&acpi_bus_notify_list,
705 // type, (void *)handle);
709 case ACPI_NOTIFY_BUS_CHECK
:
710 DPRINT("Received BUS CHECK notification for device [%s]\n",
712 acpi_bus_check_scope(handle
);
714 * TBD: We'll need to outsource certain events to non-ACPI
715 * drivers via the device manager (device.c).
719 case ACPI_NOTIFY_DEVICE_CHECK
:
720 DPRINT("Received DEVICE CHECK notification for device [%s]\n",
722 acpi_bus_check_device(handle
);
724 * TBD: We'll need to outsource certain events to non-ACPI
725 * drivers via the device manager (device.c).
729 case ACPI_NOTIFY_DEVICE_WAKE
:
730 DPRINT("Received DEVICE WAKE notification for device [%s]\n",
732 acpi_bus_check_device(handle
);
734 * TBD: We'll need to outsource certain events to non-ACPI
735 * drivers via the device manager (device.c).
739 case ACPI_NOTIFY_EJECT_REQUEST
:
740 DPRINT1("Received EJECT REQUEST notification for device [%s]\n",
745 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT
:
746 DPRINT1("Received DEVICE CHECK LIGHT notification for device [%s]\n",
748 /* TBD: Exactly what does 'light' mean? */
751 case ACPI_NOTIFY_FREQUENCY_MISMATCH
:
752 DPRINT1("Received FREQUENCY MISMATCH notification for device [%s]\n",
757 case ACPI_NOTIFY_BUS_MODE_MISMATCH
:
758 DPRINT1("Received BUS MODE MISMATCH notification for device [%s]\n",
763 case ACPI_NOTIFY_POWER_FAULT
:
764 DPRINT1("Received POWER FAULT notification for device [%s]\n",
770 DPRINT1("Received unknown/unsupported notification [%08x]\n",
775 acpi_bus_get_device(handle
, &device
);
777 driver
= device
->driver
;
778 if (driver
&& driver
->ops
.notify
&&
779 (driver
->flags
& ACPI_DRIVER_ALL_NOTIFY_EVENTS
))
780 driver
->ops
.notify(device
, type
);
785 /* --------------------------------------------------------------------------
787 -------------------------------------------------------------------------- */
790 static LIST_HEAD(acpi_bus_drivers
);
791 //static DECLARE_MUTEX(acpi_bus_drivers_lock);
797 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
798 * matches the specified driver's criteria.
802 struct acpi_device
*device
,
803 struct acpi_driver
*driver
)
807 if (device
->flags
.hardware_id
)
808 if (strstr(driver
->ids
, device
->pnp
.hardware_id
))
811 if (device
->flags
.compatible_ids
) {
812 ACPI_DEVICE_ID_LIST
*cid_list
= device
->pnp
.cid_list
;
815 /* compare multiple _CID entries against driver ids */
816 for (i
= 0; i
< cid_list
->Count
; i
++)
818 if (strstr(driver
->ids
, cid_list
->Ids
[i
].String
))
831 * acpi_bus_driver_init
832 * --------------------
833 * Used to initialize a device via its device driver. Called whenever a
834 * driver is bound to a device. Invokes the driver's add() and start() ops.
837 acpi_bus_driver_init (
838 struct acpi_device
*device
,
839 struct acpi_driver
*driver
)
843 if (!device
|| !driver
)
844 return_VALUE(AE_BAD_PARAMETER
);
846 if (!driver
->ops
.add
)
849 result
= driver
->ops
.add(device
);
851 device
->driver
= NULL
;
852 //acpi_driver_data(device) = NULL;
853 return_VALUE(result
);
856 device
->driver
= driver
;
859 * TBD - Configuration Management: Assign resources to device based
860 * upon possible configuration and currently allocated resources.
863 if (driver
->ops
.start
) {
864 result
= driver
->ops
.start(device
);
865 if (result
&& driver
->ops
.remove
)
866 driver
->ops
.remove(device
, ACPI_BUS_REMOVAL_NORMAL
);
867 return_VALUE(result
);
870 DPRINT("Driver successfully bound to device\n");
872 if (driver
->ops
.scan
) {
873 driver
->ops
.scan(device
);
883 * Callback for acpi_bus_walk() used to find devices that match a specific
884 * driver's criteria and then attach the driver.
888 struct acpi_device
*device
,
893 struct acpi_driver
*driver
= NULL
;
895 if (!device
|| !data
)
896 return_VALUE(AE_BAD_PARAMETER
);
898 driver
= (struct acpi_driver
*) data
;
903 if (!device
->status
.present
)
904 return_VALUE(AE_NOT_FOUND
);
906 result
= acpi_bus_match(device
, driver
);
908 return_VALUE(result
);
910 DPRINT("Found driver [%s] for device [%s]\n",
911 driver
->name
, device
->pnp
.bus_id
);
913 result
= acpi_bus_driver_init(device
, driver
);
915 return_VALUE(result
);
917 //down(&acpi_bus_drivers_lock);
918 ++driver
->references
;
919 //up(&acpi_bus_drivers_lock);
928 * Callback for acpi_bus_walk() used to find devices that match a specific
929 * driver's criteria and unattach the driver.
933 struct acpi_device
*device
,
938 struct acpi_driver
*driver
= (struct acpi_driver
*) data
;
940 if (!device
|| !driver
)
941 return_VALUE(AE_BAD_PARAMETER
);
943 if (device
->driver
!= driver
)
946 if (!driver
->ops
.remove
)
949 result
= driver
->ops
.remove(device
, ACPI_BUS_REMOVAL_NORMAL
);
951 return_VALUE(result
);
953 device
->driver
= NULL
;
954 acpi_driver_data(device
) = NULL
;
956 //down(&acpi_bus_drivers_lock);
957 driver
->references
--;
958 //up(&acpi_bus_drivers_lock);
965 * acpi_bus_find_driver
966 * --------------------
967 * Parses the list of registered drivers looking for a driver applicable for
968 * the specified device.
971 acpi_bus_find_driver (
972 struct acpi_device
*device
)
974 int result
= AE_NOT_FOUND
;
975 struct list_head
*entry
= NULL
;
976 struct acpi_driver
*driver
= NULL
;
978 if (!device
|| device
->driver
)
979 return_VALUE(AE_BAD_PARAMETER
);
981 //down(&acpi_bus_drivers_lock);
983 list_for_each(entry
, &acpi_bus_drivers
) {
985 driver
= list_entry(entry
, struct acpi_driver
, node
);
987 if (acpi_bus_match(device
, driver
))
990 result
= acpi_bus_driver_init(device
, driver
);
992 ++driver
->references
;
997 //up(&acpi_bus_drivers_lock);
999 return_VALUE(result
);
1004 * acpi_bus_register_driver
1005 * ------------------------
1006 * Registers a driver with the ACPI bus. Searches the namespace for all
1007 * devices that match the driver's criteria and binds.
1010 acpi_bus_register_driver (
1011 struct acpi_driver
*driver
)
1014 return_VALUE(AE_BAD_PARAMETER
);
1016 //if (acpi_disabled)
1017 // return_VALUE(AE_NOT_FOUND);
1019 //down(&acpi_bus_drivers_lock);
1020 list_add_tail(&driver
->node
, &acpi_bus_drivers
);
1021 //up(&acpi_bus_drivers_lock);
1023 acpi_bus_walk(acpi_root
, acpi_bus_attach
,
1026 return_VALUE(driver
->references
);
1031 * acpi_bus_unregister_driver
1032 * --------------------------
1033 * Unregisters a driver with the ACPI bus. Searches the namespace for all
1034 * devices that match the driver's criteria and unbinds.
1037 acpi_bus_unregister_driver (
1038 struct acpi_driver
*driver
)
1043 acpi_bus_walk(acpi_root
, acpi_bus_unattach
, WALK_UP
, driver
);
1045 if (driver
->references
)
1048 //down(&acpi_bus_drivers_lock);
1049 list_del(&driver
->node
);
1050 //up(&acpi_bus_drivers_lock);
1056 /* --------------------------------------------------------------------------
1058 -------------------------------------------------------------------------- */
1061 acpi_bus_get_flags (
1062 struct acpi_device
*device
)
1064 ACPI_STATUS status
= AE_OK
;
1065 ACPI_HANDLE temp
= NULL
;
1067 /* Presence of _STA indicates 'dynamic_status' */
1068 status
= AcpiGetHandle(device
->handle
, "_STA", &temp
);
1069 if (ACPI_SUCCESS(status
))
1070 device
->flags
.dynamic_status
= 1;
1072 /* Presence of _CID indicates 'compatible_ids' */
1073 status
= AcpiGetHandle(device
->handle
, "_CID", &temp
);
1074 if (ACPI_SUCCESS(status
))
1075 device
->flags
.compatible_ids
= 1;
1077 /* Presence of _RMV indicates 'removable' */
1078 status
= AcpiGetHandle(device
->handle
, "_RMV", &temp
);
1079 if (ACPI_SUCCESS(status
))
1080 device
->flags
.removable
= 1;
1082 /* Presence of _EJD|_EJ0 indicates 'ejectable' */
1083 status
= AcpiGetHandle(device
->handle
, "_EJD", &temp
);
1084 if (ACPI_SUCCESS(status
))
1085 device
->flags
.ejectable
= 1;
1087 status
= AcpiGetHandle(device
->handle
, "_EJ0", &temp
);
1088 if (ACPI_SUCCESS(status
))
1089 device
->flags
.ejectable
= 1;
1092 /* Presence of _LCK indicates 'lockable' */
1093 status
= AcpiGetHandle(device
->handle
, "_LCK", &temp
);
1094 if (ACPI_SUCCESS(status
))
1095 device
->flags
.lockable
= 1;
1097 /* Presence of _PS0|_PR0 indicates 'power manageable' */
1098 status
= AcpiGetHandle(device
->handle
, "_PS0", &temp
);
1099 if (ACPI_FAILURE(status
))
1100 status
= AcpiGetHandle(device
->handle
, "_PR0", &temp
);
1101 if (ACPI_SUCCESS(status
))
1102 device
->flags
.power_manageable
= 1;
1104 /* TBD: Peformance management */
1112 struct acpi_device
**child
,
1113 struct acpi_device
*parent
,
1118 ACPI_STATUS status
= AE_OK
;
1119 struct acpi_device
*device
= NULL
;
1120 char bus_id
[5] = {'?',0};
1122 ACPI_DEVICE_INFO
*info
;
1125 ACPI_DEVICE_ID_LIST
*cid_list
= NULL
;
1129 return_VALUE(AE_BAD_PARAMETER
);
1131 device
= ExAllocatePool(NonPagedPool
,sizeof(struct acpi_device
));
1133 DPRINT1("Memory allocation error\n");
1136 memset(device
, 0, sizeof(struct acpi_device
));
1138 device
->handle
= handle
;
1139 device
->parent
= parent
;
1144 * The device's Bus ID is simply the object name.
1145 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
1148 case ACPI_BUS_TYPE_SYSTEM
:
1149 sprintf(device
->pnp
.bus_id
, "%s", "ACPI");
1151 case ACPI_BUS_TYPE_POWER_BUTTON
:
1152 sprintf(device
->pnp
.bus_id
, "%s", "PWRF");
1154 case ACPI_BUS_TYPE_SLEEP_BUTTON
:
1155 sprintf(device
->pnp
.bus_id
, "%s", "SLPF");
1158 buffer
.Length
= sizeof(bus_id
);
1159 buffer
.Pointer
= bus_id
;
1160 AcpiGetName(handle
, ACPI_SINGLE_NAME
, &buffer
);
1163 /* Clean up trailing underscores (if any) */
1164 for (i
= 3; i
> 1; i
--) {
1165 if (bus_id
[i
] == '_')
1170 sprintf(device
->pnp
.bus_id
, "%s", bus_id
);
1171 buffer
.Pointer
= NULL
;
1178 * Get prior to calling acpi_bus_get_status() so we know whether
1179 * or not _STA is present. Note that we only look for object
1180 * handles -- cannot evaluate objects until we know the device is
1181 * present and properly initialized.
1183 result
= acpi_bus_get_flags(device
);
1190 * See if the device is present. We always assume that non-Device()
1191 * objects (e.g. thermal zones, power resources, processors, etc.) are
1192 * present, functioning, etc. (at least when parent object is present).
1193 * Note that _STA has a different meaning for some objects (e.g.
1194 * power resources) so we need to be careful how we use it.
1197 case ACPI_BUS_TYPE_DEVICE
:
1198 result
= acpi_bus_get_status(device
);
1203 STRUCT_TO_INT(device
->status
) = 0x0F;
1206 if (!device
->status
.present
) {
1214 * TBD: Synch with Core's enumeration/initialization process.
1218 * Hardware ID, Unique ID, & Bus Address
1219 * -------------------------------------
1222 case ACPI_BUS_TYPE_DEVICE
:
1223 status
= AcpiGetObjectInfo(handle
,&info
);
1224 if (ACPI_FAILURE(status
)) {
1225 ACPI_DEBUG_PRINT((ACPI_DB_ERROR
,
1226 "Error reading device info\n"));
1227 result
= AE_NOT_FOUND
;
1230 if (info
->Valid
& ACPI_VALID_HID
)
1231 hid
= info
->HardwareId
.String
;
1232 if (info
->Valid
& ACPI_VALID_UID
)
1233 uid
= info
->UniqueId
.String
;
1234 if (info
->Valid
& ACPI_VALID_CID
) {
1235 cid_list
= &info
->CompatibleIdList
;
1236 device
->pnp
.cid_list
= ExAllocatePool(NonPagedPool
,cid_list
->ListSize
);
1237 if (device
->pnp
.cid_list
)
1238 memcpy(device
->pnp
.cid_list
, cid_list
, cid_list
->ListSize
);
1240 DPRINT("Memory allocation error\n");
1242 if (info
->Valid
& ACPI_VALID_ADR
) {
1243 device
->pnp
.bus_address
= info
->Address
;
1244 device
->flags
.bus_address
= 1;
1247 case ACPI_BUS_TYPE_POWER
:
1248 hid
= ACPI_POWER_HID
;
1250 case ACPI_BUS_TYPE_PROCESSOR
:
1251 hid
= ACPI_PROCESSOR_HID
;
1253 case ACPI_BUS_TYPE_SYSTEM
:
1254 hid
= ACPI_SYSTEM_HID
;
1256 case ACPI_BUS_TYPE_THERMAL
:
1257 hid
= ACPI_THERMAL_HID
;
1259 case ACPI_BUS_TYPE_POWER_BUTTON
:
1260 hid
= ACPI_BUTTON_HID_POWERF
;
1262 case ACPI_BUS_TYPE_SLEEP_BUTTON
:
1263 hid
= ACPI_BUTTON_HID_SLEEPF
;
1270 * Fix for the system root bus device -- the only root-level device.
1272 if ((parent
== ACPI_ROOT_OBJECT
) && (type
== ACPI_BUS_TYPE_DEVICE
)) {
1274 sprintf(device
->pnp
.device_name
, "%s", ACPI_BUS_DEVICE_NAME
);
1275 sprintf(device
->pnp
.device_class
, "%s", ACPI_BUS_CLASS
);
1279 sprintf(device
->pnp
.hardware_id
, "%s", hid
);
1280 device
->flags
.hardware_id
= 1;
1283 sprintf(device
->pnp
.unique_id
, "%s", uid
);
1284 device
->flags
.unique_id
= 1;
1288 * If we called get_object_info, we now are finished with the buffer,
1289 * so we can free it.
1291 //if (buffer.Pointer)
1292 //AcpiOsFree(buffer.Pointer);
1298 if (device
->flags
.power_manageable
) {
1299 result
= acpi_bus_get_power_flags(device
);
1305 * Performance Management
1306 * ----------------------
1308 if (device
->flags
.performance_manageable
) {
1309 result
= acpi_bus_get_perf_flags(device
);
1317 * Attach this 'struct acpi_device' to the ACPI object. This makes
1318 * resolutions from handle->device very efficient. Note that we need
1319 * to be careful with fixed-feature devices as they all attach to the
1323 case ACPI_BUS_TYPE_POWER_BUTTON
:
1324 case ACPI_BUS_TYPE_SLEEP_BUTTON
:
1327 status
= AcpiAttachData(device
->handle
,
1328 acpi_bus_data_handler
, device
);
1331 if (ACPI_FAILURE(status
)) {
1332 ACPI_DEBUG_PRINT((ACPI_DB_ERROR
,
1333 "Error attaching device data\n"));
1334 result
= AE_NOT_FOUND
;
1341 * Link this device to its parent and siblings.
1343 INIT_LIST_HEAD(&device
->children
);
1344 if (!device
->parent
)
1345 INIT_LIST_HEAD(&device
->node
);
1347 list_add_tail(&device
->node
, &device
->parent
->children
);
1350 * Global Device Hierarchy:
1351 * ------------------------
1352 * Register this device with the global device hierarchy.
1354 acpi_device_register(device
, parent
);
1357 * Bind _ADR-Based Devices
1358 * -----------------------
1359 * If there's a a bus address (_ADR) then we utilize the parent's
1360 * 'bind' function (if exists) to bind the ACPI- and natively-
1361 * enumerated device representations.
1363 if (device
->flags
.bus_address
) {
1364 if (device
->parent
&& device
->parent
->ops
.bind
)
1365 device
->parent
->ops
.bind(device
);
1369 * Locate & Attach Driver
1370 * ----------------------
1371 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1372 * to see if there's a driver installed for this kind of device. Note
1373 * that drivers can install before or after a device is enumerated.
1375 * TBD: Assumes LDM provides driver hot-plug capability.
1377 if (device
->flags
.hardware_id
|| device
->flags
.compatible_ids
)
1378 acpi_bus_find_driver(device
);
1382 if (device
->pnp
.cid_list
) {
1383 ExFreePool(device
->pnp
.cid_list
);
1386 return_VALUE(result
);
1396 struct acpi_device
*device
,
1401 return_VALUE(AE_NOT_FOUND
);
1403 acpi_device_unregister(device
);
1405 if (device
&& device
->pnp
.cid_list
)
1406 ExFreePool(device
->pnp
.cid_list
);
1417 struct acpi_device
*start
)
1419 ACPI_STATUS status
= AE_OK
;
1420 struct acpi_device
*parent
= NULL
;
1421 struct acpi_device
*child
= NULL
;
1422 ACPI_HANDLE phandle
= 0;
1423 ACPI_HANDLE chandle
= 0;
1424 ACPI_OBJECT_TYPE type
= 0;
1428 return_VALUE(AE_BAD_PARAMETER
);
1431 phandle
= start
->handle
;
1434 * Parse through the ACPI namespace, identify all 'devices', and
1435 * create a new 'struct acpi_device' for each.
1437 while ((level
> 0) && parent
) {
1439 status
= AcpiGetNextObject(ACPI_TYPE_ANY
, phandle
,
1443 * If this scope is exhausted then move our way back up.
1445 if (ACPI_FAILURE(status
)) {
1448 AcpiGetParent(phandle
, &phandle
);
1450 parent
= parent
->parent
;
1454 status
= AcpiGetType(chandle
, &type
);
1455 if (ACPI_FAILURE(status
))
1459 * If this is a scope object then parse it (depth-first).
1461 if (type
== ACPI_TYPE_LOCAL_SCOPE
) {
1469 * We're only interested in objects that we consider 'devices'.
1472 case ACPI_TYPE_DEVICE
:
1473 type
= ACPI_BUS_TYPE_DEVICE
;
1475 case ACPI_TYPE_PROCESSOR
:
1476 type
= ACPI_BUS_TYPE_PROCESSOR
;
1478 case ACPI_TYPE_THERMAL
:
1479 type
= ACPI_BUS_TYPE_THERMAL
;
1481 case ACPI_TYPE_POWER
:
1482 type
= ACPI_BUS_TYPE_POWER
;
1488 status
= acpi_bus_add(&child
, parent
, chandle
, type
);
1489 if (ACPI_FAILURE(status
))
1493 * If the device is present, enabled, and functioning then
1494 * parse its scope (depth-first). Note that we need to
1495 * represent absent devices to facilitate PnP notifications
1496 * -- but only the subtree head (not all of its children,
1497 * which will be enumerated when the parent is inserted).
1499 * TBD: Need notifications and other detection mechanisms
1500 * in place before we can fully implement this.
1502 if (child
->status
.present
) {
1503 status
= AcpiGetNextObject(ACPI_TYPE_ANY
, chandle
,
1505 if (ACPI_SUCCESS(status
)) {
1519 acpi_bus_scan_fixed (
1520 struct acpi_device
*root
)
1523 struct acpi_device
*device
= NULL
;
1526 return_VALUE(AE_NOT_FOUND
);
1529 * Enumerate all fixed-feature devices.
1531 if (AcpiGbl_FADT
.Flags
& ACPI_FADT_POWER_BUTTON
)
1532 result
= acpi_bus_add(&device
, acpi_root
,
1533 NULL
, ACPI_BUS_TYPE_POWER_BUTTON
);
1535 if (AcpiGbl_FADT
.Flags
& ACPI_FADT_SLEEP_BUTTON
)
1536 result
= acpi_bus_add(&device
, acpi_root
,
1537 NULL
, ACPI_BUS_TYPE_SLEEP_BUTTON
);
1539 return_VALUE(result
);
1543 /* --------------------------------------------------------------------------
1544 Initialization/Cleanup
1545 -------------------------------------------------------------------------- */
1548 acpi_bus_init_irq (void)
1550 ACPI_STATUS status
= AE_OK
;
1551 ACPI_OBJECT arg
= {ACPI_TYPE_INTEGER
};
1552 ACPI_OBJECT_LIST arg_list
= {1, &arg
};
1553 //char *message = NULL;
1555 DPRINT("acpi_bus_init_irq");
1558 * Let the system know what interrupt model we are using by
1559 * evaluating the \_PIC object, if exists.
1562 //switch (acpi_irq_model) {
1563 //case ACPI_IRQ_MODEL_PIC:
1566 //case ACPI_IRQ_MODEL_IOAPIC:
1567 // message = "IOAPIC";
1569 //case ACPI_IRQ_MODEL_IOSAPIC:
1570 // message = "IOSAPIC";
1573 // DPRINT1("Unknown interrupt routing model\n");
1574 // return_VALUE(AE_NOT_FOUND);
1577 //DPRINT("Using %s for interrupt routing\n", message);
1579 //arg.Integer.Value = acpi_irq_model;
1581 //status = AcpiEvaluateObject(NULL, "\\_PIC", &arg_list, NULL);
1582 //if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
1583 // ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n"));
1584 // return_VALUE(AE_NOT_FOUND);
1592 //acpi_early_init (void)
1594 // ACPI_STATUS status = AE_OK;
1596 // DPRINT("acpi_early_init");
1598 // if (acpi_disabled)
1601 /* enable workarounds, unless strict ACPI spec. compliance */
1602 // if (!acpi_strict)
1603 // acpi_gbl_enable_interpreter_slack = TRUE;
1605 // status = acpi_reallocate_root_table();
1606 // if (ACPI_FAILURE(status)) {
1607 // printk(KERN_ERR PREFIX
1608 // "Unable to reallocate ACPI tables\n");
1612 // status = acpi_initialize_subsystem();
1613 // if (ACPI_FAILURE(status)) {
1614 // printk(KERN_ERR PREFIX
1615 // "Unable to initialize the ACPI Interpreter\n");
1619 // status = acpi_load_tables();
1620 // if (ACPI_FAILURE(status)) {
1621 // printk(KERN_ERR PREFIX
1622 // "Unable to load the System Description Tables\n");
1627 // if (!acpi_ioapic) {
1628 // /* compatible (0) means level (3) */
1629 // if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
1630 // acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
1631 // acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
1633 // /* Set PIC-mode SCI trigger type */
1634 // acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
1635 // (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
1638 // * now that acpi_gbl_FADT is initialized,
1639 // * update it with result from INT_SRC_OVR parsing
1641 // acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
1646 // acpi_enable_subsystem(~
1647 // (ACPI_NO_HARDWARE_INIT |
1648 // ACPI_NO_ACPI_ENABLE));
1649 // if (ACPI_FAILURE(status)) {
1650 // printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
1662 acpi_bus_init (void)
1665 ACPI_STATUS status
= AE_OK
;
1667 DPRINT("acpi_bus_init");
1669 status
= AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION
);
1670 if (ACPI_FAILURE(status
)) {
1671 DPRINT1("Unable to start the ACPI Interpreter\n");
1676 * ACPI 2.0 requires the EC driver to be loaded and work before
1677 * the EC device is found in the namespace. This is accomplished
1678 * by looking for the ECDT table, and getting the EC parameters out
1681 //result = acpi_ec_ecdt_probe();
1682 /* Ignore result. Not having an ECDT is not fatal. */
1684 status
= AcpiInitializeObjects(ACPI_NO_DEVICE_INIT
| ACPI_NO_OBJECT_INIT
);
1685 if (ACPI_FAILURE(status
)) {
1686 DPRINT1("Unable to initialize ACPI objects\n");
1691 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
1692 * is necessary to enable it as early as possible.
1694 //acpi_boot_ec_enable();
1696 /* Initialize sleep structures */
1697 //acpi_sleep_init();
1700 * Get the system interrupt model and evaluate \_PIC.
1702 result
= acpi_bus_init_irq();
1707 * Register the for all standard device notifications.
1709 status
= AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT
, ACPI_SYSTEM_NOTIFY
, &acpi_bus_notify
, NULL
);
1710 if (ACPI_FAILURE(status
)) {
1711 DPRINT1("Unable to register for device notifications\n");
1712 result
= AE_NOT_FOUND
;
1717 * Create the root device in the bus's device tree
1719 result
= acpi_bus_add(&acpi_root
, NULL
, ACPI_ROOT_OBJECT
,
1720 ACPI_BUS_TYPE_SYSTEM
);
1725 * Enumerate devices in the ACPI namespace.
1727 result
= acpi_bus_scan_fixed(acpi_root
);
1729 DPRINT1("acpi_bus_scan_fixed failed\n");
1730 result
= acpi_bus_scan(acpi_root
);
1732 DPRINT1("acpi_bus_scan failed\n");
1734 //acpi_motherboard_init();
1737 /* Mimic structured exception handling */
1739 AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT
,
1740 ACPI_SYSTEM_NOTIFY
, &acpi_bus_notify
);
1743 return_VALUE(AE_NOT_FOUND
);
1747 acpi_bus_exit (void)
1749 ACPI_STATUS status
= AE_OK
;
1751 DPRINT("acpi_bus_exit");
1753 status
= AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT
,
1754 ACPI_SYSTEM_NOTIFY
, acpi_bus_notify
);
1755 if (ACPI_FAILURE(status
))
1756 DPRINT1("Error removing notify handler\n");
1758 #ifdef CONFIG_ACPI_PCI
1759 acpi_pci_root_exit();
1760 acpi_pci_link_exit();
1762 #ifdef CONFIG_ACPI_EC
1765 //acpi_power_exit();
1768 acpi_bus_remove(acpi_root
, ACPI_BUS_REMOVAL_NORMAL
);
1770 status
= AcpiTerminate();
1771 if (ACPI_FAILURE(status
))
1772 DPRINT1("Unable to terminate the ACPI Interpreter\n");
1774 DPRINT1("Interpreter disabled\n");
1785 DPRINT("acpi_init");
1787 DPRINT("Subsystem revision %08x\n",ACPI_CA_VERSION
);
1789 result
= acpi_bus_init();
1792 //pci_mmcfg_late_init();
1793 //if (!(pm_flags & PM_APM))
1794 // pm_flags |= PM_ACPI;
1796 //DPRINT1("APM is already active, exiting\n");
1804 * If the laptop falls into the DMI check table, the power state check
1805 * will be disabled in the course of device power transistion.
1807 //dmi_check_system(power_nocheck_dmi_table);
1810 * Install drivers required for proper enumeration of the
1813 acpi_system_init(); /* ACPI System */
1814 acpi_power_init(); /* ACPI Bus Power Management */
1816 //acpi_ec_init(); /* ACPI Embedded Controller */
1817 #ifdef CONFIG_ACPI_PCI
1818 if (!acpi_pci_disabled
) {
1819 acpi_pci_link_init(); /* ACPI PCI Interrupt Link */
1820 acpi_pci_root_init(); /* ACPI PCI Root Bridge */
1826 //acpi_power_init();
1827 //acpi_system_init();
1828 //acpi_debug_init();
1829 //acpi_sleep_proc_init();
1830 //acpi_wakeup_device_init();
1839 DPRINT("acpi_exit");