aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/hwgpe.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-06-08 04:49:45 -0400
committerLen Brown <len.brown@intel.com>2010-06-12 00:45:05 -0400
commitc9a8bbb7704cbf515c0fc68970abbe4e91d68521 (patch)
treeae4fbfdd9bde46ba24f761e9fca8d3a3fdbe623e /drivers/acpi/acpica/hwgpe.c
parentfd247447c1d94a79d5cfc647430784306b3a8323 (diff)
ACPI / ACPICA: Avoid writing full enable masks to GPE registers
ACPICA uses acpi_hw_write_gpe_enable_reg() to re-enable a GPE after an event signaled by it has been handled. However, this function writes the entire GPE enable mask to the GPE's enable register which may not be correct. Namely, if one of the other GPEs in the same register was previously enabled by acpi_enable_gpe() and subsequently disabled using acpi_set_gpe(), acpi_hw_write_gpe_enable_reg() will re-enable it along with the target GPE. To fix this issue rework acpi_hw_write_gpe_enable_reg() so that it calls acpi_hw_low_set_gpe() with a special action value, ACPI_GPE_COND_ENABLE, that will make it only enable the GPE if the corresponding bit in its register's enable_for_run mask is set. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/hwgpe.c')
-rw-r--r--drivers/acpi/acpica/hwgpe.c18
1 files changed, 5 insertions, 13 deletions
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 40388e23e103..3450309c2786 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -118,6 +118,10 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
118 register_bit = acpi_hw_gpe_register_bit(gpe_event_info, 118 register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
119 gpe_register_info); 119 gpe_register_info);
120 switch (action) { 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
121 case ACPI_GPE_ENABLE: 125 case ACPI_GPE_ENABLE:
122 ACPI_SET_BIT(enable_mask, register_bit); 126 ACPI_SET_BIT(enable_mask, register_bit);
123 break; 127 break;
@@ -154,23 +158,11 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
154acpi_status 158acpi_status
155acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) 159acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
156{ 160{
157 struct acpi_gpe_register_info *gpe_register_info;
158 acpi_status status; 161 acpi_status status;
159 162
160 ACPI_FUNCTION_ENTRY(); 163 ACPI_FUNCTION_ENTRY();
161 164
162 /* Get the info block for the entire GPE register */ 165 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE);
163
164 gpe_register_info = gpe_event_info->register_info;
165 if (!gpe_register_info) {
166 return (AE_NOT_EXIST);
167 }
168
169 /* Write the entire GPE (runtime) enable register */
170
171 status = acpi_hw_write(gpe_register_info->enable_for_run,
172 &gpe_register_info->enable_address);
173
174 return (status); 166 return (status);
175} 167}
176 168