PageRenderTime 40ms CodeModel.GetById 15ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/acpi/events/evgpe.c

https://bitbucket.org/evzijst/gittest
C | 756 lines | 337 code | 167 blank | 252 comment | 50 complexity | 696885738f595dc12671d66bf1a53c2b MD5 | raw file
  1/******************************************************************************
  2 *
  3 * Module Name: evgpe - General Purpose Event handling and dispatch
  4 *
  5 *****************************************************************************/
  6
  7/*
  8 * Copyright (C) 2000 - 2005, R. Byron Moore
  9 * All rights reserved.
 10 *
 11 * Redistribution and use in source and binary forms, with or without
 12 * modification, are permitted provided that the following conditions
 13 * are met:
 14 * 1. Redistributions of source code must retain the above copyright
 15 *    notice, this list of conditions, and the following disclaimer,
 16 *    without modification.
 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 18 *    substantially similar to the "NO WARRANTY" disclaimer below
 19 *    ("Disclaimer") and any redistribution must be conditioned upon
 20 *    including a substantially similar Disclaimer requirement for further
 21 *    binary redistribution.
 22 * 3. Neither the names of the above-listed copyright holders nor the names
 23 *    of any contributors may be used to endorse or promote products derived
 24 *    from this software without specific prior written permission.
 25 *
 26 * Alternatively, this software may be distributed under the terms of the
 27 * GNU General Public License ("GPL") version 2 as published by the Free
 28 * Software Foundation.
 29 *
 30 * NO WARRANTY
 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 41 * POSSIBILITY OF SUCH DAMAGES.
 42 */
 43
 44#include <acpi/acpi.h>
 45#include <acpi/acevents.h>
 46#include <acpi/acnamesp.h>
 47
 48#define _COMPONENT          ACPI_EVENTS
 49	 ACPI_MODULE_NAME    ("evgpe")
 50
 51
 52/*******************************************************************************
 53 *
 54 * FUNCTION:    acpi_ev_set_gpe_type
 55 *
 56 * PARAMETERS:  gpe_event_info          - GPE to set
 57 *              Type                    - New type
 58 *
 59 * RETURN:      Status
 60 *
 61 * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
 62 *
 63 ******************************************************************************/
 64
 65acpi_status
 66acpi_ev_set_gpe_type (
 67	struct acpi_gpe_event_info      *gpe_event_info,
 68	u8                              type)
 69{
 70	acpi_status                     status;
 71
 72
 73	ACPI_FUNCTION_TRACE ("ev_set_gpe_type");
 74
 75
 76	/* Validate type and update register enable masks */
 77
 78	switch (type) {
 79	case ACPI_GPE_TYPE_WAKE:
 80	case ACPI_GPE_TYPE_RUNTIME:
 81	case ACPI_GPE_TYPE_WAKE_RUN:
 82		break;
 83
 84	default:
 85		return_ACPI_STATUS (AE_BAD_PARAMETER);
 86	}
 87
 88	/* Disable the GPE if currently enabled */
 89
 90	status = acpi_ev_disable_gpe (gpe_event_info);
 91
 92	/* Type was validated above */
 93
 94	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
 95	gpe_event_info->flags |= type;              /* Insert type */
 96	return_ACPI_STATUS (status);
 97}
 98
 99
100/*******************************************************************************
101 *
102 * FUNCTION:    acpi_ev_update_gpe_enable_masks
103 *
104 * PARAMETERS:  gpe_event_info          - GPE to update
105 *              Type                    - What to do: ACPI_GPE_DISABLE or
106 *                                        ACPI_GPE_ENABLE
107 *
108 * RETURN:      Status
109 *
110 * DESCRIPTION: Updates GPE register enable masks based on the GPE type
111 *
112 ******************************************************************************/
113
114acpi_status
115acpi_ev_update_gpe_enable_masks (
116	struct acpi_gpe_event_info      *gpe_event_info,
117	u8                              type)
118{
119	struct acpi_gpe_register_info   *gpe_register_info;
120	u8                              register_bit;
121
122
123	ACPI_FUNCTION_TRACE ("ev_update_gpe_enable_masks");
124
125
126	gpe_register_info = gpe_event_info->register_info;
127	if (!gpe_register_info) {
128		return_ACPI_STATUS (AE_NOT_EXIST);
129	}
130	register_bit = gpe_event_info->register_bit;
131
132	/* 1) Disable case.  Simply clear all enable bits */
133
134	if (type == ACPI_GPE_DISABLE) {
135		ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
136		ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
137		return_ACPI_STATUS (AE_OK);
138	}
139
140	/* 2) Enable case.  Set/Clear the appropriate enable bits */
141
142	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
143	case ACPI_GPE_TYPE_WAKE:
144		ACPI_SET_BIT   (gpe_register_info->enable_for_wake, register_bit);
145		ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
146		break;
147
148	case ACPI_GPE_TYPE_RUNTIME:
149		ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
150		ACPI_SET_BIT   (gpe_register_info->enable_for_run, register_bit);
151		break;
152
153	case ACPI_GPE_TYPE_WAKE_RUN:
154		ACPI_SET_BIT   (gpe_register_info->enable_for_wake, register_bit);
155		ACPI_SET_BIT   (gpe_register_info->enable_for_run, register_bit);
156		break;
157
158	default:
159		return_ACPI_STATUS (AE_BAD_PARAMETER);
160	}
161
162	return_ACPI_STATUS (AE_OK);
163}
164
165
166/*******************************************************************************
167 *
168 * FUNCTION:    acpi_ev_enable_gpe
169 *
170 * PARAMETERS:  gpe_event_info          - GPE to enable
171 *              write_to_hardware       - Enable now, or just mark data structs
172 *                                        (WAKE GPEs should be deferred)
173 *
174 * RETURN:      Status
175 *
176 * DESCRIPTION: Enable a GPE based on the GPE type
177 *
178 ******************************************************************************/
179
180acpi_status
181acpi_ev_enable_gpe (
182	struct acpi_gpe_event_info      *gpe_event_info,
183	u8                              write_to_hardware)
184{
185	acpi_status                     status;
186
187
188	ACPI_FUNCTION_TRACE ("ev_enable_gpe");
189
190
191	/* Make sure HW enable masks are updated */
192
193	status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_ENABLE);
194	if (ACPI_FAILURE (status)) {
195		return_ACPI_STATUS (status);
196	}
197
198	/* Mark wake-enabled or HW enable, or both */
199
200	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
201	case ACPI_GPE_TYPE_WAKE:
202
203		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
204		break;
205
206	case ACPI_GPE_TYPE_WAKE_RUN:
207
208		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
209
210		/*lint -fallthrough */
211
212	case ACPI_GPE_TYPE_RUNTIME:
213
214		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
215
216		if (write_to_hardware) {
217			/* Clear the GPE (of stale events), then enable it */
218
219			status = acpi_hw_clear_gpe (gpe_event_info);
220			if (ACPI_FAILURE (status)) {
221				return_ACPI_STATUS (status);
222			}
223
224			/* Enable the requested runtime GPE */
225
226			status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
227		}
228		break;
229
230	default:
231		return_ACPI_STATUS (AE_BAD_PARAMETER);
232	}
233
234	return_ACPI_STATUS (AE_OK);
235}
236
237
238/*******************************************************************************
239 *
240 * FUNCTION:    acpi_ev_disable_gpe
241 *
242 * PARAMETERS:  gpe_event_info          - GPE to disable
243 *
244 * RETURN:      Status
245 *
246 * DESCRIPTION: Disable a GPE based on the GPE type
247 *
248 ******************************************************************************/
249
250acpi_status
251acpi_ev_disable_gpe (
252	struct acpi_gpe_event_info      *gpe_event_info)
253{
254	acpi_status                     status;
255
256
257	ACPI_FUNCTION_TRACE ("ev_disable_gpe");
258
259
260	if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
261		return_ACPI_STATUS (AE_OK);
262	}
263
264	/* Make sure HW enable masks are updated */
265
266	status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
267	if (ACPI_FAILURE (status)) {
268		return_ACPI_STATUS (status);
269	}
270
271	/* Mark wake-disabled or HW disable, or both */
272
273	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
274	case ACPI_GPE_TYPE_WAKE:
275		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
276		break;
277
278	case ACPI_GPE_TYPE_WAKE_RUN:
279		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
280
281		/*lint -fallthrough */
282
283	case ACPI_GPE_TYPE_RUNTIME:
284
285		/* Disable the requested runtime GPE */
286
287		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
288		status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
289		break;
290
291	default:
292		return_ACPI_STATUS (AE_BAD_PARAMETER);
293	}
294
295	return_ACPI_STATUS (AE_OK);
296}
297
298
299/*******************************************************************************
300 *
301 * FUNCTION:    acpi_ev_get_gpe_event_info
302 *
303 * PARAMETERS:  gpe_device          - Device node.  NULL for GPE0/GPE1
304 *              gpe_number          - Raw GPE number
305 *
306 * RETURN:      A GPE event_info struct. NULL if not a valid GPE
307 *
308 * DESCRIPTION: Returns the event_info struct associated with this GPE.
309 *              Validates the gpe_block and the gpe_number
310 *
311 *              Should be called only when the GPE lists are semaphore locked
312 *              and not subject to change.
313 *
314 ******************************************************************************/
315
316struct acpi_gpe_event_info *
317acpi_ev_get_gpe_event_info (
318	acpi_handle                     gpe_device,
319	u32                             gpe_number)
320{
321	union acpi_operand_object       *obj_desc;
322	struct acpi_gpe_block_info      *gpe_block;
323	acpi_native_uint                i;
324
325
326	ACPI_FUNCTION_ENTRY ();
327
328
329	/* A NULL gpe_block means use the FADT-defined GPE block(s) */
330
331	if (!gpe_device) {
332		/* Examine GPE Block 0 and 1 (These blocks are permanent) */
333
334		for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
335			gpe_block = acpi_gbl_gpe_fadt_blocks[i];
336			if (gpe_block) {
337				if ((gpe_number >= gpe_block->block_base_number) &&
338					(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
339					return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
340				}
341			}
342		}
343
344		/* The gpe_number was not in the range of either FADT GPE block */
345
346		return (NULL);
347	}
348
349	/* A Non-NULL gpe_device means this is a GPE Block Device */
350
351	obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) gpe_device);
352	if (!obj_desc ||
353		!obj_desc->device.gpe_block) {
354		return (NULL);
355	}
356
357	gpe_block = obj_desc->device.gpe_block;
358
359	if ((gpe_number >= gpe_block->block_base_number) &&
360		(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
361		return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
362	}
363
364	return (NULL);
365}
366
367
368/*******************************************************************************
369 *
370 * FUNCTION:    acpi_ev_gpe_detect
371 *
372 * PARAMETERS:  gpe_xrupt_list      - Interrupt block for this interrupt.
373 *                                    Can have multiple GPE blocks attached.
374 *
375 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
376 *
377 * DESCRIPTION: Detect if any GP events have occurred.  This function is
378 *              executed at interrupt level.
379 *
380 ******************************************************************************/
381
382u32
383acpi_ev_gpe_detect (
384	struct acpi_gpe_xrupt_info      *gpe_xrupt_list)
385{
386	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
387	u8                              enabled_status_byte;
388	struct acpi_gpe_register_info   *gpe_register_info;
389	u32                             status_reg;
390	u32                             enable_reg;
391	acpi_status                     status;
392	struct acpi_gpe_block_info      *gpe_block;
393	acpi_native_uint                i;
394	acpi_native_uint                j;
395
396
397	ACPI_FUNCTION_NAME ("ev_gpe_detect");
398
399	/* Check for the case where there are no GPEs */
400
401	if (!gpe_xrupt_list) {
402		return (int_status);
403	}
404
405	/* Examine all GPE blocks attached to this interrupt level */
406
407	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
408	gpe_block = gpe_xrupt_list->gpe_block_list_head;
409	while (gpe_block) {
410		/*
411		 * Read all of the 8-bit GPE status and enable registers
412		 * in this GPE block, saving all of them.
413		 * Find all currently active GP events.
414		 */
415		for (i = 0; i < gpe_block->register_count; i++) {
416			/* Get the next status/enable pair */
417
418			gpe_register_info = &gpe_block->register_info[i];
419
420			/* Read the Status Register */
421
422			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg,
423					 &gpe_register_info->status_address);
424			if (ACPI_FAILURE (status)) {
425				goto unlock_and_exit;
426			}
427
428			/* Read the Enable Register */
429
430			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg,
431					 &gpe_register_info->enable_address);
432			if (ACPI_FAILURE (status)) {
433				goto unlock_and_exit;
434			}
435
436			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
437				"Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
438				gpe_register_info->base_gpe_number, status_reg, enable_reg));
439
440			/* First check if there is anything active at all in this register */
441
442			enabled_status_byte = (u8) (status_reg & enable_reg);
443			if (!enabled_status_byte) {
444				/* No active GPEs in this register, move on */
445
446				continue;
447			}
448
449			/* Now look at the individual GPEs in this byte register */
450
451			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
452				/* Examine one GPE bit */
453
454				if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) {
455					/*
456					 * Found an active GPE. Dispatch the event to a handler
457					 * or method.
458					 */
459					int_status |= acpi_ev_gpe_dispatch (
460							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
461							  (u32) j + gpe_register_info->base_gpe_number);
462				}
463			}
464		}
465
466		gpe_block = gpe_block->next;
467	}
468
469unlock_and_exit:
470
471	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
472	return (int_status);
473}
474
475
476/*******************************************************************************
477 *
478 * FUNCTION:    acpi_ev_asynch_execute_gpe_method
479 *
480 * PARAMETERS:  Context (gpe_event_info) - Info for this GPE
481 *
482 * RETURN:      None
483 *
484 * DESCRIPTION: Perform the actual execution of a GPE control method.  This
485 *              function is called from an invocation of acpi_os_queue_for_execution
486 *              (and therefore does NOT execute at interrupt level) so that
487 *              the control method itself is not executed in the context of
488 *              an interrupt handler.
489 *
490 ******************************************************************************/
491
492static void ACPI_SYSTEM_XFACE
493acpi_ev_asynch_execute_gpe_method (
494	void                            *context)
495{
496	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
497	u32                             gpe_number = 0;
498	acpi_status                     status;
499	struct acpi_gpe_event_info      local_gpe_event_info;
500	struct acpi_parameter_info      info;
501
502
503	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
504
505
506	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
507	if (ACPI_FAILURE (status)) {
508		return_VOID;
509	}
510
511	/* Must revalidate the gpe_number/gpe_block */
512
513	if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
514		status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
515		return_VOID;
516	}
517
518	/* Set the GPE flags for return to enabled state */
519
520	(void) acpi_ev_enable_gpe (gpe_event_info, FALSE);
521
522	/*
523	 * Take a snapshot of the GPE info for this level - we copy the
524	 * info to prevent a race condition with remove_handler/remove_block.
525	 */
526	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));
527
528	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
529	if (ACPI_FAILURE (status)) {
530		return_VOID;
531	}
532
533	/*
534	 * Must check for control method type dispatch one more
535	 * time to avoid race with ev_gpe_install_handler
536	 */
537	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
538		/*
539		 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
540		 * control method that corresponds to this GPE
541		 */
542		info.node = local_gpe_event_info.dispatch.method_node;
543		info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
544		info.parameter_type = ACPI_PARAM_GPE;
545
546		status = acpi_ns_evaluate_by_handle (&info);
547		if (ACPI_FAILURE (status)) {
548			ACPI_REPORT_ERROR ((
549				"%s while evaluating method [%4.4s] for GPE[%2X]\n",
550				acpi_format_exception (status),
551				acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
552				gpe_number));
553		}
554	}
555
556	if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
557		/*
558		 * GPE is level-triggered, we clear the GPE status bit after
559		 * handling the event.
560		 */
561		status = acpi_hw_clear_gpe (&local_gpe_event_info);
562		if (ACPI_FAILURE (status)) {
563			return_VOID;
564		}
565	}
566
567	/* Enable this GPE */
568
569	(void) acpi_hw_write_gpe_enable_reg (&local_gpe_event_info);
570	return_VOID;
571}
572
573
574/*******************************************************************************
575 *
576 * FUNCTION:    acpi_ev_gpe_dispatch
577 *
578 * PARAMETERS:  gpe_event_info  - info for this GPE
579 *              gpe_number      - Number relative to the parent GPE block
580 *
581 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
582 *
583 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
584 *              or method (e.g. _Lxx/_Exx) handler.
585 *
586 *              This function executes at interrupt level.
587 *
588 ******************************************************************************/
589
590u32
591acpi_ev_gpe_dispatch (
592	struct acpi_gpe_event_info      *gpe_event_info,
593	u32                             gpe_number)
594{
595	acpi_status                     status;
596
597
598	ACPI_FUNCTION_TRACE ("ev_gpe_dispatch");
599
600
601	/*
602	 * If edge-triggered, clear the GPE status bit now.  Note that
603	 * level-triggered events are cleared after the GPE is serviced.
604	 */
605	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_EDGE_TRIGGERED) {
606		status = acpi_hw_clear_gpe (gpe_event_info);
607		if (ACPI_FAILURE (status)) {
608			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
609				acpi_format_exception (status), gpe_number));
610			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
611		}
612	}
613
614	/* Save current system state */
615
616	if (acpi_gbl_system_awake_and_running) {
617		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
618	}
619	else {
620		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
621	}
622
623	/*
624	 * Dispatch the GPE to either an installed handler, or the control
625	 * method associated with this GPE (_Lxx or _Exx).
626	 * If a handler exists, we invoke it and do not attempt to run the method.
627	 * If there is neither a handler nor a method, we disable the level to
628	 * prevent further events from coming in here.
629	 */
630	switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
631	case ACPI_GPE_DISPATCH_HANDLER:
632
633		/*
634		 * Invoke the installed handler (at interrupt level)
635		 * Ignore return status for now.  TBD: leave GPE disabled on error?
636		 */
637		(void) gpe_event_info->dispatch.handler->address (
638				  gpe_event_info->dispatch.handler->context);
639
640		/* It is now safe to clear level-triggered events. */
641
642		if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
643			status = acpi_hw_clear_gpe (gpe_event_info);
644			if (ACPI_FAILURE (status)) {
645				ACPI_REPORT_ERROR ((
646					"acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
647					acpi_format_exception (status), gpe_number));
648				return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
649			}
650		}
651		break;
652
653	case ACPI_GPE_DISPATCH_METHOD:
654
655		/*
656		 * Disable GPE, so it doesn't keep firing before the method has a
657		 * chance to run.
658		 */
659		status = acpi_ev_disable_gpe (gpe_event_info);
660		if (ACPI_FAILURE (status)) {
661			ACPI_REPORT_ERROR ((
662				"acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
663				acpi_format_exception (status), gpe_number));
664			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
665		}
666
667		/*
668		 * Execute the method associated with the GPE
669		 * NOTE: Level-triggered GPEs are cleared after the method completes.
670		 */
671		status = acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
672				 acpi_ev_asynch_execute_gpe_method, gpe_event_info);
673		if (ACPI_FAILURE (status)) {
674			ACPI_REPORT_ERROR ((
675				"acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n",
676				acpi_format_exception (status), gpe_number));
677		}
678		break;
679
680	default:
681
682		/* No handler or method to run! */
683
684		ACPI_REPORT_ERROR ((
685			"acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n",
686			gpe_number));
687
688		/*
689		 * Disable the GPE.  The GPE will remain disabled until the ACPI
690		 * Core Subsystem is restarted, or a handler is installed.
691		 */
692		status = acpi_ev_disable_gpe (gpe_event_info);
693		if (ACPI_FAILURE (status)) {
694			ACPI_REPORT_ERROR ((
695				"acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
696				acpi_format_exception (status), gpe_number));
697			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
698		}
699		break;
700	}
701
702	return_VALUE (ACPI_INTERRUPT_HANDLED);
703}
704
705
706#ifdef ACPI_GPE_NOTIFY_CHECK
707
708/*******************************************************************************
709 * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
710 *
711 * FUNCTION:    acpi_ev_check_for_wake_only_gpe
712 *
713 * PARAMETERS:  gpe_event_info  - info for this GPE
714 *
715 * RETURN:      Status
716 *
717 * DESCRIPTION: Determine if a a GPE is "wake-only".
718 *
719 *              Called from Notify() code in interpreter when a "device_wake"
720 *              Notify comes in.
721 *
722 ******************************************************************************/
723
724acpi_status
725acpi_ev_check_for_wake_only_gpe (
726	struct acpi_gpe_event_info      *gpe_event_info)
727{
728	acpi_status                     status;
729
730
731	ACPI_FUNCTION_TRACE ("ev_check_for_wake_only_gpe");
732
733
734	if ((gpe_event_info) &&  /* Only >0 for _Lxx/_Exx */
735	   ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */ {
736		/* This must be a wake-only GPE, disable it */
737
738		status = acpi_ev_disable_gpe (gpe_event_info);
739
740		/* Set GPE to wake-only.  Do not change wake disabled/enabled status */
741
742		acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
743
744		ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
745				gpe_event_info));
746
747		/* This was a wake-only GPE */
748
749		return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
750	}
751
752	return_ACPI_STATUS (AE_OK);
753}
754#endif
755
756