evxface.c 28 KB

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