aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/hardware
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2008-06-12 20:28:55 -0400
committerAndi Kleen <andi@basil.nowhere.org>2008-07-16 17:27:01 -0400
commite38e8a0743b0e996a8a3fbea8908fe75a84f02c7 (patch)
tree93dbf03e5c1eff275742989d9b05cb1892c18fe4 /drivers/acpi/hardware
parent87dc5e3218ba3d7a9293f9113f58455747a233ac (diff)
Make GPE disable more robust
Implemented another change for the GPE disable. We now perform a read-change-write of the enable register instead of simply writing out the cached enable mask. This will prevent inadvertent enabling of GPEs if a rogue GPE is received during initialization (before GPE handlers are installed.) http://bugzilla.kernel.org/show_bug.cgi?id=6217 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
Diffstat (limited to 'drivers/acpi/hardware')
-rw-r--r--drivers/acpi/hardware/hwgpe.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 14bc4f456ae8..58347d6c43f8 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -55,6 +55,54 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
55 55
56/****************************************************************************** 56/******************************************************************************
57 * 57 *
58 * FUNCTION: acpi_hw_low_disable_gpe
59 *
60 * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Disable a single GPE in the enable register.
65 *
66 ******************************************************************************/
67
68acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
69{
70 struct acpi_gpe_register_info *gpe_register_info;
71 acpi_status status;
72 u32 enable_mask;
73
74 /* Get the info block for the entire GPE register */
75
76 gpe_register_info = gpe_event_info->register_info;
77 if (!gpe_register_info) {
78 return (AE_NOT_EXIST);
79 }
80
81 /* Get current value of the enable register that contains this GPE */
82
83 status = acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH, &enable_mask,
84 &gpe_register_info->enable_address);
85 if (ACPI_FAILURE(status)) {
86 return (status);
87 }
88
89 /* Clear just the bit that corresponds to this GPE */
90
91 ACPI_CLEAR_BIT(enable_mask,
92 ((u32) 1 <<
93 (gpe_event_info->gpe_number -
94 gpe_register_info->base_gpe_number)));
95
96 /* Write the updated enable mask */
97
98 status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, enable_mask,
99 &gpe_register_info->enable_address);
100
101 return (status);
102}
103
104/******************************************************************************
105 *
58 * FUNCTION: acpi_hw_write_gpe_enable_reg 106 * FUNCTION: acpi_hw_write_gpe_enable_reg
59 * 107 *
60 * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled 108 * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled
@@ -68,7 +116,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
68 ******************************************************************************/ 116 ******************************************************************************/
69 117
70acpi_status 118acpi_status
71acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) 119acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
72{ 120{
73 struct acpi_gpe_register_info *gpe_register_info; 121 struct acpi_gpe_register_info *gpe_register_info;
74 acpi_status status; 122 acpi_status status;