evevent.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:23k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: evevent - Fixed and General Purpose Acpi_event
  4.  *                          handling and dispatch
  5.  *              $Revision: 51 $
  6.  *
  7.  *****************************************************************************/
  8. /*
  9.  *  Copyright (C) 2000, 2001 R. Byron Moore
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25. #include "acpi.h"
  26. #include "achware.h"
  27. #include "acevents.h"
  28. #include "acnamesp.h"
  29. #define _COMPONENT          ACPI_EVENTS
  30.  MODULE_NAME         ("evevent")
  31. /*******************************************************************************
  32.  *
  33.  * FUNCTION:    Acpi_ev_initialize
  34.  *
  35.  * PARAMETERS:  None
  36.  *
  37.  * RETURN:      Status
  38.  *
  39.  * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly
  40.  *              configured, disables SCI event sources, installs the SCI
  41.  *              handler
  42.  *
  43.  ******************************************************************************/
  44. acpi_status
  45. acpi_ev_initialize (
  46. void)
  47. {
  48. acpi_status             status;
  49. FUNCTION_TRACE ("Ev_initialize");
  50. /* Make sure we have ACPI tables */
  51. if (!acpi_gbl_DSDT) {
  52. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!n"));
  53. return_ACPI_STATUS (AE_NO_ACPI_TABLES);
  54. }
  55. /* Make sure the BIOS supports ACPI mode */
  56. if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) {
  57. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "ACPI Mode is not supported!n"));
  58. return_ACPI_STATUS (AE_ERROR);
  59. }
  60. acpi_gbl_original_mode = acpi_hw_get_mode();
  61. /*
  62.  * Initialize the Fixed and General Purpose Acpi_events prior. This is
  63.  * done prior to enabling SCIs to prevent interrupts from occuring
  64.  * before handers are installed.
  65.  */
  66. status = acpi_ev_fixed_event_initialize ();
  67. if (ACPI_FAILURE (status)) {
  68. ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize fixed events.n"));
  69. return_ACPI_STATUS (status);
  70. }
  71. status = acpi_ev_gpe_initialize ();
  72. if (ACPI_FAILURE (status)) {
  73. ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize general purpose events.n"));
  74. return_ACPI_STATUS (status);
  75. }
  76. /* Install the SCI handler */
  77. status = acpi_ev_install_sci_handler ();
  78. if (ACPI_FAILURE (status)) {
  79. ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to install System Control Interrupt Handlern"));
  80. return_ACPI_STATUS (status);
  81. }
  82. /* Install handlers for control method GPE handlers (_Lxx, _Exx) */
  83. status = acpi_ev_init_gpe_control_methods ();
  84. if (ACPI_FAILURE (status)) {
  85. ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize Gpe control methodsn"));
  86. return_ACPI_STATUS (status);
  87. }
  88. /* Install the handler for the Global Lock */
  89. status = acpi_ev_init_global_lock_handler ();
  90. if (ACPI_FAILURE (status)) {
  91. ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize Global Lock handlern"));
  92. return_ACPI_STATUS (status);
  93. }
  94. return_ACPI_STATUS (status);
  95. }
  96. /*******************************************************************************
  97.  *
  98.  * FUNCTION:    Acpi_ev_fixed_event_initialize
  99.  *
  100.  * PARAMETERS:  None
  101.  *
  102.  * RETURN:      Status
  103.  *
  104.  * DESCRIPTION: Initialize the Fixed Acpi_event data structures
  105.  *
  106.  ******************************************************************************/
  107. acpi_status
  108. acpi_ev_fixed_event_initialize(void)
  109. {
  110. int                     i = 0;
  111. /* Initialize the structure that keeps track of fixed event handlers */
  112. for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
  113. acpi_gbl_fixed_event_handlers[i].handler = NULL;
  114. acpi_gbl_fixed_event_handlers[i].context = NULL;
  115. }
  116. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, TMR_EN, 0);
  117. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, GBL_EN, 0);
  118. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, PWRBTN_EN, 0);
  119. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, SLPBTN_EN, 0);
  120. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, RTC_EN, 0);
  121. return (AE_OK);
  122. }
  123. /*******************************************************************************
  124.  *
  125.  * FUNCTION:    Acpi_ev_fixed_event_detect
  126.  *
  127.  * PARAMETERS:  None
  128.  *
  129.  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  130.  *
  131.  * DESCRIPTION: Checks the PM status register for fixed events
  132.  *
  133.  ******************************************************************************/
  134. u32
  135. acpi_ev_fixed_event_detect (void)
  136. {
  137. u32                     int_status = INTERRUPT_NOT_HANDLED;
  138. u32                     status_register;
  139. u32                     enable_register;
  140. PROC_NAME ("Ev_fixed_event_detect");
  141. /*
  142.  * Read the fixed feature status and enable registers, as all the cases
  143.  * depend on their values.
  144.  */
  145. status_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
  146. enable_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
  147. ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
  148. "Fixed Acpi_event Block: Enable %08X Status %08Xn",
  149. enable_register, status_register));
  150. /* power management timer roll over */
  151. if ((status_register & ACPI_STATUS_PMTIMER) &&
  152. (enable_register & ACPI_ENABLE_PMTIMER)) {
  153. int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_PMTIMER);
  154. }
  155. /* global event (BIOS wants the global lock) */
  156. if ((status_register & ACPI_STATUS_GLOBAL) &&
  157. (enable_register & ACPI_ENABLE_GLOBAL)) {
  158. int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_GLOBAL);
  159. }
  160. /* power button event */
  161. if ((status_register & ACPI_STATUS_POWER_BUTTON) &&
  162. (enable_register & ACPI_ENABLE_POWER_BUTTON)) {
  163. int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_POWER_BUTTON);
  164. }
  165. /* sleep button event */
  166. if ((status_register & ACPI_STATUS_SLEEP_BUTTON) &&
  167. (enable_register & ACPI_ENABLE_SLEEP_BUTTON)) {
  168. int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_SLEEP_BUTTON);
  169. }
  170. return (int_status);
  171. }
  172. /*******************************************************************************
  173.  *
  174.  * FUNCTION:    Acpi_ev_fixed_event_dispatch
  175.  *
  176.  * PARAMETERS:  Event               - Event type
  177.  *
  178.  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  179.  *
  180.  * DESCRIPTION: Clears the status bit for the requested event, calls the
  181.  *              handler that previously registered for the event.
  182.  *
  183.  ******************************************************************************/
  184. u32
  185. acpi_ev_fixed_event_dispatch (
  186. u32                     event)
  187. {
  188. u32                     register_id;
  189. FUNCTION_ENTRY ();
  190. /* Clear the status bit */
  191. switch (event) {
  192. case ACPI_EVENT_PMTIMER:
  193. register_id = TMR_STS;
  194. break;
  195. case ACPI_EVENT_GLOBAL:
  196. register_id = GBL_STS;
  197. break;
  198. case ACPI_EVENT_POWER_BUTTON:
  199. register_id = PWRBTN_STS;
  200. break;
  201. case ACPI_EVENT_SLEEP_BUTTON:
  202. register_id = SLPBTN_STS;
  203. break;
  204. case ACPI_EVENT_RTC:
  205. register_id = RTC_STS;
  206. break;
  207. default:
  208. return 0;
  209. break;
  210. }
  211. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, register_id, 1);
  212. /*
  213.  * Make sure we've got a handler.  If not, report an error.
  214.  * The event is disabled to prevent further interrupts.
  215.  */
  216. if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
  217. register_id = (PM1_EN | REGISTER_BIT_ID(register_id));
  218. acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,
  219.  register_id, 0);
  220. REPORT_ERROR (
  221. ("Ev_gpe_dispatch: No installed handler for fixed event [%08X]n",
  222. event));
  223. return (INTERRUPT_NOT_HANDLED);
  224. }
  225. /* Invoke the handler */
  226. return ((acpi_gbl_fixed_event_handlers[event].handler)(
  227.   acpi_gbl_fixed_event_handlers[event].context));
  228. }
  229. /*******************************************************************************
  230.  *
  231.  * FUNCTION:    Acpi_ev_gpe_initialize
  232.  *
  233.  * PARAMETERS:  None
  234.  *
  235.  * RETURN:      Status
  236.  *
  237.  * DESCRIPTION: Initialize the GPE data structures
  238.  *
  239.  ******************************************************************************/
  240. acpi_status
  241. acpi_ev_gpe_initialize (void)
  242. {
  243. u32                     i;
  244. u32                     j;
  245. u32                     register_index;
  246. u32                     gpe_number;
  247. u16                     gpe0register_count;
  248. u16                     gpe1_register_count;
  249. FUNCTION_TRACE ("Ev_gpe_initialize");
  250. /*
  251.  * Set up various GPE counts
  252.  *
  253.  * You may ask,why are the GPE register block lengths divided by 2?
  254.  * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event
  255.  * Registers, we have,
  256.  *
  257.  * "Each register block contains two registers of equal length
  258.  * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
  259.  * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
  260.  * The length of the GPE1_STS and GPE1_EN registers is equal to
  261.  * half the GPE1_LEN. If a generic register block is not supported
  262.  * then its respective block pointer and block length values in the
  263.  * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
  264.  * to be the same size."
  265.  */
  266. gpe0register_count          = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len);
  267. gpe1_register_count         = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len);
  268. acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count;
  269. if (!acpi_gbl_gpe_register_count) {
  270. REPORT_WARNING (("Zero GPEs are defined in the FADTn"));
  271. return_ACPI_STATUS (AE_OK);
  272. }
  273. /*
  274.  * Allocate the Gpe information block
  275.  */
  276. acpi_gbl_gpe_registers = ACPI_MEM_CALLOCATE (acpi_gbl_gpe_register_count *
  277.   sizeof (acpi_gpe_registers));
  278. if (!acpi_gbl_gpe_registers) {
  279. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  280. "Could not allocate the Gpe_registers blockn"));
  281. return_ACPI_STATUS (AE_NO_MEMORY);
  282. }
  283. /*
  284.  * Allocate the Gpe dispatch handler block
  285.  * There are eight distinct GP events per register.
  286.  * Initialization to zeros is sufficient
  287.  */
  288. acpi_gbl_gpe_info = ACPI_MEM_CALLOCATE (MUL_8 (acpi_gbl_gpe_register_count) *
  289.   sizeof (acpi_gpe_level_info));
  290. if (!acpi_gbl_gpe_info) {
  291. ACPI_MEM_FREE (acpi_gbl_gpe_registers);
  292. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_info blockn"));
  293. return_ACPI_STATUS (AE_NO_MEMORY);
  294. }
  295. /* Set the Gpe validation table to GPE_INVALID */
  296. MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, ACPI_NUM_GPE);
  297. /*
  298.  * Initialize the Gpe information and validation blocks.  A goal of these
  299.  * blocks is to hide the fact that there are two separate GPE register sets
  300.  * In a given block, the status registers occupy the first half, and
  301.  * the enable registers occupy the second half.
  302.  */
  303. /* GPE Block 0 */
  304. register_index = 0;
  305. for (i = 0; i < gpe0register_count; i++) {
  306. acpi_gbl_gpe_registers[register_index].status_addr =
  307.  (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i);
  308. acpi_gbl_gpe_registers[register_index].enable_addr =
  309.  (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i + gpe0register_count);
  310. acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i);
  311. for (j = 0; j < 8; j++) {
  312. gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j;
  313. acpi_gbl_gpe_valid[gpe_number] = (u8) register_index;
  314. }
  315. /*
  316.  * Clear the status/enable registers.  Note that status registers
  317.  * are cleared by writing a '1', while enable registers are cleared
  318.  * by writing a '0'.
  319.  */
  320. acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8);
  321. acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8);
  322. register_index++;
  323. }
  324. /* GPE Block 1 */
  325. for (i = 0; i < gpe1_register_count; i++) {
  326. acpi_gbl_gpe_registers[register_index].status_addr =
  327.  (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i);
  328. acpi_gbl_gpe_registers[register_index].enable_addr =
  329.  (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i + gpe1_register_count);
  330. acpi_gbl_gpe_registers[register_index].gpe_base =
  331.  (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i));
  332. for (j = 0; j < 8; j++) {
  333. gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j;
  334. acpi_gbl_gpe_valid[gpe_number] = (u8) register_index;
  335. }
  336. /*
  337.  * Clear the status/enable registers.  Note that status registers
  338.  * are cleared by writing a '1', while enable registers are cleared
  339.  * by writing a '0'.
  340.  */
  341. acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8);
  342. acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8);
  343. register_index++;
  344. }
  345. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE registers: %X@%8.8X%8.8X (Blk0) %X@%8.8X%8.8X (Blk1)n",
  346. gpe0register_count, HIDWORD(acpi_gbl_FADT->Xgpe0blk.address), LODWORD(acpi_gbl_FADT->Xgpe0blk.address),
  347. gpe1_register_count, HIDWORD(acpi_gbl_FADT->Xgpe1_blk.address), LODWORD(acpi_gbl_FADT->Xgpe1_blk.address)));
  348. return_ACPI_STATUS (AE_OK);
  349. }
  350. /*******************************************************************************
  351.  *
  352.  * FUNCTION:    Acpi_ev_save_method_info
  353.  *
  354.  * PARAMETERS:  None
  355.  *
  356.  * RETURN:      None
  357.  *
  358.  * DESCRIPTION: Called from Acpi_walk_namespace. Expects each object to be a
  359.  *              control method under the _GPE portion of the namespace.
  360.  *              Extract the name and GPE type from the object, saving this
  361.  *              information for quick lookup during GPE dispatch
  362.  *
  363.  *              The name of each GPE control method is of the form:
  364.  *                  "_Lnn" or "_Enn"
  365.  *              Where:
  366.  *                  L      - means that the GPE is level triggered
  367.  *                  E      - means that the GPE is edge triggered
  368.  *                  nn     - is the GPE number
  369.  *
  370.  ******************************************************************************/
  371. static acpi_status
  372. acpi_ev_save_method_info (
  373. acpi_handle             obj_handle,
  374. u32                     level,
  375. void                    *obj_desc,
  376. void                    **return_value)
  377. {
  378. u32                     gpe_number;
  379. NATIVE_CHAR             name[ACPI_NAME_SIZE + 1];
  380. u8                      type;
  381. PROC_NAME ("Ev_save_method_info");
  382. /* Extract the name from the object and convert to a string */
  383. MOVE_UNALIGNED32_TO_32 (name, &((acpi_namespace_node *) obj_handle)->name);
  384. name[ACPI_NAME_SIZE] = 0;
  385. /*
  386.  * Edge/Level determination is based on the 2nd s8 of the method name
  387.  */
  388. if (name[1] == 'L') {
  389. type = ACPI_EVENT_LEVEL_TRIGGERED;
  390. }
  391. else if (name[1] == 'E') {
  392. type = ACPI_EVENT_EDGE_TRIGGERED;
  393. }
  394. else {
  395. /* Unknown method type, just ignore it! */
  396. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  397. "Unknown GPE method type: %s (name not of form _Lnn or _Enn)n",
  398. name));
  399. return (AE_OK);
  400. }
  401. /* Convert the last two characters of the name to the Gpe Number */
  402. gpe_number = STRTOUL (&name[2], NULL, 16);
  403. if (gpe_number == ACPI_UINT32_MAX) {
  404. /* Conversion failed; invalid method, just ignore it */
  405. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  406. "Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)n",
  407. name));
  408. return (AE_OK);
  409. }
  410. /* Ensure that we have a valid GPE number */
  411. if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {
  412. /* Not valid, all we can do here is ignore it */
  413. return (AE_OK);
  414. }
  415. /*
  416.  * Now we can add this information to the Gpe_info block
  417.  * for use during dispatch of this GPE.
  418.  */
  419. acpi_gbl_gpe_info [gpe_number].type         = type;
  420. acpi_gbl_gpe_info [gpe_number].method_handle = obj_handle;
  421. /*
  422.  * Enable the GPE (SCIs should be disabled at this point)
  423.  */
  424. acpi_hw_enable_gpe (gpe_number);
  425. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %Xn",
  426. name, gpe_number));
  427. return (AE_OK);
  428. }
  429. /*******************************************************************************
  430.  *
  431.  * FUNCTION:    Acpi_ev_init_gpe_control_methods
  432.  *
  433.  * PARAMETERS:  None
  434.  *
  435.  * RETURN:      None
  436.  *
  437.  * DESCRIPTION: Obtain the control methods associated with the GPEs.
  438.  *
  439.  *              NOTE: Must be called AFTER namespace initialization!
  440.  *
  441.  ******************************************************************************/
  442. acpi_status
  443. acpi_ev_init_gpe_control_methods (void)
  444. {
  445. acpi_status             status;
  446. FUNCTION_TRACE ("Ev_init_gpe_control_methods");
  447. /* Get a permanent handle to the _GPE object */
  448. status = acpi_get_handle (NULL, "\_GPE", &acpi_gbl_gpe_obj_handle);
  449. if (ACPI_FAILURE (status)) {
  450. return_ACPI_STATUS (status);
  451. }
  452. /* Traverse the namespace under _GPE to find all methods there */
  453. status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,
  454.   ACPI_UINT32_MAX, acpi_ev_save_method_info,
  455.   NULL, NULL);
  456. return_ACPI_STATUS (status);
  457. }
  458. /*******************************************************************************
  459.  *
  460.  * FUNCTION:    Acpi_ev_gpe_detect
  461.  *
  462.  * PARAMETERS:  None
  463.  *
  464.  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  465.  *
  466.  * DESCRIPTION: Detect if any GP events have occurred
  467.  *
  468.  ******************************************************************************/
  469. u32
  470. acpi_ev_gpe_detect (void)
  471. {
  472. u32                     int_status = INTERRUPT_NOT_HANDLED;
  473. u32                     i;
  474. u32                     j;
  475. u8                      enabled_status_byte;
  476. u8                      bit_mask;
  477. PROC_NAME ("Ev_gpe_detect");
  478. /*
  479.  * Read all of the 8-bit GPE status and enable registers
  480.  * in both of the register blocks, saving all of it.
  481.  * Find all currently active GP events.
  482.  */
  483. for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
  484. acpi_os_read_port (acpi_gbl_gpe_registers[i].status_addr,
  485. &acpi_gbl_gpe_registers[i].status, 8);
  486. acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr,
  487. &acpi_gbl_gpe_registers[i].enable, 8);
  488. ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
  489. "GPE block at %X - Enable %08X Status %08Xn",
  490. acpi_gbl_gpe_registers[i].enable_addr,
  491. acpi_gbl_gpe_registers[i].status,
  492. acpi_gbl_gpe_registers[i].enable));
  493. /* First check if there is anything active at all in this register */
  494. enabled_status_byte = (u8) (acpi_gbl_gpe_registers[i].status &
  495.    acpi_gbl_gpe_registers[i].enable);
  496. if (!enabled_status_byte) {
  497. /* No active GPEs in this register, move on */
  498. continue;
  499. }
  500. /* Now look at the individual GPEs in this byte register */
  501. for (j = 0, bit_mask = 1; j < 8; j++, bit_mask <<= 1) {
  502. /* Examine one GPE bit */
  503. if (enabled_status_byte & bit_mask) {
  504. /*
  505.  * Found an active GPE.  Dispatch the event to a handler
  506.  * or method.
  507.  */
  508. int_status |= acpi_ev_gpe_dispatch (
  509.   acpi_gbl_gpe_registers[i].gpe_base + j);
  510. }
  511. }
  512. }
  513. return (int_status);
  514. }
  515. /*******************************************************************************
  516.  *
  517.  * FUNCTION:    Acpi_ev_asynch_execute_gpe_method
  518.  *
  519.  * PARAMETERS:  Gpe_number      - The 0-based Gpe number
  520.  *
  521.  * RETURN:      None
  522.  *
  523.  * DESCRIPTION: Perform the actual execution of a GPE control method.  This
  524.  *              function is called from an invocation of Acpi_os_queue_for_execution
  525.  *              (and therefore does NOT execute at interrupt level) so that
  526.  *              the control method itself is not executed in the context of
  527.  *              the SCI interrupt handler.
  528.  *
  529.  ******************************************************************************/
  530. static void
  531. acpi_ev_asynch_execute_gpe_method (
  532. void                    *context)
  533. {
  534. u32                     gpe_number = (u32) context;
  535. acpi_gpe_level_info     gpe_info;
  536. FUNCTION_TRACE ("Ev_asynch_execute_gpe_method");
  537. /*
  538.  * Take a snapshot of the GPE info for this level
  539.  */
  540. acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  541. gpe_info = acpi_gbl_gpe_info [gpe_number];
  542. acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  543. /*
  544.  * Method Handler (_Lxx, _Exx):
  545.  * ----------------------------
  546.  * Evaluate the _Lxx/_Exx control method that corresponds to this GPE.
  547.  */
  548. if (gpe_info.method_handle) {
  549. acpi_ns_evaluate_by_handle (gpe_info.method_handle, NULL, NULL);
  550. }
  551. /*
  552.  * Level-Triggered?
  553.  * ----------------
  554.  * If level-triggered we clear the GPE status bit after handling the event.
  555.  */
  556. if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
  557. acpi_hw_clear_gpe (gpe_number);
  558. }
  559. /*
  560.  * Enable the GPE.
  561.  */
  562. acpi_hw_enable_gpe (gpe_number);
  563. return_VOID;
  564. }
  565. /*******************************************************************************
  566.  *
  567.  * FUNCTION:    Acpi_ev_gpe_dispatch
  568.  *
  569.  * PARAMETERS:  Gpe_number      - The 0-based Gpe number
  570.  *
  571.  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  572.  *
  573.  * DESCRIPTION: Handle and dispatch a General Purpose Acpi_event.
  574.  *              Clears the status bit for the requested event.
  575.  *
  576.  * TBD: [Investigate] is this still valid or necessary:
  577.  * The Gpe handler differs from the fixed events in that it clears the enable
  578.  * bit rather than the status bit to clear the interrupt.  This allows
  579.  * software outside of interrupt context to determine what caused the SCI and
  580.  * dispatch the correct AML.
  581.  *
  582.  ******************************************************************************/
  583. u32
  584. acpi_ev_gpe_dispatch (
  585. u32                     gpe_number)
  586. {
  587. acpi_gpe_level_info     gpe_info;
  588. FUNCTION_TRACE ("Ev_gpe_dispatch");
  589. /*
  590.  * Valid GPE number?
  591.  */
  592. if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {
  593. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid GPE bit [%X].n", gpe_number));
  594. return_VALUE (INTERRUPT_NOT_HANDLED);
  595. }
  596. /*
  597.  * Disable the GPE.
  598.  */
  599. acpi_hw_disable_gpe (gpe_number);
  600. gpe_info = acpi_gbl_gpe_info [gpe_number];
  601. /*
  602.  * Edge-Triggered?
  603.  * ---------------
  604.  * If edge-triggered, clear the GPE status bit now.  Note that
  605.  * level-triggered events are cleared after the GPE is serviced.
  606.  */
  607. if (gpe_info.type & ACPI_EVENT_EDGE_TRIGGERED) {
  608. acpi_hw_clear_gpe (gpe_number);
  609. }
  610. /*
  611.  * Function Handler (e.g. EC)?
  612.  */
  613. if (gpe_info.handler) {
  614. /* Invoke function handler (at interrupt level). */
  615. gpe_info.handler (gpe_info.context);
  616. /* Level-Triggered? */
  617. if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
  618. acpi_hw_clear_gpe (gpe_number);
  619. }
  620. /* Enable GPE */
  621. acpi_hw_enable_gpe (gpe_number);
  622. }
  623. /*
  624.  * Method Handler (e.g. _Exx/_Lxx)?
  625.  */
  626. else if (gpe_info.method_handle) {
  627. if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
  628. acpi_ev_asynch_execute_gpe_method, (void*) gpe_number))) {
  629. /*
  630.  * Shoudn't occur, but if it does report an error. Note that
  631.  * the GPE will remain disabled until the ACPI Core Subsystem
  632.  * is restarted, or the handler is removed/reinstalled.
  633.  */
  634. REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE bit [%X]n", gpe_number));
  635. }
  636. }
  637. /*
  638.  * No Handler? Report an error and leave the GPE disabled.
  639.  */
  640. else {
  641. REPORT_ERROR (("Acpi_ev_gpe_dispatch: No installed handler for GPE [%X]n", gpe_number));
  642. /* Level-Triggered? */
  643. if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
  644. acpi_hw_clear_gpe (gpe_number);
  645. }
  646. }
  647. return_VALUE (INTERRUPT_HANDLED);
  648. }