aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfevnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evxfevnt.c')
-rw-r--r--drivers/acpi/acpica/evxfevnt.c249
1 files changed, 104 insertions, 145 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 18b3f1468b7d..0ec900da5794 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -213,101 +213,71 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
213 213
214/******************************************************************************* 214/*******************************************************************************
215 * 215 *
216 * FUNCTION: acpi_clear_and_enable_gpe 216 * FUNCTION: acpi_gpe_wakeup
217 *
218 * PARAMETERS: gpe_event_info - GPE to enable
219 *
220 * RETURN: Status
221 *
222 * DESCRIPTION: Clear the given GPE from stale events and enable it.
223 *
224 ******************************************************************************/
225static acpi_status
226acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
227{
228 acpi_status status;
229
230 /*
231 * We will only allow a GPE to be enabled if it has either an
232 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
233 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
234 * first time it fires.
235 */
236 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
237 return_ACPI_STATUS(AE_NO_HANDLER);
238 }
239
240 /* Clear the GPE (of stale events) */
241 status = acpi_hw_clear_gpe(gpe_event_info);
242 if (ACPI_FAILURE(status)) {
243 return_ACPI_STATUS(status);
244 }
245
246 /* Enable the requested GPE */
247 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
248
249 return_ACPI_STATUS(status);
250}
251
252/*******************************************************************************
253 *
254 * FUNCTION: acpi_set_gpe
255 * 217 *
256 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 218 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
257 * gpe_number - GPE level within the GPE block 219 * gpe_number - GPE level within the GPE block
258 * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 220 * Action - Enable or Disable
259 * 221 *
260 * RETURN: Status 222 * RETURN: Status
261 * 223 *
262 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 224 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
263 * the reference count mechanism used in the acpi_enable_gpe and
264 * acpi_disable_gpe interfaces -- and should be used with care.
265 *
266 * Note: Typically used to disable a runtime GPE for short period of time,
267 * then re-enable it, without disturbing the existing reference counts. This
268 * is useful, for example, in the Embedded Controller (EC) driver.
269 * 225 *
270 ******************************************************************************/ 226 ******************************************************************************/
271acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) 227acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
272{ 228{
229 acpi_status status = AE_OK;
273 struct acpi_gpe_event_info *gpe_event_info; 230 struct acpi_gpe_event_info *gpe_event_info;
274 acpi_status status; 231 struct acpi_gpe_register_info *gpe_register_info;
275 acpi_cpu_flags flags; 232 acpi_cpu_flags flags;
233 u32 register_bit;
276 234
277 ACPI_FUNCTION_TRACE(acpi_set_gpe); 235 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
278 236
279 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 237 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
280 238
281 /* Ensure that we have a valid GPE number */ 239 /* Ensure that we have a valid GPE number */
282 240
283 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 241 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
284 if (!gpe_event_info) { 242 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
285 status = AE_BAD_PARAMETER; 243 status = AE_BAD_PARAMETER;
286 goto unlock_and_exit; 244 goto unlock_and_exit;
287 } 245 }
288 246
247 gpe_register_info = gpe_event_info->register_info;
248 if (!gpe_register_info) {
249 status = AE_NOT_EXIST;
250 goto unlock_and_exit;
251 }
252
253 register_bit =
254 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
255
289 /* Perform the action */ 256 /* Perform the action */
290 257
291 switch (action) { 258 switch (action) {
292 case ACPI_GPE_ENABLE: 259 case ACPI_GPE_ENABLE:
293 status = acpi_clear_and_enable_gpe(gpe_event_info); 260 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
261 (u8)register_bit);
294 break; 262 break;
295 263
296 case ACPI_GPE_DISABLE: 264 case ACPI_GPE_DISABLE:
297 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); 265 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
266 (u8)register_bit);
298 break; 267 break;
299 268
300 default: 269 default:
270 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
301 status = AE_BAD_PARAMETER; 271 status = AE_BAD_PARAMETER;
302 break; 272 break;
303 } 273 }
304 274
305 unlock_and_exit: 275unlock_and_exit:
306 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 276 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
307 return_ACPI_STATUS(status); 277 return_ACPI_STATUS(status);
308} 278}
309 279
310ACPI_EXPORT_SYMBOL(acpi_set_gpe) 280ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
311 281
312/******************************************************************************* 282/*******************************************************************************
313 * 283 *
@@ -315,17 +285,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe)
315 * 285 *
316 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 286 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
317 * gpe_number - GPE level within the GPE block 287 * gpe_number - GPE level within the GPE block
318 * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
319 * or both
320 * 288 *
321 * RETURN: Status 289 * RETURN: Status
322 * 290 *
323 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 291 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
324 * hardware-enabled (for runtime GPEs), or the GPE register mask 292 * hardware-enabled.
325 * is updated (for wake GPEs).
326 * 293 *
327 ******************************************************************************/ 294 ******************************************************************************/
328acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) 295acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
329{ 296{
330 acpi_status status = AE_OK; 297 acpi_status status = AE_OK;
331 struct acpi_gpe_event_info *gpe_event_info; 298 struct acpi_gpe_event_info *gpe_event_info;
@@ -333,12 +300,6 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
333 300
334 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 301 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
335 302
336 /* Parameter validation */
337
338 if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
339 return_ACPI_STATUS(AE_BAD_PARAMETER);
340 }
341
342 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
343 304
344 /* Ensure that we have a valid GPE number */ 305 /* Ensure that we have a valid GPE number */
@@ -349,46 +310,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
349 goto unlock_and_exit; 310 goto unlock_and_exit;
350 } 311 }
351 312
352 if (gpe_type & ACPI_GPE_TYPE_RUNTIME) { 313 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
353 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { 314 status = AE_LIMIT; /* Too many references */
354 status = AE_LIMIT; /* Too many references */ 315 goto unlock_and_exit;
355 goto unlock_and_exit;
356 }
357
358 gpe_event_info->runtime_count++;
359 if (gpe_event_info->runtime_count == 1) {
360 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
361 if (ACPI_SUCCESS(status)) {
362 status = acpi_clear_and_enable_gpe(gpe_event_info);
363 }
364
365 if (ACPI_FAILURE(status)) {
366 gpe_event_info->runtime_count--;
367 goto unlock_and_exit;
368 }
369 }
370 } 316 }
371 317
372 if (gpe_type & ACPI_GPE_TYPE_WAKE) { 318 gpe_event_info->runtime_count++;
373 /* The GPE must have the ability to wake the system */ 319 if (gpe_event_info->runtime_count == 1) {
374 320 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
375 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 321 if (ACPI_SUCCESS(status)) {
376 status = AE_TYPE; 322 status = acpi_ev_enable_gpe(gpe_event_info);
377 goto unlock_and_exit;
378 } 323 }
379 324 if (ACPI_FAILURE(status)) {
380 if (gpe_event_info->wakeup_count == ACPI_UINT8_MAX) { 325 gpe_event_info->runtime_count--;
381 status = AE_LIMIT; /* Too many references */
382 goto unlock_and_exit;
383 }
384
385 /*
386 * Update the enable mask on the first wakeup reference. Wake GPEs
387 * are only hardware-enabled just before sleeping.
388 */
389 gpe_event_info->wakeup_count++;
390 if (gpe_event_info->wakeup_count == 1) {
391 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
392 } 326 }
393 } 327 }
394 328
@@ -404,8 +338,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
404 * 338 *
405 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 339 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
406 * gpe_number - GPE level within the GPE block 340 * gpe_number - GPE level within the GPE block
407 * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
408 * or both
409 * 341 *
410 * RETURN: Status 342 * RETURN: Status
411 * 343 *
@@ -414,7 +346,7 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
414 * the GPE mask bit disabled (for wake GPEs) 346 * the GPE mask bit disabled (for wake GPEs)
415 * 347 *
416 ******************************************************************************/ 348 ******************************************************************************/
417acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) 349acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
418{ 350{
419 acpi_status status = AE_OK; 351 acpi_status status = AE_OK;
420 struct acpi_gpe_event_info *gpe_event_info; 352 struct acpi_gpe_event_info *gpe_event_info;
@@ -422,12 +354,6 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
422 354
423 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 355 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
424 356
425 /* Parameter validation */
426
427 if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
428 return_ACPI_STATUS(AE_BAD_PARAMETER);
429 }
430
431 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 357 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
432 358
433 /* Ensure that we have a valid GPE number */ 359 /* Ensure that we have a valid GPE number */
@@ -440,41 +366,21 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
440 366
441 /* Hardware-disable a runtime GPE on removal of the last reference */ 367 /* Hardware-disable a runtime GPE on removal of the last reference */
442 368
443 if (gpe_type & ACPI_GPE_TYPE_RUNTIME) { 369 if (!gpe_event_info->runtime_count) {
444 if (!gpe_event_info->runtime_count) { 370 status = AE_LIMIT; /* There are no references to remove */
445 status = AE_LIMIT; /* There are no references to remove */ 371 goto unlock_and_exit;
446 goto unlock_and_exit;
447 }
448
449 gpe_event_info->runtime_count--;
450 if (!gpe_event_info->runtime_count) {
451 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
452 if (ACPI_SUCCESS(status)) {
453 status = acpi_hw_low_set_gpe(gpe_event_info,
454 ACPI_GPE_DISABLE);
455 }
456
457 if (ACPI_FAILURE(status)) {
458 gpe_event_info->runtime_count++;
459 goto unlock_and_exit;
460 }
461 }
462 } 372 }
463 373
464 /* 374 gpe_event_info->runtime_count--;
465 * Update masks for wake GPE on removal of the last reference. 375 if (!gpe_event_info->runtime_count) {
466 * No need to hardware-disable wake GPEs here, they are not currently 376 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
467 * enabled. 377 if (ACPI_SUCCESS(status)) {
468 */ 378 status =
469 if (gpe_type & ACPI_GPE_TYPE_WAKE) { 379 acpi_hw_low_set_gpe(gpe_event_info,
470 if (!gpe_event_info->wakeup_count) { 380 ACPI_GPE_DISABLE);
471 status = AE_LIMIT; /* There are no references to remove */
472 goto unlock_and_exit;
473 } 381 }
474 382 if (ACPI_FAILURE(status)) {
475 gpe_event_info->wakeup_count--; 383 gpe_event_info->runtime_count++;
476 if (!gpe_event_info->wakeup_count) {
477 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
478 } 384 }
479 } 385 }
480 386
@@ -486,6 +392,59 @@ ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
486 392
487/******************************************************************************* 393/*******************************************************************************
488 * 394 *
395 * FUNCTION: acpi_gpe_can_wake
396 *
397 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
398 * gpe_number - GPE level within the GPE block
399 *
400 * RETURN: Status
401 *
402 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
403 * has a corresponding method and is currently enabled, disable it
404 * (GPEs with corresponding methods are enabled unconditionally
405 * during initialization, but GPEs that can wake up are expected
406 * to be initially disabled).
407 *
408 ******************************************************************************/
409acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
410{
411 acpi_status status = AE_OK;
412 struct acpi_gpe_event_info *gpe_event_info;
413 acpi_cpu_flags flags;
414 u8 disable = 0;
415
416 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
417
418 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
419
420 /* Ensure that we have a valid GPE number */
421
422 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
423 if (!gpe_event_info) {
424 status = AE_BAD_PARAMETER;
425 goto unlock_and_exit;
426 }
427
428 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
429 goto unlock_and_exit;
430 }
431
432 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
433 disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
434 && gpe_event_info->runtime_count;
435
436unlock_and_exit:
437 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
438
439 if (disable)
440 status = acpi_disable_gpe(gpe_device, gpe_number);
441
442 return_ACPI_STATUS(status);
443}
444ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
445
446/*******************************************************************************
447 *
489 * FUNCTION: acpi_disable_event 448 * FUNCTION: acpi_disable_event
490 * 449 *
491 * PARAMETERS: Event - The fixed eventto be enabled 450 * PARAMETERS: Event - The fixed eventto be enabled
@@ -800,7 +759,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
800 759
801 obj_desc->device.gpe_block = gpe_block; 760 obj_desc->device.gpe_block = gpe_block;
802 761
803 /* Run the _PRW methods and enable the runtime GPEs in the new block */ 762 /* Enable the runtime GPEs in the new block */
804 763
805 status = acpi_ev_initialize_gpe_block(node, gpe_block); 764 status = acpi_ev_initialize_gpe_block(node, gpe_block);
806 765