]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'bugzilla-15100' into release
authorLen Brown <len.brown@intel.com>
Wed, 12 Jan 2011 09:58:51 +0000 (04:58 -0500)
committerLen Brown <len.brown@intel.com>
Wed, 12 Jan 2011 09:58:51 +0000 (04:58 -0500)
44 files changed:
arch/ia64/include/asm/io.h
arch/x86/kernel/e820.c
drivers/acpi/Makefile
drivers/acpi/acpica/Makefile
drivers/acpi/acpica/acevents.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/achware.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/evevent.c
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/evgpeblk.c
drivers/acpi/acpica/evgpeinit.c
drivers/acpi/acpica/evgpeutil.c
drivers/acpi/acpica/evmisc.c
drivers/acpi/acpica/evxface.c
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/evxfgpe.c [new file with mode: 0644]
drivers/acpi/acpica/hwgpe.c
drivers/acpi/acpica/utglobal.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/internal.h
drivers/acpi/nvs.c [moved from kernel/power/nvs.c with 86% similarity]
drivers/acpi/osl.c
drivers/acpi/power.c
drivers/acpi/proc.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/thermal.c
drivers/acpi/wakeup.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/platform/x86/fujitsu-laptop.c
include/acpi/acpi_bus.h
include/acpi/acpixf.h
include/acpi/actypes.h
include/linux/acpi.h
include/linux/suspend.h
kernel/power/Kconfig
kernel/power/Makefile

index cc8335eb3110f257fb64bbd19dc202156d904a83..e5a6c3530c6cbeca311bdc40108d4e51bc51d5cc 100644 (file)
@@ -426,6 +426,11 @@ extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size)
 extern void iounmap (volatile void __iomem *addr);
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
+static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
+{
+       return ioremap(phys_addr, size);
+}
+
 
 /*
  * String version of IO memory access ops:
index 0c2b7ef7a34d5453d510ba3a598e5b15c2af6b53..294f26da0c0ce448f294ceacd162da3ff77b1f5f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/bootmem.h>
 #include <linux/pfn.h>
 #include <linux/suspend.h>
+#include <linux/acpi.h>
 #include <linux/firmware-map.h>
 #include <linux/memblock.h>
 
index 3d031d02e54b556a038be7ae2a64ebde1fa92f84..9cc9f2c4da79e7fd5322d7c001c117e66295735b 100644 (file)
@@ -24,7 +24,7 @@ acpi-y                                += atomicio.o
 # sleep related files
 acpi-y                         += wakeup.o
 acpi-y                         += sleep.o
-acpi-$(CONFIG_ACPI_SLEEP)      += proc.o
+acpi-$(CONFIG_ACPI_SLEEP)      += proc.o nvs.o
 
 
 #
index a7e1d1aa4107c29d454e774ce912e60b7ace4ce5..eec2eadd24310d7742ddc2f26847cc390d382abe 100644 (file)
@@ -14,7 +14,7 @@ acpi-y := dsfield.o   dsmthdat.o  dsopcode.o  dswexec.o  dswscope.o \
 
 acpi-y += evevent.o  evregion.o  evsci.o    evxfevnt.o \
         evmisc.o   evrgnini.o  evxface.o  evxfregn.o \
-        evgpe.o    evgpeblk.o evgpeinit.o  evgpeutil.o
+        evgpe.o    evgpeblk.o evgpeinit.o  evgpeutil.o evxfgpe.o
 
 acpi-y += exconfig.o  exfield.o  exnames.o   exoparg6.o  exresolv.o  exstorob.o\
         exconvrt.o  exfldio.o  exoparg1.o  exprep.o    exresop.o   exsystem.o\
index a6f99cc37a19947ece8c6ebb322687320e6d2853..70e0b28801aa0bffc0ceafb7d1defa576eda9111 100644 (file)
@@ -51,8 +51,6 @@ acpi_status acpi_ev_initialize_events(void);
 
 acpi_status acpi_ev_install_xrupt_handlers(void);
 
-acpi_status acpi_ev_install_fadt_gpes(void);
-
 u32 acpi_ev_fixed_event_detect(void);
 
 /*
@@ -82,9 +80,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
 
-acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
 
-acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
 
 struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
                                                       u32 gpe_number);
@@ -93,6 +91,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
                                                     struct acpi_gpe_block_info
                                                     *gpe_block);
 
+acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info);
+
 /*
  * evgpeblk - Upper-level GPE block support
  */
@@ -107,12 +107,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
 acpi_status
 acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
                             struct acpi_gpe_block_info *gpe_block,
-                            void *ignored);
+                            void *context);
 
 acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
 
 u32
-acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,
+acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
+                    struct acpi_gpe_event_info *gpe_event_info,
                     u32 gpe_number);
 
 /*
@@ -126,10 +127,6 @@ acpi_status
 acpi_ev_match_gpe_method(acpi_handle obj_handle,
                         u32 level, void *context, void **return_value);
 
-acpi_status
-acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
-                         u32 level, void *context, void **return_value);
-
 /*
  * evgpeutil - GPE utilities
  */
@@ -138,6 +135,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context);
 
 u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
 
+acpi_status
+acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+                      struct acpi_gpe_block_info *gpe_block, void *context);
+
 struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number);
 
 acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
index ad88fcae4eb9859be0c4ecf8d2780ab42dbf621e..9bb69c59bb12978fb0c33d239f6014007253d28f 100644 (file)
@@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running;
 
 extern u32 acpi_gbl_nesting_level;
 
+ACPI_EXTERN u32 acpi_gpe_count;
+ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
+
 /* Support for dynamic control method tracing mechanism */
 
 ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
@@ -370,7 +373,9 @@ ACPI_EXTERN struct acpi_fixed_event_handler
 ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
 ACPI_EXTERN struct acpi_gpe_block_info
 *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
-ACPI_EXTERN u8 acpi_all_gpes_initialized;
+ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
+ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
+ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
 
 /*****************************************************************************
  *
index 167470ad2d21756874592a51617a499f10e84907..258d628793eae2476cab0a7f9f8ec2ab5d53f651 100644 (file)
@@ -94,7 +94,7 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
                             struct acpi_gpe_register_info *gpe_register_info);
 
 acpi_status
-acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action);
+acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
 
 acpi_status
 acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
index 2ceb0c05b2d7d158a8f5489ac21fe445f4a9980f..74000f5b7daba14c0f1f3e364d02bf3694b7a020 100644 (file)
@@ -408,17 +408,18 @@ struct acpi_predefined_data {
 
 /* Dispatch info for each GPE -- either a method or handler, cannot be both */
 
-struct acpi_handler_info {
-       acpi_event_handler address;     /* Address of handler, if any */
+struct acpi_gpe_handler_info {
+       acpi_gpe_handler address;       /* Address of handler, if any */
        void *context;          /* Context to be passed to handler */
        struct acpi_namespace_node *method_node;        /* Method node for this GPE level (saved) */
-       u8 orig_flags;          /* Original misc info about this GPE */
-       u8 orig_enabled;        /* Set if the GPE was originally enabled */
+       u8 original_flags;      /* Original (pre-handler) GPE info */
+       u8 originally_enabled;  /* True if GPE was originally enabled */
 };
 
 union acpi_gpe_dispatch_info {
        struct acpi_namespace_node *method_node;        /* Method node for this GPE level */
-       struct acpi_handler_info *handler;
+       struct acpi_gpe_handler_info *handler;  /* Installed GPE handler */
+       struct acpi_namespace_node *device_node;        /* Parent _PRW device for implicit notify */
 };
 
 /*
@@ -458,7 +459,7 @@ struct acpi_gpe_block_info {
        u32 register_count;     /* Number of register pairs in block */
        u16 gpe_count;          /* Number of individual GPEs in block */
        u8 block_base_number;   /* Base GPE number for this block */
-       u8 initialized;         /* If set, the GPE block has been initialized */
+       u8 initialized;         /* TRUE if this block is initialized */
 };
 
 /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
index c61c3039c31ac3b951203640c555bb807f81c4b0..e5e313c663a57190a03edfdb2e43db6d1302e6f0 100644 (file)
@@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void)
                     status_bit_mask)
                    && (fixed_enable & acpi_gbl_fixed_event_info[i].
                        enable_bit_mask)) {
+                       /*
+                        * Found an active (signalled) event. Invoke global event
+                        * handler if present.
+                        */
+                       acpi_fixed_event_count[i]++;
+                       if (acpi_gbl_global_event_handler) {
+                               acpi_gbl_global_event_handler
+                                   (ACPI_EVENT_TYPE_FIXED, NULL, i,
+                                    acpi_gbl_global_event_handler_context);
+                       }
 
-                       /* Found an active (signalled) event */
-                       acpi_os_fixed_event_count(i);
                        int_status |= acpi_ev_fixed_event_dispatch(i);
                }
        }
index f226eac314db587668a32e8cc75cd6bfd931b5f4..7c339d34ab422dffe32028cb284513910390ddf3 100644 (file)
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("evgpe")
 /* Local prototypes */
 static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
 
+static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_update_gpe_enable_mask
@@ -102,7 +104,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Clear the given GPE from stale events and enable it.
+ * DESCRIPTION: Clear a GPE of stale events and enable it.
  *
  ******************************************************************************/
 acpi_status
@@ -113,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
        ACPI_FUNCTION_TRACE(ev_enable_gpe);
 
        /*
-        * We will only allow a GPE to be enabled if it has either an
-        * associated method (_Lxx/_Exx) or a handler. Otherwise, the
-        * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
-        * first time it fires.
+        * We will only allow a GPE to be enabled if it has either an associated
+        * method (_Lxx/_Exx) or a handler, or is using the implicit notify
+        * feature. Otherwise, the GPE will be immediately disabled by
+        * acpi_ev_gpe_dispatch the first time it fires.
         */
-       if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
+       if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+           ACPI_GPE_DISPATCH_NONE) {
                return_ACPI_STATUS(AE_NO_HANDLER);
        }
 
@@ -137,9 +140,9 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_raw_enable_gpe
+ * FUNCTION:    acpi_ev_add_gpe_reference
  *
- * PARAMETERS:  gpe_event_info  - GPE to enable
+ * PARAMETERS:  gpe_event_info          - Add a reference to this GPE
  *
  * RETURN:      Status
  *
@@ -148,16 +151,21 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
  *
  ******************************************************************************/
 
-acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
 {
        acpi_status status = AE_OK;
 
+       ACPI_FUNCTION_TRACE(ev_add_gpe_reference);
+
        if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
                return_ACPI_STATUS(AE_LIMIT);
        }
 
        gpe_event_info->runtime_count++;
        if (gpe_event_info->runtime_count == 1) {
+
+               /* Enable on first reference */
+
                status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
                if (ACPI_SUCCESS(status)) {
                        status = acpi_ev_enable_gpe(gpe_event_info);
@@ -173,9 +181,9 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_raw_disable_gpe
+ * FUNCTION:    acpi_ev_remove_gpe_reference
  *
- * PARAMETERS:  gpe_event_info  - GPE to disable
+ * PARAMETERS:  gpe_event_info          - Remove a reference to this GPE
  *
  * RETURN:      Status
  *
@@ -184,16 +192,21 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
  *
  ******************************************************************************/
 
-acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
 {
        acpi_status status = AE_OK;
 
+       ACPI_FUNCTION_TRACE(ev_remove_gpe_reference);
+
        if (!gpe_event_info->runtime_count) {
                return_ACPI_STATUS(AE_LIMIT);
        }
 
        gpe_event_info->runtime_count--;
        if (!gpe_event_info->runtime_count) {
+
+               /* Disable on last reference */
+
                status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
                if (ACPI_SUCCESS(status)) {
                        status = acpi_hw_low_set_gpe(gpe_event_info,
@@ -379,7 +392,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
                        }
 
                        ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
-                                         "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
+                                         "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
                                          gpe_register_info->base_gpe_number,
                                          status_reg, enable_reg));
 
@@ -405,7 +418,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
                                         * or method.
                                         */
                                        int_status |=
-                                           acpi_ev_gpe_dispatch(&gpe_block->
+                                           acpi_ev_gpe_dispatch(gpe_block->
+                                                                node,
+                                                                &gpe_block->
                                                event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
                                }
                        }
@@ -435,17 +450,25 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
  *              an interrupt handler.
  *
  ******************************************************************************/
-static void acpi_ev_asynch_enable_gpe(void *context);
 
 static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
 {
-       struct acpi_gpe_event_info *gpe_event_info = (void *)context;
+       struct acpi_gpe_event_info *gpe_event_info = context;
        acpi_status status;
-       struct acpi_gpe_event_info local_gpe_event_info;
+       struct acpi_gpe_event_info *local_gpe_event_info;
        struct acpi_evaluate_info *info;
 
        ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
 
+       /* Allocate a local GPE block */
+
+       local_gpe_event_info =
+           ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
+       if (!local_gpe_event_info) {
+               ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
+               return_VOID;
+       }
+
        status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
        if (ACPI_FAILURE(status)) {
                return_VOID;
@@ -462,7 +485,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
         * Take a snapshot of the GPE info for this level - we copy the info to
         * prevent a race condition with remove_handler/remove_block.
         */
-       ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info,
+       ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
                    sizeof(struct acpi_gpe_event_info));
 
        status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
@@ -470,12 +493,26 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
                return_VOID;
        }
 
-       /*
-        * Must check for control method type dispatch one more time to avoid a
-        * race with ev_gpe_install_handler
-        */
-       if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
-           ACPI_GPE_DISPATCH_METHOD) {
+       /* Do the correct dispatch - normal method or implicit notify */
+
+       switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
+       case ACPI_GPE_DISPATCH_NOTIFY:
+
+               /*
+                * Implicit notify.
+                * Dispatch a DEVICE_WAKE notify to the appropriate handler.
+                * NOTE: the request is queued for execution after this method
+                * completes. The notify handlers are NOT invoked synchronously
+                * from this thread -- because handlers may in turn run other
+                * control methods.
+                */
+               status =
+                   acpi_ev_queue_notify_request(local_gpe_event_info->dispatch.
+                                                device_node,
+                                                ACPI_NOTIFY_DEVICE_WAKE);
+               break;
+
+       case ACPI_GPE_DISPATCH_METHOD:
 
                /* Allocate the evaluation information block */
 
@@ -488,7 +525,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
                         * control method that corresponds to this GPE
                         */
                        info->prefix_node =
-                           local_gpe_event_info.dispatch.method_node;
+                           local_gpe_event_info->dispatch.method_node;
                        info->flags = ACPI_IGNORE_RETURN_VALUE;
 
                        status = acpi_ns_evaluate(info);
@@ -499,46 +536,98 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
                        ACPI_EXCEPTION((AE_INFO, status,
                                        "while evaluating GPE method [%4.4s]",
                                        acpi_ut_get_node_name
-                                       (local_gpe_event_info.dispatch.
+                                       (local_gpe_event_info->dispatch.
                                         method_node)));
                }
+
+               break;
+
+       default:
+               return_VOID;    /* Should never happen */
        }
+
        /* Defer enabling of GPE until all notify handlers are done */
-       acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
-                               gpe_event_info);
+
+       status = acpi_os_execute(OSL_NOTIFY_HANDLER,
+                                acpi_ev_asynch_enable_gpe,
+                                local_gpe_event_info);
+       if (ACPI_FAILURE(status)) {
+               ACPI_FREE(local_gpe_event_info);
+       }
        return_VOID;
 }
 
-static void acpi_ev_asynch_enable_gpe(void *context)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_asynch_enable_gpe
+ *
+ * PARAMETERS:  Context (gpe_event_info) - Info for this GPE
+ *              Callback from acpi_os_execute
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
+ *              complete (i.e., finish execution of Notify)
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
 {
        struct acpi_gpe_event_info *gpe_event_info = context;
+
+       (void)acpi_ev_finish_gpe(gpe_event_info);
+
+       ACPI_FREE(gpe_event_info);
+       return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_finish_gpe
+ *
+ * PARAMETERS:  gpe_event_info      - Info for this GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
+ *              of a GPE method or a synchronous or asynchronous GPE handler.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
+{
        acpi_status status;
+
        if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
            ACPI_GPE_LEVEL_TRIGGERED) {
                /*
-                * GPE is level-triggered, we clear the GPE status bit after handling
-                * the event.
+                * GPE is level-triggered, we clear the GPE status bit after
+                * handling the event.
                 */
                status = acpi_hw_clear_gpe(gpe_event_info);
                if (ACPI_FAILURE(status)) {
-                       return_VOID;
+                       return (status);
                }
        }
 
        /*
-        * Enable this GPE, conditionally. This means that the GPE will only be
-        * physically enabled if the enable_for_run bit is set in the event_info
+        * Enable this GPE, conditionally. This means that the GPE will
+        * only be physically enabled if the enable_for_run bit is set
+        * in the event_info.
         */
-       (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE);
-
-       return_VOID;
+       (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
+       return (AE_OK);
 }
 
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_gpe_dispatch
  *
- * PARAMETERS:  gpe_event_info  - Info for this GPE
+ * PARAMETERS:  gpe_device      - Device node. NULL for GPE0/GPE1
+ *              gpe_event_info  - Info for this GPE
  *              gpe_number      - Number relative to the parent GPE block
  *
  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
@@ -551,13 +640,22 @@ static void acpi_ev_asynch_enable_gpe(void *context)
  ******************************************************************************/
 
 u32
-acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
+acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
+                   struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 {
        acpi_status status;
+       u32 return_value;
 
        ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
 
-       acpi_os_gpe_count(gpe_number);
+       /* Invoke global event handler if present */
+
+       acpi_gpe_count++;
+       if (acpi_gbl_global_event_handler) {
+               acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
+                                             gpe_number,
+                                             acpi_gbl_global_event_handler_context);
+       }
 
        /*
         * If edge-triggered, clear the GPE status bit now. Note that
@@ -568,59 +666,55 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
                status = acpi_hw_clear_gpe(gpe_event_info);
                if (ACPI_FAILURE(status)) {
                        ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to clear GPE[0x%2X]",
-                                       gpe_number));
+                                       "Unable to clear GPE%02X", gpe_number));
                        return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
                }
        }
 
        /*
-        * Dispatch the GPE to either an installed handler, or the control method
-        * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
-        * it and do not attempt to run the method. If there is neither a handler
-        * nor a method, we disable this GPE to prevent further such pointless
-        * events from firing.
+        * Always disable the GPE so that it does not keep firing before
+        * any asynchronous activity completes (either from the execution
+        * of a GPE method or an asynchronous GPE handler.)
+        *
+        * If there is no handler or method to run, just disable the
+        * GPE and leave it disabled permanently to prevent further such
+        * pointless events from firing.
+        */
+       status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "Unable to disable GPE%02X", gpe_number));
+               return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+       }
+
+       /*
+        * Dispatch the GPE to either an installed handler or the control
+        * method associated with this GPE (_Lxx or _Exx). If a handler
+        * exists, we invoke it and do not attempt to run the method.
+        * If there is neither a handler nor a method, leave the GPE
+        * disabled.
         */
        switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
        case ACPI_GPE_DISPATCH_HANDLER:
 
-               /*
-                * Invoke the installed handler (at interrupt level)
-                * Ignore return status for now.
-                * TBD: leave GPE disabled on error?
-                */
-               (void)gpe_event_info->dispatch.handler->address(gpe_event_info->
-                                                               dispatch.
-                                                               handler->
-                                                               context);
+               /* Invoke the installed handler (at interrupt level) */
 
-               /* It is now safe to clear level-triggered events. */
+               return_value =
+                   gpe_event_info->dispatch.handler->address(gpe_device,
+                                                             gpe_number,
+                                                             gpe_event_info->
+                                                             dispatch.handler->
+                                                             context);
 
-               if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
-                   ACPI_GPE_LEVEL_TRIGGERED) {
-                       status = acpi_hw_clear_gpe(gpe_event_info);
-                       if (ACPI_FAILURE(status)) {
-                               ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to clear GPE[0x%2X]",
-                                               gpe_number));
-                               return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
-                       }
+               /* If requested, clear (if level-triggered) and reenable the GPE */
+
+               if (return_value & ACPI_REENABLE_GPE) {
+                       (void)acpi_ev_finish_gpe(gpe_event_info);
                }
                break;
 
        case ACPI_GPE_DISPATCH_METHOD:
-
-               /*
-                * Disable the GPE, so it doesn't keep firing before the method has a
-                * chance to run (it runs asynchronously with interrupts enabled).
-                */
-               status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
-               if (ACPI_FAILURE(status)) {
-                       ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to disable GPE[0x%2X]",
-                                       gpe_number));
-                       return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
-               }
+       case ACPI_GPE_DISPATCH_NOTIFY:
 
                /*
                 * Execute the method associated with the GPE
@@ -631,7 +725,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
                                         gpe_event_info);
                if (ACPI_FAILURE(status)) {
                        ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to queue handler for GPE[0x%2X] - event disabled",
+                                       "Unable to queue handler for GPE%2X - event disabled",
                                        gpe_number));
                }
                break;
@@ -644,20 +738,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
                 * a GPE to be enabled if it has no handler or method.
                 */
                ACPI_ERROR((AE_INFO,
-                           "No handler or method for GPE[0x%2X], disabling event",
+                           "No handler or method for GPE%02X, disabling event",
                            gpe_number));
 
-               /*
-                * Disable the GPE. The GPE will remain disabled a handler
-                * is installed or ACPICA is restarted.
-                */
-               status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
-               if (ACPI_FAILURE(status)) {
-                       ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to disable GPE[0x%2X]",
-                                       gpe_number));
-                       return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
-               }
                break;
        }
 
index 020add3eee1c65bfa5d7e03b3d1fee5a074558c2..9acb86958c099c0bd84703f6179528a63b90fcfd 100644 (file)
@@ -361,9 +361,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
 
        gpe_block->node = gpe_device;
        gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
+       gpe_block->initialized = FALSE;
        gpe_block->register_count = register_count;
        gpe_block->block_base_number = gpe_block_base_number;
-       gpe_block->initialized = FALSE;
 
        ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
                    sizeof(struct acpi_generic_address));
@@ -386,7 +386,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
                return_ACPI_STATUS(status);
        }
 
-       acpi_all_gpes_initialized = FALSE;
+       acpi_gbl_all_gpes_initialized = FALSE;
 
        /* Find all GPE methods (_Lxx or_Exx) for this block */
 
@@ -423,14 +423,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
  *
  * FUNCTION:    acpi_ev_initialize_gpe_block
  *
- * PARAMETERS:  gpe_device          - Handle to the parent GPE block
- *              gpe_block           - Gpe Block info
+ * PARAMETERS:  acpi_gpe_callback
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Initialize and enable a GPE block. First find and run any
- *              _PRT methods associated with the block, then enable the
- *              appropriate GPEs.
+ * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
+ *              associated methods.
  *              Note: Assumes namespace is locked.
  *
  ******************************************************************************/
@@ -450,8 +448,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
        ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
 
        /*
-        * Ignore a null GPE block (e.g., if no GPE block 1 exists) and
-        * GPE blocks that have been initialized already.
+        * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
+        * any GPE blocks that have been initialized already.
         */
        if (!gpe_block || gpe_block->initialized) {
                return_ACPI_STATUS(AE_OK);
@@ -459,8 +457,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
 
        /*
         * Enable all GPEs that have a corresponding method and have the
-        * ACPI_GPE_CAN_WAKE flag unset.  Any other GPEs within this block must
-        * be enabled via the acpi_enable_gpe() interface.
+        * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
+        * must be enabled via the acpi_enable_gpe() interface.
         */
        gpe_enabled_count = 0;
 
@@ -472,14 +470,19 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
                        gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
                        gpe_event_info = &gpe_block->event_info[gpe_index];
 
-                       /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
-
-                       if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
+                       /*
+                        * Ignore GPEs that have no corresponding _Lxx/_Exx method
+                        * and GPEs that are used to wake the system
+                        */
+                       if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+                            ACPI_GPE_DISPATCH_NONE)
+                           || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
+                               == ACPI_GPE_DISPATCH_HANDLER)
                            || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
                                continue;
                        }
 
-                       status = acpi_raw_enable_gpe(gpe_event_info);
+                       status = acpi_ev_add_gpe_reference(gpe_event_info);
                        if (ACPI_FAILURE(status)) {
                                ACPI_EXCEPTION((AE_INFO, status,
                                        "Could not enable GPE 0x%02X",
index 4c8dea513b66adeea7881d7f541237c812e5bf14..c59dc23405939b04492b897286202258933756a3 100644 (file)
 #include "accommon.h"
 #include "acevents.h"
 #include "acnamesp.h"
-#include "acinterp.h"
 
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evgpeinit")
 
+/*
+ * Note: History of _PRW support in ACPICA
+ *
+ * Originally (2000 - 2010), the GPE initialization code performed a walk of
+ * the entire namespace to execute the _PRW methods and detect all GPEs
+ * capable of waking the system.
+ *
+ * As of 10/2010, the _PRW method execution has been removed since it is
+ * actually unnecessary. The host OS must in fact execute all _PRW methods
+ * in order to identify the device/power-resource dependencies. We now put
+ * the onus on the host OS to identify the wake GPEs as part of this process
+ * and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This
+ * not only reduces the complexity of the ACPICA initialization code, but in
+ * some cases (on systems with very large namespaces) it should reduce the
+ * kernel boot time as well.
+ */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_gpe_initialize
@@ -222,7 +238,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
        acpi_status status = AE_OK;
 
        /*
-        * 2) Find any _Lxx/_Exx GPE methods that have just been loaded.
+        * Find any _Lxx/_Exx GPE methods that have just been loaded.
         *
         * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
         * enabled.
@@ -235,9 +251,9 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
                return;
        }
 
+       walk_info.count = 0;
        walk_info.owner_id = table_owner_id;
        walk_info.execute_by_owner_id = TRUE;
-       walk_info.count = 0;
 
        /* Walk the interrupt level descriptor list */
 
@@ -298,7 +314,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
  *                  xx     - is the GPE number [in HEX]
  *
  * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
- *    with that owner.
+ * with that owner.
  *
  ******************************************************************************/
 
@@ -415,6 +431,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
         * Add the GPE information from above to the gpe_event_info block for
         * use during dispatch of this GPE.
         */
+       gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK);
        gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
        gpe_event_info->dispatch.method_node = method_node;
 
index 19a0e513ea48354fac1f1d48ddf135b3d79d6a39..10e477494dcf5fdedf4bd7ad787cdfc77587d1b4 100644 (file)
@@ -152,6 +152,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
        return (FALSE);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_get_gpe_device
+ *
+ * PARAMETERS:  GPE_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
+ *              block device. NULL if the GPE is one of the FADT-defined GPEs.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+                      struct acpi_gpe_block_info *gpe_block, void *context)
+{
+       struct acpi_gpe_device_info *info = context;
+
+       /* Increment Index by the number of GPEs in this block */
+
+       info->next_block_base_index += gpe_block->gpe_count;
+
+       if (info->index < info->next_block_base_index) {
+               /*
+                * The GPE index is within this block, get the node. Leave the node
+                * NULL for the FADT-defined GPEs
+                */
+               if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
+                       info->gpe_device = gpe_block->node;
+               }
+
+               info->status = AE_OK;
+               return (AE_CTRL_END);
+       }
+
+       return (AE_OK);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_get_gpe_xrupt_block
index fcaed9fb44ff1957dee8864d3d4feba13ec3f8ba..8e31bb5a973ae2483129781eb756089554d7b694 100644 (file)
@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
  * RETURN:      ACPI_INTERRUPT_HANDLED
  *
  * DESCRIPTION: Invoked directly from the SCI handler when a global lock
- *              release interrupt occurs. Attempt to acquire the global lock,
- *              if successful, signal the thread waiting for the lock.
+ *              release interrupt occurs.  If there's a thread waiting for
+ *              the global lock, signal it.
  *
  * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
  * this is not possible for some reason, a separate thread will have to be
  * scheduled to do this.
  *
  ******************************************************************************/
+static u8 acpi_ev_global_lock_pending;
+static spinlock_t _acpi_ev_global_lock_pending_lock;
+#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
 
 static u32 acpi_ev_global_lock_handler(void *context)
 {
-       u8 acquired = FALSE;
+       acpi_status status;
+       acpi_cpu_flags flags;
 
-       /*
-        * Attempt to get the lock.
-        *
-        * 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(acpi_gbl_FACS, acquired);
-       if (acquired) {
+       flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
 
-               /* Got the lock, now wake all threads waiting for it */
+       if (!acpi_ev_global_lock_pending) {
+               goto out;
+       }
 
-               acpi_gbl_global_lock_acquired = TRUE;
-               /* Send a unit to the semaphore */
+       /* Send a unit to the semaphore */
 
-               if (ACPI_FAILURE
-                   (acpi_os_signal_semaphore
-                    (acpi_gbl_global_lock_semaphore, 1))) {
-                       ACPI_ERROR((AE_INFO,
-                                   "Could not signal Global Lock semaphore"));
-               }
+       status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
+       if (ACPI_FAILURE(status)) {
+               ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
        }
 
+       acpi_ev_global_lock_pending = FALSE;
+
+ out:
+       acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
+
        return (ACPI_INTERRUPT_HANDLED);
 }
 
@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired;
 
 acpi_status acpi_ev_acquire_global_lock(u16 timeout)
 {
+       acpi_cpu_flags flags;
        acpi_status status = AE_OK;
        u8 acquired = FALSE;
 
@@ -467,32 +468,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
                return_ACPI_STATUS(AE_OK);
        }
 
-       /* Attempt to acquire the actual hardware lock */
+       flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
+
+       do {
+
+               /* Attempt to acquire the actual hardware lock */
+
+               ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
+               if (acquired) {
+                       acpi_gbl_global_lock_acquired = TRUE;
+
+                       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                         "Acquired hardware Global Lock\n"));
+                       break;
+               }
 
-       ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
-       if (acquired) {
+               acpi_ev_global_lock_pending = TRUE;
 
-               /* We got the lock */
+               acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
 
+               /*
+                * Did not get the lock. The pending bit was set above, and we
+                * must wait until we get the global lock released interrupt.
+                */
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "Acquired hardware Global Lock\n"));
+                                 "Waiting for hardware Global Lock\n"));
 
-               acpi_gbl_global_lock_acquired = TRUE;
-               return_ACPI_STATUS(AE_OK);
-       }
+               /*
+                * Wait for handshake with the global lock interrupt handler.
+                * This interface releases the interpreter if we must wait.
+                */
+               status = acpi_ex_system_wait_semaphore(
+                                               acpi_gbl_global_lock_semaphore,
+                                               ACPI_WAIT_FOREVER);
 
-       /*
-        * Did not get the lock. The pending bit was set above, and we must now
-        * wait until we get the global lock released interrupt.
-        */
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
+               flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
 
-       /*
-        * Wait for handshake with the global lock interrupt handler.
-        * This interface releases the interpreter if we must wait.
-        */
-       status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
-                                              ACPI_WAIT_FOREVER);
+       } while (ACPI_SUCCESS(status));
+
+       acpi_ev_global_lock_pending = FALSE;
+
+       acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
 
        return_ACPI_STATUS(status);
 }
index 36af222cac654d3e2de0cb9c4ed7dc45fb4a0a49..1226689bdb1b7bd2890ccf02c91a20ed2343463b 100644 (file)
@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
 
 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
 #endif                         /*  ACPI_FUTURE_USAGE  */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_global_event_handler
+ *
+ * PARAMETERS:  Handler         - Pointer to the global event handler function
+ *              Context         - Value passed to the handler on each event
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function. The global handler
+ *              is invoked upon each incoming GPE and Fixed Event. It is
+ *              invoked at interrupt level at the time of the event dispatch.
+ *              Can be used to update event counters, etc.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
+
+       /* Parameter validation */
+
+       if (!handler) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Don't allow two handlers. */
+
+       if (acpi_gbl_global_event_handler) {
+               status = AE_ALREADY_EXISTS;
+               goto cleanup;
+       }
+
+       acpi_gbl_global_event_handler = handler;
+       acpi_gbl_global_event_handler_context = context;
+
+      cleanup:
+       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_install_fixed_event_handler
@@ -671,10 +722,10 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
 acpi_status
 acpi_install_gpe_handler(acpi_handle gpe_device,
                         u32 gpe_number,
-                        u32 type, acpi_event_handler address, void *context)
+                        u32 type, acpi_gpe_handler address, void *context)
 {
        struct acpi_gpe_event_info *gpe_event_info;
-       struct acpi_handler_info *handler;
+       struct acpi_gpe_handler_info *handler;
        acpi_status status;
        acpi_cpu_flags flags;
 
@@ -693,7 +744,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 
        /* Allocate memory for the handler object */
 
-       handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
+       handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
        if (!handler) {
                status = AE_NO_MEMORY;
                goto unlock_and_exit;
@@ -722,7 +773,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
        handler->address = address;
        handler->context = context;
        handler->method_node = gpe_event_info->dispatch.method_node;
-       handler->orig_flags = gpe_event_info->flags &
+       handler->original_flags = gpe_event_info->flags &
                        (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
 
        /*
@@ -731,10 +782,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
         * disabled now to avoid spurious execution of the handler.
         */
 
-       if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
+       if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
            && gpe_event_info->runtime_count) {
-               handler->orig_enabled = 1;
-               (void)acpi_raw_disable_gpe(gpe_event_info);
+               handler->originally_enabled = 1;
+               (void)acpi_ev_remove_gpe_reference(gpe_event_info);
        }
 
        /* Install the handler */
@@ -777,10 +828,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
  ******************************************************************************/
 acpi_status
 acpi_remove_gpe_handler(acpi_handle gpe_device,
-                       u32 gpe_number, acpi_event_handler address)
+                       u32 gpe_number, acpi_gpe_handler address)
 {
        struct acpi_gpe_event_info *gpe_event_info;
-       struct acpi_handler_info *handler;
+       struct acpi_gpe_handler_info *handler;
        acpi_status status;
        acpi_cpu_flags flags;
 
@@ -835,7 +886,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
        gpe_event_info->dispatch.method_node = handler->method_node;
        gpe_event_info->flags &=
                ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
-       gpe_event_info->flags |= handler->orig_flags;
+       gpe_event_info->flags |= handler->original_flags;
 
        /*
         * If the GPE was previously associated with a method and it was
@@ -843,9 +894,9 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
         * post-initialization configuration.
         */
 
-       if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
-           && handler->orig_enabled)
-               (void)acpi_raw_enable_gpe(gpe_event_info);
+       if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
+           && handler->originally_enabled)
+               (void)acpi_ev_add_gpe_reference(gpe_event_info);
 
        /* Now we can free the handler object */
 
index a1dabe3fd8ae771c7f8e676d907e4ad4cfba4ba3..90488c1e0f3dc475d949dc578c6275e925726dc9 100644 (file)
 
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acevents.h"
-#include "acnamesp.h"
 #include "actables.h"
 
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evxfevnt")
 
-/* Local prototypes */
-static acpi_status
-acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
-                      struct acpi_gpe_block_info *gpe_block, void *context);
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_enable
@@ -211,185 +204,6 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
 
 ACPI_EXPORT_SYMBOL(acpi_enable_event)
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_gpe_wakeup
- *
- * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
- *              gpe_number      - GPE level within the GPE block
- *              Action          - Enable or Disable
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
- *
- ******************************************************************************/
-acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
-{
-       acpi_status status = AE_OK;
-       struct acpi_gpe_event_info *gpe_event_info;
-       struct acpi_gpe_register_info *gpe_register_info;
-       acpi_cpu_flags flags;
-       u32 register_bit;
-
-       ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
-
-       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
-       /* Ensure that we have a valid GPE number */
-
-       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       gpe_register_info = gpe_event_info->register_info;
-       if (!gpe_register_info) {
-               status = AE_NOT_EXIST;
-               goto unlock_and_exit;
-       }
-
-       register_bit =
-           acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
-
-       /* Perform the action */
-
-       switch (action) {
-       case ACPI_GPE_ENABLE:
-               ACPI_SET_BIT(gpe_register_info->enable_for_wake,
-                            (u8)register_bit);
-               break;
-
-       case ACPI_GPE_DISABLE:
-               ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
-                              (u8)register_bit);
-               break;
-
-       default:
-               ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
-               status = AE_BAD_PARAMETER;
-               break;
-       }
-
-unlock_and_exit:
-       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_enable_gpe
- *
- * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
- *              gpe_number      - GPE level within the GPE block
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
- *              hardware-enabled.
- *
- ******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
-{
-       acpi_status status = AE_BAD_PARAMETER;
-       struct acpi_gpe_event_info *gpe_event_info;
-       acpi_cpu_flags flags;
-
-       ACPI_FUNCTION_TRACE(acpi_enable_gpe);
-
-       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
-       /* Ensure that we have a valid GPE number */
-
-       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (gpe_event_info) {
-               status = acpi_raw_enable_gpe(gpe_event_info);
-       }
-
-       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-       return_ACPI_STATUS(status);
-}
-ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_disable_gpe
- *
- * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
- *              gpe_number      - GPE level within the GPE block
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Remove a reference to a GPE. When the last reference is
- *              removed, only then is the GPE disabled (for runtime GPEs), or
- *              the GPE mask bit disabled (for wake GPEs)
- *
- ******************************************************************************/
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
-{
-       acpi_status status = AE_BAD_PARAMETER;
-       struct acpi_gpe_event_info *gpe_event_info;
-       acpi_cpu_flags flags;
-
-       ACPI_FUNCTION_TRACE(acpi_disable_gpe);
-
-       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
-       /* Ensure that we have a valid GPE number */
-
-       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (gpe_event_info) {
-               status = acpi_raw_disable_gpe(gpe_event_info) ;
-       }
-
-       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-       return_ACPI_STATUS(status);
-}
-ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_gpe_can_wake
- *
- * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
- *              gpe_number      - GPE level within the GPE block
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE.  If the GPE
- *              has a corresponding method and is currently enabled, disable it
- *              (GPEs with corresponding methods are enabled unconditionally
- *              during initialization, but GPEs that can wake up are expected
- *              to be initially disabled).
- *
- ******************************************************************************/
-acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
-{
-       acpi_status status = AE_OK;
-       struct acpi_gpe_event_info *gpe_event_info;
-       acpi_cpu_flags flags;
-
-       ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
-
-       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
-       /* Ensure that we have a valid GPE number */
-
-       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (gpe_event_info) {
-               gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
-       } else {
-               status = AE_BAD_PARAMETER;
-       }
-
-       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-       return_ACPI_STATUS(status);
-}
-ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_disable_event
@@ -481,44 +295,6 @@ acpi_status acpi_clear_event(u32 event)
 
 ACPI_EXPORT_SYMBOL(acpi_clear_event)
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_clear_gpe
- *
- * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
- *              gpe_number      - GPE level within the GPE block
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Clear an ACPI event (general purpose)
- *
- ******************************************************************************/
-acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
-{
-       acpi_status status = AE_OK;
-       struct acpi_gpe_event_info *gpe_event_info;
-       acpi_cpu_flags flags;
-
-       ACPI_FUNCTION_TRACE(acpi_clear_gpe);
-
-       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
-       /* Ensure that we have a valid GPE number */
-
-       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (!gpe_event_info) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       status = acpi_hw_clear_gpe(gpe_event_info);
-
-      unlock_and_exit:
-       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_event_status
@@ -575,379 +351,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_get_gpe_status
- *
- * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
- *              gpe_number      - GPE level within the GPE block
- *              event_status    - Where the current status of the event will
- *                                be returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Get status of an event (general purpose)
- *
- ******************************************************************************/
-acpi_status
-acpi_get_gpe_status(acpi_handle gpe_device,
-                   u32 gpe_number, acpi_event_status *event_status)
-{
-       acpi_status status = AE_OK;
-       struct acpi_gpe_event_info *gpe_event_info;
-       acpi_cpu_flags flags;
-
-       ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
-
-       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
-       /* Ensure that we have a valid GPE number */
-
-       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (!gpe_event_info) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       /* Obtain status on the requested GPE number */
-
-       status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
-
-       if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
-               *event_status |= ACPI_EVENT_FLAG_HANDLE;
-
-      unlock_and_exit:
-       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
-/*******************************************************************************
- *
- * FUNCTION:    acpi_install_gpe_block
- *
- * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
- *              gpe_block_address   - Address and space_iD
- *              register_count      - Number of GPE register pairs in the block
- *              interrupt_number    - H/W interrupt for the block
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create and Install a block of GPE registers
- *
- ******************************************************************************/
-acpi_status
-acpi_install_gpe_block(acpi_handle gpe_device,
-                      struct acpi_generic_address *gpe_block_address,
-                      u32 register_count, u32 interrupt_number)
-{
-       acpi_status status = AE_OK;
-       union acpi_operand_object *obj_desc;
-       struct acpi_namespace_node *node;
-       struct acpi_gpe_block_info *gpe_block;
-
-       ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
-
-       if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
-       }
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-       if (ACPI_FAILURE(status)) {
-               return (status);
-       }
-
-       node = acpi_ns_validate_handle(gpe_device);
-       if (!node) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       /*
-        * For user-installed GPE Block Devices, the gpe_block_base_number
-        * is always zero
-        */
-       status =
-           acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
-                                    interrupt_number, &gpe_block);
-       if (ACPI_FAILURE(status)) {
-               goto unlock_and_exit;
-       }
-
-       /* Install block in the device_object attached to the node */
-
-       obj_desc = acpi_ns_get_attached_object(node);
-       if (!obj_desc) {
-
-               /*
-                * No object, create a new one (Device nodes do not always have
-                * an attached object)
-                */
-               obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
-               if (!obj_desc) {
-                       status = AE_NO_MEMORY;
-                       goto unlock_and_exit;
-               }
-
-               status =
-                   acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
-
-               /* Remove local reference to the object */
-
-               acpi_ut_remove_reference(obj_desc);
-
-               if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
-               }
-       }
-
-       /* Now install the GPE block in the device_object */
-
-       obj_desc->device.gpe_block = gpe_block;
-
-      unlock_and_exit:
-       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_remove_gpe_block
- *
- * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Remove a previously installed block of GPE registers
- *
- ******************************************************************************/
-acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
-{
-       union acpi_operand_object *obj_desc;
-       acpi_status status;
-       struct acpi_namespace_node *node;
-
-       ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
-
-       if (!gpe_device) {
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
-       }
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-       if (ACPI_FAILURE(status)) {
-               return (status);
-       }
-
-       node = acpi_ns_validate_handle(gpe_device);
-       if (!node) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       /* Get the device_object attached to the node */
-
-       obj_desc = acpi_ns_get_attached_object(node);
-       if (!obj_desc || !obj_desc->device.gpe_block) {
-               return_ACPI_STATUS(AE_NULL_OBJECT);
-       }
-
-       /* Delete the GPE block (but not the device_object) */
-
-       status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
-       if (ACPI_SUCCESS(status)) {
-               obj_desc->device.gpe_block = NULL;
-       }
-
-      unlock_and_exit:
-       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_get_gpe_device
- *
- * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
- *              gpe_device          - Where the parent GPE Device is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
- *              gpe device indicates that the gpe number is contained in one of
- *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
- *
- ******************************************************************************/
-acpi_status
-acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
-{
-       struct acpi_gpe_device_info info;
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
-
-       if (!gpe_device) {
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
-       }
-
-       if (index >= acpi_current_gpe_count) {
-               return_ACPI_STATUS(AE_NOT_EXIST);
-       }
-
-       /* Setup and walk the GPE list */
-
-       info.index = index;
-       info.status = AE_NOT_EXIST;
-       info.gpe_device = NULL;
-       info.next_block_base_index = 0;
-
-       status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       *gpe_device = info.gpe_device;
-       return_ACPI_STATUS(info.status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_get_gpe_device
- *
- * PARAMETERS:  GPE_WALK_CALLBACK
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
- *              block device. NULL if the GPE is one of the FADT-defined GPEs.
- *
- ******************************************************************************/
-static acpi_status
-acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
-                      struct acpi_gpe_block_info *gpe_block, void *context)
-{
-       struct acpi_gpe_device_info *info = context;
-
-       /* Increment Index by the number of GPEs in this block */
-
-       info->next_block_base_index += gpe_block->gpe_count;
-
-       if (info->index < info->next_block_base_index) {
-               /*
-                * The GPE index is within this block, get the node. Leave the node
-                * NULL for the FADT-defined GPEs
-                */
-               if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
-                       info->gpe_device = gpe_block->node;
-               }
-
-               info->status = AE_OK;
-               return (AE_CTRL_END);
-       }
-
-       return (AE_OK);
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_disable_all_gpes
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
- *
- ******************************************************************************/
-
-acpi_status acpi_disable_all_gpes(void)
-{
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       status = acpi_hw_disable_all_gpes();
-       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-
-       return_ACPI_STATUS(status);
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_enable_all_runtime_gpes
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
- *
- ******************************************************************************/
-
-acpi_status acpi_enable_all_runtime_gpes(void)
-{
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       status = acpi_hw_enable_all_runtime_gpes();
-       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-
-       return_ACPI_STATUS(status);
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_update_gpes
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
- *              are not pointed to by any device _PRW methods indicating that
- *              these GPEs are generally intended for system or device wakeup
- *              (such GPEs have to be enabled directly when the devices whose
- *              _PRW methods point to them are set up for wakeup signaling).
- *
- ******************************************************************************/
-
-acpi_status acpi_update_gpes(void)
-{
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(acpi_update_gpes);
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       } else if (acpi_all_gpes_initialized) {
-               goto unlock;
-       }
-
-       status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
-       if (ACPI_SUCCESS(status)) {
-               acpi_all_gpes_initialized = TRUE;
-       }
-
-unlock:
-       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-
-       return_ACPI_STATUS(status);
-}
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
new file mode 100644 (file)
index 0000000..416845b
--- /dev/null
@@ -0,0 +1,669 @@
+/******************************************************************************
+ *
+ * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2010, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_EVENTS
+ACPI_MODULE_NAME("evxfgpe")
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_update_all_gpes
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
+ *              associated _Lxx or _Exx methods and are not pointed to by any
+ *              device _PRW methods (this indicates that these GPEs are
+ *              generally intended for system or device wakeup. Such GPEs
+ *              have to be enabled directly when the devices whose _PRW
+ *              methods point to them are set up for wakeup signaling.)
+ *
+ * NOTE: Should be called after any GPEs are added to the system. Primarily,
+ * after the system _PRW methods have been run, but also after a GPE Block
+ * Device has been added or if any new GPE methods have been added via a
+ * dynamic table load.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_update_all_gpes(void)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       if (acpi_gbl_all_gpes_initialized) {
+               goto unlock_and_exit;
+       }
+
+       status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
+       if (ACPI_SUCCESS(status)) {
+               acpi_gbl_all_gpes_initialized = TRUE;
+       }
+
+unlock_and_exit:
+       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_gpe
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number      - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ *              hardware-enabled.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+       acpi_status status = AE_BAD_PARAMETER;
+       struct acpi_gpe_event_info *gpe_event_info;
+       acpi_cpu_flags flags;
+
+       ACPI_FUNCTION_TRACE(acpi_enable_gpe);
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /* Ensure that we have a valid GPE number */
+
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (gpe_event_info) {
+               status = acpi_ev_add_gpe_reference(gpe_event_info);
+       }
+
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_disable_gpe
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number      - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ *              removed, only then is the GPE disabled (for runtime GPEs), or
+ *              the GPE mask bit disabled (for wake GPEs)
+ *
+ ******************************************************************************/
+
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+       acpi_status status = AE_BAD_PARAMETER;
+       struct acpi_gpe_event_info *gpe_event_info;
+       acpi_cpu_flags flags;
+
+       ACPI_FUNCTION_TRACE(acpi_disable_gpe);
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /* Ensure that we have a valid GPE number */
+
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (gpe_event_info) {
+               status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
+       }
+
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_setup_gpe_for_wake
+ *
+ * PARAMETERS:  wake_device         - Device associated with the GPE (via _PRW)
+ *              gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number          - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
+ *              interface is intended to be used as the host executes the
+ *              _PRW methods (Power Resources for Wake) in the system tables.
+ *              Each _PRW appears under a Device Object (The wake_device), and
+ *              contains the info for the wake GPE associated with the
+ *              wake_device.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_setup_gpe_for_wake(acpi_handle wake_device,
+                       acpi_handle gpe_device, u32 gpe_number)
+{
+       acpi_status status = AE_BAD_PARAMETER;
+       struct acpi_gpe_event_info *gpe_event_info;
+       struct acpi_namespace_node *device_node;
+       acpi_cpu_flags flags;
+
+       ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
+
+       /* Parameter Validation */
+
+       if (!wake_device) {
+               /*
+                * By forcing wake_device to be valid, we automatically enable the
+                * implicit notify feature on all hosts.
+                */
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       /* Validate wake_device is of type Device */
+
+       device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
+       if (device_node->type != ACPI_TYPE_DEVICE) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /* Ensure that we have a valid GPE number */
+
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (gpe_event_info) {
+               /*
+                * If there is no method or handler for this GPE, then the
+                * wake_device will be notified whenever this GPE fires (aka
+                * "implicit notify") Note: The GPE is assumed to be
+                * level-triggered (for windows compatibility).
+                */
+               if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+                   ACPI_GPE_DISPATCH_NONE) {
+                       gpe_event_info->flags =
+                           (ACPI_GPE_DISPATCH_NOTIFY |
+                            ACPI_GPE_LEVEL_TRIGGERED);
+                       gpe_event_info->dispatch.device_node = device_node;
+               }
+
+               gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
+               status = AE_OK;
+       }
+
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_set_gpe_wake_mask
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number      - GPE level within the GPE block
+ *              Action          - Enable or Disable
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
+ *              already be marked as a WAKE GPE.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
+{
+       acpi_status status = AE_OK;
+       struct acpi_gpe_event_info *gpe_event_info;
+       struct acpi_gpe_register_info *gpe_register_info;
+       acpi_cpu_flags flags;
+       u32 register_bit;
+
+       ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /*
+        * Ensure that we have a valid GPE number and that this GPE is in
+        * fact a wake GPE
+        */
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (!gpe_event_info) {
+               status = AE_BAD_PARAMETER;
+               goto unlock_and_exit;
+       }
+
+       if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
+               status = AE_TYPE;
+               goto unlock_and_exit;
+       }
+
+       gpe_register_info = gpe_event_info->register_info;
+       if (!gpe_register_info) {
+               status = AE_NOT_EXIST;
+               goto unlock_and_exit;
+       }
+
+       register_bit =
+           acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+
+       /* Perform the action */
+
+       switch (action) {
+       case ACPI_GPE_ENABLE:
+               ACPI_SET_BIT(gpe_register_info->enable_for_wake,
+                            (u8)register_bit);
+               break;
+
+       case ACPI_GPE_DISABLE:
+               ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
+                              (u8)register_bit);
+               break;
+
+       default:
+               ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
+               status = AE_BAD_PARAMETER;
+               break;
+       }
+
+unlock_and_exit:
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_clear_gpe
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number      - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+       acpi_status status = AE_OK;
+       struct acpi_gpe_event_info *gpe_event_info;
+       acpi_cpu_flags flags;
+
+       ACPI_FUNCTION_TRACE(acpi_clear_gpe);
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /* Ensure that we have a valid GPE number */
+
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (!gpe_event_info) {
+               status = AE_BAD_PARAMETER;
+               goto unlock_and_exit;
+       }
+
+       status = acpi_hw_clear_gpe(gpe_event_info);
+
+      unlock_and_exit:
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_gpe_status
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number      - GPE level within the GPE block
+ *              event_status    - Where the current status of the event will
+ *                                be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_gpe_status(acpi_handle gpe_device,
+                   u32 gpe_number, acpi_event_status *event_status)
+{
+       acpi_status status = AE_OK;
+       struct acpi_gpe_event_info *gpe_event_info;
+       acpi_cpu_flags flags;
+
+       ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /* Ensure that we have a valid GPE number */
+
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (!gpe_event_info) {
+               status = AE_BAD_PARAMETER;
+               goto unlock_and_exit;
+       }
+
+       /* Obtain status on the requested GPE number */
+
+       status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
+
+       if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
+               *event_status |= ACPI_EVENT_FLAG_HANDLE;
+
+      unlock_and_exit:
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_disable_all_gpes
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
+ *
+ ******************************************************************************/
+
+acpi_status acpi_disable_all_gpes(void)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       status = acpi_hw_disable_all_gpes();
+       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_all_runtime_gpes
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
+ *
+ ******************************************************************************/
+
+acpi_status acpi_enable_all_runtime_gpes(void)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       status = acpi_hw_enable_all_runtime_gpes();
+       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_gpe_block
+ *
+ * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
+ *              gpe_block_address   - Address and space_iD
+ *              register_count      - Number of GPE register pairs in the block
+ *              interrupt_number    - H/W interrupt for the block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
+ *              enabled here.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_install_gpe_block(acpi_handle gpe_device,
+                      struct acpi_generic_address *gpe_block_address,
+                      u32 register_count, u32 interrupt_number)
+{
+       acpi_status status;
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *node;
+       struct acpi_gpe_block_info *gpe_block;
+
+       ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
+
+       if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       node = acpi_ns_validate_handle(gpe_device);
+       if (!node) {
+               status = AE_BAD_PARAMETER;
+               goto unlock_and_exit;
+       }
+
+       /*
+        * For user-installed GPE Block Devices, the gpe_block_base_number
+        * is always zero
+        */
+       status =
+           acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
+                                    interrupt_number, &gpe_block);
+       if (ACPI_FAILURE(status)) {
+               goto unlock_and_exit;
+       }
+
+       /* Install block in the device_object attached to the node */
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (!obj_desc) {
+
+               /*
+                * No object, create a new one (Device nodes do not always have
+                * an attached object)
+                */
+               obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
+               if (!obj_desc) {
+                       status = AE_NO_MEMORY;
+                       goto unlock_and_exit;
+               }
+
+               status =
+                   acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
+
+               /* Remove local reference to the object */
+
+               acpi_ut_remove_reference(obj_desc);
+
+               if (ACPI_FAILURE(status)) {
+                       goto unlock_and_exit;
+               }
+       }
+
+       /* Now install the GPE block in the device_object */
+
+       obj_desc->device.gpe_block = gpe_block;
+
+      unlock_and_exit:
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_gpe_block
+ *
+ * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a previously installed block of GPE registers
+ *
+ ******************************************************************************/
+acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
+{
+       union acpi_operand_object *obj_desc;
+       acpi_status status;
+       struct acpi_namespace_node *node;
+
+       ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
+
+       if (!gpe_device) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       node = acpi_ns_validate_handle(gpe_device);
+       if (!node) {
+               status = AE_BAD_PARAMETER;
+               goto unlock_and_exit;
+       }
+
+       /* Get the device_object attached to the node */
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (!obj_desc || !obj_desc->device.gpe_block) {
+               return_ACPI_STATUS(AE_NULL_OBJECT);
+       }
+
+       /* Delete the GPE block (but not the device_object) */
+
+       status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
+       if (ACPI_SUCCESS(status)) {
+               obj_desc->device.gpe_block = NULL;
+       }
+
+      unlock_and_exit:
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_gpe_device
+ *
+ * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
+ *              gpe_device          - Where the parent GPE Device is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
+ *              gpe device indicates that the gpe number is contained in one of
+ *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
+{
+       struct acpi_gpe_device_info info;
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
+
+       if (!gpe_device) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       if (index >= acpi_current_gpe_count) {
+               return_ACPI_STATUS(AE_NOT_EXIST);
+       }
+
+       /* Setup and walk the GPE list */
+
+       info.index = index;
+       info.status = AE_NOT_EXIST;
+       info.gpe_device = NULL;
+       info.next_block_base_index = 0;
+
+       status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
+       return_ACPI_STATUS(info.status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
index 14750db2a1b8e102da17cb047e65f51bdbc8b708..85c3cbd4304dedc9e63c4bd5854da2993edd3584 100644 (file)
@@ -62,10 +62,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  * PARAMETERS: gpe_event_info      - Info block for the GPE
  *             gpe_register_info   - Info block for the GPE register
  *
- * RETURN:     Status
+ * RETURN:     Register mask with a one in the GPE bit position
  *
- * DESCRIPTION:        Compute GPE enable mask with one bit corresponding to the given
- *             GPE set.
+ * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
+ *              correct position for the input GPE.
  *
  ******************************************************************************/
 
@@ -85,12 +85,12 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
  *
  * RETURN:     Status
  *
- * DESCRIPTION: Enable or disable a single GPE in its enable register.
+ * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
+acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
 {
        struct acpi_gpe_register_info *gpe_register_info;
        acpi_status status;
@@ -113,14 +113,20 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
                return (status);
        }
 
-       /* Set ot clear just the bit that corresponds to this GPE */
+       /* Set or clear just the bit that corresponds to this GPE */
 
        register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
                                                gpe_register_info);
        switch (action) {
-       case ACPI_GPE_COND_ENABLE:
-               if (!(register_bit & gpe_register_info->enable_for_run))
+       case ACPI_GPE_CONDITIONAL_ENABLE:
+
+               /* Only enable if the enable_for_run bit is set */
+
+               if (!(register_bit & gpe_register_info->enable_for_run)) {
                        return (AE_BAD_PARAMETER);
+               }
+
+               /*lint -fallthrough */
 
        case ACPI_GPE_ENABLE:
                ACPI_SET_BIT(enable_mask, register_bit);
@@ -131,7 +137,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
                break;
 
        default:
-               ACPI_ERROR((AE_INFO, "Invalid action\n"));
+               ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
                return (AE_BAD_PARAMETER);
        }
 
@@ -168,13 +174,13 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
                return (AE_NOT_EXIST);
        }
 
-       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-                                               gpe_register_info);
-
        /*
         * Write a one to the appropriate bit in the status register to
         * clear this GPE.
         */
+       register_bit =
+           acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+
        status = acpi_hw_write(register_bit,
                               &gpe_register_info->status_address);
 
@@ -201,8 +207,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
        u32 in_byte;
        u32 register_bit;
        struct acpi_gpe_register_info *gpe_register_info;
-       acpi_status status;
        acpi_event_status local_event_status = 0;
+       acpi_status status;
 
        ACPI_FUNCTION_ENTRY();
 
index e87bc6760be6e01e1b0d5ed52912a2194a7246f3..508537f884acb05c80245e6ac3beb6d9fc127e38 100644 (file)
@@ -768,7 +768,7 @@ acpi_status acpi_ut_init_globals(void)
        acpi_gbl_gpe_fadt_blocks[0] = NULL;
        acpi_gbl_gpe_fadt_blocks[1] = NULL;
        acpi_current_gpe_count = 0;
-       acpi_all_gpes_initialized = FALSE;
+       acpi_gbl_all_gpes_initialized = FALSE;
 
        /* Global handlers */
 
@@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void)
        acpi_gbl_init_handler = NULL;
        acpi_gbl_table_handler = NULL;
        acpi_gbl_interface_handler = NULL;
+       acpi_gbl_global_event_handler = NULL;
 
        /* Global Lock support */
 
index d68bd61072bb797e3e7f0413d6b97a9650f99222..7ced61f394924e3e0eeb208de094f894cfd5e623 100644 (file)
@@ -52,22 +52,6 @@ EXPORT_SYMBOL(acpi_root_dir);
 
 #define STRUCT_TO_INT(s)       (*((int*)&s))
 
-static int set_power_nocheck(const struct dmi_system_id *id)
-{
-       printk(KERN_NOTICE PREFIX "%s detected - "
-               "disable power check in power transition\n", id->ident);
-       acpi_power_nocheck = 1;
-       return 0;
-}
-static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
-       {
-       set_power_nocheck, "HP Pavilion 05", {
-       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
-       DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
-       DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
-       {},
-};
-
 
 #ifdef CONFIG_X86
 static int set_copy_dsdt(const struct dmi_system_id *id)
@@ -196,33 +180,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
                                  Power Management
    -------------------------------------------------------------------------- */
 
-int acpi_bus_get_power(acpi_handle handle, int *state)
+static int __acpi_bus_get_power(struct acpi_device *device, int *state)
 {
        int result = 0;
        acpi_status status = 0;
-       struct acpi_device *device = NULL;
        unsigned long long psc = 0;
 
-
-       result = acpi_bus_get_device(handle, &device);
-       if (result)
-               return result;
+       if (!device || !state)
+               return -EINVAL;
 
        *state = ACPI_STATE_UNKNOWN;
 
-       if (!device->flags.power_manageable) {
-               /* TBD: Non-recursive algorithm for walking up hierarchy */
-               if (device->parent)
-                       *state = device->parent->power.state;
-               else
-                       *state = ACPI_STATE_D0;
-       } else {
+       if (device->flags.power_manageable) {
                /*
                 * Get the device's power state either directly (via _PSC) or
                 * indirectly (via power resources).
                 */
                if (device->power.flags.power_resources) {
-                       result = acpi_power_get_inferred_state(device);
+                       result = acpi_power_get_inferred_state(device, state);
                        if (result)
                                return result;
                } else if (device->power.flags.explicit_get) {
@@ -230,59 +205,33 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
                                                       NULL, &psc);
                        if (ACPI_FAILURE(status))
                                return -ENODEV;
-                       device->power.state = (int)psc;
+                       *state = (int)psc;
                }
-
-               *state = device->power.state;
+       } else {
+               /* TBD: Non-recursive algorithm for walking up hierarchy. */
+               *state = device->parent ?
+                       device->parent->power.state : ACPI_STATE_D0;
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
-                         device->pnp.bus_id, device->power.state));
+                         device->pnp.bus_id, *state));
 
        return 0;
 }
 
-EXPORT_SYMBOL(acpi_bus_get_power);
 
-int acpi_bus_set_power(acpi_handle handle, int state)
+static int __acpi_bus_set_power(struct acpi_device *device, int state)
 {
        int result = 0;
        acpi_status status = AE_OK;
-       struct acpi_device *device = NULL;
        char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
 
-
-       result = acpi_bus_get_device(handle, &device);
-       if (result)
-               return result;
-
-       if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
+       if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
                return -EINVAL;
 
        /* Make sure this is a valid target state */
 
-       if (!device->flags.power_manageable) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
-                               kobject_name(&device->dev.kobj)));
-               return -ENODEV;
-       }
-       /*
-        * Get device's current power state
-        */
-       if (!acpi_power_nocheck) {
-               /*
-                * Maybe the incorrect power state is returned on the bogus
-                * bios, which is different with the real power state.
-                * For example: the bios returns D0 state and the real power
-                * state is D3. OS expects to set the device to D0 state. In
-                * such case if OS uses the power state returned by the BIOS,
-                * the device can't be transisted to the correct power state.
-                * So if the acpi_power_nocheck is set, it is unnecessary to
-                * get the power state by calling acpi_bus_get_power.
-                */
-               acpi_bus_get_power(device->handle, &device->power.state);
-       }
-       if ((state == device->power.state) && !device->flags.force_power_state) {
+       if (state == device->power.state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
                                  state));
                return 0;
@@ -351,8 +300,75 @@ int acpi_bus_set_power(acpi_handle handle, int state)
        return result;
 }
 
+
+int acpi_bus_set_power(acpi_handle handle, int state)
+{
+       struct acpi_device *device;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       if (result)
+               return result;
+
+       if (!device->flags.power_manageable) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                               "Device [%s] is not power manageable\n",
+                               dev_name(&device->dev)));
+               return -ENODEV;
+       }
+
+       return __acpi_bus_set_power(device, state);
+}
 EXPORT_SYMBOL(acpi_bus_set_power);
 
+
+int acpi_bus_init_power(struct acpi_device *device)
+{
+       int state;
+       int result;
+
+       if (!device)
+               return -EINVAL;
+
+       device->power.state = ACPI_STATE_UNKNOWN;
+
+       result = __acpi_bus_get_power(device, &state);
+       if (result)
+               return result;
+
+       if (device->power.flags.power_resources)
+               result = acpi_power_on_resources(device, state);
+
+       if (!result)
+               device->power.state = state;
+
+       return result;
+}
+
+
+int acpi_bus_update_power(acpi_handle handle, int *state_p)
+{
+       struct acpi_device *device;
+       int state;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       if (result)
+               return result;
+
+       result = __acpi_bus_get_power(device, &state);
+       if (result)
+               return result;
+
+       result = __acpi_bus_set_power(device, state);
+       if (!result && state_p)
+               *state_p = state;
+
+       return result;
+}
+EXPORT_SYMBOL_GPL(acpi_bus_update_power);
+
+
 bool acpi_bus_power_manageable(acpi_handle handle)
 {
        struct acpi_device *device;
@@ -1023,15 +1039,8 @@ static int __init acpi_init(void)
        if (acpi_disabled)
                return result;
 
-       /*
-        * If the laptop falls into the DMI check table, the power state check
-        * will be disabled in the course of device power transition.
-        */
-       dmi_check_system(power_nocheck_dmi_table);
-
        acpi_scan_init();
        acpi_ec_init();
-       acpi_power_init();
        acpi_debugfs_init();
        acpi_sleep_proc_init();
        acpi_wakeup_device_init();
index 71ef9cd0735f2fadd8c76d67cee4029bc72b1ce1..76bbb78a5ad957525c066b90ec2457ae533934e6 100644 (file)
@@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device)
        input_report_switch(button->input, SW_LID, !state);
        input_sync(button->input);
 
+       if (state)
+               pm_wakeup_event(&device->dev, 0);
+
        ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
        if (ret == NOTIFY_DONE)
                ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
@@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
                        input_sync(input);
                        input_report_key(input, keycode, 0);
                        input_sync(input);
+
+                       pm_wakeup_event(&device->dev, 0);
                }
 
                acpi_bus_generate_proc_event(device, event, ++button->pushed);
@@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device)
                acpi_enable_gpe(device->wakeup.gpe_device,
                                device->wakeup.gpe_number);
                device->wakeup.run_wake_count++;
-               device->wakeup.state.enabled = 1;
+               device_set_wakeup_enable(&device->dev, true);
        }
 
        printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
@@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
                acpi_disable_gpe(device->wakeup.gpe_device,
                                device->wakeup.gpe_number);
                device->wakeup.run_wake_count--;
-               device->wakeup.state.enabled = 0;
+               device_set_wakeup_enable(&device->dev, false);
        }
 
        acpi_button_remove_fs(device);
index 81514a4918cc11ee1313b234aec2daa6d6b0765b..1864ad3cf89590267919eebe6c62f62ebba84cb3 100644 (file)
@@ -725,7 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
                        complete_dock(ds);
                        dock_event(ds, event, DOCK_EVENT);
                        dock_lock(ds, 1);
-                       acpi_update_gpes();
+                       acpi_update_all_gpes();
                        break;
                }
                if (dock_present(ds) || dock_in_progress(ds))
index 302b31ed31f1ea099faa48b989114e9c99dc1485..fa848c4116a84b3572f0142ccb3d87df8dff2ada 100644 (file)
@@ -606,7 +606,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
        return 0;
 }
 
-static u32 acpi_ec_gpe_handler(void *data)
+static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
+       u32 gpe_number, void *data)
 {
        struct acpi_ec *ec = data;
 
@@ -618,7 +619,7 @@ static u32 acpi_ec_gpe_handler(void *data)
                wake_up(&ec->wait);
                ec_check_sci(ec, acpi_ec_read_status(ec));
        }
-       return ACPI_INTERRUPT_HANDLED;
+       return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
 }
 
 /* --------------------------------------------------------------------------
index 60049080c86985755109074a26a260e660ae7a72..467479f07c1fd35932390cba80ffe90add0dba65 100644 (file)
@@ -86,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
        if (!device)
                return -EINVAL;
 
-       result = acpi_bus_get_power(device->handle, &acpi_state);
+       result = acpi_bus_update_power(device->handle, &acpi_state);
        if (result)
                return result;
 
@@ -123,7 +123,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = {
 static int acpi_fan_add(struct acpi_device *device)
 {
        int result = 0;
-       int state = 0;
        struct thermal_cooling_device *cdev;
 
        if (!device)
@@ -132,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device)
        strcpy(acpi_device_name(device), "Fan");
        strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
 
-       result = acpi_bus_get_power(device->handle, &state);
+       result = acpi_bus_update_power(device->handle, NULL);
        if (result) {
-               printk(KERN_ERR PREFIX "Reading power state\n");
+               printk(KERN_ERR PREFIX "Setting initial power state\n");
                goto end;
        }
 
-       device->flags.force_power_state = 1;
-       acpi_bus_set_power(device->handle, state);
-       device->flags.force_power_state = 0;
-
        cdev = thermal_cooling_device_register("Fan", device,
                                                &fan_cooling_ops);
        if (IS_ERR(cdev)) {
@@ -200,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
 
 static int acpi_fan_resume(struct acpi_device *device)
 {
-       int result = 0;
-       int power_state = 0;
+       int result;
 
        if (!device)
                return -EINVAL;
 
-       result = acpi_bus_get_power(device->handle, &power_state);
-       if (result) {
-               printk(KERN_ERR PREFIX
-                                 "Error reading fan power state\n");
-               return result;
-       }
-
-       device->flags.force_power_state = 1;
-       acpi_bus_set_power(device->handle, power_state);
-       device->flags.force_power_state = 0;
+       result = acpi_bus_update_power(device->handle, NULL);
+       if (result)
+               printk(KERN_ERR PREFIX "Error updating fan power state\n");
 
        return result;
 }
index 78b0164c35b2ccaa25647e9ea0397a249d51656b..7c47ed55e528be27ea167bfaa5a6872b9b609bb1 100644 (file)
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
                                "firmware_node");
                ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
                                "physical_node");
-               if (acpi_dev->wakeup.flags.valid) {
+               if (acpi_dev->wakeup.flags.valid)
                        device_set_wakeup_capable(dev, true);
-                       device_set_wakeup_enable(dev,
-                                               acpi_dev->wakeup.state.enabled);
-               }
        }
 
        return 0;
index a212bfeddf8c0247e2ccfd9a34da8df325bc6576..bc428a9607df7c2da973151dcdc93f2e58b7001d 100644 (file)
@@ -41,9 +41,10 @@ static inline int acpi_debugfs_init(void) { return 0; }
 int acpi_power_init(void);
 int acpi_device_sleep_wake(struct acpi_device *dev,
                            int enable, int sleep_state, int dev_state);
-int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
+int acpi_power_on_resources(struct acpi_device *device, int state);
 int acpi_power_transition(struct acpi_device *device, int state);
-extern int acpi_power_nocheck;
+int acpi_bus_init_power(struct acpi_device *device);
 
 int acpi_wakeup_device_init(void);
 void acpi_early_processor_set_pdc(void);
@@ -82,8 +83,16 @@ extern int acpi_sleep_init(void);
 
 #ifdef CONFIG_ACPI_SLEEP
 int acpi_sleep_proc_init(void);
+int suspend_nvs_alloc(void);
+void suspend_nvs_free(void);
+int suspend_nvs_save(void);
+void suspend_nvs_restore(void);
 #else
 static inline int acpi_sleep_proc_init(void) { return 0; }
+static inline int suspend_nvs_alloc(void) { return 0; }
+static inline void suspend_nvs_free(void) {}
+static inline int suspend_nvs_save(void) {}
+static inline void suspend_nvs_restore(void) {}
 #endif
 
 #endif /* _ACPI_INTERNAL_H_ */
similarity index 86%
rename from kernel/power/nvs.c
rename to drivers/acpi/nvs.c
index 1836db60bbb6d56c2ba06f6a0b01b35bc2183fa2..54b6ab8040a6ed05039ce59d576969371e7fa3f8 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
+ * nvs.c - Routines for saving and restoring ACPI NVS memory region
  *
- * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
  *
  * This file is released under the GPLv2.
  */
@@ -11,7 +11,8 @@
 #include <linux/list.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/suspend.h>
+#include <linux/acpi.h>
+#include <acpi/acpiosxf.h>
 
 /*
  * Platforms, like ACPI, may want us to save some memory used by them during
@@ -79,7 +80,7 @@ void suspend_nvs_free(void)
                        free_page((unsigned long)entry->data);
                        entry->data = NULL;
                        if (entry->kaddr) {
-                               iounmap(entry->kaddr);
+                               acpi_os_unmap_memory(entry->kaddr, entry->size);
                                entry->kaddr = NULL;
                        }
                }
@@ -105,7 +106,7 @@ int suspend_nvs_alloc(void)
 /**
  *     suspend_nvs_save - save NVS memory regions
  */
-void suspend_nvs_save(void)
+int suspend_nvs_save(void)
 {
        struct nvs_page *entry;
 
@@ -113,9 +114,16 @@ void suspend_nvs_save(void)
 
        list_for_each_entry(entry, &nvs_list, node)
                if (entry->data) {
-                       entry->kaddr = ioremap(entry->phys_start, entry->size);
+                       entry->kaddr = acpi_os_map_memory(entry->phys_start,
+                                                         entry->size);
+                       if (!entry->kaddr) {
+                               suspend_nvs_free();
+                               return -ENOMEM;
+                       }
                        memcpy(entry->data, entry->kaddr, entry->size);
                }
+
+       return 0;
 }
 
 /**
index 055d7b701fff16d18fe5de5ea243ba8ec477e3ec..3a7b4879fd9974ab1af49c4f60eee09fe7cf7fad 100644 (file)
@@ -320,7 +320,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 
        pg_off = round_down(phys, PAGE_SIZE);
        pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
-       virt = ioremap(pg_off, pg_sz);
+       virt = ioremap_cache(pg_off, pg_sz);
        if (!virt) {
                kfree(map);
                return NULL;
@@ -642,7 +642,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
        virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
        rcu_read_unlock();
        if (!virt_addr) {
-               virt_addr = ioremap(phys_addr, size);
+               virt_addr = ioremap_cache(phys_addr, size);
                unmap = 1;
        }
        if (!value)
@@ -678,7 +678,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
        virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
        rcu_read_unlock();
        if (!virt_addr) {
-               virt_addr = ioremap(phys_addr, size);
+               virt_addr = ioremap_cache(phys_addr, size);
                unmap = 1;
        }
 
index 4c9c2fb5d98f9a14a67e8618b44dc6f2c642887b..0003f1009885c692c89f07c2f4321df33ceb562a 100644 (file)
@@ -56,9 +56,6 @@ ACPI_MODULE_NAME("power");
 #define ACPI_POWER_RESOURCE_STATE_ON   0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 
-int acpi_power_nocheck;
-module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
-
 static int acpi_power_add(struct acpi_device *device);
 static int acpi_power_remove(struct acpi_device *device, int type);
 static int acpi_power_resume(struct acpi_device *device);
@@ -266,6 +263,35 @@ static int acpi_power_off_device(acpi_handle handle)
        return result;
 }
 
+static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
+{
+       int i;
+
+       for (i = num_res - 1; i >= 0 ; i--)
+               acpi_power_off_device(list->handles[i]);
+}
+
+static void acpi_power_off_list(struct acpi_handle_list *list)
+{
+       __acpi_power_off_list(list, list->count);
+}
+
+static int acpi_power_on_list(struct acpi_handle_list *list)
+{
+       int result = 0;
+       int i;
+
+       for (i = 0; i < list->count; i++) {
+               result = acpi_power_on(list->handles[i]);
+               if (result) {
+                       __acpi_power_off_list(list, i);
+                       break;
+               }
+       }
+
+       return result;
+}
+
 /**
  * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
  *                          ACPI 3.0) _PSW (Power State Wake)
@@ -423,19 +449,16 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
                              Device Power Management
    -------------------------------------------------------------------------- */
 
-int acpi_power_get_inferred_state(struct acpi_device *device)
+int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
 {
        int result = 0;
        struct acpi_handle_list *list = NULL;
        int list_state = 0;
        int i = 0;
 
-
-       if (!device)
+       if (!device || !state)
                return -EINVAL;
 
-       device->power.state = ACPI_STATE_UNKNOWN;
-
        /*
         * We know a device's inferred power state when all the resources
         * required for a given D-state are 'on'.
@@ -450,22 +473,26 @@ int acpi_power_get_inferred_state(struct acpi_device *device)
                        return result;
 
                if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
-                       device->power.state = i;
+                       *state = i;
                        return 0;
                }
        }
 
-       device->power.state = ACPI_STATE_D3;
-
+       *state = ACPI_STATE_D3;
        return 0;
 }
 
+int acpi_power_on_resources(struct acpi_device *device, int state)
+{
+       if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
+               return -EINVAL;
+
+       return acpi_power_on_list(&device->power.states[state].resources);
+}
+
 int acpi_power_transition(struct acpi_device *device, int state)
 {
-       int result = 0;
-       struct acpi_handle_list *cl = NULL;     /* Current Resources */
-       struct acpi_handle_list *tl = NULL;     /* Target Resources */
-       int i = 0;
+       int result;
 
        if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
                return -EINVAL;
@@ -477,37 +504,20 @@ int acpi_power_transition(struct acpi_device *device, int state)
            || (device->power.state > ACPI_STATE_D3))
                return -ENODEV;
 
-       cl = &device->power.states[device->power.state].resources;
-       tl = &device->power.states[state].resources;
-
        /* TBD: Resources must be ordered. */
 
        /*
         * First we reference all power resources required in the target list
-        * (e.g. so the device doesn't lose power while transitioning).
+        * (e.g. so the device doesn't lose power while transitioning).  Then,
+        * we dereference all power resources used in the current list.
         */
-       for (i = 0; i < tl->count; i++) {
-               result = acpi_power_on(tl->handles[i]);
-               if (result)
-                       goto end;
-       }
-
-       /*
-        * Then we dereference all power resources used in the current list.
-        */
-       for (i = 0; i < cl->count; i++) {
-               result = acpi_power_off_device(cl->handles[i]);
-               if (result)
-                       goto end;
-       }
+       result = acpi_power_on_list(&device->power.states[state].resources);
+       if (!result)
+               acpi_power_off_list(
+                       &device->power.states[device->power.state].resources);
 
-     end:
-       if (result)
-               device->power.state = ACPI_STATE_UNKNOWN;
-       else {
-       /* We shouldn't change the state till all above operations succeed */
-               device->power.state = state;
-       }
+       /* We shouldn't change the state unless the above operations succeed. */
+       device->power.state = result ? ACPI_STATE_UNKNOWN : state;
 
        return result;
 }
index afad67769db6216352348ecb207112f13180e862..f5f986991b52f8a5a5faae4f3446105e1d2fe2bf 100644 (file)
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
                           dev->pnp.bus_id,
                           (u32) dev->wakeup.sleep_state,
                           dev->wakeup.flags.run_wake ? '*' : ' ',
-                          dev->wakeup.state.enabled ? "enabled" : "disabled");
+                          (device_may_wakeup(&dev->dev)
+                            || (ldev && device_may_wakeup(ldev))) ?
+                              "enabled" : "disabled");
                if (ldev)
                        seq_printf(seq, "%s:%s",
                                   ldev->bus ? ldev->bus->name : "no-bus",
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
 {
        struct device *dev = acpi_get_physical_device(adev->handle);
 
-       if (dev && device_can_wakeup(dev))
-               device_set_wakeup_enable(dev, adev->wakeup.state.enabled);
+       if (dev && device_can_wakeup(dev)) {
+               bool enable = !device_may_wakeup(dev);
+               device_set_wakeup_enable(dev, enable);
+       }
 }
 
 static ssize_t
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file,
        char strbuf[5];
        char str[5] = "";
        unsigned int len = count;
-       struct acpi_device *found_dev = NULL;
 
        if (len > 4)
                len = 4;
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file,
                        continue;
 
                if (!strncmp(dev->pnp.bus_id, str, 4)) {
-                       dev->wakeup.state.enabled =
-                           dev->wakeup.state.enabled ? 0 : 1;
-                       found_dev = dev;
-                       break;
-               }
-       }
-       if (found_dev) {
-               physical_device_enable_wakeup(found_dev);
-               list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-                       struct acpi_device *dev = container_of(node,
-                                                              struct
-                                                              acpi_device,
-                                                              wakeup_list);
-
-                       if ((dev != found_dev) &&
-                           (dev->wakeup.gpe_number ==
-                            found_dev->wakeup.gpe_number)
-                           && (dev->wakeup.gpe_device ==
-                               found_dev->wakeup.gpe_device)) {
-                               printk(KERN_WARNING
-                                      "ACPI: '%s' and '%s' have the same GPE, "
-                                      "can't disable/enable one separately\n",
-                                      dev->pnp.bus_id, found_dev->pnp.bus_id);
-                               dev->wakeup.state.enabled =
-                                   found_dev->wakeup.state.enabled;
+                       if (device_can_wakeup(&dev->dev)) {
+                               bool enable = !device_may_wakeup(&dev->dev);
+                               device_set_wakeup_enable(&dev->dev, enable);
+                       } else {
                                physical_device_enable_wakeup(dev);
                        }
+                       break;
                }
        }
        mutex_unlock(&acpi_device_lock);
index 29ef505c487b92efe1b12e79c2231aa85c0298ce..64d4da0d6d5255bbbd7112f44c4d9a88f045fef0 100644 (file)
@@ -778,7 +778,7 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
                wakeup->resources.handles[i] = element->reference.handle;
        }
 
-       acpi_gpe_can_wake(wakeup->gpe_device, wakeup->gpe_number);
+       acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
 
  out:
        kfree(buffer.pointer);
@@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
        /* Power button, Lid switch always enable wakeup */
        if (!acpi_match_device_ids(device, button_device_ids)) {
                device->wakeup.flags.run_wake = 1;
-               device->wakeup.flags.always_enabled = 1;
+               device_set_wakeup_capable(&device->dev, true);
                return;
        }
 
@@ -847,6 +847,8 @@ end:
        return 0;
 }
 
+static void acpi_bus_add_power_resource(acpi_handle handle);
+
 static int acpi_bus_get_power_flags(struct acpi_device *device)
 {
        acpi_status status = 0;
@@ -875,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
                acpi_evaluate_reference(device->handle, object_name, NULL,
                                        &ps->resources);
                if (ps->resources.count) {
+                       int j;
+
                        device->power.flags.power_resources = 1;
                        ps->flags.valid = 1;
+                       for (j = 0; j < ps->resources.count; j++)
+                               acpi_bus_add_power_resource(ps->resources.handles[j]);
                }
 
                /* Evaluate "_PSx" to see if we can do explicit sets */
@@ -901,10 +907,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
        device->power.states[ACPI_STATE_D3].flags.valid = 1;
        device->power.states[ACPI_STATE_D3].power = 0;
 
-       /* TBD: System wake support and resource requirements. */
-
-       device->power.state = ACPI_STATE_UNKNOWN;
-       acpi_bus_get_power(device->handle, &(device->power.state));
+       acpi_bus_init_power(device);
 
        return 0;
 }
@@ -1326,6 +1329,20 @@ end:
 #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
                          ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)
 
+static void acpi_bus_add_power_resource(acpi_handle handle)
+{
+       struct acpi_bus_ops ops = {
+               .acpi_op_add = 1,
+               .acpi_op_start = 1,
+       };
+       struct acpi_device *device = NULL;
+
+       acpi_bus_get_device(handle, &device);
+       if (!device)
+               acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
+                                       ACPI_STA_DEFAULT, &ops);
+}
+
 static int acpi_bus_type_and_status(acpi_handle handle, int *type,
                                    unsigned long long *sta)
 {
@@ -1467,7 +1484,7 @@ int acpi_bus_start(struct acpi_device *device)
 
        result = acpi_bus_scan(device->handle, &ops, NULL);
 
-       acpi_update_gpes();
+       acpi_update_all_gpes();
 
        return result;
 }
@@ -1573,6 +1590,8 @@ int __init acpi_scan_init(void)
                printk(KERN_ERR PREFIX "Could not register bus type\n");
        }
 
+       acpi_power_init();
+
        /*
         * Enumerate devices in the ACPI namespace.
         */
@@ -1584,7 +1603,7 @@ int __init acpi_scan_init(void)
        if (result)
                acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
        else
-               acpi_update_gpes();
+               acpi_update_all_gpes();
 
        return result;
 }
index febb153b5a68cf216fdd1b528ac44159e73abcba..75c23208474014acb06f781050fe56c21089a237 100644 (file)
@@ -124,8 +124,7 @@ static int acpi_pm_freeze(void)
 static int acpi_pm_pre_suspend(void)
 {
        acpi_pm_freeze();
-       suspend_nvs_save();
-       return 0;
+       return suspend_nvs_save();
 }
 
 /**
@@ -151,7 +150,7 @@ static int acpi_pm_prepare(void)
 {
        int error = __acpi_pm_prepare();
        if (!error)
-               acpi_pm_pre_suspend();
+               error = acpi_pm_pre_suspend();
 
        return error;
 }
@@ -435,6 +434,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
                },
        },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Averatec AV1020-ED2",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index f8588f81048ac989d6af1d727693a234f54bc27b..61891e75583da971f7973393fc9071b5ec14dfaa 100644 (file)
@@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void)
        return;
 }
 
-void acpi_os_gpe_count(u32 gpe_number)
+static void gpe_count(u32 gpe_number)
 {
        acpi_gpe_count++;
 
@@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number)
        return;
 }
 
-void acpi_os_fixed_event_count(u32 event_number)
+static void fixed_event_count(u32 event_number)
 {
        if (!all_counters)
                return;
@@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number)
        return;
 }
 
+static void acpi_gbl_event_handler(u32 event_type, acpi_handle device,
+       u32 event_number, void *context)
+{
+       if (event_type == ACPI_EVENT_TYPE_GPE)
+               gpe_count(event_number);
+
+       if (event_type == ACPI_EVENT_TYPE_FIXED)
+               fixed_event_count(event_number);
+}
+
 static int get_status(u32 index, acpi_event_status *status,
                      acpi_handle *handle)
 {
@@ -601,6 +611,7 @@ end:
 
 void acpi_irq_stats_init(void)
 {
+       acpi_status status;
        int i;
 
        if (all_counters)
@@ -619,6 +630,10 @@ void acpi_irq_stats_init(void)
        if (all_counters == NULL)
                goto fail;
 
+       status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL);
+       if (ACPI_FAILURE(status))
+               goto fail;
+
        counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
                                GFP_KERNEL);
        if (counter_attrs == NULL)
index 5a27b0a313151714976f88b2299df0937d29c8be..2607e17b520f9b39a5d60f7bee508ba62b813ea0 100644 (file)
@@ -1059,8 +1059,9 @@ static int acpi_thermal_resume(struct acpi_device *device)
                        break;
                tz->trips.active[i].flags.enabled = 1;
                for (j = 0; j < tz->trips.active[i].devices.count; j++) {
-                       result = acpi_bus_get_power(tz->trips.active[i].devices.
-                           handles[j], &power_state);
+                       result = acpi_bus_update_power(
+                                       tz->trips.active[i].devices.handles[j],
+                                       &power_state);
                        if (result || (power_state != ACPI_STATE_D0)) {
                                tz->trips.active[i].flags.enabled = 0;
                                break;
index f62a50c3ed3401e20fe7c0af8555584110cecb8e..ed6501452507ff73ee796fd07f29097987b0dd01 100644 (file)
@@ -37,15 +37,16 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
                        container_of(node, struct acpi_device, wakeup_list);
 
                if (!dev->wakeup.flags.valid
-                   || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count)
-                   || sleep_state > (u32) dev->wakeup.sleep_state)
+                   || sleep_state > (u32) dev->wakeup.sleep_state
+                   || !(device_may_wakeup(&dev->dev)
+                       || dev->wakeup.prepare_count))
                        continue;
 
-               if (dev->wakeup.state.enabled)
+               if (device_may_wakeup(&dev->dev))
                        acpi_enable_wakeup_device_power(dev, sleep_state);
 
                /* The wake-up power should have been enabled already. */
-               acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
+               acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
                                ACPI_GPE_ENABLE);
        }
 }
@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
                        container_of(node, struct acpi_device, wakeup_list);
 
                if (!dev->wakeup.flags.valid
-                   || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count)
-                   || (sleep_state > (u32) dev->wakeup.sleep_state))
+                   || sleep_state > (u32) dev->wakeup.sleep_state
+                   || !(device_may_wakeup(&dev->dev)
+                       || dev->wakeup.prepare_count))
                        continue;
 
-               acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
+               acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
                                ACPI_GPE_DISABLE);
 
-               if (dev->wakeup.state.enabled)
+               if (device_may_wakeup(&dev->dev))
                        acpi_disable_wakeup_device_power(dev);
        }
 }
@@ -84,8 +86,8 @@ int __init acpi_wakeup_device_init(void)
                struct acpi_device *dev = container_of(node,
                                                       struct acpi_device,
                                                       wakeup_list);
-               if (dev->wakeup.flags.always_enabled)
-                       dev->wakeup.state.enabled = 1;
+               if (device_can_wakeup(&dev->dev))
+                       device_set_wakeup_enable(&dev->dev, true);
        }
        mutex_unlock(&acpi_device_lock);
        return 0;
index 035da9e64a1704fce0d28e35cb74a5bdd8ef0593..c4bacc6ec450fc0cf76d8c8e4cf37ad9d98333f6 100644 (file)
@@ -1928,7 +1928,8 @@ static void __devinit hardcode_find_bmc(void)
 static int acpi_failure;
 
 /* For GPE-type interrupts. */
-static u32 ipmi_acpi_gpe(void *context)
+static u32 ipmi_acpi_gpe(acpi_handle gpe_device,
+       u32 gpe_number, void *context)
 {
        struct smi_info *smi_info = context;
        unsigned long   flags;
index f44cd2620ff9e123fab32ee1ce7355b9d477d1cc..cf6c47250c56a04cfb92cabd16b320f1e627fd56 100644 (file)
@@ -689,7 +689,7 @@ static int acpi_fujitsu_add(struct acpi_device *device)
        if (error)
                goto err_free_input_dev;
 
-       result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
+       result = acpi_bus_update_power(fujitsu->acpi_handle, &state);
        if (result) {
                printk(KERN_ERR "Error reading power state\n");
                goto err_unregister_input_dev;
@@ -857,7 +857,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
        if (error)
                goto err_free_input_dev;
 
-       result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state);
+       result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state);
        if (result) {
                printk(KERN_ERR "Error reading power state\n");
                goto err_unregister_input_dev;
index 359ef11725a65da5bf6d07d8fc0cccee33be803f..20b05cd6866340a82e8cee11e3de18332f494edc 100644 (file)
@@ -149,8 +149,7 @@ struct acpi_device_flags {
        u32 power_manageable:1;
        u32 performance_manageable:1;
        u32 wake_capable:1;     /* Wakeup(_PRW) supported? */
-       u32 force_power_state:1;
-       u32 reserved:22;
+       u32 reserved:23;
 };
 
 /* File System */
@@ -242,20 +241,14 @@ struct acpi_device_perf {
 struct acpi_device_wakeup_flags {
        u8 valid:1;             /* Can successfully enable wakeup? */
        u8 run_wake:1;          /* Run-Wake GPE devices */
-       u8 always_enabled:1;    /* Run-wake devices that are always enabled */
        u8 notifier_present:1;  /* Wake-up notify handler has been installed */
 };
 
-struct acpi_device_wakeup_state {
-       u8 enabled:1;
-};
-
 struct acpi_device_wakeup {
        acpi_handle gpe_device;
        u64 gpe_number;
        u64 sleep_state;
        struct acpi_handle_list resources;
-       struct acpi_device_wakeup_state state;
        struct acpi_device_wakeup_flags flags;
        int prepare_count;
        int run_wake_count;
@@ -328,8 +321,8 @@ void acpi_bus_data_handler(acpi_handle handle, void *context);
 acpi_status acpi_bus_get_status_handle(acpi_handle handle,
                                       unsigned long long *sta);
 int acpi_bus_get_status(struct acpi_device *device);
-int acpi_bus_get_power(acpi_handle handle, int *state);
 int acpi_bus_set_power(acpi_handle handle, int state);
+int acpi_bus_update_power(acpi_handle handle, int *state_p);
 bool acpi_bus_power_manageable(acpi_handle handle);
 bool acpi_bus_can_wakeup(acpi_handle handle);
 #ifdef CONFIG_ACPI_PROC_EVENT
index 53b7cfd924a300ec924ca0cea5ed9dde18ba8e40..241b8a04c83c83b5dfb082eed7b696c05b4e2840 100644 (file)
@@ -47,7 +47,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20101013
+#define ACPI_CA_VERSION                 0x20101209
 
 #include "actypes.h"
 #include "actbl.h"
@@ -228,6 +228,10 @@ acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
 acpi_status
 acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
 
+acpi_status
+acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler,
+                                void *context);
+
 acpi_status
 acpi_install_fixed_event_handler(u32 acpi_event,
                                 acpi_event_handler handler, void *context);
@@ -258,11 +262,11 @@ acpi_remove_address_space_handler(acpi_handle device,
 acpi_status
 acpi_install_gpe_handler(acpi_handle gpe_device,
                         u32 gpe_number,
-                        u32 type, acpi_event_handler address, void *context);
+                        u32 type, acpi_gpe_handler address, void *context);
 
 acpi_status
 acpi_remove_gpe_handler(acpi_handle gpe_device,
-                       u32 gpe_number, acpi_event_handler address);
+                       u32 gpe_number, acpi_gpe_handler address);
 
 #ifdef ACPI_FUTURE_USAGE
 acpi_status acpi_install_exception_handler(acpi_exception_handler handler);
@@ -292,11 +296,13 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);
 
 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);
 
-acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number);
-
 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number);
 
-acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action);
+acpi_status
+acpi_setup_gpe_for_wake(acpi_handle parent_device,
+                       acpi_handle gpe_device, u32 gpe_number);
+
+acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action);
 
 acpi_status
 acpi_get_gpe_status(acpi_handle gpe_device,
@@ -315,7 +321,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
 
 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device);
 
-acpi_status acpi_update_gpes(void);
+acpi_status acpi_update_all_gpes(void);
 
 /*
  * Resource interfaces
index 2b134b691e349dbbab0f87966e96e3d70185e4f5..939a431a6ab61b34bd1809964da9484e5e2a382b 100644 (file)
@@ -656,33 +656,34 @@ typedef u32 acpi_event_status;
 #define ACPI_GPE_MAX                    0xFF
 #define ACPI_NUM_GPE                    256
 
-/* Actions for acpi_gpe_wakeup, acpi_hw_low_set_gpe */
+/* Actions for acpi_set_gpe_wake_mask, acpi_hw_low_set_gpe */
 
 #define ACPI_GPE_ENABLE                 0
 #define ACPI_GPE_DISABLE                1
-#define ACPI_GPE_COND_ENABLE            2
+#define ACPI_GPE_CONDITIONAL_ENABLE     2
 
 /*
  * GPE info flags - Per GPE
- * +-------+---+-+-+
- * |  7:4  |3:2|1|0|
- * +-------+---+-+-+
- *     |     |  | |
- *     |     |  | +--- Interrupt type: edge or level triggered
- *     |     |  +----- GPE can wake the system
- *     |     +-------- Type of dispatch:to method, handler, or none
- *     +-------------- <Reserved>
+ * +-------+-+-+---+
+ * |  7:4  |3|2|1:0|
+ * +-------+-+-+---+
+ *     |    | |  |
+ *     |    | |  +-- Type of dispatch:to method, handler, notify, or none
+ *     |    | +----- Interrupt type: edge or level triggered
+ *     |    +------- Is a Wake GPE
+ *     +------------ <Reserved>
  */
-#define ACPI_GPE_XRUPT_TYPE_MASK        (u8) 0x01
-#define ACPI_GPE_LEVEL_TRIGGERED        (u8) 0x01
-#define ACPI_GPE_EDGE_TRIGGERED         (u8) 0x00
+#define ACPI_GPE_DISPATCH_NONE          (u8) 0x00
+#define ACPI_GPE_DISPATCH_METHOD        (u8) 0x01
+#define ACPI_GPE_DISPATCH_HANDLER       (u8) 0x02
+#define ACPI_GPE_DISPATCH_NOTIFY        (u8) 0x03
+#define ACPI_GPE_DISPATCH_MASK          (u8) 0x03
 
-#define ACPI_GPE_CAN_WAKE              (u8) 0x02
+#define ACPI_GPE_LEVEL_TRIGGERED        (u8) 0x04
+#define ACPI_GPE_EDGE_TRIGGERED         (u8) 0x00
+#define ACPI_GPE_XRUPT_TYPE_MASK        (u8) 0x04
 
-#define ACPI_GPE_DISPATCH_MASK          (u8) 0x0C
-#define ACPI_GPE_DISPATCH_HANDLER       (u8) 0x04
-#define ACPI_GPE_DISPATCH_METHOD        (u8) 0x08
-#define ACPI_GPE_DISPATCH_NOT_USED      (u8) 0x00
+#define ACPI_GPE_CAN_WAKE               (u8) 0x08
 
 /*
  * Flags for GPE and Lock interfaces
@@ -894,8 +895,19 @@ typedef void
 /*
  * Various handlers and callback procedures
  */
+typedef
+void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type,
+                              acpi_handle device,
+                              u32 event_number, void *context);
+
+#define ACPI_EVENT_TYPE_GPE         0
+#define ACPI_EVENT_TYPE_FIXED       1
+
 typedef u32(*acpi_event_handler) (void *context);
 
+typedef
+u32 (*acpi_gpe_handler) (acpi_handle gpe_device, u32 gpe_number, void *context);
+
 typedef
 void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context);
 
@@ -951,6 +963,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
 #define ACPI_INTERRUPT_NOT_HANDLED      0x00
 #define ACPI_INTERRUPT_HANDLED          0x01
 
+/* GPE handler return values */
+
+#define ACPI_REENABLE_GPE               0x80
+
 /* Length of 32-bit EISAID values when converted back to a string */
 
 #define ACPI_EISAID_STRING_SIZE         8      /* Includes null terminator */
index 67c91b4418b06e59ea9de82e0c67dfb4cc5a7554..fa7ed6a983d0b2bbd4367c053eb6b77b0deb5e22 100644 (file)
@@ -254,6 +254,15 @@ void __init acpi_old_suspend_ordering(void);
 void __init acpi_nvs_nosave(void);
 #endif /* CONFIG_PM_SLEEP */
 
+#ifdef CONFIG_ACPI_SLEEP
+int suspend_nvs_register(unsigned long start, unsigned long size);
+#else
+static inline int suspend_nvs_register(unsigned long a, unsigned long b)
+{
+       return 0;
+}
+#endif
+
 struct acpi_osc_context {
        char *uuid_str; /* uuid string */
        int rev;
index 26697514c5ece07d72f6e07022f43ee86d187de0..0e288e3c37be645103f987e80445b39fdb801f14 100644 (file)
@@ -258,23 +258,6 @@ static inline int hibernate(void) { return -ENOSYS; }
 static inline bool system_entering_hibernation(void) { return false; }
 #endif /* CONFIG_HIBERNATION */
 
-#ifdef CONFIG_SUSPEND_NVS
-extern int suspend_nvs_register(unsigned long start, unsigned long size);
-extern int suspend_nvs_alloc(void);
-extern void suspend_nvs_free(void);
-extern void suspend_nvs_save(void);
-extern void suspend_nvs_restore(void);
-#else /* CONFIG_SUSPEND_NVS */
-static inline int suspend_nvs_register(unsigned long a, unsigned long b)
-{
-       return 0;
-}
-static inline int suspend_nvs_alloc(void) { return 0; }
-static inline void suspend_nvs_free(void) {}
-static inline void suspend_nvs_save(void) {}
-static inline void suspend_nvs_restore(void) {}
-#endif /* CONFIG_SUSPEND_NVS */
-
 #ifdef CONFIG_PM_SLEEP
 void save_processor_state(void);
 void restore_processor_state(void);
index a5aff3ebad38b68629d341cb5a28856afb970796..265729966ece61898c9f37a5b8fde49978bcce8c 100644 (file)
@@ -100,13 +100,9 @@ config PM_SLEEP_ADVANCED_DEBUG
        depends on PM_ADVANCED_DEBUG
        default n
 
-config SUSPEND_NVS
-       bool
-
 config SUSPEND
        bool "Suspend to RAM and standby"
        depends on PM && ARCH_SUSPEND_POSSIBLE
-       select SUSPEND_NVS if HAS_IOMEM
        default y
        ---help---
          Allow the system to enter sleep states in which main memory is
@@ -140,7 +136,6 @@ config HIBERNATION
        depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
        select LZO_COMPRESS
        select LZO_DECOMPRESS
-       select SUSPEND_NVS if HAS_IOMEM
        ---help---
          Enable the suspend to disk (STD) functionality, which is usually
          called "hibernation" in user interfaces.  STD checkpoints the
index f9063c6b185d2917124f06350753ad96e0b184d1..120a15823325990c1d2a16e6ad048b7a392232e9 100644 (file)
@@ -10,6 +10,5 @@ obj-$(CONFIG_SUSPEND)         += suspend.o
 obj-$(CONFIG_PM_TEST_SUSPEND)  += suspend_test.o
 obj-$(CONFIG_HIBERNATION)      += hibernate.o snapshot.o swap.o user.o \
                                   block_io.o
-obj-$(CONFIG_SUSPEND_NVS)      += nvs.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)      += poweroff.o