ACPICA: Restructure includes into public/private
[deliverable/linux.git] / drivers / acpi / events / evmisc.c
index 21cb749d0c75567534ebee05c78551bb289f1972..16f2c1a00167cbfac9addeb329fbb5f4fcca64db 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
  */
 
 #include <acpi/acpi.h>
+#include <acpi/accommon.h>
 #include <acpi/acevents.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acinterp.h>
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evmisc")
 
-/* Names for Notify() values, used for debug output */
-#ifdef ACPI_DEBUG_OUTPUT
-static const char *acpi_notify_value_names[] = {
-       "Bus Check",
-       "Device Check",
-       "Device Wake",
-       "Eject Request",
-       "Device Check Light",
-       "Frequency Mismatch",
-       "Bus Mode Mismatch",
-       "Power Fault"
-};
-#endif
-
-/* Pointer to FACS needed for the Global Lock */
-
-static struct acpi_table_facs *facs = NULL;
-
 /* Local prototypes */
-
 static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
 
 static u32 acpi_ev_global_lock_handler(void *context);
@@ -94,7 +76,6 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
        switch (node->type) {
        case ACPI_TYPE_DEVICE:
        case ACPI_TYPE_PROCESSOR:
-       case ACPI_TYPE_POWER:
        case ACPI_TYPE_THERMAL:
                /*
                 * These are the ONLY objects that can receive ACPI notifications
@@ -139,17 +120,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
         *   initiate soft-off or sleep operation?
         */
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                         "Dispatching Notify(%X) on node %p\n", notify_value,
-                         node));
-
-       if (notify_value <= 7) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n",
-                                 acpi_notify_value_names[notify_value]));
-       } else {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Notify value: 0x%2.2X **Device Specific**\n",
-                                 notify_value));
-       }
+                         "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
+                         acpi_ut_get_node_name(node), node, notify_value,
+                         acpi_ut_get_notify_name(notify_value)));
 
        /* Get the notify object attached to the NS Node */
 
@@ -159,10 +132,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                /* We have the notify object, Get the right handler */
 
                switch (node->type) {
+
+                       /* Notify allowed only on these types */
+
                case ACPI_TYPE_DEVICE:
                case ACPI_TYPE_THERMAL:
                case ACPI_TYPE_PROCESSOR:
-               case ACPI_TYPE_POWER:
 
                        if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
                                handler_obj =
@@ -174,13 +149,20 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                        break;
 
                default:
+
                        /* All other types are not supported */
+
                        return (AE_TYPE);
                }
        }
 
-       /* If there is any handler to run, schedule the dispatcher */
-
+       /*
+        * If there is any handler to run, schedule the dispatcher.
+        * Check for:
+        * 1) Global system notify handler
+        * 2) Global device notify handler
+        * 3) Per-device notify handler
+        */
        if ((acpi_gbl_system_notify.handler
             && (notify_value <= ACPI_MAX_SYS_NOTIFY))
            || (acpi_gbl_device_notify.handler
@@ -190,6 +172,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                        return (AE_NO_MEMORY);
                }
 
+               if (!handler_obj) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                         "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+                                         acpi_ut_get_node_name(node),
+                                         notify_value, node));
+               }
+
                notify_info->common.descriptor_type =
                    ACPI_DESC_TYPE_STATE_NOTIFY;
                notify_info->notify.node = node;
@@ -202,15 +191,11 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                if (ACPI_FAILURE(status)) {
                        acpi_ut_delete_generic_state(notify_info);
                }
-       }
+       } else {
+               /* There is no notify handler (per-device or system) for this device */
 
-       if (!handler_obj) {
-               /*
-                * There is no per-device notify handler for this device.
-                * This may or may not be a problem.
-                */
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "No notify handler for Notify(%4.4s, %X) node %p\n",
+                                 "No notify handler for Notify (%4.4s, %X) node %p\n",
                                  acpi_ut_get_node_name(node), notify_value,
                                  node));
        }
@@ -242,9 +227,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
        ACPI_FUNCTION_ENTRY();
 
        /*
-        * We will invoke a global notify handler if installed.
-        * This is done _before_ we invoke the per-device handler attached
-        * to the device.
+        * We will invoke a global notify handler if installed. This is done
+        * _before_ we invoke the per-device handler attached to the device.
         */
        if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
 
@@ -312,7 +296,7 @@ static u32 acpi_ev_global_lock_handler(void *context)
         * If we don't get it now, it will be marked pending and we will
         * take another interrupt when it becomes free.
         */
-       ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
+       ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
        if (acquired) {
 
                /* Got the lock, now wake all threads waiting for it */
@@ -349,33 +333,27 @@ acpi_status acpi_ev_init_global_lock_handler(void)
 
        ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
 
-       status =
-           acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
-                                   (struct acpi_table_header **)&facs);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
+       /* Attempt installation of the global lock handler */
 
-       acpi_gbl_global_lock_present = TRUE;
        status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
                                                  acpi_ev_global_lock_handler,
                                                  NULL);
 
        /*
-        * If the global lock does not exist on this platform, the attempt
-        * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick)
-        * Map to AE_OK, but mark global lock as not present.
-        * Any attempt to actually use the global lock will be flagged
-        * with an error.
+        * If the global lock does not exist on this platform, the attempt to
+        * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
+        * Map to AE_OK, but mark global lock as not present. Any attempt to
+        * actually use the global lock will be flagged with an error.
         */
        if (status == AE_NO_HARDWARE_RESPONSE) {
                ACPI_ERROR((AE_INFO,
                            "No response from Global Lock hardware, disabling lock"));
 
                acpi_gbl_global_lock_present = FALSE;
-               status = AE_OK;
+               return_ACPI_STATUS(AE_OK);
        }
 
+       acpi_gbl_global_lock_present = TRUE;
        return_ACPI_STATUS(status);
 }
 
@@ -439,7 +417,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
         * Only one thread can acquire the GL at a time, the global_lock_mutex
         * enforces this. This interface releases the interpreter if we must wait.
         */
-       status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0);
+       status = acpi_ex_system_wait_mutex(
+                       acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
        if (status == AE_TIME) {
                if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
                        acpi_ev_global_lock_acquired++;
@@ -448,9 +427,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
        }
 
        if (ACPI_FAILURE(status)) {
-               status =
-                   acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex,
-                                             timeout);
+               status = acpi_ex_system_wait_mutex(
+                               acpi_gbl_global_lock_mutex->mutex.os_mutex,
+                               timeout);
        }
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
@@ -460,8 +439,21 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
        acpi_ev_global_lock_acquired++;
 
        /*
-        * Make sure that a global lock actually exists. If not, just treat
-        * the lock as a standard mutex.
+        * Update the global lock handle and check for wraparound. The handle is
+        * only used for the external global lock interfaces, but it is updated
+        * here to properly handle the case where a single thread may acquire the
+        * lock via both the AML and the acpi_acquire_global_lock interfaces. The
+        * handle is therefore updated on the first acquire from a given thread
+        * regardless of where the acquisition request originated.
+        */
+       acpi_gbl_global_lock_handle++;
+       if (acpi_gbl_global_lock_handle == 0) {
+               acpi_gbl_global_lock_handle = 1;
+       }
+
+       /*
+        * Make sure that a global lock actually exists. If not, just treat the
+        * lock as a standard mutex.
         */
        if (!acpi_gbl_global_lock_present) {
                acpi_gbl_global_lock_acquired = TRUE;
@@ -470,7 +462,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
 
        /* Attempt to acquire the actual hardware lock */
 
-       ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
+       ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
        if (acquired) {
 
                /* We got the lock */
@@ -534,7 +526,7 @@ acpi_status acpi_ev_release_global_lock(void)
 
                /* Allow any thread to release the lock */
 
-               ACPI_RELEASE_GLOBAL_LOCK(facs, pending);
+               ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
 
                /*
                 * If the pending bit was set, we must write GBL_RLS to the control
@@ -555,7 +547,7 @@ acpi_status acpi_ev_release_global_lock(void)
        /* Release the local GL mutex */
        acpi_ev_global_lock_thread_id = NULL;
        acpi_ev_global_lock_acquired = 0;
-       acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
+       acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
        return_ACPI_STATUS(status);
 }
 
@@ -573,21 +565,21 @@ acpi_status acpi_ev_release_global_lock(void)
 
 void acpi_ev_terminate(void)
 {
-       acpi_native_uint i;
+       u32 i;
        acpi_status status;
 
        ACPI_FUNCTION_TRACE(ev_terminate);
 
        if (acpi_gbl_events_initialized) {
                /*
-                * Disable all event-related functionality.
-                * In all cases, on error, print a message but obviously we don't abort.
+                * Disable all event-related functionality. In all cases, on error,
+                * print a message but obviously we don't abort.
                 */
 
                /* Disable all fixed events */
 
                for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
-                       status = acpi_disable_event((u32) i, 0);
+                       status = acpi_disable_event(i, 0);
                        if (ACPI_FAILURE(status)) {
                                ACPI_ERROR((AE_INFO,
                                            "Could not disable fixed event %d",
@@ -597,7 +589,7 @@ void acpi_ev_terminate(void)
 
                /* Disable all GPEs in all GPE blocks */
 
-               status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block);
+               status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
 
                /* Remove SCI handler */
 
@@ -615,7 +607,7 @@ void acpi_ev_terminate(void)
 
        /* Deallocate all handler objects installed within GPE info structs */
 
-       status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers);
+       status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL);
 
        /* Return to original mode if necessary */
 
This page took 0.03229 seconds and 5 git commands to generate.