Skip to content

Commit ea12883

Browse files
committed
ACPICA: Introduce acpi_any_gpe_status_set()
Introduce a new helper function, acpi_any_gpe_status_set(), for checking the status bits of all enabled GPEs in one go. It is needed to distinguish spurious SCIs from genuine ones when deciding whether or not to wake up the system from suspend-to-idle. Cc: 5.4+ <[email protected]> # 5.4+ Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent e3728b5 commit ea12883

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

drivers/acpi/acpica/achware.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ acpi_status acpi_hw_enable_all_runtime_gpes(void);
101101

102102
acpi_status acpi_hw_enable_all_wakeup_gpes(void);
103103

104+
u8 acpi_hw_check_all_gpes(void);
105+
104106
acpi_status
105107
acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
106108
struct acpi_gpe_block_info *gpe_block,

drivers/acpi/acpica/evxfgpe.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,38 @@ acpi_status acpi_enable_all_wakeup_gpes(void)
795795

796796
ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
797797

798+
/******************************************************************************
799+
*
800+
* FUNCTION: acpi_any_gpe_status_set
801+
*
802+
* PARAMETERS: None
803+
*
804+
* RETURN: Whether or not the status bit is set for any GPE
805+
*
806+
* DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
807+
* of them is set or FALSE otherwise.
808+
*
809+
******************************************************************************/
810+
u32 acpi_any_gpe_status_set(void)
811+
{
812+
acpi_status status;
813+
u8 ret;
814+
815+
ACPI_FUNCTION_TRACE(acpi_any_gpe_status_set);
816+
817+
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
818+
if (ACPI_FAILURE(status)) {
819+
return (FALSE);
820+
}
821+
822+
ret = acpi_hw_check_all_gpes();
823+
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
824+
825+
return (ret);
826+
}
827+
828+
ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set)
829+
798830
/*******************************************************************************
799831
*
800832
* FUNCTION: acpi_install_gpe_block

drivers/acpi/acpica/hwgpe.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,53 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
444444
return (AE_OK);
445445
}
446446

447+
/******************************************************************************
448+
*
449+
* FUNCTION: acpi_hw_get_gpe_block_status
450+
*
451+
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
452+
* gpe_block - Gpe Block info
453+
*
454+
* RETURN: Success
455+
*
456+
* DESCRIPTION: Produce a combined GPE status bits mask for the given block.
457+
*
458+
******************************************************************************/
459+
460+
static acpi_status
461+
acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
462+
struct acpi_gpe_block_info *gpe_block,
463+
void *ret_ptr)
464+
{
465+
struct acpi_gpe_register_info *gpe_register_info;
466+
u64 in_enable, in_status;
467+
acpi_status status;
468+
u8 *ret = ret_ptr;
469+
u32 i;
470+
471+
/* Examine each GPE Register within the block */
472+
473+
for (i = 0; i < gpe_block->register_count; i++) {
474+
gpe_register_info = &gpe_block->register_info[i];
475+
476+
status = acpi_hw_read(&in_enable,
477+
&gpe_register_info->enable_address);
478+
if (ACPI_FAILURE(status)) {
479+
continue;
480+
}
481+
482+
status = acpi_hw_read(&in_status,
483+
&gpe_register_info->status_address);
484+
if (ACPI_FAILURE(status)) {
485+
continue;
486+
}
487+
488+
*ret |= in_enable & in_status;
489+
}
490+
491+
return (AE_OK);
492+
}
493+
447494
/******************************************************************************
448495
*
449496
* FUNCTION: acpi_hw_disable_all_gpes
@@ -510,4 +557,28 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void)
510557
return_ACPI_STATUS(status);
511558
}
512559

560+
/******************************************************************************
561+
*
562+
* FUNCTION: acpi_hw_check_all_gpes
563+
*
564+
* PARAMETERS: None
565+
*
566+
* RETURN: Combined status of all GPEs
567+
*
568+
* DESCRIPTION: Check all enabled GPEs in all GPE blocks and return TRUE if the
569+
* status bit is set for at least one of them of FALSE otherwise.
570+
*
571+
******************************************************************************/
572+
573+
u8 acpi_hw_check_all_gpes(void)
574+
{
575+
u8 ret = 0;
576+
577+
ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes);
578+
579+
(void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &ret);
580+
581+
return (ret != 0);
582+
}
583+
513584
#endif /* !ACPI_REDUCED_HARDWARE */

include/acpi/acpixf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_dispatch_gpe(acpi_handle gpe_device, u3
752752
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void))
753753
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void))
754754
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void))
755+
ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_gpe_status_set(void))
755756

756757
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
757758
acpi_get_gpe_device(u32 gpe_index,

0 commit comments

Comments
 (0)