evxface.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. /******************************************************************************
  2. *
  3. * Module Name: evxface - External interfaces for ACPI events
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2005, R. Byron Moore
  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 <linux/module.h>
  43. #include <acpi/acpi.h>
  44. #include <acpi/acnamesp.h>
  45. #include <acpi/acevents.h>
  46. #include <acpi/acinterp.h>
  47. #define _COMPONENT ACPI_EVENTS
  48. ACPI_MODULE_NAME ("evxface")
  49. /*******************************************************************************
  50. *
  51. * FUNCTION: acpi_install_exception_handler
  52. *
  53. * PARAMETERS: Handler - Pointer to the handler function for the
  54. * event
  55. *
  56. * RETURN: Status
  57. *
  58. * DESCRIPTION: Saves the pointer to the handler function
  59. *
  60. ******************************************************************************/
  61. #ifdef ACPI_FUTURE_USAGE
  62. acpi_status
  63. acpi_install_exception_handler (
  64. acpi_exception_handler handler)
  65. {
  66. acpi_status status;
  67. ACPI_FUNCTION_TRACE ("acpi_install_exception_handler");
  68. status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  69. if (ACPI_FAILURE (status)) {
  70. return_ACPI_STATUS (status);
  71. }
  72. /* Don't allow two handlers. */
  73. if (acpi_gbl_exception_handler) {
  74. status = AE_ALREADY_EXISTS;
  75. goto cleanup;
  76. }
  77. /* Install the handler */
  78. acpi_gbl_exception_handler = handler;
  79. cleanup:
  80. (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  81. return_ACPI_STATUS (status);
  82. }
  83. #endif /* ACPI_FUTURE_USAGE */
  84. /*******************************************************************************
  85. *
  86. * FUNCTION: acpi_install_fixed_event_handler
  87. *
  88. * PARAMETERS: Event - Event type to enable.
  89. * Handler - Pointer to the handler function for the
  90. * event
  91. * Context - Value passed to the handler on each GPE
  92. *
  93. * RETURN: Status
  94. *
  95. * DESCRIPTION: Saves the pointer to the handler function and then enables the
  96. * event.
  97. *
  98. ******************************************************************************/
  99. acpi_status
  100. acpi_install_fixed_event_handler (
  101. u32 event,
  102. acpi_event_handler handler,
  103. void *context)
  104. {
  105. acpi_status status;
  106. ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler");
  107. /* Parameter validation */
  108. if (event > ACPI_EVENT_MAX) {
  109. return_ACPI_STATUS (AE_BAD_PARAMETER);
  110. }
  111. status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  112. if (ACPI_FAILURE (status)) {
  113. return_ACPI_STATUS (status);
  114. }
  115. /* Don't allow two handlers. */
  116. if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
  117. status = AE_ALREADY_EXISTS;
  118. goto cleanup;
  119. }
  120. /* Install the handler before enabling the event */
  121. acpi_gbl_fixed_event_handlers[event].handler = handler;
  122. acpi_gbl_fixed_event_handlers[event].context = context;
  123. status = acpi_clear_event (event);
  124. if (ACPI_SUCCESS(status))
  125. status = acpi_enable_event (event, 0);
  126. if (ACPI_FAILURE (status)) {
  127. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
  128. /* Remove the handler */
  129. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  130. acpi_gbl_fixed_event_handlers[event].context = NULL;
  131. }
  132. else {
  133. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  134. "Enabled fixed event %X, Handler=%p\n", event, handler));
  135. }
  136. cleanup:
  137. (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  138. return_ACPI_STATUS (status);
  139. }
  140. EXPORT_SYMBOL(acpi_install_fixed_event_handler);
  141. /*******************************************************************************
  142. *
  143. * FUNCTION: acpi_remove_fixed_event_handler
  144. *
  145. * PARAMETERS: Event - Event type to disable.
  146. * Handler - Address of the handler
  147. *
  148. * RETURN: Status
  149. *
  150. * DESCRIPTION: Disables the event and unregisters the event handler.
  151. *
  152. ******************************************************************************/
  153. acpi_status
  154. acpi_remove_fixed_event_handler (
  155. u32 event,
  156. acpi_event_handler handler)
  157. {
  158. acpi_status status = AE_OK;
  159. ACPI_FUNCTION_TRACE ("acpi_remove_fixed_event_handler");
  160. /* Parameter validation */
  161. if (event > ACPI_EVENT_MAX) {
  162. return_ACPI_STATUS (AE_BAD_PARAMETER);
  163. }
  164. status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  165. if (ACPI_FAILURE (status)) {
  166. return_ACPI_STATUS (status);
  167. }
  168. /* Disable the event before removing the handler */
  169. status = acpi_disable_event (event, 0);
  170. /* Always Remove the handler */
  171. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  172. acpi_gbl_fixed_event_handlers[event].context = NULL;
  173. if (ACPI_FAILURE (status)) {
  174. ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
  175. "Could not write to fixed event enable register.\n"));
  176. }
  177. else {
  178. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", event));
  179. }
  180. (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  181. return_ACPI_STATUS (status);
  182. }
  183. EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
  184. /*******************************************************************************
  185. *
  186. * FUNCTION: acpi_install_notify_handler
  187. *
  188. * PARAMETERS: Device - The device for which notifies will be handled
  189. * handler_type - The type of handler:
  190. * ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
  191. * ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
  192. * ACPI_ALL_NOTIFY: both system and device
  193. * Handler - Address of the handler
  194. * Context - Value passed to the handler on each GPE
  195. *
  196. * RETURN: Status
  197. *
  198. * DESCRIPTION: Install a handler for notifies on an ACPI device
  199. *
  200. ******************************************************************************/
  201. acpi_status
  202. acpi_install_notify_handler (
  203. acpi_handle device,
  204. u32 handler_type,
  205. acpi_notify_handler handler,
  206. void *context)
  207. {
  208. union acpi_operand_object *obj_desc;
  209. union acpi_operand_object *notify_obj;
  210. struct acpi_namespace_node *node;
  211. acpi_status status;
  212. ACPI_FUNCTION_TRACE ("acpi_install_notify_handler");
  213. /* Parameter validation */
  214. if ((!device) ||
  215. (!handler) ||
  216. (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
  217. return_ACPI_STATUS (AE_BAD_PARAMETER);
  218. }
  219. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  220. if (ACPI_FAILURE (status)) {
  221. return_ACPI_STATUS (status);
  222. }
  223. /* Convert and validate the device handle */
  224. node = acpi_ns_map_handle_to_node (device);
  225. if (!node) {
  226. status = AE_BAD_PARAMETER;
  227. goto unlock_and_exit;
  228. }
  229. /*
  230. * Root Object:
  231. * Registering a notify handler on the root object indicates that the
  232. * caller wishes to receive notifications for all objects. Note that
  233. * only one <external> global handler can be regsitered (per notify type).
  234. */
  235. if (device == ACPI_ROOT_OBJECT) {
  236. /* Make sure the handler is not already installed */
  237. if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
  238. acpi_gbl_system_notify.handler) ||
  239. ((handler_type & ACPI_DEVICE_NOTIFY) &&
  240. acpi_gbl_device_notify.handler)) {
  241. status = AE_ALREADY_EXISTS;
  242. goto unlock_and_exit;
  243. }
  244. if (handler_type & ACPI_SYSTEM_NOTIFY) {
  245. acpi_gbl_system_notify.node = node;
  246. acpi_gbl_system_notify.handler = handler;
  247. acpi_gbl_system_notify.context = context;
  248. }
  249. if (handler_type & ACPI_DEVICE_NOTIFY) {
  250. acpi_gbl_device_notify.node = node;
  251. acpi_gbl_device_notify.handler = handler;
  252. acpi_gbl_device_notify.context = context;
  253. }
  254. /* Global notify handler installed */
  255. }
  256. /*
  257. * All Other Objects:
  258. * Caller will only receive notifications specific to the target object.
  259. * Note that only certain object types can receive notifications.
  260. */
  261. else {
  262. /* Notifies allowed on this object? */
  263. if (!acpi_ev_is_notify_object (node)) {
  264. status = AE_TYPE;
  265. goto unlock_and_exit;
  266. }
  267. /* Check for an existing internal object */
  268. obj_desc = acpi_ns_get_attached_object (node);
  269. if (obj_desc) {
  270. /* Object exists - make sure there's no handler */
  271. if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
  272. obj_desc->common_notify.system_notify) ||
  273. ((handler_type & ACPI_DEVICE_NOTIFY) &&
  274. obj_desc->common_notify.device_notify)) {
  275. status = AE_ALREADY_EXISTS;
  276. goto unlock_and_exit;
  277. }
  278. }
  279. else {
  280. /* Create a new object */
  281. obj_desc = acpi_ut_create_internal_object (node->type);
  282. if (!obj_desc) {
  283. status = AE_NO_MEMORY;
  284. goto unlock_and_exit;
  285. }
  286. /* Attach new object to the Node */
  287. status = acpi_ns_attach_object (device, obj_desc, node->type);
  288. /* Remove local reference to the object */
  289. acpi_ut_remove_reference (obj_desc);
  290. if (ACPI_FAILURE (status)) {
  291. goto unlock_and_exit;
  292. }
  293. }
  294. /* Install the handler */
  295. notify_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_NOTIFY);
  296. if (!notify_obj) {
  297. status = AE_NO_MEMORY;
  298. goto unlock_and_exit;
  299. }
  300. notify_obj->notify.node = node;
  301. notify_obj->notify.handler = handler;
  302. notify_obj->notify.context = context;
  303. if (handler_type & ACPI_SYSTEM_NOTIFY) {
  304. obj_desc->common_notify.system_notify = notify_obj;
  305. }
  306. if (handler_type & ACPI_DEVICE_NOTIFY) {
  307. obj_desc->common_notify.device_notify = notify_obj;
  308. }
  309. if (handler_type == ACPI_ALL_NOTIFY) {
  310. /* Extra ref if installed in both */
  311. acpi_ut_add_reference (notify_obj);
  312. }
  313. }
  314. unlock_and_exit:
  315. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  316. return_ACPI_STATUS (status);
  317. }
  318. EXPORT_SYMBOL(acpi_install_notify_handler);
  319. /*******************************************************************************
  320. *
  321. * FUNCTION: acpi_remove_notify_handler
  322. *
  323. * PARAMETERS: Device - The device for which notifies will be handled
  324. * handler_type - The type of handler:
  325. * ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
  326. * ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
  327. * ACPI_ALL_NOTIFY: both system and device
  328. * Handler - Address of the handler
  329. *
  330. * RETURN: Status
  331. *
  332. * DESCRIPTION: Remove a handler for notifies on an ACPI device
  333. *
  334. ******************************************************************************/
  335. acpi_status
  336. acpi_remove_notify_handler (
  337. acpi_handle device,
  338. u32 handler_type,
  339. acpi_notify_handler handler)
  340. {
  341. union acpi_operand_object *notify_obj;
  342. union acpi_operand_object *obj_desc;
  343. struct acpi_namespace_node *node;
  344. acpi_status status;
  345. ACPI_FUNCTION_TRACE ("acpi_remove_notify_handler");
  346. /* Parameter validation */
  347. if ((!device) ||
  348. (!handler) ||
  349. (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
  350. return_ACPI_STATUS (AE_BAD_PARAMETER);
  351. }
  352. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  353. if (ACPI_FAILURE (status)) {
  354. return_ACPI_STATUS (status);
  355. }
  356. /* Convert and validate the device handle */
  357. node = acpi_ns_map_handle_to_node (device);
  358. if (!node) {
  359. status = AE_BAD_PARAMETER;
  360. goto unlock_and_exit;
  361. }
  362. /* Root Object */
  363. if (device == ACPI_ROOT_OBJECT) {
  364. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
  365. if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
  366. !acpi_gbl_system_notify.handler) ||
  367. ((handler_type & ACPI_DEVICE_NOTIFY) &&
  368. !acpi_gbl_device_notify.handler)) {
  369. status = AE_NOT_EXIST;
  370. goto unlock_and_exit;
  371. }
  372. /* Make sure all deferred tasks are completed */
  373. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  374. acpi_os_wait_events_complete(NULL);
  375. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  376. if (ACPI_FAILURE (status)) {
  377. return_ACPI_STATUS (status);
  378. }
  379. if (handler_type & ACPI_SYSTEM_NOTIFY) {
  380. acpi_gbl_system_notify.node = NULL;
  381. acpi_gbl_system_notify.handler = NULL;
  382. acpi_gbl_system_notify.context = NULL;
  383. }
  384. if (handler_type & ACPI_DEVICE_NOTIFY) {
  385. acpi_gbl_device_notify.node = NULL;
  386. acpi_gbl_device_notify.handler = NULL;
  387. acpi_gbl_device_notify.context = NULL;
  388. }
  389. }
  390. /* All Other Objects */
  391. else {
  392. /* Notifies allowed on this object? */
  393. if (!acpi_ev_is_notify_object (node)) {
  394. status = AE_TYPE;
  395. goto unlock_and_exit;
  396. }
  397. /* Check for an existing internal object */
  398. obj_desc = acpi_ns_get_attached_object (node);
  399. if (!obj_desc) {
  400. status = AE_NOT_EXIST;
  401. goto unlock_and_exit;
  402. }
  403. /* Object exists - make sure there's an existing handler */
  404. if (handler_type & ACPI_SYSTEM_NOTIFY) {
  405. notify_obj = obj_desc->common_notify.system_notify;
  406. if ((!notify_obj) ||
  407. (notify_obj->notify.handler != handler)) {
  408. status = AE_BAD_PARAMETER;
  409. goto unlock_and_exit;
  410. }
  411. /* Make sure all deferred tasks are completed */
  412. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  413. acpi_os_wait_events_complete(NULL);
  414. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  415. if (ACPI_FAILURE (status)) {
  416. return_ACPI_STATUS (status);
  417. }
  418. /* Remove the handler */
  419. obj_desc->common_notify.system_notify = NULL;
  420. acpi_ut_remove_reference (notify_obj);
  421. }
  422. if (handler_type & ACPI_DEVICE_NOTIFY) {
  423. notify_obj = obj_desc->common_notify.device_notify;
  424. if ((!notify_obj) ||
  425. (notify_obj->notify.handler != handler)) {
  426. status = AE_BAD_PARAMETER;
  427. goto unlock_and_exit;
  428. }
  429. /* Make sure all deferred tasks are completed */
  430. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  431. acpi_os_wait_events_complete(NULL);
  432. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  433. if (ACPI_FAILURE (status)) {
  434. return_ACPI_STATUS (status);
  435. }
  436. /* Remove the handler */
  437. obj_desc->common_notify.device_notify = NULL;
  438. acpi_ut_remove_reference (notify_obj);
  439. }
  440. }
  441. unlock_and_exit:
  442. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  443. return_ACPI_STATUS (status);
  444. }
  445. EXPORT_SYMBOL(acpi_remove_notify_handler);
  446. /*******************************************************************************
  447. *
  448. * FUNCTION: acpi_install_gpe_handler
  449. *
  450. * PARAMETERS: gpe_number - The GPE number within the GPE block
  451. * gpe_block - GPE block (NULL == FADT GPEs)
  452. * Type - Whether this GPE should be treated as an
  453. * edge- or level-triggered interrupt.
  454. * Address - Address of the handler
  455. * Context - Value passed to the handler on each GPE
  456. *
  457. * RETURN: Status
  458. *
  459. * DESCRIPTION: Install a handler for a General Purpose Event.
  460. *
  461. ******************************************************************************/
  462. acpi_status
  463. acpi_install_gpe_handler (
  464. acpi_handle gpe_device,
  465. u32 gpe_number,
  466. u32 type,
  467. acpi_event_handler address,
  468. void *context)
  469. {
  470. struct acpi_gpe_event_info *gpe_event_info;
  471. struct acpi_handler_info *handler;
  472. acpi_status status;
  473. ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
  474. /* Parameter validation */
  475. if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
  476. return_ACPI_STATUS (AE_BAD_PARAMETER);
  477. }
  478. status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  479. if (ACPI_FAILURE (status)) {
  480. return_ACPI_STATUS (status);
  481. }
  482. /* Ensure that we have a valid GPE number */
  483. gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
  484. if (!gpe_event_info) {
  485. status = AE_BAD_PARAMETER;
  486. goto unlock_and_exit;
  487. }
  488. /* Make sure that there isn't a handler there already */
  489. if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
  490. status = AE_ALREADY_EXISTS;
  491. goto unlock_and_exit;
  492. }
  493. /* Allocate and init handler object */
  494. handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info));
  495. if (!handler) {
  496. status = AE_NO_MEMORY;
  497. goto unlock_and_exit;
  498. }
  499. handler->address = address;
  500. handler->context = context;
  501. handler->method_node = gpe_event_info->dispatch.method_node;
  502. /* Disable the GPE before installing the handler */
  503. status = acpi_ev_disable_gpe (gpe_event_info);
  504. if (ACPI_FAILURE (status)) {
  505. goto unlock_and_exit;
  506. }
  507. /* Install the handler */
  508. acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
  509. gpe_event_info->dispatch.handler = handler;
  510. /* Setup up dispatch flags to indicate handler (vs. method) */
  511. gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
  512. gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
  513. acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
  514. unlock_and_exit:
  515. (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  516. return_ACPI_STATUS (status);
  517. }
  518. EXPORT_SYMBOL(acpi_install_gpe_handler);
  519. /*******************************************************************************
  520. *
  521. * FUNCTION: acpi_remove_gpe_handler
  522. *
  523. * PARAMETERS: gpe_number - The event to remove a handler
  524. * gpe_block - GPE block (NULL == FADT GPEs)
  525. * Address - Address of the handler
  526. *
  527. * RETURN: Status
  528. *
  529. * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
  530. *
  531. ******************************************************************************/
  532. acpi_status
  533. acpi_remove_gpe_handler (
  534. acpi_handle gpe_device,
  535. u32 gpe_number,
  536. acpi_event_handler address)
  537. {
  538. struct acpi_gpe_event_info *gpe_event_info;
  539. struct acpi_handler_info *handler;
  540. acpi_status status;
  541. ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
  542. /* Parameter validation */
  543. if (!address) {
  544. return_ACPI_STATUS (AE_BAD_PARAMETER);
  545. }
  546. status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  547. if (ACPI_FAILURE (status)) {
  548. return_ACPI_STATUS (status);
  549. }
  550. /* Ensure that we have a valid GPE number */
  551. gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
  552. if (!gpe_event_info) {
  553. status = AE_BAD_PARAMETER;
  554. goto unlock_and_exit;
  555. }
  556. /* Make sure that a handler is indeed installed */
  557. if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
  558. status = AE_NOT_EXIST;
  559. goto unlock_and_exit;
  560. }
  561. /* Make sure that the installed handler is the same */
  562. if (gpe_event_info->dispatch.handler->address != address) {
  563. status = AE_BAD_PARAMETER;
  564. goto unlock_and_exit;
  565. }
  566. /* Disable the GPE before removing the handler */
  567. status = acpi_ev_disable_gpe (gpe_event_info);
  568. if (ACPI_FAILURE (status)) {
  569. goto unlock_and_exit;
  570. }
  571. /* Make sure all deferred tasks are completed */
  572. (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  573. acpi_os_wait_events_complete(NULL);
  574. status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  575. if (ACPI_FAILURE (status)) {
  576. return_ACPI_STATUS (status);
  577. }
  578. /* Remove the handler */
  579. acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
  580. handler = gpe_event_info->dispatch.handler;
  581. /* Restore Method node (if any), set dispatch flags */
  582. gpe_event_info->dispatch.method_node = handler->method_node;
  583. gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
  584. if (handler->method_node) {
  585. gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
  586. }
  587. acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
  588. /* Now we can free the handler object */
  589. ACPI_MEM_FREE (handler);
  590. unlock_and_exit:
  591. (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  592. return_ACPI_STATUS (status);
  593. }
  594. EXPORT_SYMBOL(acpi_remove_gpe_handler);
  595. /*******************************************************************************
  596. *
  597. * FUNCTION: acpi_acquire_global_lock
  598. *
  599. * PARAMETERS: Timeout - How long the caller is willing to wait
  600. * out_handle - A handle to the lock if acquired
  601. *
  602. * RETURN: Status
  603. *
  604. * DESCRIPTION: Acquire the ACPI Global Lock
  605. *
  606. ******************************************************************************/
  607. acpi_status
  608. acpi_acquire_global_lock (
  609. u16 timeout,
  610. u32 *handle)
  611. {
  612. acpi_status status;
  613. if (!handle) {
  614. return (AE_BAD_PARAMETER);
  615. }
  616. status = acpi_ex_enter_interpreter ();
  617. if (ACPI_FAILURE (status)) {
  618. return (status);
  619. }
  620. status = acpi_ev_acquire_global_lock (timeout);
  621. acpi_ex_exit_interpreter ();
  622. if (ACPI_SUCCESS (status)) {
  623. acpi_gbl_global_lock_handle++;
  624. *handle = acpi_gbl_global_lock_handle;
  625. }
  626. return (status);
  627. }
  628. EXPORT_SYMBOL(acpi_acquire_global_lock);
  629. /*******************************************************************************
  630. *
  631. * FUNCTION: acpi_release_global_lock
  632. *
  633. * PARAMETERS: Handle - Returned from acpi_acquire_global_lock
  634. *
  635. * RETURN: Status
  636. *
  637. * DESCRIPTION: Release the ACPI Global Lock
  638. *
  639. ******************************************************************************/
  640. acpi_status
  641. acpi_release_global_lock (
  642. u32 handle)
  643. {
  644. acpi_status status;
  645. if (handle != acpi_gbl_global_lock_handle) {
  646. return (AE_NOT_ACQUIRED);
  647. }
  648. status = acpi_ev_release_global_lock ();
  649. return (status);
  650. }
  651. EXPORT_SYMBOL(acpi_release_global_lock);