evxfevnt.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. /******************************************************************************
  2. *
  3. * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2010, Intel Corp.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include <acpi/acpi.h>
  43. #include "accommon.h"
  44. #include "acevents.h"
  45. #include "acnamesp.h"
  46. #include "actables.h"
  47. #define _COMPONENT ACPI_EVENTS
  48. ACPI_MODULE_NAME("evxfevnt")
  49. /* Local prototypes */
  50. static acpi_status
  51. acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  52. struct acpi_gpe_block_info *gpe_block, void *context);
  53. /*******************************************************************************
  54. *
  55. * FUNCTION: acpi_enable
  56. *
  57. * PARAMETERS: None
  58. *
  59. * RETURN: Status
  60. *
  61. * DESCRIPTION: Transfers the system into ACPI mode.
  62. *
  63. ******************************************************************************/
  64. acpi_status acpi_enable(void)
  65. {
  66. acpi_status status;
  67. ACPI_FUNCTION_TRACE(acpi_enable);
  68. /* ACPI tables must be present */
  69. if (!acpi_tb_tables_loaded()) {
  70. return_ACPI_STATUS(AE_NO_ACPI_TABLES);
  71. }
  72. /* Check current mode */
  73. if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
  74. ACPI_DEBUG_PRINT((ACPI_DB_INIT,
  75. "System is already in ACPI mode\n"));
  76. return_ACPI_STATUS(AE_OK);
  77. }
  78. /* Transition to ACPI mode */
  79. status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
  80. if (ACPI_FAILURE(status)) {
  81. ACPI_ERROR((AE_INFO,
  82. "Could not transition to ACPI mode"));
  83. return_ACPI_STATUS(status);
  84. }
  85. /* Sanity check that transition succeeded */
  86. if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) {
  87. ACPI_ERROR((AE_INFO,
  88. "Hardware did not enter ACPI mode"));
  89. return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
  90. }
  91. ACPI_DEBUG_PRINT((ACPI_DB_INIT,
  92. "Transition to ACPI mode successful\n"));
  93. return_ACPI_STATUS(AE_OK);
  94. }
  95. ACPI_EXPORT_SYMBOL(acpi_enable)
  96. /*******************************************************************************
  97. *
  98. * FUNCTION: acpi_disable
  99. *
  100. * PARAMETERS: None
  101. *
  102. * RETURN: Status
  103. *
  104. * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
  105. *
  106. ******************************************************************************/
  107. acpi_status acpi_disable(void)
  108. {
  109. acpi_status status = AE_OK;
  110. ACPI_FUNCTION_TRACE(acpi_disable);
  111. if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
  112. ACPI_DEBUG_PRINT((ACPI_DB_INIT,
  113. "System is already in legacy (non-ACPI) mode\n"));
  114. } else {
  115. /* Transition to LEGACY mode */
  116. status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
  117. if (ACPI_FAILURE(status)) {
  118. ACPI_ERROR((AE_INFO,
  119. "Could not exit ACPI mode to legacy mode"));
  120. return_ACPI_STATUS(status);
  121. }
  122. ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
  123. }
  124. return_ACPI_STATUS(status);
  125. }
  126. ACPI_EXPORT_SYMBOL(acpi_disable)
  127. /*******************************************************************************
  128. *
  129. * FUNCTION: acpi_enable_event
  130. *
  131. * PARAMETERS: Event - The fixed eventto be enabled
  132. * Flags - Reserved
  133. *
  134. * RETURN: Status
  135. *
  136. * DESCRIPTION: Enable an ACPI event (fixed)
  137. *
  138. ******************************************************************************/
  139. acpi_status acpi_enable_event(u32 event, u32 flags)
  140. {
  141. acpi_status status = AE_OK;
  142. u32 value;
  143. ACPI_FUNCTION_TRACE(acpi_enable_event);
  144. /* Decode the Fixed Event */
  145. if (event > ACPI_EVENT_MAX) {
  146. return_ACPI_STATUS(AE_BAD_PARAMETER);
  147. }
  148. /*
  149. * Enable the requested fixed event (by writing a one to the enable
  150. * register bit)
  151. */
  152. status =
  153. acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
  154. enable_register_id, ACPI_ENABLE_EVENT);
  155. if (ACPI_FAILURE(status)) {
  156. return_ACPI_STATUS(status);
  157. }
  158. /* Make sure that the hardware responded */
  159. status =
  160. acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
  161. enable_register_id, &value);
  162. if (ACPI_FAILURE(status)) {
  163. return_ACPI_STATUS(status);
  164. }
  165. if (value != 1) {
  166. ACPI_ERROR((AE_INFO,
  167. "Could not enable %s event",
  168. acpi_ut_get_event_name(event)));
  169. return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
  170. }
  171. return_ACPI_STATUS(status);
  172. }
  173. ACPI_EXPORT_SYMBOL(acpi_enable_event)
  174. /*******************************************************************************
  175. *
  176. * FUNCTION: acpi_clear_and_enable_gpe
  177. *
  178. * PARAMETERS: gpe_event_info - GPE to enable
  179. *
  180. * RETURN: Status
  181. *
  182. * DESCRIPTION: Clear the given GPE from stale events and enable it.
  183. *
  184. ******************************************************************************/
  185. static acpi_status
  186. acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
  187. {
  188. acpi_status status;
  189. /*
  190. * We will only allow a GPE to be enabled if it has either an
  191. * associated method (_Lxx/_Exx) or a handler. Otherwise, the
  192. * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
  193. * first time it fires.
  194. */
  195. if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
  196. return_ACPI_STATUS(AE_NO_HANDLER);
  197. }
  198. /* Clear the GPE (of stale events) */
  199. status = acpi_hw_clear_gpe(gpe_event_info);
  200. if (ACPI_FAILURE(status)) {
  201. return_ACPI_STATUS(status);
  202. }
  203. /* Enable the requested GPE */
  204. status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
  205. return_ACPI_STATUS(status);
  206. }
  207. /*******************************************************************************
  208. *
  209. * FUNCTION: acpi_set_gpe
  210. *
  211. * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
  212. * gpe_number - GPE level within the GPE block
  213. * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
  214. *
  215. * RETURN: Status
  216. *
  217. * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
  218. * the reference count mechanism used in the acpi_enable_gpe and
  219. * acpi_disable_gpe interfaces -- and should be used with care.
  220. *
  221. * Note: Typically used to disable a runtime GPE for short period of time,
  222. * then re-enable it, without disturbing the existing reference counts. This
  223. * is useful, for example, in the Embedded Controller (EC) driver.
  224. *
  225. ******************************************************************************/
  226. acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
  227. {
  228. struct acpi_gpe_event_info *gpe_event_info;
  229. acpi_status status;
  230. acpi_cpu_flags flags;
  231. ACPI_FUNCTION_TRACE(acpi_set_gpe);
  232. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  233. /* Ensure that we have a valid GPE number */
  234. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  235. if (!gpe_event_info) {
  236. status = AE_BAD_PARAMETER;
  237. goto unlock_and_exit;
  238. }
  239. /* Perform the action */
  240. switch (action) {
  241. case ACPI_GPE_ENABLE:
  242. status = acpi_clear_and_enable_gpe(gpe_event_info);
  243. break;
  244. case ACPI_GPE_DISABLE:
  245. status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
  246. break;
  247. default:
  248. status = AE_BAD_PARAMETER;
  249. break;
  250. }
  251. unlock_and_exit:
  252. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  253. return_ACPI_STATUS(status);
  254. }
  255. ACPI_EXPORT_SYMBOL(acpi_set_gpe)
  256. /*******************************************************************************
  257. *
  258. * FUNCTION: acpi_gpe_wakeup
  259. *
  260. * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
  261. * gpe_number - GPE level within the GPE block
  262. * Action - Enable or Disable
  263. *
  264. * RETURN: Status
  265. *
  266. * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
  267. *
  268. ******************************************************************************/
  269. acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
  270. {
  271. acpi_status status = AE_OK;
  272. struct acpi_gpe_event_info *gpe_event_info;
  273. struct acpi_gpe_register_info *gpe_register_info;
  274. acpi_cpu_flags flags;
  275. u32 register_bit;
  276. ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
  277. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  278. /* Ensure that we have a valid GPE number */
  279. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  280. if (!gpe_event_info) {
  281. status = AE_BAD_PARAMETER;
  282. goto unlock_and_exit;
  283. }
  284. gpe_register_info = gpe_event_info->register_info;
  285. if (!gpe_register_info) {
  286. status = AE_NOT_EXIST;
  287. goto unlock_and_exit;
  288. }
  289. register_bit =
  290. acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
  291. /* Perform the action */
  292. switch (action) {
  293. case ACPI_GPE_ENABLE:
  294. ACPI_SET_BIT(gpe_register_info->enable_for_wake,
  295. (u8)register_bit);
  296. break;
  297. case ACPI_GPE_DISABLE:
  298. ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
  299. (u8)register_bit);
  300. break;
  301. default:
  302. ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
  303. status = AE_BAD_PARAMETER;
  304. break;
  305. }
  306. unlock_and_exit:
  307. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  308. return_ACPI_STATUS(status);
  309. }
  310. ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
  311. /*******************************************************************************
  312. *
  313. * FUNCTION: acpi_enable_gpe
  314. *
  315. * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
  316. * gpe_number - GPE level within the GPE block
  317. *
  318. * RETURN: Status
  319. *
  320. * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
  321. * hardware-enabled.
  322. *
  323. ******************************************************************************/
  324. acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
  325. {
  326. acpi_status status = AE_OK;
  327. struct acpi_gpe_event_info *gpe_event_info;
  328. acpi_cpu_flags flags;
  329. ACPI_FUNCTION_TRACE(acpi_enable_gpe);
  330. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  331. /* Ensure that we have a valid GPE number */
  332. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  333. if (!gpe_event_info) {
  334. status = AE_BAD_PARAMETER;
  335. goto unlock_and_exit;
  336. }
  337. if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
  338. status = AE_LIMIT; /* Too many references */
  339. goto unlock_and_exit;
  340. }
  341. gpe_event_info->runtime_count++;
  342. if (gpe_event_info->runtime_count == 1) {
  343. status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
  344. if (ACPI_SUCCESS(status)) {
  345. status = acpi_clear_and_enable_gpe(gpe_event_info);
  346. }
  347. if (ACPI_FAILURE(status)) {
  348. gpe_event_info->runtime_count--;
  349. }
  350. }
  351. unlock_and_exit:
  352. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  353. return_ACPI_STATUS(status);
  354. }
  355. ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
  356. /*******************************************************************************
  357. *
  358. * FUNCTION: acpi_disable_gpe
  359. *
  360. * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
  361. * gpe_number - GPE level within the GPE block
  362. *
  363. * RETURN: Status
  364. *
  365. * DESCRIPTION: Remove a reference to a GPE. When the last reference is
  366. * removed, only then is the GPE disabled (for runtime GPEs), or
  367. * the GPE mask bit disabled (for wake GPEs)
  368. *
  369. ******************************************************************************/
  370. acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
  371. {
  372. acpi_status status = AE_OK;
  373. struct acpi_gpe_event_info *gpe_event_info;
  374. acpi_cpu_flags flags;
  375. ACPI_FUNCTION_TRACE(acpi_disable_gpe);
  376. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  377. /* Ensure that we have a valid GPE number */
  378. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  379. if (!gpe_event_info) {
  380. status = AE_BAD_PARAMETER;
  381. goto unlock_and_exit;
  382. }
  383. /* Hardware-disable a runtime GPE on removal of the last reference */
  384. if (!gpe_event_info->runtime_count) {
  385. status = AE_LIMIT; /* There are no references to remove */
  386. goto unlock_and_exit;
  387. }
  388. gpe_event_info->runtime_count--;
  389. if (!gpe_event_info->runtime_count) {
  390. status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
  391. if (ACPI_SUCCESS(status)) {
  392. status =
  393. acpi_hw_low_set_gpe(gpe_event_info,
  394. ACPI_GPE_DISABLE);
  395. }
  396. if (ACPI_FAILURE(status)) {
  397. gpe_event_info->runtime_count++;
  398. }
  399. }
  400. unlock_and_exit:
  401. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  402. return_ACPI_STATUS(status);
  403. }
  404. ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
  405. /*******************************************************************************
  406. *
  407. * FUNCTION: acpi_disable_event
  408. *
  409. * PARAMETERS: Event - The fixed eventto be enabled
  410. * Flags - Reserved
  411. *
  412. * RETURN: Status
  413. *
  414. * DESCRIPTION: Disable an ACPI event (fixed)
  415. *
  416. ******************************************************************************/
  417. acpi_status acpi_disable_event(u32 event, u32 flags)
  418. {
  419. acpi_status status = AE_OK;
  420. u32 value;
  421. ACPI_FUNCTION_TRACE(acpi_disable_event);
  422. /* Decode the Fixed Event */
  423. if (event > ACPI_EVENT_MAX) {
  424. return_ACPI_STATUS(AE_BAD_PARAMETER);
  425. }
  426. /*
  427. * Disable the requested fixed event (by writing a zero to the enable
  428. * register bit)
  429. */
  430. status =
  431. acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
  432. enable_register_id, ACPI_DISABLE_EVENT);
  433. if (ACPI_FAILURE(status)) {
  434. return_ACPI_STATUS(status);
  435. }
  436. status =
  437. acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
  438. enable_register_id, &value);
  439. if (ACPI_FAILURE(status)) {
  440. return_ACPI_STATUS(status);
  441. }
  442. if (value != 0) {
  443. ACPI_ERROR((AE_INFO,
  444. "Could not disable %s events",
  445. acpi_ut_get_event_name(event)));
  446. return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
  447. }
  448. return_ACPI_STATUS(status);
  449. }
  450. ACPI_EXPORT_SYMBOL(acpi_disable_event)
  451. /*******************************************************************************
  452. *
  453. * FUNCTION: acpi_clear_event
  454. *
  455. * PARAMETERS: Event - The fixed event to be cleared
  456. *
  457. * RETURN: Status
  458. *
  459. * DESCRIPTION: Clear an ACPI event (fixed)
  460. *
  461. ******************************************************************************/
  462. acpi_status acpi_clear_event(u32 event)
  463. {
  464. acpi_status status = AE_OK;
  465. ACPI_FUNCTION_TRACE(acpi_clear_event);
  466. /* Decode the Fixed Event */
  467. if (event > ACPI_EVENT_MAX) {
  468. return_ACPI_STATUS(AE_BAD_PARAMETER);
  469. }
  470. /*
  471. * Clear the requested fixed event (By writing a one to the status
  472. * register bit)
  473. */
  474. status =
  475. acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
  476. status_register_id, ACPI_CLEAR_STATUS);
  477. return_ACPI_STATUS(status);
  478. }
  479. ACPI_EXPORT_SYMBOL(acpi_clear_event)
  480. /*******************************************************************************
  481. *
  482. * FUNCTION: acpi_clear_gpe
  483. *
  484. * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
  485. * gpe_number - GPE level within the GPE block
  486. *
  487. * RETURN: Status
  488. *
  489. * DESCRIPTION: Clear an ACPI event (general purpose)
  490. *
  491. ******************************************************************************/
  492. acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
  493. {
  494. acpi_status status = AE_OK;
  495. struct acpi_gpe_event_info *gpe_event_info;
  496. acpi_cpu_flags flags;
  497. ACPI_FUNCTION_TRACE(acpi_clear_gpe);
  498. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  499. /* Ensure that we have a valid GPE number */
  500. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  501. if (!gpe_event_info) {
  502. status = AE_BAD_PARAMETER;
  503. goto unlock_and_exit;
  504. }
  505. status = acpi_hw_clear_gpe(gpe_event_info);
  506. unlock_and_exit:
  507. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  508. return_ACPI_STATUS(status);
  509. }
  510. ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
  511. /*******************************************************************************
  512. *
  513. * FUNCTION: acpi_get_event_status
  514. *
  515. * PARAMETERS: Event - The fixed event
  516. * event_status - Where the current status of the event will
  517. * be returned
  518. *
  519. * RETURN: Status
  520. *
  521. * DESCRIPTION: Obtains and returns the current status of the event
  522. *
  523. ******************************************************************************/
  524. acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
  525. {
  526. acpi_status status = AE_OK;
  527. u32 value;
  528. ACPI_FUNCTION_TRACE(acpi_get_event_status);
  529. if (!event_status) {
  530. return_ACPI_STATUS(AE_BAD_PARAMETER);
  531. }
  532. /* Decode the Fixed Event */
  533. if (event > ACPI_EVENT_MAX) {
  534. return_ACPI_STATUS(AE_BAD_PARAMETER);
  535. }
  536. /* Get the status of the requested fixed event */
  537. status =
  538. acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
  539. enable_register_id, &value);
  540. if (ACPI_FAILURE(status))
  541. return_ACPI_STATUS(status);
  542. *event_status = value;
  543. status =
  544. acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
  545. status_register_id, &value);
  546. if (ACPI_FAILURE(status))
  547. return_ACPI_STATUS(status);
  548. if (value)
  549. *event_status |= ACPI_EVENT_FLAG_SET;
  550. if (acpi_gbl_fixed_event_handlers[event].handler)
  551. *event_status |= ACPI_EVENT_FLAG_HANDLE;
  552. return_ACPI_STATUS(status);
  553. }
  554. ACPI_EXPORT_SYMBOL(acpi_get_event_status)
  555. /*******************************************************************************
  556. *
  557. * FUNCTION: acpi_get_gpe_status
  558. *
  559. * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
  560. * gpe_number - GPE level within the GPE block
  561. * event_status - Where the current status of the event will
  562. * be returned
  563. *
  564. * RETURN: Status
  565. *
  566. * DESCRIPTION: Get status of an event (general purpose)
  567. *
  568. ******************************************************************************/
  569. acpi_status
  570. acpi_get_gpe_status(acpi_handle gpe_device,
  571. u32 gpe_number, acpi_event_status *event_status)
  572. {
  573. acpi_status status = AE_OK;
  574. struct acpi_gpe_event_info *gpe_event_info;
  575. acpi_cpu_flags flags;
  576. ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
  577. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  578. /* Ensure that we have a valid GPE number */
  579. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  580. if (!gpe_event_info) {
  581. status = AE_BAD_PARAMETER;
  582. goto unlock_and_exit;
  583. }
  584. /* Obtain status on the requested GPE number */
  585. status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
  586. if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
  587. *event_status |= ACPI_EVENT_FLAG_HANDLE;
  588. unlock_and_exit:
  589. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  590. return_ACPI_STATUS(status);
  591. }
  592. ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
  593. /*******************************************************************************
  594. *
  595. * FUNCTION: acpi_install_gpe_block
  596. *
  597. * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
  598. * gpe_block_address - Address and space_iD
  599. * register_count - Number of GPE register pairs in the block
  600. * interrupt_number - H/W interrupt for the block
  601. *
  602. * RETURN: Status
  603. *
  604. * DESCRIPTION: Create and Install a block of GPE registers
  605. *
  606. ******************************************************************************/
  607. acpi_status
  608. acpi_install_gpe_block(acpi_handle gpe_device,
  609. struct acpi_generic_address *gpe_block_address,
  610. u32 register_count, u32 interrupt_number)
  611. {
  612. acpi_status status;
  613. union acpi_operand_object *obj_desc;
  614. struct acpi_namespace_node *node;
  615. struct acpi_gpe_block_info *gpe_block;
  616. ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
  617. if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
  618. return_ACPI_STATUS(AE_BAD_PARAMETER);
  619. }
  620. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  621. if (ACPI_FAILURE(status)) {
  622. return (status);
  623. }
  624. node = acpi_ns_validate_handle(gpe_device);
  625. if (!node) {
  626. status = AE_BAD_PARAMETER;
  627. goto unlock_and_exit;
  628. }
  629. /*
  630. * For user-installed GPE Block Devices, the gpe_block_base_number
  631. * is always zero
  632. */
  633. status =
  634. acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
  635. interrupt_number, &gpe_block);
  636. if (ACPI_FAILURE(status)) {
  637. goto unlock_and_exit;
  638. }
  639. /* Install block in the device_object attached to the node */
  640. obj_desc = acpi_ns_get_attached_object(node);
  641. if (!obj_desc) {
  642. /*
  643. * No object, create a new one (Device nodes do not always have
  644. * an attached object)
  645. */
  646. obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
  647. if (!obj_desc) {
  648. status = AE_NO_MEMORY;
  649. goto unlock_and_exit;
  650. }
  651. status =
  652. acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
  653. /* Remove local reference to the object */
  654. acpi_ut_remove_reference(obj_desc);
  655. if (ACPI_FAILURE(status)) {
  656. goto unlock_and_exit;
  657. }
  658. }
  659. /* Now install the GPE block in the device_object */
  660. obj_desc->device.gpe_block = gpe_block;
  661. /* Run the _PRW methods and enable the runtime GPEs in the new block */
  662. status = acpi_ev_initialize_gpe_block(node, gpe_block);
  663. unlock_and_exit:
  664. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  665. return_ACPI_STATUS(status);
  666. }
  667. ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
  668. /*******************************************************************************
  669. *
  670. * FUNCTION: acpi_remove_gpe_block
  671. *
  672. * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
  673. *
  674. * RETURN: Status
  675. *
  676. * DESCRIPTION: Remove a previously installed block of GPE registers
  677. *
  678. ******************************************************************************/
  679. acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
  680. {
  681. union acpi_operand_object *obj_desc;
  682. acpi_status status;
  683. struct acpi_namespace_node *node;
  684. ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
  685. if (!gpe_device) {
  686. return_ACPI_STATUS(AE_BAD_PARAMETER);
  687. }
  688. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  689. if (ACPI_FAILURE(status)) {
  690. return (status);
  691. }
  692. node = acpi_ns_validate_handle(gpe_device);
  693. if (!node) {
  694. status = AE_BAD_PARAMETER;
  695. goto unlock_and_exit;
  696. }
  697. /* Get the device_object attached to the node */
  698. obj_desc = acpi_ns_get_attached_object(node);
  699. if (!obj_desc || !obj_desc->device.gpe_block) {
  700. return_ACPI_STATUS(AE_NULL_OBJECT);
  701. }
  702. /* Delete the GPE block (but not the device_object) */
  703. status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
  704. if (ACPI_SUCCESS(status)) {
  705. obj_desc->device.gpe_block = NULL;
  706. }
  707. unlock_and_exit:
  708. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  709. return_ACPI_STATUS(status);
  710. }
  711. ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
  712. /*******************************************************************************
  713. *
  714. * FUNCTION: acpi_get_gpe_device
  715. *
  716. * PARAMETERS: Index - System GPE index (0-current_gpe_count)
  717. * gpe_device - Where the parent GPE Device is returned
  718. *
  719. * RETURN: Status
  720. *
  721. * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
  722. * gpe device indicates that the gpe number is contained in one of
  723. * the FADT-defined gpe blocks. Otherwise, the GPE block device.
  724. *
  725. ******************************************************************************/
  726. acpi_status
  727. acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
  728. {
  729. struct acpi_gpe_device_info info;
  730. acpi_status status;
  731. ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
  732. if (!gpe_device) {
  733. return_ACPI_STATUS(AE_BAD_PARAMETER);
  734. }
  735. if (index >= acpi_current_gpe_count) {
  736. return_ACPI_STATUS(AE_NOT_EXIST);
  737. }
  738. /* Setup and walk the GPE list */
  739. info.index = index;
  740. info.status = AE_NOT_EXIST;
  741. info.gpe_device = NULL;
  742. info.next_block_base_index = 0;
  743. status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
  744. if (ACPI_FAILURE(status)) {
  745. return_ACPI_STATUS(status);
  746. }
  747. *gpe_device = info.gpe_device;
  748. return_ACPI_STATUS(info.status);
  749. }
  750. ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
  751. /*******************************************************************************
  752. *
  753. * FUNCTION: acpi_ev_get_gpe_device
  754. *
  755. * PARAMETERS: GPE_WALK_CALLBACK
  756. *
  757. * RETURN: Status
  758. *
  759. * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
  760. * block device. NULL if the GPE is one of the FADT-defined GPEs.
  761. *
  762. ******************************************************************************/
  763. static acpi_status
  764. acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  765. struct acpi_gpe_block_info *gpe_block, void *context)
  766. {
  767. struct acpi_gpe_device_info *info = context;
  768. /* Increment Index by the number of GPEs in this block */
  769. info->next_block_base_index += gpe_block->gpe_count;
  770. if (info->index < info->next_block_base_index) {
  771. /*
  772. * The GPE index is within this block, get the node. Leave the node
  773. * NULL for the FADT-defined GPEs
  774. */
  775. if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
  776. info->gpe_device = gpe_block->node;
  777. }
  778. info->status = AE_OK;
  779. return (AE_CTRL_END);
  780. }
  781. return (AE_OK);
  782. }
  783. /******************************************************************************
  784. *
  785. * FUNCTION: acpi_disable_all_gpes
  786. *
  787. * PARAMETERS: None
  788. *
  789. * RETURN: Status
  790. *
  791. * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
  792. *
  793. ******************************************************************************/
  794. acpi_status acpi_disable_all_gpes(void)
  795. {
  796. acpi_status status;
  797. ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
  798. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  799. if (ACPI_FAILURE(status)) {
  800. return_ACPI_STATUS(status);
  801. }
  802. status = acpi_hw_disable_all_gpes();
  803. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  804. return_ACPI_STATUS(status);
  805. }
  806. /******************************************************************************
  807. *
  808. * FUNCTION: acpi_enable_all_runtime_gpes
  809. *
  810. * PARAMETERS: None
  811. *
  812. * RETURN: Status
  813. *
  814. * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
  815. *
  816. ******************************************************************************/
  817. acpi_status acpi_enable_all_runtime_gpes(void)
  818. {
  819. acpi_status status;
  820. ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
  821. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  822. if (ACPI_FAILURE(status)) {
  823. return_ACPI_STATUS(status);
  824. }
  825. status = acpi_hw_enable_all_runtime_gpes();
  826. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  827. return_ACPI_STATUS(status);
  828. }