aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evgpeblk.c
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2010-04-06 02:52:37 -0400
committerLen Brown <len.brown@intel.com>2010-04-20 10:43:16 -0400
commit0f849d2cc6863c7874889ea60a871fb71399dd3f (patch)
treec8c14ac12dfc92c7147a049e5374d3a9036247b7 /drivers/acpi/acpica/evgpeblk.c
parentaa2110cb1a7510f9b834adfb39b05d4843a35d35 (diff)
ACPICA: Minimize the differences between linux GPE code and ACPICA code base
We have ported Rafael's major GPE changes (ACPI: Use GPE reference counting to support shared GPEs) into ACPICA code base. But the port and Rafael's original patch have some differences, so we made below patch to make linux GPE code consistent with ACPICA code base. Most changes are about comments and coding styles. Other noticeable changes are based on: Rafael: Reduce code duplication related to GPE lookup https://patchwork.kernel.org/patch/86237/ Rafael: Always use the same lock for GPE locking https://patchwork.kernel.org/patch/90471/ A new field gpe_count in struct acpi_gpe_block_info to record the number of individual GPEs in block. Rename acpi_ev_save_method_info to acpi_ev_match_gpe_method. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Robert Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/evgpeblk.c')
-rw-r--r--drivers/acpi/acpica/evgpeblk.c143
1 files changed, 76 insertions, 67 deletions
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index fa47e3522ab..85ded1f2540 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -51,7 +51,7 @@ ACPI_MODULE_NAME("evgpeblk")
51 51
52/* Local prototypes */ 52/* Local prototypes */
53static acpi_status 53static acpi_status
54acpi_ev_save_method_info(acpi_handle obj_handle, 54acpi_ev_match_gpe_method(acpi_handle obj_handle,
55 u32 level, void *obj_desc, void **return_value); 55 u32 level, void *obj_desc, void **return_value);
56 56
57static acpi_status 57static acpi_status
@@ -104,9 +104,7 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
104 104
105 while (gpe_block) { 105 while (gpe_block) {
106 if ((&gpe_block->event_info[0] <= gpe_event_info) && 106 if ((&gpe_block->event_info[0] <= gpe_event_info) &&
107 (&gpe_block->event_info[((acpi_size) 107 (&gpe_block->event_info[gpe_block->gpe_count] >
108 gpe_block->
109 register_count) * 8] >
110 gpe_event_info)) { 108 gpe_event_info)) {
111 return (TRUE); 109 return (TRUE);
112 } 110 }
@@ -229,7 +227,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
229 227
230/******************************************************************************* 228/*******************************************************************************
231 * 229 *
232 * FUNCTION: acpi_ev_save_method_info 230 * FUNCTION: acpi_ev_match_gpe_method
233 * 231 *
234 * PARAMETERS: Callback from walk_namespace 232 * PARAMETERS: Callback from walk_namespace
235 * 233 *
@@ -241,8 +239,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
241 * information for quick lookup during GPE dispatch 239 * information for quick lookup during GPE dispatch
242 * 240 *
243 * The name of each GPE control method is of the form: 241 * The name of each GPE control method is of the form:
244 * "_Lxx" or "_Exx" 242 * "_Lxx" or "_Exx", where:
245 * Where:
246 * L - means that the GPE is level triggered 243 * L - means that the GPE is level triggered
247 * E - means that the GPE is edge triggered 244 * E - means that the GPE is edge triggered
248 * xx - is the GPE number [in HEX] 245 * xx - is the GPE number [in HEX]
@@ -250,9 +247,11 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
250 ******************************************************************************/ 247 ******************************************************************************/
251 248
252static acpi_status 249static acpi_status
253acpi_ev_save_method_info(acpi_handle obj_handle, 250acpi_ev_match_gpe_method(acpi_handle obj_handle,
254 u32 level, void *obj_desc, void **return_value) 251 u32 level, void *obj_desc, void **return_value)
255{ 252{
253 struct acpi_namespace_node *method_node =
254 ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
256 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc; 255 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc;
257 struct acpi_gpe_event_info *gpe_event_info; 256 struct acpi_gpe_event_info *gpe_event_info;
258 u32 gpe_number; 257 u32 gpe_number;
@@ -262,21 +261,25 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
262 ACPI_FUNCTION_TRACE(ev_save_method_info); 261 ACPI_FUNCTION_TRACE(ev_save_method_info);
263 262
264 /* 263 /*
265 * _Lxx and _Exx GPE method support 264 * Match and decode the _Lxx and _Exx GPE method names
266 * 265 *
267 * 1) Extract the name from the object and convert to a string 266 * 1) Extract the method name and null terminate it
268 */ 267 */
269 ACPI_MOVE_32_TO_32(name, 268 ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
270 &((struct acpi_namespace_node *)obj_handle)->name.
271 integer);
272 name[ACPI_NAME_SIZE] = 0; 269 name[ACPI_NAME_SIZE] = 0;
273 270
271 /* 2) Name must begin with an underscore */
272
273 if (name[0] != '_') {
274 return_ACPI_STATUS(AE_OK); /* Ignore this method */
275 }
276
274 /* 277 /*
275 * 2) Edge/Level determination is based on the 2nd character 278 * 3) Edge/Level determination is based on the 2nd character
276 * of the method name 279 * of the method name
277 * 280 *
278 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE 281 * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
279 * if a _PRW object is found that points to this GPE. 282 * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
280 */ 283 */
281 switch (name[1]) { 284 switch (name[1]) {
282 case 'L': 285 case 'L':
@@ -288,7 +291,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
288 break; 291 break;
289 292
290 default: 293 default:
291 /* Unknown method type, just ignore it! */ 294 /* Unknown method type, just ignore it */
292 295
293 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 296 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
294 "Ignoring unknown GPE method type: %s " 297 "Ignoring unknown GPE method type: %s "
@@ -296,7 +299,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
296 return_ACPI_STATUS(AE_OK); 299 return_ACPI_STATUS(AE_OK);
297 } 300 }
298 301
299 /* Convert the last two characters of the name to the GPE Number */ 302 /* 4) The last two characters of the name are the hex GPE Number */
300 303
301 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16); 304 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16);
302 if (gpe_number == ACPI_UINT32_MAX) { 305 if (gpe_number == ACPI_UINT32_MAX) {
@@ -311,28 +314,22 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
311 314
312 /* Ensure that we have a valid GPE number for this GPE block */ 315 /* Ensure that we have a valid GPE number for this GPE block */
313 316
314 if ((gpe_number < gpe_block->block_base_number) || 317 gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
315 (gpe_number >= (gpe_block->block_base_number + 318 if (!gpe_event_info) {
316 (gpe_block->register_count * 8)))) {
317 /* 319 /*
318 * Not valid for this GPE block, just ignore it. However, it may be 320 * This gpe_number is not valid for this GPE block, just ignore it.
319 * valid for a different GPE block, since GPE0 and GPE1 methods both 321 * However, it may be valid for a different GPE block, since GPE0
320 * appear under \_GPE. 322 * and GPE1 methods both appear under \_GPE.
321 */ 323 */
322 return_ACPI_STATUS(AE_OK); 324 return_ACPI_STATUS(AE_OK);
323 } 325 }
324 326
325 /* 327 /*
326 * Now we can add this information to the gpe_event_info block for use 328 * Add the GPE information from above to the gpe_event_info block for
327 * during dispatch of this GPE. 329 * use during dispatch of this GPE.
328 */ 330 */
329 gpe_event_info = 331 gpe_event_info->flags = (u8)(type | ACPI_GPE_DISPATCH_METHOD);
330 &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; 332 gpe_event_info->dispatch.method_node = method_node;
331
332 gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD);
333
334 gpe_event_info->dispatch.method_node =
335 (struct acpi_namespace_node *)obj_handle;
336 333
337 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 334 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
338 "Registered GPE method %s as GPE number 0x%.2X\n", 335 "Registered GPE method %s as GPE number 0x%.2X\n",
@@ -351,7 +348,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
351 * 348 *
352 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a 349 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
353 * Device. Run the _PRW method. If present, extract the GPE 350 * Device. Run the _PRW method. If present, extract the GPE
354 * number and mark the GPE as a WAKE GPE. 351 * number and mark the GPE as a CAN_WAKE GPE.
355 * 352 *
356 ******************************************************************************/ 353 ******************************************************************************/
357 354
@@ -377,7 +374,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
377 ACPI_BTYPE_PACKAGE, &pkg_desc); 374 ACPI_BTYPE_PACKAGE, &pkg_desc);
378 if (ACPI_FAILURE(status)) { 375 if (ACPI_FAILURE(status)) {
379 376
380 /* Ignore all errors from _PRW, we don't want to abort the subsystem */ 377 /* Ignore all errors from _PRW, we don't want to abort the walk */
381 378
382 return_ACPI_STATUS(AE_OK); 379 return_ACPI_STATUS(AE_OK);
383 } 380 }
@@ -439,13 +436,13 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
439 * 2) The GPE index(number) is within the range of the Gpe Block 436 * 2) The GPE index(number) is within the range of the Gpe Block
440 * associated with the GPE device. 437 * associated with the GPE device.
441 */ 438 */
442 if ((gpe_device == target_gpe_device) && 439 if (gpe_device != target_gpe_device) {
443 (gpe_number >= gpe_block->block_base_number) && 440 goto cleanup;
444 (gpe_number < gpe_block->block_base_number + 441 }
445 (gpe_block->register_count * 8))) { 442
446 gpe_event_info = &gpe_block->event_info[gpe_number - 443 gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
447 gpe_block-> 444 if (gpe_event_info) {
448 block_base_number]; 445 /* This GPE can wake the system */
449 446
450 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 447 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
451 } 448 }
@@ -705,8 +702,7 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
705 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 702 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
706 } 703 }
707 704
708 acpi_current_gpe_count -= 705 acpi_current_gpe_count -= gpe_block->gpe_count;
709 gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH;
710 706
711 /* Free the gpe_block */ 707 /* Free the gpe_block */
712 708
@@ -760,9 +756,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
760 * Allocate the GPE event_info block. There are eight distinct GPEs 756 * Allocate the GPE event_info block. There are eight distinct GPEs
761 * per register. Initialization to zeros is sufficient. 757 * per register. Initialization to zeros is sufficient.
762 */ 758 */
763 gpe_event_info = ACPI_ALLOCATE_ZEROED(((acpi_size) gpe_block-> 759 gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->gpe_count *
764 register_count *
765 ACPI_GPE_REGISTER_WIDTH) *
766 sizeof(struct 760 sizeof(struct
767 acpi_gpe_event_info)); 761 acpi_gpe_event_info));
768 if (!gpe_event_info) { 762 if (!gpe_event_info) {
@@ -897,6 +891,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
897 /* Initialize the new GPE block */ 891 /* Initialize the new GPE block */
898 892
899 gpe_block->node = gpe_device; 893 gpe_block->node = gpe_device;
894 gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
900 gpe_block->register_count = register_count; 895 gpe_block->register_count = register_count;
901 gpe_block->block_base_number = gpe_block_base_number; 896 gpe_block->block_base_number = gpe_block_base_number;
902 897
@@ -925,7 +920,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
925 920
926 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, 921 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
927 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 922 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
928 acpi_ev_save_method_info, NULL, 923 acpi_ev_match_gpe_method, NULL,
929 gpe_block, NULL); 924 gpe_block, NULL);
930 925
931 /* Return the new block */ 926 /* Return the new block */
@@ -938,14 +933,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
938 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", 933 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
939 (u32) gpe_block->block_base_number, 934 (u32) gpe_block->block_base_number,
940 (u32) (gpe_block->block_base_number + 935 (u32) (gpe_block->block_base_number +
941 ((gpe_block->register_count * 936 (gpe_block->gpe_count - 1)),
942 ACPI_GPE_REGISTER_WIDTH) - 1)),
943 gpe_device->name.ascii, gpe_block->register_count, 937 gpe_device->name.ascii, gpe_block->register_count,
944 interrupt_number)); 938 interrupt_number));
945 939
946 /* Update global count of currently available GPEs */ 940 /* Update global count of currently available GPEs */
947 941
948 acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH; 942 acpi_current_gpe_count += gpe_block->gpe_count;
949 return_ACPI_STATUS(AE_OK); 943 return_ACPI_STATUS(AE_OK);
950} 944}
951 945
@@ -969,10 +963,13 @@ acpi_status
969acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 963acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
970 struct acpi_gpe_block_info *gpe_block) 964 struct acpi_gpe_block_info *gpe_block)
971{ 965{
966 acpi_status status;
972 struct acpi_gpe_event_info *gpe_event_info; 967 struct acpi_gpe_event_info *gpe_event_info;
973 struct acpi_gpe_walk_info gpe_info; 968 struct acpi_gpe_walk_info gpe_info;
974 u32 wake_gpe_count; 969 u32 wake_gpe_count;
975 u32 gpe_enabled_count; 970 u32 gpe_enabled_count;
971 u32 gpe_index;
972 u32 gpe_number;
976 u32 i; 973 u32 i;
977 u32 j; 974 u32 j;
978 975
@@ -998,50 +995,62 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
998 gpe_info.gpe_block = gpe_block; 995 gpe_info.gpe_block = gpe_block;
999 gpe_info.gpe_device = gpe_device; 996 gpe_info.gpe_device = gpe_device;
1000 997
1001 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 998 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1002 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 999 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1003 acpi_ev_match_prw_and_gpe, NULL, 1000 acpi_ev_match_prw_and_gpe, NULL,
1004 &gpe_info, NULL); 1001 &gpe_info, NULL);
1002 if (ACPI_FAILURE(status)) {
1003 ACPI_EXCEPTION((AE_INFO, status,
1004 "While executing _PRW methods"));
1005 }
1005 } 1006 }
1006 1007
1007 /* 1008 /*
1008 * Enable all GPEs that have a corresponding method and aren't 1009 * Enable all GPEs that have a corresponding method and are not
1009 * capable of generating wakeups. Any other GPEs within this block 1010 * capable of generating wakeups. Any other GPEs within this block
1010 * must be enabled via the acpi_enable_gpe() interface. 1011 * must be enabled via the acpi_enable_gpe interface.
1011 */ 1012 */
1012 wake_gpe_count = 0; 1013 wake_gpe_count = 0;
1013 gpe_enabled_count = 0; 1014 gpe_enabled_count = 0;
1014 if (gpe_device == acpi_gbl_fadt_gpe_device) 1015
1016 if (gpe_device == acpi_gbl_fadt_gpe_device) {
1015 gpe_device = NULL; 1017 gpe_device = NULL;
1018 }
1016 1019
1017 for (i = 0; i < gpe_block->register_count; i++) { 1020 for (i = 0; i < gpe_block->register_count; i++) {
1018 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 1021 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
1019 acpi_status status;
1020 acpi_size gpe_index;
1021 int gpe_number;
1022 1022
1023 /* Get the info block for this particular GPE */ 1023 /* Get the info block for this particular GPE */
1024 gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j; 1024
1025 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
1025 gpe_event_info = &gpe_block->event_info[gpe_index]; 1026 gpe_event_info = &gpe_block->event_info[gpe_index];
1026 1027
1027 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { 1028 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
1028 wake_gpe_count++; 1029 wake_gpe_count++;
1029 if (acpi_gbl_leave_wake_gpes_disabled) 1030 if (acpi_gbl_leave_wake_gpes_disabled) {
1030 continue; 1031 continue;
1032 }
1031 } 1033 }
1032 1034
1033 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) 1035 /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
1036
1037 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
1034 continue; 1038 continue;
1039 }
1040
1041 /* Enable this GPE */
1035 1042
1036 gpe_number = gpe_index + gpe_block->block_base_number; 1043 gpe_number = gpe_index + gpe_block->block_base_number;
1037 status = acpi_enable_gpe(gpe_device, gpe_number, 1044 status = acpi_enable_gpe(gpe_device, gpe_number,
1038 ACPI_GPE_TYPE_RUNTIME); 1045 ACPI_GPE_TYPE_RUNTIME);
1039 if (ACPI_FAILURE(status)) 1046 if (ACPI_FAILURE(status)) {
1040 ACPI_ERROR((AE_INFO, 1047 ACPI_EXCEPTION((AE_INFO, status,
1041 "Failed to enable GPE %02X\n", 1048 "Could not enable GPE 0x%02X",
1042 gpe_number)); 1049 gpe_number));
1043 else 1050 continue;
1044 gpe_enabled_count++; 1051 }
1052
1053 gpe_enabled_count++;
1045 } 1054 }
1046 } 1055 }
1047 1056