evxface.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. /******************************************************************************
  2. *
  3. * Module Name: evxface - External interfaces for ACPI events
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2014, 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. #define EXPORT_ACPI_INTERFACES
  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 = AE_OK;
  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. /* Root Object. Global handlers are removed here */
  215. if (device == ACPI_ROOT_OBJECT) {
  216. for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
  217. if (handler_type & (i + 1)) {
  218. status =
  219. acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  220. if (ACPI_FAILURE(status)) {
  221. return_ACPI_STATUS(status);
  222. }
  223. if (!acpi_gbl_global_notify[i].handler ||
  224. (acpi_gbl_global_notify[i].handler !=
  225. handler)) {
  226. status = AE_NOT_EXIST;
  227. goto unlock_and_exit;
  228. }
  229. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  230. "Removing global notify handler\n"));
  231. acpi_gbl_global_notify[i].handler = NULL;
  232. acpi_gbl_global_notify[i].context = NULL;
  233. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  234. /* Make sure all deferred notify tasks are completed */
  235. acpi_os_wait_events_complete();
  236. }
  237. }
  238. return_ACPI_STATUS(AE_OK);
  239. }
  240. /* All other objects: Are Notifies allowed on this object? */
  241. if (!acpi_ev_is_notify_object(node)) {
  242. return_ACPI_STATUS(AE_TYPE);
  243. }
  244. /* Must have an existing internal object */
  245. obj_desc = acpi_ns_get_attached_object(node);
  246. if (!obj_desc) {
  247. return_ACPI_STATUS(AE_NOT_EXIST);
  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. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  253. if (ACPI_FAILURE(status)) {
  254. return_ACPI_STATUS(status);
  255. }
  256. handler_obj = obj_desc->common_notify.notify_list[i];
  257. previous_handler_obj = NULL;
  258. /* Attempt to find the handler in the handler list */
  259. while (handler_obj &&
  260. (handler_obj->notify.handler != handler)) {
  261. previous_handler_obj = handler_obj;
  262. handler_obj = handler_obj->notify.next[i];
  263. }
  264. if (!handler_obj) {
  265. status = AE_NOT_EXIST;
  266. goto unlock_and_exit;
  267. }
  268. /* Remove the handler object from the list */
  269. if (previous_handler_obj) { /* Handler is not at the list head */
  270. previous_handler_obj->notify.next[i] =
  271. handler_obj->notify.next[i];
  272. } else { /* Handler is at the list head */
  273. obj_desc->common_notify.notify_list[i] =
  274. handler_obj->notify.next[i];
  275. }
  276. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  277. /* Make sure all deferred notify tasks are completed */
  278. acpi_os_wait_events_complete();
  279. acpi_ut_remove_reference(handler_obj);
  280. }
  281. }
  282. return_ACPI_STATUS(status);
  283. unlock_and_exit:
  284. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  285. return_ACPI_STATUS(status);
  286. }
  287. ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
  288. /*******************************************************************************
  289. *
  290. * FUNCTION: acpi_install_exception_handler
  291. *
  292. * PARAMETERS: handler - Pointer to the handler function for the
  293. * event
  294. *
  295. * RETURN: Status
  296. *
  297. * DESCRIPTION: Saves the pointer to the handler function
  298. *
  299. ******************************************************************************/
  300. #ifdef ACPI_FUTURE_USAGE
  301. acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
  302. {
  303. acpi_status status;
  304. ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
  305. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  306. if (ACPI_FAILURE(status)) {
  307. return_ACPI_STATUS(status);
  308. }
  309. /* Don't allow two handlers. */
  310. if (acpi_gbl_exception_handler) {
  311. status = AE_ALREADY_EXISTS;
  312. goto cleanup;
  313. }
  314. /* Install the handler */
  315. acpi_gbl_exception_handler = handler;
  316. cleanup:
  317. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  318. return_ACPI_STATUS(status);
  319. }
  320. ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
  321. #endif /* ACPI_FUTURE_USAGE */
  322. #if (!ACPI_REDUCED_HARDWARE)
  323. /*******************************************************************************
  324. *
  325. * FUNCTION: acpi_install_sci_handler
  326. *
  327. * PARAMETERS: address - Address of the handler
  328. * context - Value passed to the handler on each SCI
  329. *
  330. * RETURN: Status
  331. *
  332. * DESCRIPTION: Install a handler for a System Control Interrupt.
  333. *
  334. ******************************************************************************/
  335. acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
  336. {
  337. struct acpi_sci_handler_info *new_sci_handler;
  338. struct acpi_sci_handler_info *sci_handler;
  339. acpi_cpu_flags flags;
  340. acpi_status status;
  341. ACPI_FUNCTION_TRACE(acpi_install_sci_handler);
  342. if (!address) {
  343. return_ACPI_STATUS(AE_BAD_PARAMETER);
  344. }
  345. /* Allocate and init a handler object */
  346. new_sci_handler = ACPI_ALLOCATE(sizeof(struct acpi_sci_handler_info));
  347. if (!new_sci_handler) {
  348. return_ACPI_STATUS(AE_NO_MEMORY);
  349. }
  350. new_sci_handler->address = address;
  351. new_sci_handler->context = context;
  352. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  353. if (ACPI_FAILURE(status)) {
  354. goto exit;
  355. }
  356. /* Lock list during installation */
  357. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  358. sci_handler = acpi_gbl_sci_handler_list;
  359. /* Ensure handler does not already exist */
  360. while (sci_handler) {
  361. if (address == sci_handler->address) {
  362. status = AE_ALREADY_EXISTS;
  363. goto unlock_and_exit;
  364. }
  365. sci_handler = sci_handler->next;
  366. }
  367. /* Install the new handler into the global list (at head) */
  368. new_sci_handler->next = acpi_gbl_sci_handler_list;
  369. acpi_gbl_sci_handler_list = new_sci_handler;
  370. unlock_and_exit:
  371. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  372. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  373. exit:
  374. if (ACPI_FAILURE(status)) {
  375. ACPI_FREE(new_sci_handler);
  376. }
  377. return_ACPI_STATUS(status);
  378. }
  379. ACPI_EXPORT_SYMBOL(acpi_install_sci_handler)
  380. /*******************************************************************************
  381. *
  382. * FUNCTION: acpi_remove_sci_handler
  383. *
  384. * PARAMETERS: address - Address of the handler
  385. *
  386. * RETURN: Status
  387. *
  388. * DESCRIPTION: Remove a handler for a System Control Interrupt.
  389. *
  390. ******************************************************************************/
  391. acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
  392. {
  393. struct acpi_sci_handler_info *prev_sci_handler;
  394. struct acpi_sci_handler_info *next_sci_handler;
  395. acpi_cpu_flags flags;
  396. acpi_status status;
  397. ACPI_FUNCTION_TRACE(acpi_remove_sci_handler);
  398. if (!address) {
  399. return_ACPI_STATUS(AE_BAD_PARAMETER);
  400. }
  401. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  402. if (ACPI_FAILURE(status)) {
  403. return_ACPI_STATUS(status);
  404. }
  405. /* Remove the SCI handler with lock */
  406. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  407. prev_sci_handler = NULL;
  408. next_sci_handler = acpi_gbl_sci_handler_list;
  409. while (next_sci_handler) {
  410. if (next_sci_handler->address == address) {
  411. /* Unlink and free the SCI handler info block */
  412. if (prev_sci_handler) {
  413. prev_sci_handler->next = next_sci_handler->next;
  414. } else {
  415. acpi_gbl_sci_handler_list =
  416. next_sci_handler->next;
  417. }
  418. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  419. ACPI_FREE(next_sci_handler);
  420. goto unlock_and_exit;
  421. }
  422. prev_sci_handler = next_sci_handler;
  423. next_sci_handler = next_sci_handler->next;
  424. }
  425. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  426. status = AE_NOT_EXIST;
  427. unlock_and_exit:
  428. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  429. return_ACPI_STATUS(status);
  430. }
  431. ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler)
  432. /*******************************************************************************
  433. *
  434. * FUNCTION: acpi_install_global_event_handler
  435. *
  436. * PARAMETERS: handler - Pointer to the global event handler function
  437. * context - Value passed to the handler on each event
  438. *
  439. * RETURN: Status
  440. *
  441. * DESCRIPTION: Saves the pointer to the handler function. The global handler
  442. * is invoked upon each incoming GPE and Fixed Event. It is
  443. * invoked at interrupt level at the time of the event dispatch.
  444. * Can be used to update event counters, etc.
  445. *
  446. ******************************************************************************/
  447. acpi_status
  448. acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
  449. {
  450. acpi_status status;
  451. ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
  452. /* Parameter validation */
  453. if (!handler) {
  454. return_ACPI_STATUS(AE_BAD_PARAMETER);
  455. }
  456. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  457. if (ACPI_FAILURE(status)) {
  458. return_ACPI_STATUS(status);
  459. }
  460. /* Don't allow two handlers. */
  461. if (acpi_gbl_global_event_handler) {
  462. status = AE_ALREADY_EXISTS;
  463. goto cleanup;
  464. }
  465. acpi_gbl_global_event_handler = handler;
  466. acpi_gbl_global_event_handler_context = context;
  467. cleanup:
  468. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  469. return_ACPI_STATUS(status);
  470. }
  471. ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
  472. /*******************************************************************************
  473. *
  474. * FUNCTION: acpi_install_fixed_event_handler
  475. *
  476. * PARAMETERS: event - Event type to enable.
  477. * handler - Pointer to the handler function for the
  478. * event
  479. * context - Value passed to the handler on each GPE
  480. *
  481. * RETURN: Status
  482. *
  483. * DESCRIPTION: Saves the pointer to the handler function and then enables the
  484. * event.
  485. *
  486. ******************************************************************************/
  487. acpi_status
  488. acpi_install_fixed_event_handler(u32 event,
  489. acpi_event_handler handler, void *context)
  490. {
  491. acpi_status status;
  492. ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
  493. /* Parameter validation */
  494. if (event > ACPI_EVENT_MAX) {
  495. return_ACPI_STATUS(AE_BAD_PARAMETER);
  496. }
  497. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  498. if (ACPI_FAILURE(status)) {
  499. return_ACPI_STATUS(status);
  500. }
  501. /* Do not allow multiple handlers */
  502. if (acpi_gbl_fixed_event_handlers[event].handler) {
  503. status = AE_ALREADY_EXISTS;
  504. goto cleanup;
  505. }
  506. /* Install the handler before enabling the event */
  507. acpi_gbl_fixed_event_handlers[event].handler = handler;
  508. acpi_gbl_fixed_event_handlers[event].context = context;
  509. status = acpi_clear_event(event);
  510. if (ACPI_SUCCESS(status))
  511. status = acpi_enable_event(event, 0);
  512. if (ACPI_FAILURE(status)) {
  513. ACPI_WARNING((AE_INFO,
  514. "Could not enable fixed event - %s (%u)",
  515. acpi_ut_get_event_name(event), event));
  516. /* Remove the handler */
  517. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  518. acpi_gbl_fixed_event_handlers[event].context = NULL;
  519. } else {
  520. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  521. "Enabled fixed event %s (%X), Handler=%p\n",
  522. acpi_ut_get_event_name(event), event,
  523. handler));
  524. }
  525. cleanup:
  526. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  527. return_ACPI_STATUS(status);
  528. }
  529. ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
  530. /*******************************************************************************
  531. *
  532. * FUNCTION: acpi_remove_fixed_event_handler
  533. *
  534. * PARAMETERS: event - Event type to disable.
  535. * handler - Address of the handler
  536. *
  537. * RETURN: Status
  538. *
  539. * DESCRIPTION: Disables the event and unregisters the event handler.
  540. *
  541. ******************************************************************************/
  542. acpi_status
  543. acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
  544. {
  545. acpi_status status = AE_OK;
  546. ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
  547. /* Parameter validation */
  548. if (event > ACPI_EVENT_MAX) {
  549. return_ACPI_STATUS(AE_BAD_PARAMETER);
  550. }
  551. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  552. if (ACPI_FAILURE(status)) {
  553. return_ACPI_STATUS(status);
  554. }
  555. /* Disable the event before removing the handler */
  556. status = acpi_disable_event(event, 0);
  557. /* Always Remove the handler */
  558. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  559. acpi_gbl_fixed_event_handlers[event].context = NULL;
  560. if (ACPI_FAILURE(status)) {
  561. ACPI_WARNING((AE_INFO,
  562. "Could not disable fixed event - %s (%u)",
  563. acpi_ut_get_event_name(event), event));
  564. } else {
  565. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  566. "Disabled fixed event - %s (%X)\n",
  567. acpi_ut_get_event_name(event), event));
  568. }
  569. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  570. return_ACPI_STATUS(status);
  571. }
  572. ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
  573. /*******************************************************************************
  574. *
  575. * FUNCTION: acpi_install_gpe_handler
  576. *
  577. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  578. * defined GPEs)
  579. * gpe_number - The GPE number within the GPE block
  580. * type - Whether this GPE should be treated as an
  581. * edge- or level-triggered interrupt.
  582. * address - Address of the handler
  583. * context - Value passed to the handler on each GPE
  584. *
  585. * RETURN: Status
  586. *
  587. * DESCRIPTION: Install a handler for a General Purpose Event.
  588. *
  589. ******************************************************************************/
  590. acpi_status
  591. acpi_install_gpe_handler(acpi_handle gpe_device,
  592. u32 gpe_number,
  593. u32 type, acpi_gpe_handler address, void *context)
  594. {
  595. struct acpi_gpe_event_info *gpe_event_info;
  596. struct acpi_gpe_handler_info *handler;
  597. acpi_status status;
  598. acpi_cpu_flags flags;
  599. ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
  600. /* Parameter validation */
  601. if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
  602. return_ACPI_STATUS(AE_BAD_PARAMETER);
  603. }
  604. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  605. if (ACPI_FAILURE(status)) {
  606. return_ACPI_STATUS(status);
  607. }
  608. /* Allocate and init handler object (before lock) */
  609. handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
  610. if (!handler) {
  611. status = AE_NO_MEMORY;
  612. goto unlock_and_exit;
  613. }
  614. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  615. /* Ensure that we have a valid GPE number */
  616. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  617. if (!gpe_event_info) {
  618. status = AE_BAD_PARAMETER;
  619. goto free_and_exit;
  620. }
  621. /* Make sure that there isn't a handler there already */
  622. if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
  623. ACPI_GPE_DISPATCH_HANDLER) {
  624. status = AE_ALREADY_EXISTS;
  625. goto free_and_exit;
  626. }
  627. handler->address = address;
  628. handler->context = context;
  629. handler->method_node = gpe_event_info->dispatch.method_node;
  630. handler->original_flags = (u8)(gpe_event_info->flags &
  631. (ACPI_GPE_XRUPT_TYPE_MASK |
  632. ACPI_GPE_DISPATCH_MASK));
  633. /*
  634. * If the GPE is associated with a method, it may have been enabled
  635. * automatically during initialization, in which case it has to be
  636. * disabled now to avoid spurious execution of the handler.
  637. */
  638. if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
  639. && gpe_event_info->runtime_count) {
  640. handler->originally_enabled = 1;
  641. (void)acpi_ev_remove_gpe_reference(gpe_event_info);
  642. }
  643. /* Install the handler */
  644. gpe_event_info->dispatch.handler = handler;
  645. /* Setup up dispatch flags to indicate handler (vs. method/notify) */
  646. gpe_event_info->flags &=
  647. ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  648. gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
  649. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  650. unlock_and_exit:
  651. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  652. return_ACPI_STATUS(status);
  653. free_and_exit:
  654. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  655. ACPI_FREE(handler);
  656. goto unlock_and_exit;
  657. }
  658. ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
  659. /*******************************************************************************
  660. *
  661. * FUNCTION: acpi_remove_gpe_handler
  662. *
  663. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  664. * defined GPEs)
  665. * gpe_number - The event to remove a handler
  666. * address - Address of the handler
  667. *
  668. * RETURN: Status
  669. *
  670. * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
  671. *
  672. ******************************************************************************/
  673. acpi_status
  674. acpi_remove_gpe_handler(acpi_handle gpe_device,
  675. u32 gpe_number, acpi_gpe_handler address)
  676. {
  677. struct acpi_gpe_event_info *gpe_event_info;
  678. struct acpi_gpe_handler_info *handler;
  679. acpi_status status;
  680. acpi_cpu_flags flags;
  681. ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
  682. /* Parameter validation */
  683. if (!address) {
  684. return_ACPI_STATUS(AE_BAD_PARAMETER);
  685. }
  686. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  687. if (ACPI_FAILURE(status)) {
  688. return_ACPI_STATUS(status);
  689. }
  690. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  691. /* Ensure that we have a valid GPE number */
  692. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  693. if (!gpe_event_info) {
  694. status = AE_BAD_PARAMETER;
  695. goto unlock_and_exit;
  696. }
  697. /* Make sure that a handler is indeed installed */
  698. if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
  699. ACPI_GPE_DISPATCH_HANDLER) {
  700. status = AE_NOT_EXIST;
  701. goto unlock_and_exit;
  702. }
  703. /* Make sure that the installed handler is the same */
  704. if (gpe_event_info->dispatch.handler->address != address) {
  705. status = AE_BAD_PARAMETER;
  706. goto unlock_and_exit;
  707. }
  708. /* Remove the handler */
  709. handler = gpe_event_info->dispatch.handler;
  710. /* Restore Method node (if any), set dispatch flags */
  711. gpe_event_info->dispatch.method_node = handler->method_node;
  712. gpe_event_info->flags &=
  713. ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  714. gpe_event_info->flags |= handler->original_flags;
  715. /*
  716. * If the GPE was previously associated with a method and it was
  717. * enabled, it should be enabled at this point to restore the
  718. * post-initialization configuration.
  719. */
  720. if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) &&
  721. handler->originally_enabled) {
  722. (void)acpi_ev_add_gpe_reference(gpe_event_info);
  723. }
  724. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  725. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  726. /* Make sure all deferred GPE tasks are completed */
  727. acpi_os_wait_events_complete();
  728. /* Now we can free the handler object */
  729. ACPI_FREE(handler);
  730. return_ACPI_STATUS(status);
  731. unlock_and_exit:
  732. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  733. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  734. return_ACPI_STATUS(status);
  735. }
  736. ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
  737. /*******************************************************************************
  738. *
  739. * FUNCTION: acpi_acquire_global_lock
  740. *
  741. * PARAMETERS: timeout - How long the caller is willing to wait
  742. * handle - Where the handle to the lock is returned
  743. * (if acquired)
  744. *
  745. * RETURN: Status
  746. *
  747. * DESCRIPTION: Acquire the ACPI Global Lock
  748. *
  749. * Note: Allows callers with the same thread ID to acquire the global lock
  750. * multiple times. In other words, externally, the behavior of the global lock
  751. * is identical to an AML mutex. On the first acquire, a new handle is
  752. * returned. On any subsequent calls to acquire by the same thread, the same
  753. * handle is returned.
  754. *
  755. ******************************************************************************/
  756. acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
  757. {
  758. acpi_status status;
  759. if (!handle) {
  760. return (AE_BAD_PARAMETER);
  761. }
  762. /* Must lock interpreter to prevent race conditions */
  763. acpi_ex_enter_interpreter();
  764. status = acpi_ex_acquire_mutex_object(timeout,
  765. acpi_gbl_global_lock_mutex,
  766. acpi_os_get_thread_id());
  767. if (ACPI_SUCCESS(status)) {
  768. /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
  769. *handle = acpi_gbl_global_lock_handle;
  770. }
  771. acpi_ex_exit_interpreter();
  772. return (status);
  773. }
  774. ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
  775. /*******************************************************************************
  776. *
  777. * FUNCTION: acpi_release_global_lock
  778. *
  779. * PARAMETERS: handle - Returned from acpi_acquire_global_lock
  780. *
  781. * RETURN: Status
  782. *
  783. * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
  784. *
  785. ******************************************************************************/
  786. acpi_status acpi_release_global_lock(u32 handle)
  787. {
  788. acpi_status status;
  789. if (!handle || (handle != acpi_gbl_global_lock_handle)) {
  790. return (AE_NOT_ACQUIRED);
  791. }
  792. status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
  793. return (status);
  794. }
  795. ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
  796. #endif /* !ACPI_REDUCED_HARDWARE */