evxface.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: evxface - External interfaces for ACPI events
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #define EXPORT_ACPI_INTERFACES
  10. #include <acpi/acpi.h>
  11. #include "accommon.h"
  12. #include "acnamesp.h"
  13. #include "acevents.h"
  14. #include "acinterp.h"
  15. #define _COMPONENT ACPI_EVENTS
  16. ACPI_MODULE_NAME("evxface")
  17. #if (!ACPI_REDUCED_HARDWARE)
  18. /* Local prototypes */
  19. static acpi_status
  20. acpi_ev_install_gpe_handler(acpi_handle gpe_device,
  21. u32 gpe_number,
  22. u32 type,
  23. u8 is_raw_handler,
  24. acpi_gpe_handler address, void *context);
  25. #endif
  26. /*******************************************************************************
  27. *
  28. * FUNCTION: acpi_install_notify_handler
  29. *
  30. * PARAMETERS: device - The device for which notifies will be handled
  31. * handler_type - The type of handler:
  32. * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
  33. * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
  34. * ACPI_ALL_NOTIFY: Both System and Device
  35. * handler - Address of the handler
  36. * context - Value passed to the handler on each GPE
  37. *
  38. * RETURN: Status
  39. *
  40. * DESCRIPTION: Install a handler for notifications on an ACPI Device,
  41. * thermal_zone, or Processor object.
  42. *
  43. * NOTES: The Root namespace object may have only one handler for each
  44. * type of notify (System/Device). Device/Thermal/Processor objects
  45. * may have one device notify handler, and multiple system notify
  46. * handlers.
  47. *
  48. ******************************************************************************/
  49. acpi_status
  50. acpi_install_notify_handler(acpi_handle device,
  51. u32 handler_type,
  52. acpi_notify_handler handler, void *context)
  53. {
  54. struct acpi_namespace_node *node =
  55. ACPI_CAST_PTR(struct acpi_namespace_node, device);
  56. union acpi_operand_object *obj_desc;
  57. union acpi_operand_object *handler_obj;
  58. acpi_status status;
  59. u32 i;
  60. ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
  61. /* Parameter validation */
  62. if ((!device) || (!handler) || (!handler_type) ||
  63. (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
  64. return_ACPI_STATUS(AE_BAD_PARAMETER);
  65. }
  66. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  67. if (ACPI_FAILURE(status)) {
  68. return_ACPI_STATUS(status);
  69. }
  70. /*
  71. * Root Object:
  72. * Registering a notify handler on the root object indicates that the
  73. * caller wishes to receive notifications for all objects. Note that
  74. * only one global handler can be registered per notify type.
  75. * Ensure that a handler is not already installed.
  76. */
  77. if (device == ACPI_ROOT_OBJECT) {
  78. for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
  79. if (handler_type & (i + 1)) {
  80. if (acpi_gbl_global_notify[i].handler) {
  81. status = AE_ALREADY_EXISTS;
  82. goto unlock_and_exit;
  83. }
  84. acpi_gbl_global_notify[i].handler = handler;
  85. acpi_gbl_global_notify[i].context = context;
  86. }
  87. }
  88. goto unlock_and_exit; /* Global notify handler installed, all done */
  89. }
  90. /*
  91. * All Other Objects:
  92. * Caller will only receive notifications specific to the target
  93. * object. Note that only certain object types are allowed to
  94. * receive notifications.
  95. */
  96. /* Are Notifies allowed on this object? */
  97. if (!acpi_ev_is_notify_object(node)) {
  98. status = AE_TYPE;
  99. goto unlock_and_exit;
  100. }
  101. /* Check for an existing internal object, might not exist */
  102. obj_desc = acpi_ns_get_attached_object(node);
  103. if (!obj_desc) {
  104. /* Create a new object */
  105. obj_desc = acpi_ut_create_internal_object(node->type);
  106. if (!obj_desc) {
  107. status = AE_NO_MEMORY;
  108. goto unlock_and_exit;
  109. }
  110. /* Attach new object to the Node, remove local reference */
  111. status = acpi_ns_attach_object(device, obj_desc, node->type);
  112. acpi_ut_remove_reference(obj_desc);
  113. if (ACPI_FAILURE(status)) {
  114. goto unlock_and_exit;
  115. }
  116. }
  117. /* Ensure that the handler is not already installed in the lists */
  118. for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
  119. if (handler_type & (i + 1)) {
  120. handler_obj = obj_desc->common_notify.notify_list[i];
  121. while (handler_obj) {
  122. if (handler_obj->notify.handler == handler) {
  123. status = AE_ALREADY_EXISTS;
  124. goto unlock_and_exit;
  125. }
  126. handler_obj = handler_obj->notify.next[i];
  127. }
  128. }
  129. }
  130. /* Create and populate a new notify handler object */
  131. handler_obj = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
  132. if (!handler_obj) {
  133. status = AE_NO_MEMORY;
  134. goto unlock_and_exit;
  135. }
  136. handler_obj->notify.node = node;
  137. handler_obj->notify.handler_type = handler_type;
  138. handler_obj->notify.handler = handler;
  139. handler_obj->notify.context = context;
  140. /* Install the handler at the list head(s) */
  141. for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
  142. if (handler_type & (i + 1)) {
  143. handler_obj->notify.next[i] =
  144. obj_desc->common_notify.notify_list[i];
  145. obj_desc->common_notify.notify_list[i] = handler_obj;
  146. }
  147. }
  148. /* Add an extra reference if handler was installed in both lists */
  149. if (handler_type == ACPI_ALL_NOTIFY) {
  150. acpi_ut_add_reference(handler_obj);
  151. }
  152. unlock_and_exit:
  153. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  154. return_ACPI_STATUS(status);
  155. }
  156. ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
  157. /*******************************************************************************
  158. *
  159. * FUNCTION: acpi_remove_notify_handler
  160. *
  161. * PARAMETERS: device - The device for which the handler is installed
  162. * handler_type - The type of handler:
  163. * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
  164. * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
  165. * ACPI_ALL_NOTIFY: Both System and Device
  166. * handler - Address of the handler
  167. *
  168. * RETURN: Status
  169. *
  170. * DESCRIPTION: Remove a handler for notifies on an ACPI device
  171. *
  172. ******************************************************************************/
  173. acpi_status
  174. acpi_remove_notify_handler(acpi_handle device,
  175. u32 handler_type, acpi_notify_handler handler)
  176. {
  177. struct acpi_namespace_node *node =
  178. ACPI_CAST_PTR(struct acpi_namespace_node, device);
  179. union acpi_operand_object *obj_desc;
  180. union acpi_operand_object *handler_obj;
  181. union acpi_operand_object *previous_handler_obj;
  182. acpi_status status = AE_OK;
  183. u32 i;
  184. ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
  185. /* Parameter validation */
  186. if ((!device) || (!handler) || (!handler_type) ||
  187. (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
  188. return_ACPI_STATUS(AE_BAD_PARAMETER);
  189. }
  190. /* Root Object. Global handlers are removed here */
  191. if (device == ACPI_ROOT_OBJECT) {
  192. for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
  193. if (handler_type & (i + 1)) {
  194. status =
  195. acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  196. if (ACPI_FAILURE(status)) {
  197. return_ACPI_STATUS(status);
  198. }
  199. if (!acpi_gbl_global_notify[i].handler ||
  200. (acpi_gbl_global_notify[i].handler !=
  201. handler)) {
  202. status = AE_NOT_EXIST;
  203. goto unlock_and_exit;
  204. }
  205. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  206. "Removing global notify handler\n"));
  207. acpi_gbl_global_notify[i].handler = NULL;
  208. acpi_gbl_global_notify[i].context = NULL;
  209. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  210. /* Make sure all deferred notify tasks are completed */
  211. acpi_os_wait_events_complete();
  212. }
  213. }
  214. return_ACPI_STATUS(AE_OK);
  215. }
  216. /* All other objects: Are Notifies allowed on this object? */
  217. if (!acpi_ev_is_notify_object(node)) {
  218. return_ACPI_STATUS(AE_TYPE);
  219. }
  220. /* Must have an existing internal object */
  221. obj_desc = acpi_ns_get_attached_object(node);
  222. if (!obj_desc) {
  223. return_ACPI_STATUS(AE_NOT_EXIST);
  224. }
  225. /* Internal object exists. Find the handler and remove it */
  226. for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
  227. if (handler_type & (i + 1)) {
  228. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  229. if (ACPI_FAILURE(status)) {
  230. return_ACPI_STATUS(status);
  231. }
  232. handler_obj = obj_desc->common_notify.notify_list[i];
  233. previous_handler_obj = NULL;
  234. /* Attempt to find the handler in the handler list */
  235. while (handler_obj &&
  236. (handler_obj->notify.handler != handler)) {
  237. previous_handler_obj = handler_obj;
  238. handler_obj = handler_obj->notify.next[i];
  239. }
  240. if (!handler_obj) {
  241. status = AE_NOT_EXIST;
  242. goto unlock_and_exit;
  243. }
  244. /* Remove the handler object from the list */
  245. if (previous_handler_obj) { /* Handler is not at the list head */
  246. previous_handler_obj->notify.next[i] =
  247. handler_obj->notify.next[i];
  248. } else { /* Handler is at the list head */
  249. obj_desc->common_notify.notify_list[i] =
  250. handler_obj->notify.next[i];
  251. }
  252. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  253. /* Make sure all deferred notify tasks are completed */
  254. acpi_os_wait_events_complete();
  255. acpi_ut_remove_reference(handler_obj);
  256. }
  257. }
  258. return_ACPI_STATUS(status);
  259. unlock_and_exit:
  260. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  261. return_ACPI_STATUS(status);
  262. }
  263. ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
  264. /*******************************************************************************
  265. *
  266. * FUNCTION: acpi_install_exception_handler
  267. *
  268. * PARAMETERS: handler - Pointer to the handler function for the
  269. * event
  270. *
  271. * RETURN: Status
  272. *
  273. * DESCRIPTION: Saves the pointer to the handler function
  274. *
  275. ******************************************************************************/
  276. #ifdef ACPI_FUTURE_USAGE
  277. acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
  278. {
  279. acpi_status status;
  280. ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
  281. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  282. if (ACPI_FAILURE(status)) {
  283. return_ACPI_STATUS(status);
  284. }
  285. /* Don't allow two handlers. */
  286. if (acpi_gbl_exception_handler) {
  287. status = AE_ALREADY_EXISTS;
  288. goto cleanup;
  289. }
  290. /* Install the handler */
  291. acpi_gbl_exception_handler = handler;
  292. cleanup:
  293. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  294. return_ACPI_STATUS(status);
  295. }
  296. ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
  297. #endif
  298. #if (!ACPI_REDUCED_HARDWARE)
  299. /*******************************************************************************
  300. *
  301. * FUNCTION: acpi_install_sci_handler
  302. *
  303. * PARAMETERS: address - Address of the handler
  304. * context - Value passed to the handler on each SCI
  305. *
  306. * RETURN: Status
  307. *
  308. * DESCRIPTION: Install a handler for a System Control Interrupt.
  309. *
  310. ******************************************************************************/
  311. acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
  312. {
  313. struct acpi_sci_handler_info *new_sci_handler;
  314. struct acpi_sci_handler_info *sci_handler;
  315. acpi_cpu_flags flags;
  316. acpi_status status;
  317. ACPI_FUNCTION_TRACE(acpi_install_sci_handler);
  318. if (!address) {
  319. return_ACPI_STATUS(AE_BAD_PARAMETER);
  320. }
  321. /* Allocate and init a handler object */
  322. new_sci_handler = ACPI_ALLOCATE(sizeof(struct acpi_sci_handler_info));
  323. if (!new_sci_handler) {
  324. return_ACPI_STATUS(AE_NO_MEMORY);
  325. }
  326. new_sci_handler->address = address;
  327. new_sci_handler->context = context;
  328. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  329. if (ACPI_FAILURE(status)) {
  330. goto exit;
  331. }
  332. /* Lock list during installation */
  333. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  334. sci_handler = acpi_gbl_sci_handler_list;
  335. /* Ensure handler does not already exist */
  336. while (sci_handler) {
  337. if (address == sci_handler->address) {
  338. status = AE_ALREADY_EXISTS;
  339. goto unlock_and_exit;
  340. }
  341. sci_handler = sci_handler->next;
  342. }
  343. /* Install the new handler into the global list (at head) */
  344. new_sci_handler->next = acpi_gbl_sci_handler_list;
  345. acpi_gbl_sci_handler_list = new_sci_handler;
  346. unlock_and_exit:
  347. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  348. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  349. exit:
  350. if (ACPI_FAILURE(status)) {
  351. ACPI_FREE(new_sci_handler);
  352. }
  353. return_ACPI_STATUS(status);
  354. }
  355. ACPI_EXPORT_SYMBOL(acpi_install_sci_handler)
  356. /*******************************************************************************
  357. *
  358. * FUNCTION: acpi_remove_sci_handler
  359. *
  360. * PARAMETERS: address - Address of the handler
  361. *
  362. * RETURN: Status
  363. *
  364. * DESCRIPTION: Remove a handler for a System Control Interrupt.
  365. *
  366. ******************************************************************************/
  367. acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
  368. {
  369. struct acpi_sci_handler_info *prev_sci_handler;
  370. struct acpi_sci_handler_info *next_sci_handler;
  371. acpi_cpu_flags flags;
  372. acpi_status status;
  373. ACPI_FUNCTION_TRACE(acpi_remove_sci_handler);
  374. if (!address) {
  375. return_ACPI_STATUS(AE_BAD_PARAMETER);
  376. }
  377. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  378. if (ACPI_FAILURE(status)) {
  379. return_ACPI_STATUS(status);
  380. }
  381. /* Remove the SCI handler with lock */
  382. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  383. prev_sci_handler = NULL;
  384. next_sci_handler = acpi_gbl_sci_handler_list;
  385. while (next_sci_handler) {
  386. if (next_sci_handler->address == address) {
  387. /* Unlink and free the SCI handler info block */
  388. if (prev_sci_handler) {
  389. prev_sci_handler->next = next_sci_handler->next;
  390. } else {
  391. acpi_gbl_sci_handler_list =
  392. next_sci_handler->next;
  393. }
  394. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  395. ACPI_FREE(next_sci_handler);
  396. goto unlock_and_exit;
  397. }
  398. prev_sci_handler = next_sci_handler;
  399. next_sci_handler = next_sci_handler->next;
  400. }
  401. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  402. status = AE_NOT_EXIST;
  403. unlock_and_exit:
  404. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  405. return_ACPI_STATUS(status);
  406. }
  407. ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler)
  408. /*******************************************************************************
  409. *
  410. * FUNCTION: acpi_install_global_event_handler
  411. *
  412. * PARAMETERS: handler - Pointer to the global event handler function
  413. * context - Value passed to the handler on each event
  414. *
  415. * RETURN: Status
  416. *
  417. * DESCRIPTION: Saves the pointer to the handler function. The global handler
  418. * is invoked upon each incoming GPE and Fixed Event. It is
  419. * invoked at interrupt level at the time of the event dispatch.
  420. * Can be used to update event counters, etc.
  421. *
  422. ******************************************************************************/
  423. acpi_status
  424. acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
  425. {
  426. acpi_status status;
  427. ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
  428. /* Parameter validation */
  429. if (!handler) {
  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. /* Don't allow two handlers. */
  437. if (acpi_gbl_global_event_handler) {
  438. status = AE_ALREADY_EXISTS;
  439. goto cleanup;
  440. }
  441. acpi_gbl_global_event_handler = handler;
  442. acpi_gbl_global_event_handler_context = context;
  443. cleanup:
  444. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  445. return_ACPI_STATUS(status);
  446. }
  447. ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
  448. /*******************************************************************************
  449. *
  450. * FUNCTION: acpi_install_fixed_event_handler
  451. *
  452. * PARAMETERS: event - Event type to enable.
  453. * handler - Pointer to the handler function for the
  454. * event
  455. * context - Value passed to the handler on each GPE
  456. *
  457. * RETURN: Status
  458. *
  459. * DESCRIPTION: Saves the pointer to the handler function and then enables the
  460. * event.
  461. *
  462. ******************************************************************************/
  463. acpi_status
  464. acpi_install_fixed_event_handler(u32 event,
  465. acpi_event_handler handler, void *context)
  466. {
  467. acpi_status status;
  468. ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
  469. /* Parameter validation */
  470. if (event > ACPI_EVENT_MAX) {
  471. return_ACPI_STATUS(AE_BAD_PARAMETER);
  472. }
  473. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  474. if (ACPI_FAILURE(status)) {
  475. return_ACPI_STATUS(status);
  476. }
  477. /* Do not allow multiple handlers */
  478. if (acpi_gbl_fixed_event_handlers[event].handler) {
  479. status = AE_ALREADY_EXISTS;
  480. goto cleanup;
  481. }
  482. /* Install the handler before enabling the event */
  483. acpi_gbl_fixed_event_handlers[event].handler = handler;
  484. acpi_gbl_fixed_event_handlers[event].context = context;
  485. status = acpi_clear_event(event);
  486. if (ACPI_SUCCESS(status))
  487. status = acpi_enable_event(event, 0);
  488. if (ACPI_FAILURE(status)) {
  489. ACPI_WARNING((AE_INFO,
  490. "Could not enable fixed event - %s (%u)",
  491. acpi_ut_get_event_name(event), event));
  492. /* Remove the handler */
  493. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  494. acpi_gbl_fixed_event_handlers[event].context = NULL;
  495. } else {
  496. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  497. "Enabled fixed event %s (%X), Handler=%p\n",
  498. acpi_ut_get_event_name(event), event,
  499. handler));
  500. }
  501. cleanup:
  502. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  503. return_ACPI_STATUS(status);
  504. }
  505. ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
  506. /*******************************************************************************
  507. *
  508. * FUNCTION: acpi_remove_fixed_event_handler
  509. *
  510. * PARAMETERS: event - Event type to disable.
  511. * handler - Address of the handler
  512. *
  513. * RETURN: Status
  514. *
  515. * DESCRIPTION: Disables the event and unregisters the event handler.
  516. *
  517. ******************************************************************************/
  518. acpi_status
  519. acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
  520. {
  521. acpi_status status = AE_OK;
  522. ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
  523. /* Parameter validation */
  524. if (event > ACPI_EVENT_MAX) {
  525. return_ACPI_STATUS(AE_BAD_PARAMETER);
  526. }
  527. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  528. if (ACPI_FAILURE(status)) {
  529. return_ACPI_STATUS(status);
  530. }
  531. /* Disable the event before removing the handler */
  532. status = acpi_disable_event(event, 0);
  533. /* Always Remove the handler */
  534. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  535. acpi_gbl_fixed_event_handlers[event].context = NULL;
  536. if (ACPI_FAILURE(status)) {
  537. ACPI_WARNING((AE_INFO,
  538. "Could not disable fixed event - %s (%u)",
  539. acpi_ut_get_event_name(event), event));
  540. } else {
  541. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  542. "Disabled fixed event - %s (%X)\n",
  543. acpi_ut_get_event_name(event), event));
  544. }
  545. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  546. return_ACPI_STATUS(status);
  547. }
  548. ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
  549. /*******************************************************************************
  550. *
  551. * FUNCTION: acpi_ev_install_gpe_handler
  552. *
  553. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  554. * defined GPEs)
  555. * gpe_number - The GPE number within the GPE block
  556. * type - Whether this GPE should be treated as an
  557. * edge- or level-triggered interrupt.
  558. * is_raw_handler - Whether this GPE should be handled using
  559. * the special GPE handler mode.
  560. * address - Address of the handler
  561. * context - Value passed to the handler on each GPE
  562. *
  563. * RETURN: Status
  564. *
  565. * DESCRIPTION: Internal function to install a handler for a General Purpose
  566. * Event.
  567. *
  568. ******************************************************************************/
  569. static acpi_status
  570. acpi_ev_install_gpe_handler(acpi_handle gpe_device,
  571. u32 gpe_number,
  572. u32 type,
  573. u8 is_raw_handler,
  574. acpi_gpe_handler address, void *context)
  575. {
  576. struct acpi_gpe_event_info *gpe_event_info;
  577. struct acpi_gpe_handler_info *handler;
  578. acpi_status status;
  579. acpi_cpu_flags flags;
  580. ACPI_FUNCTION_TRACE(ev_install_gpe_handler);
  581. /* Parameter validation */
  582. if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
  583. return_ACPI_STATUS(AE_BAD_PARAMETER);
  584. }
  585. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  586. if (ACPI_FAILURE(status)) {
  587. return_ACPI_STATUS(status);
  588. }
  589. /* Allocate and init handler object (before lock) */
  590. handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
  591. if (!handler) {
  592. status = AE_NO_MEMORY;
  593. goto unlock_and_exit;
  594. }
  595. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  596. /* Ensure that we have a valid GPE number */
  597. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  598. if (!gpe_event_info) {
  599. status = AE_BAD_PARAMETER;
  600. goto free_and_exit;
  601. }
  602. /* Make sure that there isn't a handler there already */
  603. if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
  604. ACPI_GPE_DISPATCH_HANDLER) ||
  605. (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
  606. ACPI_GPE_DISPATCH_RAW_HANDLER)) {
  607. status = AE_ALREADY_EXISTS;
  608. goto free_and_exit;
  609. }
  610. handler->address = address;
  611. handler->context = context;
  612. handler->method_node = gpe_event_info->dispatch.method_node;
  613. handler->original_flags = (u8)(gpe_event_info->flags &
  614. (ACPI_GPE_XRUPT_TYPE_MASK |
  615. ACPI_GPE_DISPATCH_MASK));
  616. /*
  617. * If the GPE is associated with a method, it may have been enabled
  618. * automatically during initialization, in which case it has to be
  619. * disabled now to avoid spurious execution of the handler.
  620. */
  621. if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
  622. ACPI_GPE_DISPATCH_METHOD) ||
  623. (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
  624. ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) {
  625. handler->originally_enabled = TRUE;
  626. (void)acpi_ev_remove_gpe_reference(gpe_event_info);
  627. /* Sanity check of original type against new type */
  628. if (type !=
  629. (u32)(gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK)) {
  630. ACPI_WARNING((AE_INFO,
  631. "GPE type mismatch (level/edge)"));
  632. }
  633. }
  634. /* Install the handler */
  635. gpe_event_info->dispatch.handler = handler;
  636. /* Setup up dispatch flags to indicate handler (vs. method/notify) */
  637. gpe_event_info->flags &=
  638. ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  639. gpe_event_info->flags |=
  640. (u8)(type |
  641. (is_raw_handler ? ACPI_GPE_DISPATCH_RAW_HANDLER :
  642. ACPI_GPE_DISPATCH_HANDLER));
  643. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  644. unlock_and_exit:
  645. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  646. return_ACPI_STATUS(status);
  647. free_and_exit:
  648. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  649. ACPI_FREE(handler);
  650. goto unlock_and_exit;
  651. }
  652. /*******************************************************************************
  653. *
  654. * FUNCTION: acpi_install_gpe_handler
  655. *
  656. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  657. * defined GPEs)
  658. * gpe_number - The GPE number within the GPE block
  659. * type - Whether this GPE should be treated as an
  660. * edge- or level-triggered interrupt.
  661. * address - Address of the handler
  662. * context - Value passed to the handler on each GPE
  663. *
  664. * RETURN: Status
  665. *
  666. * DESCRIPTION: Install a handler for a General Purpose Event.
  667. *
  668. ******************************************************************************/
  669. acpi_status
  670. acpi_install_gpe_handler(acpi_handle gpe_device,
  671. u32 gpe_number,
  672. u32 type, acpi_gpe_handler address, void *context)
  673. {
  674. acpi_status status;
  675. ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
  676. status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type,
  677. FALSE, address, context);
  678. return_ACPI_STATUS(status);
  679. }
  680. ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
  681. /*******************************************************************************
  682. *
  683. * FUNCTION: acpi_install_gpe_raw_handler
  684. *
  685. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  686. * defined GPEs)
  687. * gpe_number - The GPE number within the GPE block
  688. * type - Whether this GPE should be treated as an
  689. * edge- or level-triggered interrupt.
  690. * address - Address of the handler
  691. * context - Value passed to the handler on each GPE
  692. *
  693. * RETURN: Status
  694. *
  695. * DESCRIPTION: Install a handler for a General Purpose Event.
  696. *
  697. ******************************************************************************/
  698. acpi_status
  699. acpi_install_gpe_raw_handler(acpi_handle gpe_device,
  700. u32 gpe_number,
  701. u32 type, acpi_gpe_handler address, void *context)
  702. {
  703. acpi_status status;
  704. ACPI_FUNCTION_TRACE(acpi_install_gpe_raw_handler);
  705. status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type,
  706. TRUE, address, context);
  707. return_ACPI_STATUS(status);
  708. }
  709. ACPI_EXPORT_SYMBOL(acpi_install_gpe_raw_handler)
  710. /*******************************************************************************
  711. *
  712. * FUNCTION: acpi_remove_gpe_handler
  713. *
  714. * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
  715. * defined GPEs)
  716. * gpe_number - The event to remove a handler
  717. * address - Address of the handler
  718. *
  719. * RETURN: Status
  720. *
  721. * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
  722. *
  723. ******************************************************************************/
  724. acpi_status
  725. acpi_remove_gpe_handler(acpi_handle gpe_device,
  726. u32 gpe_number, acpi_gpe_handler address)
  727. {
  728. struct acpi_gpe_event_info *gpe_event_info;
  729. struct acpi_gpe_handler_info *handler;
  730. acpi_status status;
  731. acpi_cpu_flags flags;
  732. ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
  733. /* Parameter validation */
  734. if (!address) {
  735. return_ACPI_STATUS(AE_BAD_PARAMETER);
  736. }
  737. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  738. if (ACPI_FAILURE(status)) {
  739. return_ACPI_STATUS(status);
  740. }
  741. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  742. /* Ensure that we have a valid GPE number */
  743. gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
  744. if (!gpe_event_info) {
  745. status = AE_BAD_PARAMETER;
  746. goto unlock_and_exit;
  747. }
  748. /* Make sure that a handler is indeed installed */
  749. if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
  750. ACPI_GPE_DISPATCH_HANDLER) &&
  751. (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
  752. ACPI_GPE_DISPATCH_RAW_HANDLER)) {
  753. status = AE_NOT_EXIST;
  754. goto unlock_and_exit;
  755. }
  756. /* Make sure that the installed handler is the same */
  757. if (gpe_event_info->dispatch.handler->address != address) {
  758. status = AE_BAD_PARAMETER;
  759. goto unlock_and_exit;
  760. }
  761. /* Remove the handler */
  762. handler = gpe_event_info->dispatch.handler;
  763. gpe_event_info->dispatch.handler = NULL;
  764. /* Restore Method node (if any), set dispatch flags */
  765. gpe_event_info->dispatch.method_node = handler->method_node;
  766. gpe_event_info->flags &=
  767. ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  768. gpe_event_info->flags |= handler->original_flags;
  769. /*
  770. * If the GPE was previously associated with a method and it was
  771. * enabled, it should be enabled at this point to restore the
  772. * post-initialization configuration.
  773. */
  774. if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
  775. ACPI_GPE_DISPATCH_METHOD) ||
  776. (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
  777. ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) {
  778. (void)acpi_ev_add_gpe_reference(gpe_event_info, FALSE);
  779. if (ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
  780. /* Poll edge triggered GPEs to handle existing events */
  781. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  782. (void)acpi_ev_detect_gpe(gpe_device, gpe_event_info,
  783. gpe_number);
  784. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  785. }
  786. }
  787. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  788. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  789. /* Make sure all deferred GPE tasks are completed */
  790. acpi_os_wait_events_complete();
  791. /* Now we can free the handler object */
  792. ACPI_FREE(handler);
  793. return_ACPI_STATUS(status);
  794. unlock_and_exit:
  795. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  796. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  797. return_ACPI_STATUS(status);
  798. }
  799. ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
  800. /*******************************************************************************
  801. *
  802. * FUNCTION: acpi_acquire_global_lock
  803. *
  804. * PARAMETERS: timeout - How long the caller is willing to wait
  805. * handle - Where the handle to the lock is returned
  806. * (if acquired)
  807. *
  808. * RETURN: Status
  809. *
  810. * DESCRIPTION: Acquire the ACPI Global Lock
  811. *
  812. * Note: Allows callers with the same thread ID to acquire the global lock
  813. * multiple times. In other words, externally, the behavior of the global lock
  814. * is identical to an AML mutex. On the first acquire, a new handle is
  815. * returned. On any subsequent calls to acquire by the same thread, the same
  816. * handle is returned.
  817. *
  818. ******************************************************************************/
  819. acpi_status acpi_acquire_global_lock(u16 timeout, u32 *handle)
  820. {
  821. acpi_status status;
  822. if (!handle) {
  823. return (AE_BAD_PARAMETER);
  824. }
  825. /* Must lock interpreter to prevent race conditions */
  826. acpi_ex_enter_interpreter();
  827. status = acpi_ex_acquire_mutex_object(timeout,
  828. acpi_gbl_global_lock_mutex,
  829. acpi_os_get_thread_id());
  830. if (ACPI_SUCCESS(status)) {
  831. /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
  832. *handle = acpi_gbl_global_lock_handle;
  833. }
  834. acpi_ex_exit_interpreter();
  835. return (status);
  836. }
  837. ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
  838. /*******************************************************************************
  839. *
  840. * FUNCTION: acpi_release_global_lock
  841. *
  842. * PARAMETERS: handle - Returned from acpi_acquire_global_lock
  843. *
  844. * RETURN: Status
  845. *
  846. * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
  847. *
  848. ******************************************************************************/
  849. acpi_status acpi_release_global_lock(u32 handle)
  850. {
  851. acpi_status status;
  852. if (!handle || (handle != acpi_gbl_global_lock_handle)) {
  853. return (AE_NOT_ACQUIRED);
  854. }
  855. status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
  856. return (status);
  857. }
  858. ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
  859. #endif /* !ACPI_REDUCED_HARDWARE */