aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfevnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evxfevnt.c')
-rw-r--r--drivers/acpi/acpica/evxfevnt.c191
1 files changed, 113 insertions, 78 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 5ff32c78ea2d..7c7bbb4d402c 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -203,21 +203,26 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
203 * 203 *
204 * FUNCTION: acpi_set_gpe 204 * FUNCTION: acpi_set_gpe
205 * 205 *
206 * PARAMETERS: gpe_device - Parent GPE Device 206 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
207 * gpe_number - GPE level within the GPE block 207 * gpe_number - GPE level within the GPE block
208 * action - Enable or disable 208 * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
209 * Called from ISR or not
210 * 209 *
211 * RETURN: Status 210 * RETURN: Status
212 * 211 *
213 * DESCRIPTION: Enable or disable an ACPI event (general purpose) 212 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
213 * the reference count mechanism used in the acpi_enable_gpe and
214 * acpi_disable_gpe interfaces -- and should be used with care.
215 *
216 * Note: Typically used to disable a runtime GPE for short period of time,
217 * then re-enable it, without disturbing the existing reference counts. This
218 * is useful, for example, in the Embedded Controller (EC) driver.
214 * 219 *
215 ******************************************************************************/ 220 ******************************************************************************/
216acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) 221acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
217{ 222{
218 acpi_status status = AE_OK;
219 acpi_cpu_flags flags;
220 struct acpi_gpe_event_info *gpe_event_info; 223 struct acpi_gpe_event_info *gpe_event_info;
224 acpi_status status;
225 acpi_cpu_flags flags;
221 226
222 ACPI_FUNCTION_TRACE(acpi_set_gpe); 227 ACPI_FUNCTION_TRACE(acpi_set_gpe);
223 228
@@ -243,7 +248,6 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
243 break; 248 break;
244 249
245 default: 250 default:
246 ACPI_ERROR((AE_INFO, "Invalid action\n"));
247 status = AE_BAD_PARAMETER; 251 status = AE_BAD_PARAMETER;
248 break; 252 break;
249 } 253 }
@@ -259,25 +263,31 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe)
259 * 263 *
260 * FUNCTION: acpi_enable_gpe 264 * FUNCTION: acpi_enable_gpe
261 * 265 *
262 * PARAMETERS: gpe_device - Parent GPE Device 266 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
263 * gpe_number - GPE level within the GPE block 267 * gpe_number - GPE level within the GPE block
264 * type - Purpose the GPE will be used for 268 * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
269 * or both
265 * 270 *
266 * RETURN: Status 271 * RETURN: Status
267 * 272 *
268 * DESCRIPTION: Take a reference to a GPE and enable it if necessary 273 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
274 * hardware-enabled (for runtime GPEs), or the GPE register mask
275 * is updated (for wake GPEs).
269 * 276 *
270 ******************************************************************************/ 277 ******************************************************************************/
271acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) 278acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
272{ 279{
273 acpi_status status = AE_OK; 280 acpi_status status = AE_OK;
274 acpi_cpu_flags flags;
275 struct acpi_gpe_event_info *gpe_event_info; 281 struct acpi_gpe_event_info *gpe_event_info;
282 acpi_cpu_flags flags;
276 283
277 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 284 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
278 285
279 if (type & ~ACPI_GPE_TYPE_WAKE_RUN) 286 /* Parameter validation */
287
288 if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
280 return_ACPI_STATUS(AE_BAD_PARAMETER); 289 return_ACPI_STATUS(AE_BAD_PARAMETER);
290 }
281 291
282 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 292 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
283 293
@@ -289,26 +299,43 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
289 goto unlock_and_exit; 299 goto unlock_and_exit;
290 } 300 }
291 301
292 if (type & ACPI_GPE_TYPE_RUNTIME) { 302 if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
293 if (++gpe_event_info->runtime_count == 1) { 303 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
304 status = AE_LIMIT; /* Too many references */
305 goto unlock_and_exit;
306 }
307
308 gpe_event_info->runtime_count++;
309 if (gpe_event_info->runtime_count == 1) {
294 status = acpi_ev_enable_gpe(gpe_event_info); 310 status = acpi_ev_enable_gpe(gpe_event_info);
295 if (ACPI_FAILURE(status)) 311 if (ACPI_FAILURE(status)) {
296 gpe_event_info->runtime_count--; 312 gpe_event_info->runtime_count--;
313 goto unlock_and_exit;
314 }
297 } 315 }
298 } 316 }
299 317
300 if (type & ACPI_GPE_TYPE_WAKE) { 318 if (gpe_type & ACPI_GPE_TYPE_WAKE) {
319 /* The GPE must have the ability to wake the system */
320
301 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 321 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
302 status = AE_BAD_PARAMETER; 322 status = AE_TYPE;
323 goto unlock_and_exit;
324 }
325
326 if (gpe_event_info->wakeup_count == ACPI_UINT8_MAX) {
327 status = AE_LIMIT; /* Too many references */
303 goto unlock_and_exit; 328 goto unlock_and_exit;
304 } 329 }
305 330
306 /* 331 /*
307 * Wake-up GPEs are only enabled right prior to putting the 332 * Update the enable mask on the first wakeup reference. Wake GPEs
308 * system into a sleep state. 333 * are only hardware-enabled just before sleeping.
309 */ 334 */
310 if (++gpe_event_info->wakeup_count == 1) 335 gpe_event_info->wakeup_count++;
311 acpi_ev_update_gpe_enable_masks(gpe_event_info); 336 if (gpe_event_info->wakeup_count == 1) {
337 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
338 }
312 } 339 }
313 340
314unlock_and_exit: 341unlock_and_exit:
@@ -321,27 +348,34 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
321 * 348 *
322 * FUNCTION: acpi_disable_gpe 349 * FUNCTION: acpi_disable_gpe
323 * 350 *
324 * PARAMETERS: gpe_device - Parent GPE Device 351 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
325 * gpe_number - GPE level within the GPE block 352 * gpe_number - GPE level within the GPE block
326 * type - Purpose the GPE won't be used for any more 353 * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
354 * or both
327 * 355 *
328 * RETURN: Status 356 * RETURN: Status
329 * 357 *
330 * DESCRIPTION: Release a reference to a GPE and disable it if necessary 358 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
359 * removed, only then is the GPE disabled (for runtime GPEs), or
360 * the GPE mask bit disabled (for wake GPEs)
331 * 361 *
332 ******************************************************************************/ 362 ******************************************************************************/
333acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) 363acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
334{ 364{
335 acpi_status status = AE_OK; 365 acpi_status status = AE_OK;
336 acpi_cpu_flags flags;
337 struct acpi_gpe_event_info *gpe_event_info; 366 struct acpi_gpe_event_info *gpe_event_info;
367 acpi_cpu_flags flags;
338 368
339 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 369 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
340 370
341 if (type & ~ACPI_GPE_TYPE_WAKE_RUN) 371 /* Parameter validation */
372
373 if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
342 return_ACPI_STATUS(AE_BAD_PARAMETER); 374 return_ACPI_STATUS(AE_BAD_PARAMETER);
375 }
343 376
344 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 377 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
378
345 /* Ensure that we have a valid GPE number */ 379 /* Ensure that we have a valid GPE number */
346 380
347 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 381 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
@@ -350,18 +384,39 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
350 goto unlock_and_exit; 384 goto unlock_and_exit;
351 } 385 }
352 386
353 if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) { 387 /* Hardware-disable a runtime GPE on removal of the last reference */
354 if (--gpe_event_info->runtime_count == 0) 388
389 if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
390 if (!gpe_event_info->runtime_count) {
391 status = AE_LIMIT; /* There are no references to remove */
392 goto unlock_and_exit;
393 }
394
395 gpe_event_info->runtime_count--;
396 if (!gpe_event_info->runtime_count) {
355 status = acpi_ev_disable_gpe(gpe_event_info); 397 status = acpi_ev_disable_gpe(gpe_event_info);
398 if (ACPI_FAILURE(status)) {
399 gpe_event_info->runtime_count++;
400 goto unlock_and_exit;
401 }
402 }
356 } 403 }
357 404
358 if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) { 405 /*
359 /* 406 * Update masks for wake GPE on removal of the last reference.
360 * Wake-up GPEs are not enabled after leaving system sleep 407 * No need to hardware-disable wake GPEs here, they are not currently
361 * states, so we don't need to disable them here. 408 * enabled.
362 */ 409 */
363 if (--gpe_event_info->wakeup_count == 0) 410 if (gpe_type & ACPI_GPE_TYPE_WAKE) {
364 acpi_ev_update_gpe_enable_masks(gpe_event_info); 411 if (!gpe_event_info->wakeup_count) {
412 status = AE_LIMIT; /* There are no references to remove */
413 goto unlock_and_exit;
414 }
415
416 gpe_event_info->wakeup_count--;
417 if (!gpe_event_info->wakeup_count) {
418 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
419 }
365 } 420 }
366 421
367unlock_and_exit: 422unlock_and_exit:
@@ -465,30 +520,23 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event)
465 * 520 *
466 * FUNCTION: acpi_clear_gpe 521 * FUNCTION: acpi_clear_gpe
467 * 522 *
468 * PARAMETERS: gpe_device - Parent GPE Device 523 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
469 * gpe_number - GPE level within the GPE block 524 * gpe_number - GPE level within the GPE block
470 * Flags - Called from an ISR or not
471 * 525 *
472 * RETURN: Status 526 * RETURN: Status
473 * 527 *
474 * DESCRIPTION: Clear an ACPI event (general purpose) 528 * DESCRIPTION: Clear an ACPI event (general purpose)
475 * 529 *
476 ******************************************************************************/ 530 ******************************************************************************/
477acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) 531acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
478{ 532{
479 acpi_status status = AE_OK; 533 acpi_status status = AE_OK;
480 struct acpi_gpe_event_info *gpe_event_info; 534 struct acpi_gpe_event_info *gpe_event_info;
535 acpi_cpu_flags flags;
481 536
482 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 537 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
483 538
484 /* Use semaphore lock if not executing at interrupt level */ 539 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
485
486 if (flags & ACPI_NOT_ISR) {
487 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
488 if (ACPI_FAILURE(status)) {
489 return_ACPI_STATUS(status);
490 }
491 }
492 540
493 /* Ensure that we have a valid GPE number */ 541 /* Ensure that we have a valid GPE number */
494 542
@@ -501,9 +549,7 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
501 status = acpi_hw_clear_gpe(gpe_event_info); 549 status = acpi_hw_clear_gpe(gpe_event_info);
502 550
503 unlock_and_exit: 551 unlock_and_exit:
504 if (flags & ACPI_NOT_ISR) { 552 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
505 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
506 }
507 return_ACPI_STATUS(status); 553 return_ACPI_STATUS(status);
508} 554}
509 555
@@ -569,9 +615,8 @@ ACPI_EXPORT_SYMBOL(acpi_get_event_status)
569 * 615 *
570 * FUNCTION: acpi_get_gpe_status 616 * FUNCTION: acpi_get_gpe_status
571 * 617 *
572 * PARAMETERS: gpe_device - Parent GPE Device 618 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
573 * gpe_number - GPE level within the GPE block 619 * gpe_number - GPE level within the GPE block
574 * Flags - Called from an ISR or not
575 * event_status - Where the current status of the event will 620 * event_status - Where the current status of the event will
576 * be returned 621 * be returned
577 * 622 *
@@ -582,21 +627,15 @@ ACPI_EXPORT_SYMBOL(acpi_get_event_status)
582 ******************************************************************************/ 627 ******************************************************************************/
583acpi_status 628acpi_status
584acpi_get_gpe_status(acpi_handle gpe_device, 629acpi_get_gpe_status(acpi_handle gpe_device,
585 u32 gpe_number, u32 flags, acpi_event_status * event_status) 630 u32 gpe_number, acpi_event_status *event_status)
586{ 631{
587 acpi_status status = AE_OK; 632 acpi_status status = AE_OK;
588 struct acpi_gpe_event_info *gpe_event_info; 633 struct acpi_gpe_event_info *gpe_event_info;
634 acpi_cpu_flags flags;
589 635
590 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 636 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
591 637
592 /* Use semaphore lock if not executing at interrupt level */ 638 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
593
594 if (flags & ACPI_NOT_ISR) {
595 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
596 if (ACPI_FAILURE(status)) {
597 return_ACPI_STATUS(status);
598 }
599 }
600 639
601 /* Ensure that we have a valid GPE number */ 640 /* Ensure that we have a valid GPE number */
602 641
@@ -614,9 +653,7 @@ acpi_get_gpe_status(acpi_handle gpe_device,
614 *event_status |= ACPI_EVENT_FLAG_HANDLE; 653 *event_status |= ACPI_EVENT_FLAG_HANDLE;
615 654
616 unlock_and_exit: 655 unlock_and_exit:
617 if (flags & ACPI_NOT_ISR) { 656 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
618 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
619 }
620 return_ACPI_STATUS(status); 657 return_ACPI_STATUS(status);
621} 658}
622 659
@@ -673,20 +710,15 @@ acpi_install_gpe_block(acpi_handle gpe_device,
673 goto unlock_and_exit; 710 goto unlock_and_exit;
674 } 711 }
675 712
676 /* Run the _PRW methods and enable the GPEs */ 713 /* Install block in the device_object attached to the node */
677
678 status = acpi_ev_initialize_gpe_block(node, gpe_block);
679 if (ACPI_FAILURE(status)) {
680 goto unlock_and_exit;
681 }
682
683 /* Get the device_object attached to the node */
684 714
685 obj_desc = acpi_ns_get_attached_object(node); 715 obj_desc = acpi_ns_get_attached_object(node);
686 if (!obj_desc) { 716 if (!obj_desc) {
687 717
688 /* No object, create a new one */ 718 /*
689 719 * No object, create a new one (Device nodes do not always have
720 * an attached object)
721 */
690 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 722 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
691 if (!obj_desc) { 723 if (!obj_desc) {
692 status = AE_NO_MEMORY; 724 status = AE_NO_MEMORY;
@@ -705,10 +737,14 @@ acpi_install_gpe_block(acpi_handle gpe_device,
705 } 737 }
706 } 738 }
707 739
708 /* Install the GPE block in the device_object */ 740 /* Now install the GPE block in the device_object */
709 741
710 obj_desc->device.gpe_block = gpe_block; 742 obj_desc->device.gpe_block = gpe_block;
711 743
744 /* Run the _PRW methods and enable the runtime GPEs in the new block */
745
746 status = acpi_ev_initialize_gpe_block(node, gpe_block);
747
712 unlock_and_exit: 748 unlock_and_exit:
713 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 749 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
714 return_ACPI_STATUS(status); 750 return_ACPI_STATUS(status);
@@ -839,8 +875,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
839 875
840 /* Increment Index by the number of GPEs in this block */ 876 /* Increment Index by the number of GPEs in this block */
841 877
842 info->next_block_base_index += 878 info->next_block_base_index += gpe_block->gpe_count;
843 (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);
844 879
845 if (info->index < info->next_block_base_index) { 880 if (info->index < info->next_block_base_index) {
846 /* 881 /*