evxface.c 24 KB

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