diff options
Diffstat (limited to 'drivers/acpi/acpica/hwgpe.c')
| -rw-r--r-- | drivers/acpi/acpica/hwgpe.c | 129 |
1 files changed, 73 insertions, 56 deletions
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index c28c41b3180..2e6caabba07 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions @@ -6,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,7 +47,7 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwgpe") - +#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /* Local prototypes */ static acpi_status acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, @@ -57,21 +56,47 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /****************************************************************************** * - * FUNCTION: acpi_hw_low_disable_gpe + * FUNCTION: acpi_hw_get_gpe_register_bit + * + * PARAMETERS: gpe_event_info - Info block for the GPE + * + * RETURN: Register mask with a one in the GPE bit position + * + * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the + * correct position for the input GPE. + * + ******************************************************************************/ + +u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info) +{ + + return ((u32)1 << + (gpe_event_info->gpe_number - + gpe_event_info->register_info->base_gpe_number)); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_low_set_gpe * * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled + * action - Enable or disable * * RETURN: Status * - * DESCRIPTION: Disable a single GPE in the enable register. + * DESCRIPTION: Enable or disable a single GPE in the parent enable register. * ******************************************************************************/ -acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) +acpi_status +acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) { struct acpi_gpe_register_info *gpe_register_info; acpi_status status; u32 enable_mask; + u32 register_bit; + + ACPI_FUNCTION_ENTRY(); /* Get the info block for the entire GPE register */ @@ -87,52 +112,39 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) return (status); } - /* Clear just the bit that corresponds to this GPE */ + /* Set or clear just the bit that corresponds to this GPE */ - ACPI_CLEAR_BIT(enable_mask, ((u32)1 << - (gpe_event_info->gpe_number - - gpe_register_info->base_gpe_number))); + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); + switch (action) { + case ACPI_GPE_CONDITIONAL_ENABLE: - /* Write the updated enable mask */ + /* Only enable if the enable_for_run bit is set */ - status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); - return (status); -} + if (!(register_bit & gpe_register_info->enable_for_run)) { + return (AE_BAD_PARAMETER); + } -/****************************************************************************** - * - * FUNCTION: acpi_hw_write_gpe_enable_reg - * - * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled - * - * RETURN: Status - * - * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must - * already be cleared or set in the parent register - * enable_for_run mask. - * - ******************************************************************************/ + /*lint -fallthrough */ -acpi_status -acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) -{ - struct acpi_gpe_register_info *gpe_register_info; - acpi_status status; + case ACPI_GPE_ENABLE: - ACPI_FUNCTION_ENTRY(); + ACPI_SET_BIT(enable_mask, register_bit); + break; - /* Get the info block for the entire GPE register */ + case ACPI_GPE_DISABLE: - gpe_register_info = gpe_event_info->register_info; - if (!gpe_register_info) { - return (AE_NOT_EXIST); - } + ACPI_CLEAR_BIT(enable_mask, register_bit); + break; - /* Write the entire GPE (runtime) enable register */ + default: - status = acpi_hw_write(gpe_register_info->enable_for_run, - &gpe_register_info->enable_address); + ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action)); + return (AE_BAD_PARAMETER); + } + /* Write the updated enable mask */ + + status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); return (status); } @@ -150,21 +162,27 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) { + struct acpi_gpe_register_info *gpe_register_info; acpi_status status; - u8 register_bit; + u32 register_bit; ACPI_FUNCTION_ENTRY(); - register_bit = (u8)(1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + /* Get the info block for the entire GPE register */ + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return (AE_NOT_EXIST); + } /* * Write a one to the appropriate bit in the status register to * clear this GPE. */ + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); + status = acpi_hw_write(register_bit, - &gpe_event_info->register_info->status_address); + &gpe_register_info->status_address); return (status); } @@ -187,10 +205,10 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, acpi_event_status * event_status) { u32 in_byte; - u8 register_bit; + u32 register_bit; struct acpi_gpe_register_info *gpe_register_info; - acpi_status status; acpi_event_status local_event_status = 0; + acpi_status status; ACPI_FUNCTION_ENTRY(); @@ -204,9 +222,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Get the register bitmask for this GPE */ - register_bit = (u8)(1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); /* GPE currently enabled? (enabled for runtime?) */ @@ -224,7 +240,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { - goto unlock_and_exit; + return (status); } if (register_bit & in_byte) { @@ -234,9 +250,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Set return value */ (*event_status) = local_event_status; - - unlock_and_exit: - return (status); + return (AE_OK); } /****************************************************************************** @@ -329,7 +343,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_status acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block, void *context) + struct acpi_gpe_block_info * gpe_block, + void *context) { u32 i; acpi_status status; @@ -464,3 +479,5 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void) status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); return_ACPI_STATUS(status); } + +#endif /* !ACPI_REDUCED_HARDWARE */ |
