diff options
author | Lin Ming <ming.m.lin@intel.com> | 2010-12-13 00:39:17 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-01-12 04:27:00 -0500 |
commit | bba63a296ffab20e08d9e8252d2f0d99050ac859 (patch) | |
tree | 53d4abf7dc5fcf8b563a6cce554312d800c760e0 /drivers/acpi/acpica/evxfgpe.c | |
parent | 5a284cd75d635e3c5db0210dc9a9a44c6839f460 (diff) |
ACPICA: Implicit notify support
This feature provides an automatic device notification for wake devices
when a wakeup GPE occurs and there is no corresponding GPE method or
handler. Rather than ignoring such a GPE, an implicit AML Notify
operation is performed on the parent device object.
This feature is not part of the ACPI specification and is provided for
Windows compatibility only.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/evxfgpe.c')
-rw-r--r-- | drivers/acpi/acpica/evxfgpe.c | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 99f77ab29729..fcf4a5cdc9a4 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -166,39 +166,75 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
166 | } | 166 | } |
167 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | 167 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) |
168 | 168 | ||
169 | |||
169 | /******************************************************************************* | 170 | /******************************************************************************* |
170 | * | 171 | * |
171 | * FUNCTION: acpi_setup_gpe_for_wake | 172 | * FUNCTION: acpi_setup_gpe_for_wake |
172 | * | 173 | * |
173 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | 174 | * PARAMETERS: wake_device - Device associated with the GPE (via _PRW) |
174 | * gpe_number - GPE level within the GPE block | 175 | * gpe_device - Parent GPE Device. NULL for GPE0/GPE1 |
176 | * gpe_number - GPE level within the GPE block | ||
175 | * | 177 | * |
176 | * RETURN: Status | 178 | * RETURN: Status |
177 | * | 179 | * |
178 | * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE | 180 | * DESCRIPTION: Mark a GPE as having the ability to wake the system. This |
179 | * has a corresponding method and is currently enabled, disable it | 181 | * interface is intended to be used as the host executes the |
180 | * (GPEs with corresponding methods are enabled unconditionally | 182 | * _PRW methods (Power Resources for Wake) in the system tables. |
181 | * during initialization, but GPEs that can wake up are expected | 183 | * Each _PRW appears under a Device Object (The wake_device), and |
182 | * to be initially disabled). | 184 | * contains the info for the wake GPE associated with the |
185 | * wake_device. | ||
183 | * | 186 | * |
184 | ******************************************************************************/ | 187 | ******************************************************************************/ |
185 | acpi_status acpi_setup_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number) | 188 | acpi_status |
189 | acpi_setup_gpe_for_wake(acpi_handle wake_device, | ||
190 | acpi_handle gpe_device, u32 gpe_number) | ||
186 | { | 191 | { |
187 | acpi_status status = AE_OK; | 192 | acpi_status status = AE_BAD_PARAMETER; |
188 | struct acpi_gpe_event_info *gpe_event_info; | 193 | struct acpi_gpe_event_info *gpe_event_info; |
194 | struct acpi_namespace_node *device_node; | ||
189 | acpi_cpu_flags flags; | 195 | acpi_cpu_flags flags; |
190 | 196 | ||
191 | ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); | 197 | ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); |
192 | 198 | ||
199 | /* Parameter Validation */ | ||
200 | |||
201 | if (!wake_device) { | ||
202 | /* | ||
203 | * By forcing wake_device to be valid, we automatically enable the | ||
204 | * implicit notify feature on all hosts. | ||
205 | */ | ||
206 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
207 | } | ||
208 | |||
209 | /* Validate wake_device is of type Device */ | ||
210 | |||
211 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); | ||
212 | if (device_node->type != ACPI_TYPE_DEVICE) { | ||
213 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
214 | } | ||
215 | |||
193 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 216 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
194 | 217 | ||
195 | /* Ensure that we have a valid GPE number */ | 218 | /* Ensure that we have a valid GPE number */ |
196 | 219 | ||
197 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 220 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
198 | if (gpe_event_info) { | 221 | if (gpe_event_info) { |
222 | /* | ||
223 | * If there is no method or handler for this GPE, then the | ||
224 | * wake_device will be notified whenever this GPE fires (aka | ||
225 | * "implicit notify") Note: The GPE is assumed to be | ||
226 | * level-triggered (for windows compatibility). | ||
227 | */ | ||
228 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
229 | ACPI_GPE_DISPATCH_NONE) { | ||
230 | gpe_event_info->flags = | ||
231 | (ACPI_GPE_DISPATCH_NOTIFY | | ||
232 | ACPI_GPE_LEVEL_TRIGGERED); | ||
233 | gpe_event_info->dispatch.device_node = device_node; | ||
234 | } | ||
235 | |||
199 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | 236 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; |
200 | } else { | 237 | status = AE_OK; |
201 | status = AE_BAD_PARAMETER; | ||
202 | } | 238 | } |
203 | 239 | ||
204 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 240 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |