evgpeblk.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: evgpeblk - GPE block creation and initialization.
  5. *
  6. * Copyright (C) 2000 - 2018, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acevents.h"
  12. #include "acnamesp.h"
  13. #define _COMPONENT ACPI_EVENTS
  14. ACPI_MODULE_NAME("evgpeblk")
  15. #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
  16. /* Local prototypes */
  17. static acpi_status
  18. acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
  19. u32 interrupt_number);
  20. static acpi_status
  21. acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block);
  22. /*******************************************************************************
  23. *
  24. * FUNCTION: acpi_ev_install_gpe_block
  25. *
  26. * PARAMETERS: gpe_block - New GPE block
  27. * interrupt_number - Xrupt to be associated with this
  28. * GPE block
  29. *
  30. * RETURN: Status
  31. *
  32. * DESCRIPTION: Install new GPE block with mutex support
  33. *
  34. ******************************************************************************/
  35. static acpi_status
  36. acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
  37. u32 interrupt_number)
  38. {
  39. struct acpi_gpe_block_info *next_gpe_block;
  40. struct acpi_gpe_xrupt_info *gpe_xrupt_block;
  41. acpi_status status;
  42. acpi_cpu_flags flags;
  43. ACPI_FUNCTION_TRACE(ev_install_gpe_block);
  44. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  45. if (ACPI_FAILURE(status)) {
  46. return_ACPI_STATUS(status);
  47. }
  48. status =
  49. acpi_ev_get_gpe_xrupt_block(interrupt_number, &gpe_xrupt_block);
  50. if (ACPI_FAILURE(status)) {
  51. goto unlock_and_exit;
  52. }
  53. /* Install the new block at the end of the list with lock */
  54. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  55. if (gpe_xrupt_block->gpe_block_list_head) {
  56. next_gpe_block = gpe_xrupt_block->gpe_block_list_head;
  57. while (next_gpe_block->next) {
  58. next_gpe_block = next_gpe_block->next;
  59. }
  60. next_gpe_block->next = gpe_block;
  61. gpe_block->previous = next_gpe_block;
  62. } else {
  63. gpe_xrupt_block->gpe_block_list_head = gpe_block;
  64. }
  65. gpe_block->xrupt_block = gpe_xrupt_block;
  66. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  67. unlock_and_exit:
  68. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  69. return_ACPI_STATUS(status);
  70. }
  71. /*******************************************************************************
  72. *
  73. * FUNCTION: acpi_ev_delete_gpe_block
  74. *
  75. * PARAMETERS: gpe_block - Existing GPE block
  76. *
  77. * RETURN: Status
  78. *
  79. * DESCRIPTION: Remove a GPE block
  80. *
  81. ******************************************************************************/
  82. acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
  83. {
  84. acpi_status status;
  85. acpi_cpu_flags flags;
  86. ACPI_FUNCTION_TRACE(ev_install_gpe_block);
  87. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  88. if (ACPI_FAILURE(status)) {
  89. return_ACPI_STATUS(status);
  90. }
  91. /* Disable all GPEs in this block */
  92. status =
  93. acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL);
  94. if (!gpe_block->previous && !gpe_block->next) {
  95. /* This is the last gpe_block on this interrupt */
  96. status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block);
  97. if (ACPI_FAILURE(status)) {
  98. goto unlock_and_exit;
  99. }
  100. } else {
  101. /* Remove the block on this interrupt with lock */
  102. flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
  103. if (gpe_block->previous) {
  104. gpe_block->previous->next = gpe_block->next;
  105. } else {
  106. gpe_block->xrupt_block->gpe_block_list_head =
  107. gpe_block->next;
  108. }
  109. if (gpe_block->next) {
  110. gpe_block->next->previous = gpe_block->previous;
  111. }
  112. acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
  113. }
  114. acpi_current_gpe_count -= gpe_block->gpe_count;
  115. /* Free the gpe_block */
  116. ACPI_FREE(gpe_block->register_info);
  117. ACPI_FREE(gpe_block->event_info);
  118. ACPI_FREE(gpe_block);
  119. unlock_and_exit:
  120. status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  121. return_ACPI_STATUS(status);
  122. }
  123. /*******************************************************************************
  124. *
  125. * FUNCTION: acpi_ev_create_gpe_info_blocks
  126. *
  127. * PARAMETERS: gpe_block - New GPE block
  128. *
  129. * RETURN: Status
  130. *
  131. * DESCRIPTION: Create the register_info and event_info blocks for this GPE block
  132. *
  133. ******************************************************************************/
  134. static acpi_status
  135. acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
  136. {
  137. struct acpi_gpe_register_info *gpe_register_info = NULL;
  138. struct acpi_gpe_event_info *gpe_event_info = NULL;
  139. struct acpi_gpe_event_info *this_event;
  140. struct acpi_gpe_register_info *this_register;
  141. u32 i;
  142. u32 j;
  143. acpi_status status;
  144. ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks);
  145. /* Allocate the GPE register information block */
  146. gpe_register_info = ACPI_ALLOCATE_ZEROED((acpi_size)gpe_block->
  147. register_count *
  148. sizeof(struct
  149. acpi_gpe_register_info));
  150. if (!gpe_register_info) {
  151. ACPI_ERROR((AE_INFO,
  152. "Could not allocate the GpeRegisterInfo table"));
  153. return_ACPI_STATUS(AE_NO_MEMORY);
  154. }
  155. /*
  156. * Allocate the GPE event_info block. There are eight distinct GPEs
  157. * per register. Initialization to zeros is sufficient.
  158. */
  159. gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size)gpe_block->gpe_count *
  160. sizeof(struct
  161. acpi_gpe_event_info));
  162. if (!gpe_event_info) {
  163. ACPI_ERROR((AE_INFO,
  164. "Could not allocate the GpeEventInfo table"));
  165. status = AE_NO_MEMORY;
  166. goto error_exit;
  167. }
  168. /* Save the new Info arrays in the GPE block */
  169. gpe_block->register_info = gpe_register_info;
  170. gpe_block->event_info = gpe_event_info;
  171. /*
  172. * Initialize the GPE Register and Event structures. A goal of these
  173. * tables is to hide the fact that there are two separate GPE register
  174. * sets in a given GPE hardware block, the status registers occupy the
  175. * first half, and the enable registers occupy the second half.
  176. */
  177. this_register = gpe_register_info;
  178. this_event = gpe_event_info;
  179. for (i = 0; i < gpe_block->register_count; i++) {
  180. /* Init the register_info for this GPE register (8 GPEs) */
  181. this_register->base_gpe_number = (u16)
  182. (gpe_block->block_base_number +
  183. (i * ACPI_GPE_REGISTER_WIDTH));
  184. this_register->status_address.address = gpe_block->address + i;
  185. this_register->enable_address.address =
  186. gpe_block->address + i + gpe_block->register_count;
  187. this_register->status_address.space_id = gpe_block->space_id;
  188. this_register->enable_address.space_id = gpe_block->space_id;
  189. this_register->status_address.bit_width =
  190. ACPI_GPE_REGISTER_WIDTH;
  191. this_register->enable_address.bit_width =
  192. ACPI_GPE_REGISTER_WIDTH;
  193. this_register->status_address.bit_offset = 0;
  194. this_register->enable_address.bit_offset = 0;
  195. /* Init the event_info for each GPE within this register */
  196. for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
  197. this_event->gpe_number =
  198. (u8) (this_register->base_gpe_number + j);
  199. this_event->register_info = this_register;
  200. this_event++;
  201. }
  202. /* Disable all GPEs within this register */
  203. status = acpi_hw_write(0x00, &this_register->enable_address);
  204. if (ACPI_FAILURE(status)) {
  205. goto error_exit;
  206. }
  207. /* Clear any pending GPE events within this register */
  208. status = acpi_hw_write(0xFF, &this_register->status_address);
  209. if (ACPI_FAILURE(status)) {
  210. goto error_exit;
  211. }
  212. this_register++;
  213. }
  214. return_ACPI_STATUS(AE_OK);
  215. error_exit:
  216. if (gpe_register_info) {
  217. ACPI_FREE(gpe_register_info);
  218. }
  219. if (gpe_event_info) {
  220. ACPI_FREE(gpe_event_info);
  221. }
  222. return_ACPI_STATUS(status);
  223. }
  224. /*******************************************************************************
  225. *
  226. * FUNCTION: acpi_ev_create_gpe_block
  227. *
  228. * PARAMETERS: gpe_device - Handle to the parent GPE block
  229. * gpe_block_address - Address and space_ID
  230. * register_count - Number of GPE register pairs in the block
  231. * gpe_block_base_number - Starting GPE number for the block
  232. * interrupt_number - H/W interrupt for the block
  233. * return_gpe_block - Where the new block descriptor is returned
  234. *
  235. * RETURN: Status
  236. *
  237. * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
  238. * the block are disabled at exit.
  239. * Note: Assumes namespace is locked.
  240. *
  241. ******************************************************************************/
  242. acpi_status
  243. acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
  244. u64 address,
  245. u8 space_id,
  246. u32 register_count,
  247. u16 gpe_block_base_number,
  248. u32 interrupt_number,
  249. struct acpi_gpe_block_info **return_gpe_block)
  250. {
  251. acpi_status status;
  252. struct acpi_gpe_block_info *gpe_block;
  253. struct acpi_gpe_walk_info walk_info;
  254. ACPI_FUNCTION_TRACE(ev_create_gpe_block);
  255. if (!register_count) {
  256. return_ACPI_STATUS(AE_OK);
  257. }
  258. /* Allocate a new GPE block */
  259. gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info));
  260. if (!gpe_block) {
  261. return_ACPI_STATUS(AE_NO_MEMORY);
  262. }
  263. /* Initialize the new GPE block */
  264. gpe_block->address = address;
  265. gpe_block->space_id = space_id;
  266. gpe_block->node = gpe_device;
  267. gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
  268. gpe_block->initialized = FALSE;
  269. gpe_block->register_count = register_count;
  270. gpe_block->block_base_number = gpe_block_base_number;
  271. /*
  272. * Create the register_info and event_info sub-structures
  273. * Note: disables and clears all GPEs in the block
  274. */
  275. status = acpi_ev_create_gpe_info_blocks(gpe_block);
  276. if (ACPI_FAILURE(status)) {
  277. ACPI_FREE(gpe_block);
  278. return_ACPI_STATUS(status);
  279. }
  280. /* Install the new block in the global lists */
  281. status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
  282. if (ACPI_FAILURE(status)) {
  283. ACPI_FREE(gpe_block->register_info);
  284. ACPI_FREE(gpe_block->event_info);
  285. ACPI_FREE(gpe_block);
  286. return_ACPI_STATUS(status);
  287. }
  288. acpi_gbl_all_gpes_initialized = FALSE;
  289. /* Find all GPE methods (_Lxx or_Exx) for this block */
  290. walk_info.gpe_block = gpe_block;
  291. walk_info.gpe_device = gpe_device;
  292. walk_info.execute_by_owner_id = FALSE;
  293. status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
  294. ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
  295. acpi_ev_match_gpe_method, NULL,
  296. &walk_info, NULL);
  297. /* Return the new block */
  298. if (return_gpe_block) {
  299. (*return_gpe_block) = gpe_block;
  300. }
  301. ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
  302. " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n",
  303. (u32)gpe_block->block_base_number,
  304. (u32)(gpe_block->block_base_number +
  305. (gpe_block->gpe_count - 1)),
  306. gpe_device->name.ascii, gpe_block->register_count,
  307. interrupt_number,
  308. interrupt_number ==
  309. acpi_gbl_FADT.sci_interrupt ? " (SCI)" : ""));
  310. /* Update global count of currently available GPEs */
  311. acpi_current_gpe_count += gpe_block->gpe_count;
  312. return_ACPI_STATUS(AE_OK);
  313. }
  314. /*******************************************************************************
  315. *
  316. * FUNCTION: acpi_ev_initialize_gpe_block
  317. *
  318. * PARAMETERS: acpi_gpe_callback
  319. *
  320. * RETURN: Status
  321. *
  322. * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
  323. * associated methods.
  324. * Note: Assumes namespace is locked.
  325. *
  326. ******************************************************************************/
  327. acpi_status
  328. acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  329. struct acpi_gpe_block_info *gpe_block,
  330. void *context)
  331. {
  332. acpi_status status;
  333. struct acpi_gpe_event_info *gpe_event_info;
  334. u32 gpe_enabled_count;
  335. u32 gpe_index;
  336. u32 i;
  337. u32 j;
  338. u8 *is_polling_needed = context;
  339. ACPI_ERROR_ONLY(u32 gpe_number);
  340. ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
  341. /*
  342. * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
  343. * any GPE blocks that have been initialized already.
  344. */
  345. if (!gpe_block || gpe_block->initialized) {
  346. return_ACPI_STATUS(AE_OK);
  347. }
  348. /*
  349. * Enable all GPEs that have a corresponding method and have the
  350. * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
  351. * must be enabled via the acpi_enable_gpe() interface.
  352. */
  353. gpe_enabled_count = 0;
  354. for (i = 0; i < gpe_block->register_count; i++) {
  355. for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
  356. /* Get the info block for this particular GPE */
  357. gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
  358. gpe_event_info = &gpe_block->event_info[gpe_index];
  359. ACPI_ERROR_ONLY(gpe_number =
  360. gpe_block->block_base_number +
  361. gpe_index);
  362. gpe_event_info->flags |= ACPI_GPE_INITIALIZED;
  363. /*
  364. * Ignore GPEs that have no corresponding _Lxx/_Exx method
  365. * and GPEs that are used for wakeup
  366. */
  367. if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
  368. ACPI_GPE_DISPATCH_METHOD)
  369. || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
  370. continue;
  371. }
  372. status = acpi_ev_add_gpe_reference(gpe_event_info);
  373. if (ACPI_FAILURE(status)) {
  374. ACPI_EXCEPTION((AE_INFO, status,
  375. "Could not enable GPE 0x%02X",
  376. gpe_number));
  377. continue;
  378. }
  379. gpe_event_info->flags |= ACPI_GPE_AUTO_ENABLED;
  380. if (is_polling_needed &&
  381. ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
  382. *is_polling_needed = TRUE;
  383. }
  384. gpe_enabled_count++;
  385. }
  386. }
  387. if (gpe_enabled_count) {
  388. ACPI_INFO(("Enabled %u GPEs in block %02X to %02X",
  389. gpe_enabled_count, (u32)gpe_block->block_base_number,
  390. (u32)(gpe_block->block_base_number +
  391. (gpe_block->gpe_count - 1))));
  392. }
  393. gpe_block->initialized = TRUE;
  394. return_ACPI_STATUS(AE_OK);
  395. }
  396. #endif /* !ACPI_REDUCED_HARDWARE */