diff options
Diffstat (limited to 'drivers/acpi/acpica/hwgpe.c')
| -rw-r--r-- | drivers/acpi/acpica/hwgpe.c | 94 |
1 files changed, 65 insertions, 29 deletions
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index bd72319a38f0..3450309c2786 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
| @@ -57,21 +57,47 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
| 57 | 57 | ||
| 58 | /****************************************************************************** | 58 | /****************************************************************************** |
| 59 | * | 59 | * |
| 60 | * FUNCTION: acpi_hw_low_disable_gpe | 60 | * FUNCTION: acpi_hw_gpe_register_bit |
| 61 | * | ||
| 62 | * PARAMETERS: gpe_event_info - Info block for the GPE | ||
| 63 | * gpe_register_info - Info block for the GPE register | ||
| 64 | * | ||
| 65 | * RETURN: Status | ||
| 66 | * | ||
| 67 | * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given | ||
| 68 | * GPE set. | ||
| 69 | * | ||
| 70 | ******************************************************************************/ | ||
| 71 | |||
| 72 | u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | ||
| 73 | struct acpi_gpe_register_info *gpe_register_info) | ||
| 74 | { | ||
| 75 | return (u32)1 << (gpe_event_info->gpe_number - | ||
| 76 | gpe_register_info->base_gpe_number); | ||
| 77 | } | ||
| 78 | |||
| 79 | /****************************************************************************** | ||
| 80 | * | ||
| 81 | * FUNCTION: acpi_hw_low_set_gpe | ||
| 61 | * | 82 | * |
| 62 | * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled | 83 | * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled |
| 84 | * action - Enable or disable | ||
| 63 | * | 85 | * |
| 64 | * RETURN: Status | 86 | * RETURN: Status |
| 65 | * | 87 | * |
| 66 | * DESCRIPTION: Disable a single GPE in the enable register. | 88 | * DESCRIPTION: Enable or disable a single GPE in its enable register. |
| 67 | * | 89 | * |
| 68 | ******************************************************************************/ | 90 | ******************************************************************************/ |
| 69 | 91 | ||
| 70 | acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 92 | acpi_status |
| 93 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | ||
| 71 | { | 94 | { |
| 72 | struct acpi_gpe_register_info *gpe_register_info; | 95 | struct acpi_gpe_register_info *gpe_register_info; |
| 73 | acpi_status status; | 96 | acpi_status status; |
| 74 | u32 enable_mask; | 97 | u32 enable_mask; |
| 98 | u32 register_bit; | ||
| 99 | |||
| 100 | ACPI_FUNCTION_ENTRY(); | ||
| 75 | 101 | ||
| 76 | /* Get the info block for the entire GPE register */ | 102 | /* Get the info block for the entire GPE register */ |
| 77 | 103 | ||
| @@ -87,11 +113,27 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
| 87 | return (status); | 113 | return (status); |
| 88 | } | 114 | } |
| 89 | 115 | ||
| 90 | /* Clear just the bit that corresponds to this GPE */ | 116 | /* Set ot clear just the bit that corresponds to this GPE */ |
| 91 | 117 | ||
| 92 | ACPI_CLEAR_BIT(enable_mask, ((u32)1 << | 118 | register_bit = acpi_hw_gpe_register_bit(gpe_event_info, |
| 93 | (gpe_event_info->gpe_number - | 119 | gpe_register_info); |
| 94 | gpe_register_info->base_gpe_number))); | 120 | switch (action) { |
| 121 | case ACPI_GPE_COND_ENABLE: | ||
| 122 | if (!(register_bit & gpe_register_info->enable_for_run)) | ||
| 123 | return (AE_BAD_PARAMETER); | ||
| 124 | |||
| 125 | case ACPI_GPE_ENABLE: | ||
| 126 | ACPI_SET_BIT(enable_mask, register_bit); | ||
| 127 | break; | ||
| 128 | |||
| 129 | case ACPI_GPE_DISABLE: | ||
| 130 | ACPI_CLEAR_BIT(enable_mask, register_bit); | ||
| 131 | break; | ||
| 132 | |||
| 133 | default: | ||
| 134 | ACPI_ERROR((AE_INFO, "Invalid action\n")); | ||
| 135 | return (AE_BAD_PARAMETER); | ||
| 136 | } | ||
| 95 | 137 | ||
| 96 | /* Write the updated enable mask */ | 138 | /* Write the updated enable mask */ |
| 97 | 139 | ||
| @@ -116,23 +158,11 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
| 116 | acpi_status | 158 | acpi_status |
| 117 | acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) | 159 | acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) |
| 118 | { | 160 | { |
| 119 | struct acpi_gpe_register_info *gpe_register_info; | ||
| 120 | acpi_status status; | 161 | acpi_status status; |
| 121 | 162 | ||
| 122 | ACPI_FUNCTION_ENTRY(); | 163 | ACPI_FUNCTION_ENTRY(); |
| 123 | 164 | ||
| 124 | /* Get the info block for the entire GPE register */ | 165 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); |
| 125 | |||
| 126 | gpe_register_info = gpe_event_info->register_info; | ||
| 127 | if (!gpe_register_info) { | ||
| 128 | return (AE_NOT_EXIST); | ||
| 129 | } | ||
| 130 | |||
| 131 | /* Write the entire GPE (runtime) enable register */ | ||
| 132 | |||
| 133 | status = acpi_hw_write(gpe_register_info->enable_for_run, | ||
| 134 | &gpe_register_info->enable_address); | ||
| 135 | |||
| 136 | return (status); | 166 | return (status); |
| 137 | } | 167 | } |
| 138 | 168 | ||
| @@ -150,21 +180,28 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) | |||
| 150 | 180 | ||
| 151 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | 181 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) |
| 152 | { | 182 | { |
| 183 | struct acpi_gpe_register_info *gpe_register_info; | ||
| 153 | acpi_status status; | 184 | acpi_status status; |
| 154 | u8 register_bit; | 185 | u32 register_bit; |
| 155 | 186 | ||
| 156 | ACPI_FUNCTION_ENTRY(); | 187 | ACPI_FUNCTION_ENTRY(); |
| 157 | 188 | ||
| 158 | register_bit = (u8)(1 << | 189 | /* Get the info block for the entire GPE register */ |
| 159 | (gpe_event_info->gpe_number - | 190 | |
| 160 | gpe_event_info->register_info->base_gpe_number)); | 191 | gpe_register_info = gpe_event_info->register_info; |
| 192 | if (!gpe_register_info) { | ||
| 193 | return (AE_NOT_EXIST); | ||
| 194 | } | ||
| 195 | |||
| 196 | register_bit = acpi_hw_gpe_register_bit(gpe_event_info, | ||
| 197 | gpe_register_info); | ||
| 161 | 198 | ||
| 162 | /* | 199 | /* |
| 163 | * Write a one to the appropriate bit in the status register to | 200 | * Write a one to the appropriate bit in the status register to |
| 164 | * clear this GPE. | 201 | * clear this GPE. |
| 165 | */ | 202 | */ |
| 166 | status = acpi_hw_write(register_bit, | 203 | status = acpi_hw_write(register_bit, |
| 167 | &gpe_event_info->register_info->status_address); | 204 | &gpe_register_info->status_address); |
| 168 | 205 | ||
| 169 | return (status); | 206 | return (status); |
| 170 | } | 207 | } |
| @@ -187,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
| 187 | acpi_event_status * event_status) | 224 | acpi_event_status * event_status) |
| 188 | { | 225 | { |
| 189 | u32 in_byte; | 226 | u32 in_byte; |
| 190 | u8 register_bit; | 227 | u32 register_bit; |
| 191 | struct acpi_gpe_register_info *gpe_register_info; | 228 | struct acpi_gpe_register_info *gpe_register_info; |
| 192 | acpi_status status; | 229 | acpi_status status; |
| 193 | acpi_event_status local_event_status = 0; | 230 | acpi_event_status local_event_status = 0; |
| @@ -204,9 +241,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
| 204 | 241 | ||
| 205 | /* Get the register bitmask for this GPE */ | 242 | /* Get the register bitmask for this GPE */ |
| 206 | 243 | ||
| 207 | register_bit = (u8)(1 << | 244 | register_bit = acpi_hw_gpe_register_bit(gpe_event_info, |
| 208 | (gpe_event_info->gpe_number - | 245 | gpe_register_info); |
| 209 | gpe_event_info->register_info->base_gpe_number)); | ||
| 210 | 246 | ||
| 211 | /* GPE currently enabled? (enabled for runtime?) */ | 247 | /* GPE currently enabled? (enabled for runtime?) */ |
| 212 | 248 | ||
