Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions, and the following disclaimer,
  16.  *    without modification.
  17.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18.  *    substantially similar to the "NO WARRANTY" disclaimer below
  19.  *    ("Disclaimer") and any redistribution must be conditioned upon
  20.  *    including a substantially similar Disclaimer requirement for further
  21.  *    binary redistribution.
  22.  * 3. Neither the names of the above-listed copyright holders nor the names
  23.  *    of any contributors may be used to endorse or promote products derived
  24.  *    from this software without specific prior written permission.
  25.  *
  26.  * Alternatively, this software may be distributed under the terms of the
  27.  * GNU General Public License ("GPL") version 2 as published by the Free
  28.  * Software Foundation.
  29.  *
  30.  * NO WARRANTY
  31.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41.  * POSSIBILITY OF SUCH DAMAGES.
  42.  */
  43.  
  44. #define EXPORT_ACPI_INTERFACES
  45.  
  46. #include <acpi/acpi.h>
  47. #include "accommon.h"
  48. #include "acevents.h"
  49. #include "acnamesp.h"
  50.  
  51. #define _COMPONENT          ACPI_EVENTS
  52. ACPI_MODULE_NAME("evxfgpe")
  53.  
  54. #if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
  55. /*******************************************************************************
  56.  *
  57.  * FUNCTION:    acpi_update_all_gpes
  58.  *
  59.  * PARAMETERS:  None
  60.  *
  61.  * RETURN:      Status
  62.  *
  63.  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
  64.  *              associated _Lxx or _Exx methods and are not pointed to by any
  65.  *              device _PRW methods (this indicates that these GPEs are
  66.  *              generally intended for system or device wakeup. Such GPEs
  67.  *              have to be enabled directly when the devices whose _PRW
  68.  *              methods point to them are set up for wakeup signaling.)
  69.  *
  70.  * NOTE: Should be called after any GPEs are added to the system. Primarily,
  71.  * after the system _PRW methods have been run, but also after a GPE Block
  72.  * Device has been added or if any new GPE methods have been added via a
  73.  * dynamic table load.
  74.  *
  75.  ******************************************************************************/
  76.  
  77. acpi_status acpi_update_all_gpes(void)
  78. {
  79.         acpi_status status;
  80.  
  81.         ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
  82.  
  83.         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  84.         if (ACPI_FAILURE(status)) {
  85.                 return_ACPI_STATUS(status);
  86.         }
  87.  
  88.         if (acpi_gbl_all_gpes_initialized) {
  89.                 goto unlock_and_exit;
  90.         }
  91.  
  92.         status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
  93.         if (ACPI_SUCCESS(status)) {
  94.                 acpi_gbl_all_gpes_initialized = TRUE;
  95.         }
  96.  
  97. unlock_and_exit:
  98.         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  99.  
  100.         return_ACPI_STATUS(status);
  101. }
  102.  
  103. ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
  104.  
  105. /*******************************************************************************
  106.  *
  107.  * FUNCTION:    acpi_enable_gpe
  108.  *
  109.  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
  110.  *              gpe_number          - GPE level within the GPE block
  111.  *
  112.  * RETURN:      Status
  113.  *
  114.  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
  115.  *              hardware-enabled.
  116.  *
  117.  ******************************************************************************/
  118. acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
  119. {
  120.         acpi_status status = AE_BAD_PARAMETER;
  121.         struct acpi_gpe_event_info *gpe_event_info;
  122.         acpi_cpu_flags flags;
  123.  
  124.         ACPI_FUNCTION_TRACE(acpi_enable_gpe);
  125.  
  126.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  127.  
  128.         /*
  129.          * Ensure that we have a valid GPE number and that there is some way
  130.          * of handling the GPE (handler or a GPE method). In other words, we
  131.          * won't allow a valid GPE to be enabled if there is no way to handle it.
  132.          */
  133.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  134.         if (gpe_event_info) {
  135.                 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
  136.                     ACPI_GPE_DISPATCH_NONE) {
  137.                         status = acpi_ev_add_gpe_reference(gpe_event_info);
  138.                 } else {
  139.                         status = AE_NO_HANDLER;
  140.                 }
  141.         }
  142.  
  143.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  144.         return_ACPI_STATUS(status);
  145. }
  146. ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
  147.  
  148. /*******************************************************************************
  149.  *
  150.  * FUNCTION:    acpi_disable_gpe
  151.  *
  152.  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  153.  *              gpe_number      - GPE level within the GPE block
  154.  *
  155.  * RETURN:      Status
  156.  *
  157.  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
  158.  *              removed, only then is the GPE disabled (for runtime GPEs), or
  159.  *              the GPE mask bit disabled (for wake GPEs)
  160.  *
  161.  ******************************************************************************/
  162.  
  163. acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
  164. {
  165.         acpi_status status = AE_BAD_PARAMETER;
  166.         struct acpi_gpe_event_info *gpe_event_info;
  167.         acpi_cpu_flags flags;
  168.  
  169.         ACPI_FUNCTION_TRACE(acpi_disable_gpe);
  170.  
  171.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  172.  
  173.         /* Ensure that we have a valid GPE number */
  174.  
  175.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  176.         if (gpe_event_info) {
  177.                 status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
  178.         }
  179.  
  180.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  181.         return_ACPI_STATUS(status);
  182. }
  183.  
  184. ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
  185.  
  186. /*******************************************************************************
  187.  *
  188.  * FUNCTION:    acpi_set_gpe
  189.  *
  190.  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
  191.  *              gpe_number          - GPE level within the GPE block
  192.  *              action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
  193.  *
  194.  * RETURN:      Status
  195.  *
  196.  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
  197.  *              the reference count mechanism used in the acpi_enable_gpe(),
  198.  *              acpi_disable_gpe() interfaces.
  199.  *              This API is typically used by the GPE raw handler mode driver
  200.  *              to switch between the polling mode and the interrupt mode after
  201.  *              the driver has enabled the GPE.
  202.  *              The APIs should be invoked in this order:
  203.  *               acpi_enable_gpe()            <- Ensure the reference count > 0
  204.  *               acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
  205.  *               acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
  206.  *               acpi_disable_gpe()           <- Decrease the reference count
  207.  *
  208.  * Note: If a GPE is shared by 2 silicon components, then both the drivers
  209.  *       should support GPE polling mode or disabling the GPE for long period
  210.  *       for one driver may break the other. So use it with care since all
  211.  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
  212.  *
  213.  ******************************************************************************/
  214. acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
  215. {
  216.         struct acpi_gpe_event_info *gpe_event_info;
  217.         acpi_status status;
  218.         acpi_cpu_flags flags;
  219.  
  220.         ACPI_FUNCTION_TRACE(acpi_set_gpe);
  221.  
  222.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  223.  
  224.         /* Ensure that we have a valid GPE number */
  225.  
  226.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  227.         if (!gpe_event_info) {
  228.                 status = AE_BAD_PARAMETER;
  229.                 goto unlock_and_exit;
  230.         }
  231.  
  232.         /* Perform the action */
  233.  
  234.         switch (action) {
  235.         case ACPI_GPE_ENABLE:
  236.  
  237.                 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
  238.                 break;
  239.  
  240.         case ACPI_GPE_DISABLE:
  241.  
  242.                 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
  243.                 break;
  244.  
  245.         default:
  246.  
  247.                 status = AE_BAD_PARAMETER;
  248.                 break;
  249.         }
  250.  
  251. unlock_and_exit:
  252.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  253.         return_ACPI_STATUS(status);
  254. }
  255.  
  256. ACPI_EXPORT_SYMBOL(acpi_set_gpe)
  257.  
  258. /*******************************************************************************
  259.  *
  260.  * FUNCTION:    acpi_mark_gpe_for_wake
  261.  *
  262.  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
  263.  *              gpe_number          - GPE level within the GPE block
  264.  *
  265.  * RETURN:      Status
  266.  *
  267.  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
  268.  *              sets the ACPI_GPE_CAN_WAKE flag.
  269.  *
  270.  * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
  271.  * there won't be any notify handlers installed for device wake notifications
  272.  * from the given GPE (one example is a button GPE in Linux). For these cases,
  273.  * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
  274.  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
  275.  * setup implicit wake notification for it (since there's no handler method).
  276.  *
  277.  ******************************************************************************/
  278. acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
  279. {
  280.         struct acpi_gpe_event_info *gpe_event_info;
  281.         acpi_status status = AE_BAD_PARAMETER;
  282.         acpi_cpu_flags flags;
  283.  
  284.         ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
  285.  
  286.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  287.  
  288.         /* Ensure that we have a valid GPE number */
  289.  
  290.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  291.         if (gpe_event_info) {
  292.  
  293.                 /* Mark the GPE as a possible wake event */
  294.  
  295.                 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
  296.                 status = AE_OK;
  297.         }
  298.  
  299.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  300.         return_ACPI_STATUS(status);
  301. }
  302.  
  303. ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
  304.  
  305. /*******************************************************************************
  306.  *
  307.  * FUNCTION:    acpi_setup_gpe_for_wake
  308.  *
  309.  * PARAMETERS:  wake_device         - Device associated with the GPE (via _PRW)
  310.  *              gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
  311.  *              gpe_number          - GPE level within the GPE block
  312.  *
  313.  * RETURN:      Status
  314.  *
  315.  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
  316.  *              interface is intended to be used as the host executes the
  317.  *              _PRW methods (Power Resources for Wake) in the system tables.
  318.  *              Each _PRW appears under a Device Object (The wake_device), and
  319.  *              contains the info for the wake GPE associated with the
  320.  *              wake_device.
  321.  *
  322.  ******************************************************************************/
  323. acpi_status
  324. acpi_setup_gpe_for_wake(acpi_handle wake_device,
  325.                         acpi_handle gpe_device, u32 gpe_number)
  326. {
  327.         acpi_status status;
  328.         struct acpi_gpe_event_info *gpe_event_info;
  329.         struct acpi_namespace_node *device_node;
  330.         struct acpi_gpe_notify_info *notify;
  331.         struct acpi_gpe_notify_info *new_notify;
  332.         acpi_cpu_flags flags;
  333.  
  334.         ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
  335.  
  336.         /* Parameter Validation */
  337.  
  338.         if (!wake_device) {
  339.                 /*
  340.                  * By forcing wake_device to be valid, we automatically enable the
  341.                  * implicit notify feature on all hosts.
  342.                  */
  343.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  344.         }
  345.  
  346.         /* Handle root object case */
  347.  
  348.         if (wake_device == ACPI_ROOT_OBJECT) {
  349.                 device_node = acpi_gbl_root_node;
  350.         } else {
  351.                 device_node =
  352.                     ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
  353.         }
  354.  
  355.         /* Validate wake_device is of type Device */
  356.  
  357.         if (device_node->type != ACPI_TYPE_DEVICE) {
  358.                 return_ACPI_STATUS (AE_BAD_PARAMETER);
  359.         }
  360.  
  361.         /*
  362.          * Allocate a new notify object up front, in case it is needed.
  363.          * Memory allocation while holding a spinlock is a big no-no
  364.          * on some hosts.
  365.          */
  366.         new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info));
  367.         if (!new_notify) {
  368.                 return_ACPI_STATUS(AE_NO_MEMORY);
  369.         }
  370.  
  371.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  372.  
  373.         /* Ensure that we have a valid GPE number */
  374.  
  375.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  376.         if (!gpe_event_info) {
  377.                 status = AE_BAD_PARAMETER;
  378.                 goto unlock_and_exit;
  379.         }
  380.  
  381.         /*
  382.          * If there is no method or handler for this GPE, then the
  383.          * wake_device will be notified whenever this GPE fires. This is
  384.          * known as an "implicit notify". Note: The GPE is assumed to be
  385.          * level-triggered (for windows compatibility).
  386.          */
  387.         if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
  388.             ACPI_GPE_DISPATCH_NONE) {
  389.                 /*
  390.                  * This is the first device for implicit notify on this GPE.
  391.                  * Just set the flags here, and enter the NOTIFY block below.
  392.                  */
  393.                 gpe_event_info->flags =
  394.                     (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
  395.         }
  396.  
  397.         /*
  398.          * If we already have an implicit notify on this GPE, add
  399.          * this device to the notify list.
  400.          */
  401.         if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
  402.             ACPI_GPE_DISPATCH_NOTIFY) {
  403.  
  404.                 /* Ensure that the device is not already in the list */
  405.  
  406.                 notify = gpe_event_info->dispatch.notify_list;
  407.                 while (notify) {
  408.                         if (notify->device_node == device_node) {
  409.                                 status = AE_ALREADY_EXISTS;
  410.                                 goto unlock_and_exit;
  411.                         }
  412.                         notify = notify->next;
  413.                 }
  414.  
  415.                 /* Add this device to the notify list for this GPE */
  416.  
  417.                 new_notify->device_node = device_node;
  418.                 new_notify->next = gpe_event_info->dispatch.notify_list;
  419.                 gpe_event_info->dispatch.notify_list = new_notify;
  420.                 new_notify = NULL;
  421.         }
  422.  
  423.         /* Mark the GPE as a possible wake event */
  424.  
  425.         gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
  426.         status = AE_OK;
  427.  
  428. unlock_and_exit:
  429.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  430.  
  431.         /* Delete the notify object if it was not used above */
  432.  
  433.         if (new_notify) {
  434.                 ACPI_FREE(new_notify);
  435.         }
  436.         return_ACPI_STATUS(status);
  437. }
  438. ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
  439.  
  440. /*******************************************************************************
  441.  *
  442.  * FUNCTION:    acpi_set_gpe_wake_mask
  443.  *
  444.  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  445.  *              gpe_number      - GPE level within the GPE block
  446.  *              action              - Enable or Disable
  447.  *
  448.  * RETURN:      Status
  449.  *
  450.  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
  451.  *              already be marked as a WAKE GPE.
  452.  *
  453.  ******************************************************************************/
  454.  
  455. acpi_status
  456. acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
  457. {
  458.         acpi_status status = AE_OK;
  459.         struct acpi_gpe_event_info *gpe_event_info;
  460.         struct acpi_gpe_register_info *gpe_register_info;
  461.         acpi_cpu_flags flags;
  462.         u32 register_bit;
  463.  
  464.         ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
  465.  
  466.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  467.  
  468.         /*
  469.          * Ensure that we have a valid GPE number and that this GPE is in
  470.          * fact a wake GPE
  471.          */
  472.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  473.         if (!gpe_event_info) {
  474.                 status = AE_BAD_PARAMETER;
  475.                 goto unlock_and_exit;
  476.         }
  477.  
  478.         if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
  479.                 status = AE_TYPE;
  480.                 goto unlock_and_exit;
  481.         }
  482.  
  483.         gpe_register_info = gpe_event_info->register_info;
  484.         if (!gpe_register_info) {
  485.                 status = AE_NOT_EXIST;
  486.                 goto unlock_and_exit;
  487.         }
  488.  
  489.         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
  490.  
  491.         /* Perform the action */
  492.  
  493.         switch (action) {
  494.         case ACPI_GPE_ENABLE:
  495.  
  496.                 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
  497.                              (u8)register_bit);
  498.                 break;
  499.  
  500.         case ACPI_GPE_DISABLE:
  501.  
  502.                 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
  503.                                (u8)register_bit);
  504.                 break;
  505.  
  506.         default:
  507.  
  508.                 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
  509.                 status = AE_BAD_PARAMETER;
  510.                 break;
  511.         }
  512.  
  513. unlock_and_exit:
  514.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  515.         return_ACPI_STATUS(status);
  516. }
  517.  
  518. ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
  519.  
  520. /*******************************************************************************
  521.  *
  522.  * FUNCTION:    acpi_clear_gpe
  523.  *
  524.  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  525.  *              gpe_number      - GPE level within the GPE block
  526.  *
  527.  * RETURN:      Status
  528.  *
  529.  * DESCRIPTION: Clear an ACPI event (general purpose)
  530.  *
  531.  ******************************************************************************/
  532. acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
  533. {
  534.         acpi_status status = AE_OK;
  535.         struct acpi_gpe_event_info *gpe_event_info;
  536.         acpi_cpu_flags flags;
  537.  
  538.         ACPI_FUNCTION_TRACE(acpi_clear_gpe);
  539.  
  540.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  541.  
  542.         /* Ensure that we have a valid GPE number */
  543.  
  544.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  545.         if (!gpe_event_info) {
  546.                 status = AE_BAD_PARAMETER;
  547.                 goto unlock_and_exit;
  548.         }
  549.  
  550.         status = acpi_hw_clear_gpe(gpe_event_info);
  551.  
  552.       unlock_and_exit:
  553.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  554.         return_ACPI_STATUS(status);
  555. }
  556.  
  557. ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
  558.  
  559. /*******************************************************************************
  560.  *
  561.  * FUNCTION:    acpi_get_gpe_status
  562.  *
  563.  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
  564.  *              gpe_number          - GPE level within the GPE block
  565.  *              event_status        - Where the current status of the event
  566.  *                                    will be returned
  567.  *
  568.  * RETURN:      Status
  569.  *
  570.  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
  571.  *
  572.  ******************************************************************************/
  573. acpi_status
  574. acpi_get_gpe_status(acpi_handle gpe_device,
  575.                     u32 gpe_number, acpi_event_status *event_status)
  576. {
  577.         acpi_status status = AE_OK;
  578.         struct acpi_gpe_event_info *gpe_event_info;
  579.         acpi_cpu_flags flags;
  580.  
  581.         ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
  582.  
  583.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  584.  
  585.         /* Ensure that we have a valid GPE number */
  586.  
  587.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  588.         if (!gpe_event_info) {
  589.                 status = AE_BAD_PARAMETER;
  590.                 goto unlock_and_exit;
  591.         }
  592.  
  593.         /* Obtain status on the requested GPE number */
  594.  
  595.         status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
  596.  
  597. unlock_and_exit:
  598.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  599.         return_ACPI_STATUS(status);
  600. }
  601.  
  602. ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
  603.  
  604. /*******************************************************************************
  605.  *
  606.  * FUNCTION:    acpi_finish_gpe
  607.  *
  608.  * PARAMETERS:  gpe_device          - Namespace node for the GPE Block
  609.  *                                    (NULL for FADT defined GPEs)
  610.  *              gpe_number          - GPE level within the GPE block
  611.  *
  612.  * RETURN:      Status
  613.  *
  614.  * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
  615.  *              processing. Intended for use by asynchronous host-installed
  616.  *              GPE handlers. The GPE is only reenabled if the enable_for_run bit
  617.  *              is set in the GPE info.
  618.  *
  619.  ******************************************************************************/
  620. acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)
  621. {
  622.         struct acpi_gpe_event_info *gpe_event_info;
  623.         acpi_status status;
  624.         acpi_cpu_flags flags;
  625.  
  626.         ACPI_FUNCTION_TRACE(acpi_finish_gpe);
  627.  
  628.         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  629.  
  630.         /* Ensure that we have a valid GPE number */
  631.  
  632.         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  633.         if (!gpe_event_info) {
  634.                 status = AE_BAD_PARAMETER;
  635.                 goto unlock_and_exit;
  636.         }
  637.  
  638.         status = acpi_ev_finish_gpe(gpe_event_info);
  639.  
  640. unlock_and_exit:
  641.         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  642.         return_ACPI_STATUS(status);
  643. }
  644.  
  645. ACPI_EXPORT_SYMBOL(acpi_finish_gpe)
  646.  
  647. /******************************************************************************
  648.  *
  649.  * FUNCTION:    acpi_disable_all_gpes
  650.  *
  651.  * PARAMETERS:  None
  652.  *
  653.  * RETURN:      Status
  654.  *
  655.  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
  656.  *
  657.  ******************************************************************************/
  658.  
  659. acpi_status acpi_disable_all_gpes(void)
  660. {
  661.         acpi_status status;
  662.  
  663.         ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
  664.  
  665.         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  666.         if (ACPI_FAILURE(status)) {
  667.                 return_ACPI_STATUS(status);
  668.         }
  669.  
  670.         status = acpi_hw_disable_all_gpes();
  671.         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  672.  
  673.         return_ACPI_STATUS(status);
  674. }
  675.  
  676. ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
  677.  
  678. /******************************************************************************
  679.  *
  680.  * FUNCTION:    acpi_enable_all_runtime_gpes
  681.  *
  682.  * PARAMETERS:  None
  683.  *
  684.  * RETURN:      Status
  685.  *
  686.  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
  687.  *
  688.  ******************************************************************************/
  689.  
  690. acpi_status acpi_enable_all_runtime_gpes(void)
  691. {
  692.         acpi_status status;
  693.  
  694.         ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
  695.  
  696.         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  697.         if (ACPI_FAILURE(status)) {
  698.                 return_ACPI_STATUS(status);
  699.         }
  700.  
  701.         status = acpi_hw_enable_all_runtime_gpes();
  702.         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  703.  
  704.         return_ACPI_STATUS(status);
  705. }
  706.  
  707. ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
  708.  
  709. /******************************************************************************
  710.  *
  711.  * FUNCTION:    acpi_enable_all_wakeup_gpes
  712.  *
  713.  * PARAMETERS:  None
  714.  *
  715.  * RETURN:      Status
  716.  *
  717.  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
  718.  *              all GPE blocks.
  719.  *
  720.  ******************************************************************************/
  721. acpi_status acpi_enable_all_wakeup_gpes(void)
  722. {
  723.         acpi_status status;
  724.  
  725.         ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes);
  726.  
  727.         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  728.         if (ACPI_FAILURE(status)) {
  729.                 return_ACPI_STATUS(status);
  730.         }
  731.  
  732.         status = acpi_hw_enable_all_wakeup_gpes();
  733.         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  734.  
  735.         return_ACPI_STATUS(status);
  736. }
  737.  
  738. ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
  739.  
  740. /*******************************************************************************
  741.  *
  742.  * FUNCTION:    acpi_install_gpe_block
  743.  *
  744.  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
  745.  *              gpe_block_address   - Address and space_ID
  746.  *              register_count      - Number of GPE register pairs in the block
  747.  *              interrupt_number    - H/W interrupt for the block
  748.  *
  749.  * RETURN:      Status
  750.  *
  751.  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
  752.  *              enabled here.
  753.  *
  754.  ******************************************************************************/
  755. acpi_status
  756. acpi_install_gpe_block(acpi_handle gpe_device,
  757.                        struct acpi_generic_address *gpe_block_address,
  758.                        u32 register_count, u32 interrupt_number)
  759. {
  760.         acpi_status status;
  761.         union acpi_operand_object *obj_desc;
  762.         struct acpi_namespace_node *node;
  763.         struct acpi_gpe_block_info *gpe_block;
  764.  
  765.         ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
  766.  
  767.         if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
  768.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  769.         }
  770.  
  771.         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  772.         if (ACPI_FAILURE(status)) {
  773.                 return_ACPI_STATUS(status);
  774.         }
  775.  
  776.         node = acpi_ns_validate_handle(gpe_device);
  777.         if (!node) {
  778.                 status = AE_BAD_PARAMETER;
  779.                 goto unlock_and_exit;
  780.         }
  781.  
  782.         /* Validate the parent device */
  783.  
  784.         if (node->type != ACPI_TYPE_DEVICE) {
  785.                 status = AE_TYPE;
  786.                 goto unlock_and_exit;
  787.         }
  788.  
  789.         if (node->object) {
  790.                 status = AE_ALREADY_EXISTS;
  791.                 goto unlock_and_exit;
  792.         }
  793.  
  794.         /*
  795.          * For user-installed GPE Block Devices, the gpe_block_base_number
  796.          * is always zero
  797.          */
  798.         status = acpi_ev_create_gpe_block(node, gpe_block_address->address,
  799.                                           gpe_block_address->space_id,
  800.                                           register_count, 0, interrupt_number,
  801.                                           &gpe_block);
  802.         if (ACPI_FAILURE(status)) {
  803.                 goto unlock_and_exit;
  804.         }
  805.  
  806.         /* Install block in the device_object attached to the node */
  807.  
  808.         obj_desc = acpi_ns_get_attached_object(node);
  809.         if (!obj_desc) {
  810.  
  811.                 /*
  812.                  * No object, create a new one (Device nodes do not always have
  813.                  * an attached object)
  814.                  */
  815.                 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
  816.                 if (!obj_desc) {
  817.                         status = AE_NO_MEMORY;
  818.                         goto unlock_and_exit;
  819.                 }
  820.  
  821.                 status =
  822.                     acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
  823.  
  824.                 /* Remove local reference to the object */
  825.  
  826.                 acpi_ut_remove_reference(obj_desc);
  827.  
  828.                 if (ACPI_FAILURE(status)) {
  829.                         goto unlock_and_exit;
  830.                 }
  831.         }
  832.  
  833.         /* Now install the GPE block in the device_object */
  834.  
  835.         obj_desc->device.gpe_block = gpe_block;
  836.  
  837. unlock_and_exit:
  838.         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  839.         return_ACPI_STATUS(status);
  840. }
  841.  
  842. ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
  843.  
  844. /*******************************************************************************
  845.  *
  846.  * FUNCTION:    acpi_remove_gpe_block
  847.  *
  848.  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
  849.  *
  850.  * RETURN:      Status
  851.  *
  852.  * DESCRIPTION: Remove a previously installed block of GPE registers
  853.  *
  854.  ******************************************************************************/
  855. acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
  856. {
  857.         union acpi_operand_object *obj_desc;
  858.         acpi_status status;
  859.         struct acpi_namespace_node *node;
  860.  
  861.         ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
  862.  
  863.         if (!gpe_device) {
  864.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  865.         }
  866.  
  867.         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  868.         if (ACPI_FAILURE(status)) {
  869.                 return_ACPI_STATUS(status);
  870.         }
  871.  
  872.         node = acpi_ns_validate_handle(gpe_device);
  873.         if (!node) {
  874.                 status = AE_BAD_PARAMETER;
  875.                 goto unlock_and_exit;
  876.         }
  877.  
  878.         /* Validate the parent device */
  879.  
  880.         if (node->type != ACPI_TYPE_DEVICE) {
  881.                 status = AE_TYPE;
  882.                 goto unlock_and_exit;
  883.         }
  884.  
  885.         /* Get the device_object attached to the node */
  886.  
  887.         obj_desc = acpi_ns_get_attached_object(node);
  888.         if (!obj_desc || !obj_desc->device.gpe_block) {
  889.                 return_ACPI_STATUS(AE_NULL_OBJECT);
  890.         }
  891.  
  892.         /* Delete the GPE block (but not the device_object) */
  893.  
  894.         status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
  895.         if (ACPI_SUCCESS(status)) {
  896.                 obj_desc->device.gpe_block = NULL;
  897.         }
  898.  
  899. unlock_and_exit:
  900.         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  901.         return_ACPI_STATUS(status);
  902. }
  903.  
  904. ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
  905.  
  906. /*******************************************************************************
  907.  *
  908.  * FUNCTION:    acpi_get_gpe_device
  909.  *
  910.  * PARAMETERS:  index               - System GPE index (0-current_gpe_count)
  911.  *              gpe_device          - Where the parent GPE Device is returned
  912.  *
  913.  * RETURN:      Status
  914.  *
  915.  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
  916.  *              gpe device indicates that the gpe number is contained in one of
  917.  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
  918.  *
  919.  ******************************************************************************/
  920. acpi_status acpi_get_gpe_device(u32 index, acpi_handle * gpe_device)
  921. {
  922.         struct acpi_gpe_device_info info;
  923.         acpi_status status;
  924.  
  925.         ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
  926.  
  927.         if (!gpe_device) {
  928.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  929.         }
  930.  
  931.         if (index >= acpi_current_gpe_count) {
  932.                 return_ACPI_STATUS(AE_NOT_EXIST);
  933.         }
  934.  
  935.         /* Setup and walk the GPE list */
  936.  
  937.         info.index = index;
  938.         info.status = AE_NOT_EXIST;
  939.         info.gpe_device = NULL;
  940.         info.next_block_base_index = 0;
  941.  
  942.         status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
  943.         if (ACPI_FAILURE(status)) {
  944.                 return_ACPI_STATUS(status);
  945.         }
  946.  
  947.         *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
  948.         return_ACPI_STATUS(info.status);
  949. }
  950.  
  951. ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
  952. #endif                          /* !ACPI_REDUCED_HARDWARE */
  953.