aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfgpe.c
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2010-12-13 00:39:17 -0500
committerLen Brown <len.brown@intel.com>2011-01-12 04:27:00 -0500
commitbba63a296ffab20e08d9e8252d2f0d99050ac859 (patch)
tree53d4abf7dc5fcf8b563a6cce554312d800c760e0 /drivers/acpi/acpica/evxfgpe.c
parent5a284cd75d635e3c5db0210dc9a9a44c6839f460 (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.c58
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}
167ACPI_EXPORT_SYMBOL(acpi_disable_gpe) 167ACPI_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 ******************************************************************************/
185acpi_status acpi_setup_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number) 188acpi_status
189acpi_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);