evxface.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. /******************************************************************************
  2. *
  3. * Module Name: evxface - External interfaces for ACPI events
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2013, 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 notify 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. /* Do not allow multiple handlers */
  385. if (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,
  397. "Could not enable fixed event - %s (%u)",
  398. acpi_ut_get_event_name(event), event));
  399. /* Remove the handler */
  400. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  401. acpi_gbl_fixed_event_handlers[event].context = NULL;
  402. } else {
  403. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  404. "Enabled fixed event %s (%X), Handler=%p\n",
  405. acpi_ut_get_event_name(event), event,
  406. handler));
  407. }
  408. cleanup:
  409. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  410. return_ACPI_STATUS(status);
  411. }
  412. ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
  413. /*******************************************************************************
  414. *
  415. * FUNCTION: acpi_remove_fixed_event_handler
  416. *
  417. * PARAMETERS: event - Event type to disable.
  418. * handler - Address of the handler
  419. *
  420. * RETURN: Status
  421. *
  422. * DESCRIPTION: Disables the event and unregisters the event handler.
  423. *
  424. ******************************************************************************/
  425. acpi_status
  426. acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
  427. {
  428. acpi_status status = AE_OK;
  429. ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
  430. /* Parameter validation */
  431. if (event > ACPI_EVENT_MAX) {
  432. return_ACPI_STATUS(AE_BAD_PARAMETER);
  433. }
  434. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  435. if (ACPI_FAILURE(status)) {
  436. return_ACPI_STATUS(status);
  437. }
  438. /* Disable the event before removing the handler */
  439. status = acpi_disable_event(event, 0);
  440. /* Always Remove the handler */
  441. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  442. acpi_gbl_fixed_event_handlers[event].context = NULL;
  443. if (ACPI_FAILURE(status)) {
  444. ACPI_WARNING((AE_INFO,
  445. "Could not disable fixed event - %s (%u)",
  446. acpi_ut_get_event_name(event), event));
  447. } else {
  448. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  449. "Disabled fixed event - %s (%X)\n",
  450. acpi_ut_get_event_name(event), event));
  451. }
  452. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  453. return_ACPI_STATUS(status);
  454. }
  455. ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
  456. /*******************************************************************************
  457. *
  458. * FUNCTION: acpi_install_gpe_handler
  459. *
  460. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  461. * defined GPEs)
  462. * gpe_number - The GPE number within the GPE block
  463. * type - Whether this GPE should be treated as an
  464. * edge- or level-triggered interrupt.
  465. * address - Address of the handler
  466. * context - Value passed to the handler on each GPE
  467. *
  468. * RETURN: Status
  469. *
  470. * DESCRIPTION: Install a handler for a General Purpose Event.
  471. *
  472. ******************************************************************************/
  473. acpi_status
  474. acpi_install_gpe_handler(acpi_handle gpe_device,
  475. u32 gpe_number,
  476. u32 type, acpi_gpe_handler address, void *context)
  477. {
  478. struct acpi_gpe_event_info *gpe_event_info;
  479. struct acpi_gpe_handler_info *handler;
  480. acpi_status status;
  481. acpi_cpu_flags flags;
  482. ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
  483. /* Parameter validation */
  484. if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
  485. return_ACPI_STATUS(AE_BAD_PARAMETER);
  486. }
  487. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  488. if (ACPI_FAILURE(status)) {
  489. return_ACPI_STATUS(status);
  490. }
  491. /* Allocate and init handler object (before lock) */
  492. handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
  493. if (!handler) {
  494. status = AE_NO_MEMORY;
  495. goto unlock_and_exit;
  496. }
  497. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  498. /* Ensure that we have a valid GPE number */
  499. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  500. if (!gpe_event_info) {
  501. status = AE_BAD_PARAMETER;
  502. goto free_and_exit;
  503. }
  504. /* Make sure that there isn't a handler there already */
  505. if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
  506. ACPI_GPE_DISPATCH_HANDLER) {
  507. status = AE_ALREADY_EXISTS;
  508. goto free_and_exit;
  509. }
  510. handler->address = address;
  511. handler->context = context;
  512. handler->method_node = gpe_event_info->dispatch.method_node;
  513. handler->original_flags = (u8)(gpe_event_info->flags &
  514. (ACPI_GPE_XRUPT_TYPE_MASK |
  515. ACPI_GPE_DISPATCH_MASK));
  516. /*
  517. * If the GPE is associated with a method, it may have been enabled
  518. * automatically during initialization, in which case it has to be
  519. * disabled now to avoid spurious execution of the handler.
  520. */
  521. if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
  522. && gpe_event_info->runtime_count) {
  523. handler->originally_enabled = 1;
  524. (void)acpi_ev_remove_gpe_reference(gpe_event_info);
  525. }
  526. /* Install the handler */
  527. gpe_event_info->dispatch.handler = handler;
  528. /* Setup up dispatch flags to indicate handler (vs. method/notify) */
  529. gpe_event_info->flags &=
  530. ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  531. gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
  532. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  533. unlock_and_exit:
  534. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  535. return_ACPI_STATUS(status);
  536. free_and_exit:
  537. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  538. ACPI_FREE(handler);
  539. goto unlock_and_exit;
  540. }
  541. ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
  542. /*******************************************************************************
  543. *
  544. * FUNCTION: acpi_remove_gpe_handler
  545. *
  546. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  547. * defined GPEs)
  548. * gpe_number - The event to remove a handler
  549. * address - Address of the handler
  550. *
  551. * RETURN: Status
  552. *
  553. * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
  554. *
  555. ******************************************************************************/
  556. acpi_status
  557. acpi_remove_gpe_handler(acpi_handle gpe_device,
  558. u32 gpe_number, acpi_gpe_handler address)
  559. {
  560. struct acpi_gpe_event_info *gpe_event_info;
  561. struct acpi_gpe_handler_info *handler;
  562. acpi_status status;
  563. acpi_cpu_flags flags;
  564. ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
  565. /* Parameter validation */
  566. if (!address) {
  567. return_ACPI_STATUS(AE_BAD_PARAMETER);
  568. }
  569. /* Make sure all deferred GPE tasks are completed */
  570. acpi_os_wait_events_complete();
  571. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  572. if (ACPI_FAILURE(status)) {
  573. return_ACPI_STATUS(status);
  574. }
  575. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  576. /* Ensure that we have a valid GPE number */
  577. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  578. if (!gpe_event_info) {
  579. status = AE_BAD_PARAMETER;
  580. goto unlock_and_exit;
  581. }
  582. /* Make sure that a handler is indeed installed */
  583. if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
  584. ACPI_GPE_DISPATCH_HANDLER) {
  585. status = AE_NOT_EXIST;
  586. goto unlock_and_exit;
  587. }
  588. /* Make sure that the installed handler is the same */
  589. if (gpe_event_info->dispatch.handler->address != address) {
  590. status = AE_BAD_PARAMETER;
  591. goto unlock_and_exit;
  592. }
  593. /* Remove the handler */
  594. handler = gpe_event_info->dispatch.handler;
  595. /* Restore Method node (if any), set dispatch flags */
  596. gpe_event_info->dispatch.method_node = handler->method_node;
  597. gpe_event_info->flags &=
  598. ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  599. gpe_event_info->flags |= handler->original_flags;
  600. /*
  601. * If the GPE was previously associated with a method and it was
  602. * enabled, it should be enabled at this point to restore the
  603. * post-initialization configuration.
  604. */
  605. if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) &&
  606. handler->originally_enabled) {
  607. (void)acpi_ev_add_gpe_reference(gpe_event_info);
  608. }
  609. /* Now we can free the handler object */
  610. ACPI_FREE(handler);
  611. unlock_and_exit:
  612. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  613. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  614. return_ACPI_STATUS(status);
  615. }
  616. ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
  617. /*******************************************************************************
  618. *
  619. * FUNCTION: acpi_acquire_global_lock
  620. *
  621. * PARAMETERS: timeout - How long the caller is willing to wait
  622. * handle - Where the handle to the lock is returned
  623. * (if acquired)
  624. *
  625. * RETURN: Status
  626. *
  627. * DESCRIPTION: Acquire the ACPI Global Lock
  628. *
  629. * Note: Allows callers with the same thread ID to acquire the global lock
  630. * multiple times. In other words, externally, the behavior of the global lock
  631. * is identical to an AML mutex. On the first acquire, a new handle is
  632. * returned. On any subsequent calls to acquire by the same thread, the same
  633. * handle is returned.
  634. *
  635. ******************************************************************************/
  636. acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
  637. {
  638. acpi_status status;
  639. if (!handle) {
  640. return (AE_BAD_PARAMETER);
  641. }
  642. /* Must lock interpreter to prevent race conditions */
  643. acpi_ex_enter_interpreter();
  644. status = acpi_ex_acquire_mutex_object(timeout,
  645. acpi_gbl_global_lock_mutex,
  646. acpi_os_get_thread_id());
  647. if (ACPI_SUCCESS(status)) {
  648. /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
  649. *handle = acpi_gbl_global_lock_handle;
  650. }
  651. acpi_ex_exit_interpreter();
  652. return (status);
  653. }
  654. ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
  655. /*******************************************************************************
  656. *
  657. * FUNCTION: acpi_release_global_lock
  658. *
  659. * PARAMETERS: handle - Returned from acpi_acquire_global_lock
  660. *
  661. * RETURN: Status
  662. *
  663. * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
  664. *
  665. ******************************************************************************/
  666. acpi_status acpi_release_global_lock(u32 handle)
  667. {
  668. acpi_status status;
  669. if (!handle || (handle != acpi_gbl_global_lock_handle)) {
  670. return (AE_NOT_ACQUIRED);
  671. }
  672. status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
  673. return (status);
  674. }
  675. ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
  676. #endif /* !ACPI_REDUCED_HARDWARE */