cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

evxfgpe.c (30306B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#define EXPORT_ACPI_INTERFACES
     11
     12#include <acpi/acpi.h>
     13#include "accommon.h"
     14#include "acevents.h"
     15#include "acnamesp.h"
     16
     17#define _COMPONENT          ACPI_EVENTS
     18ACPI_MODULE_NAME("evxfgpe")
     19
     20#if (!ACPI_REDUCED_HARDWARE)	/* Entire module */
     21/*******************************************************************************
     22 *
     23 * FUNCTION:    acpi_update_all_gpes
     24 *
     25 * PARAMETERS:  None
     26 *
     27 * RETURN:      Status
     28 *
     29 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
     30 *              associated _Lxx or _Exx methods and are not pointed to by any
     31 *              device _PRW methods (this indicates that these GPEs are
     32 *              generally intended for system or device wakeup. Such GPEs
     33 *              have to be enabled directly when the devices whose _PRW
     34 *              methods point to them are set up for wakeup signaling.)
     35 *
     36 * NOTE: Should be called after any GPEs are added to the system. Primarily,
     37 * after the system _PRW methods have been run, but also after a GPE Block
     38 * Device has been added or if any new GPE methods have been added via a
     39 * dynamic table load.
     40 *
     41 ******************************************************************************/
     42
     43acpi_status acpi_update_all_gpes(void)
     44{
     45	acpi_status status;
     46	u8 is_polling_needed = FALSE;
     47
     48	ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
     49
     50	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     51	if (ACPI_FAILURE(status)) {
     52		return_ACPI_STATUS(status);
     53	}
     54
     55	if (acpi_gbl_all_gpes_initialized) {
     56		goto unlock_and_exit;
     57	}
     58
     59	status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block,
     60				       &is_polling_needed);
     61	if (ACPI_SUCCESS(status)) {
     62		acpi_gbl_all_gpes_initialized = TRUE;
     63	}
     64
     65unlock_and_exit:
     66	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     67
     68	if (is_polling_needed && acpi_gbl_all_gpes_initialized) {
     69
     70		/* Poll GPEs to handle already triggered events */
     71
     72		acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head);
     73	}
     74	return_ACPI_STATUS(status);
     75}
     76
     77ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
     78
     79/*******************************************************************************
     80 *
     81 * FUNCTION:    acpi_enable_gpe
     82 *
     83 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
     84 *              gpe_number          - GPE level within the GPE block
     85 *
     86 * RETURN:      Status
     87 *
     88 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
     89 *              hardware-enabled.
     90 *
     91 ******************************************************************************/
     92acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
     93{
     94	acpi_status status = AE_BAD_PARAMETER;
     95	struct acpi_gpe_event_info *gpe_event_info;
     96	acpi_cpu_flags flags;
     97
     98	ACPI_FUNCTION_TRACE(acpi_enable_gpe);
     99
    100	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    101
    102	/*
    103	 * Ensure that we have a valid GPE number and that there is some way
    104	 * of handling the GPE (handler or a GPE method). In other words, we
    105	 * won't allow a valid GPE to be enabled if there is no way to handle it.
    106	 */
    107	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    108	if (gpe_event_info) {
    109		if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
    110		    ACPI_GPE_DISPATCH_NONE) {
    111			status = acpi_ev_add_gpe_reference(gpe_event_info, TRUE);
    112			if (ACPI_SUCCESS(status) &&
    113			    ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
    114
    115				/* Poll edge-triggered GPEs to handle existing events */
    116
    117				acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    118				(void)acpi_ev_detect_gpe(gpe_device,
    119							 gpe_event_info,
    120							 gpe_number);
    121				flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    122			}
    123		} else {
    124			status = AE_NO_HANDLER;
    125		}
    126	}
    127
    128	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    129	return_ACPI_STATUS(status);
    130}
    131ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
    132
    133/*******************************************************************************
    134 *
    135 * FUNCTION:    acpi_disable_gpe
    136 *
    137 * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
    138 *              gpe_number      - GPE level within the GPE block
    139 *
    140 * RETURN:      Status
    141 *
    142 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
    143 *              removed, only then is the GPE disabled (for runtime GPEs), or
    144 *              the GPE mask bit disabled (for wake GPEs)
    145 *
    146 ******************************************************************************/
    147
    148acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
    149{
    150	acpi_status status = AE_BAD_PARAMETER;
    151	struct acpi_gpe_event_info *gpe_event_info;
    152	acpi_cpu_flags flags;
    153
    154	ACPI_FUNCTION_TRACE(acpi_disable_gpe);
    155
    156	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    157
    158	/* Ensure that we have a valid GPE number */
    159
    160	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    161	if (gpe_event_info) {
    162		status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
    163	}
    164
    165	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    166	return_ACPI_STATUS(status);
    167}
    168
    169ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
    170
    171/*******************************************************************************
    172 *
    173 * FUNCTION:    acpi_set_gpe
    174 *
    175 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
    176 *              gpe_number          - GPE level within the GPE block
    177 *              action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
    178 *
    179 * RETURN:      Status
    180 *
    181 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
    182 *              the reference count mechanism used in the acpi_enable_gpe(),
    183 *              acpi_disable_gpe() interfaces.
    184 *              This API is typically used by the GPE raw handler mode driver
    185 *              to switch between the polling mode and the interrupt mode after
    186 *              the driver has enabled the GPE.
    187 *              The APIs should be invoked in this order:
    188 *               acpi_enable_gpe()            <- Ensure the reference count > 0
    189 *               acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
    190 *               acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
    191 *               acpi_disable_gpe()           <- Decrease the reference count
    192 *
    193 * Note: If a GPE is shared by 2 silicon components, then both the drivers
    194 *       should support GPE polling mode or disabling the GPE for long period
    195 *       for one driver may break the other. So use it with care since all
    196 *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
    197 *
    198 ******************************************************************************/
    199acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
    200{
    201	struct acpi_gpe_event_info *gpe_event_info;
    202	acpi_status status;
    203	acpi_cpu_flags flags;
    204
    205	ACPI_FUNCTION_TRACE(acpi_set_gpe);
    206
    207	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    208
    209	/* Ensure that we have a valid GPE number */
    210
    211	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    212	if (!gpe_event_info) {
    213		status = AE_BAD_PARAMETER;
    214		goto unlock_and_exit;
    215	}
    216
    217	/* Perform the action */
    218
    219	switch (action) {
    220	case ACPI_GPE_ENABLE:
    221
    222		status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
    223		gpe_event_info->disable_for_dispatch = FALSE;
    224		break;
    225
    226	case ACPI_GPE_DISABLE:
    227
    228		status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
    229		gpe_event_info->disable_for_dispatch = TRUE;
    230		break;
    231
    232	default:
    233
    234		status = AE_BAD_PARAMETER;
    235		break;
    236	}
    237
    238unlock_and_exit:
    239	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    240	return_ACPI_STATUS(status);
    241}
    242
    243ACPI_EXPORT_SYMBOL(acpi_set_gpe)
    244
    245/*******************************************************************************
    246 *
    247 * FUNCTION:    acpi_mask_gpe
    248 *
    249 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
    250 *              gpe_number          - GPE level within the GPE block
    251 *              is_masked           - Whether the GPE is masked or not
    252 *
    253 * RETURN:      Status
    254 *
    255 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
    256 *              prevent a GPE flooding.
    257 *
    258 ******************************************************************************/
    259acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked)
    260{
    261	struct acpi_gpe_event_info *gpe_event_info;
    262	acpi_status status;
    263	acpi_cpu_flags flags;
    264
    265	ACPI_FUNCTION_TRACE(acpi_mask_gpe);
    266
    267	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    268
    269	/* Ensure that we have a valid GPE number */
    270
    271	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    272	if (!gpe_event_info) {
    273		status = AE_BAD_PARAMETER;
    274		goto unlock_and_exit;
    275	}
    276
    277	status = acpi_ev_mask_gpe(gpe_event_info, is_masked);
    278
    279unlock_and_exit:
    280	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    281	return_ACPI_STATUS(status);
    282}
    283
    284ACPI_EXPORT_SYMBOL(acpi_mask_gpe)
    285
    286/*******************************************************************************
    287 *
    288 * FUNCTION:    acpi_mark_gpe_for_wake
    289 *
    290 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
    291 *              gpe_number          - GPE level within the GPE block
    292 *
    293 * RETURN:      Status
    294 *
    295 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
    296 *              sets the ACPI_GPE_CAN_WAKE flag.
    297 *
    298 * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
    299 * there won't be any notify handlers installed for device wake notifications
    300 * from the given GPE (one example is a button GPE in Linux). For these cases,
    301 * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
    302 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
    303 * setup implicit wake notification for it (since there's no handler method).
    304 *
    305 ******************************************************************************/
    306acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
    307{
    308	struct acpi_gpe_event_info *gpe_event_info;
    309	acpi_status status = AE_BAD_PARAMETER;
    310	acpi_cpu_flags flags;
    311
    312	ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
    313
    314	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    315
    316	/* Ensure that we have a valid GPE number */
    317
    318	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    319	if (gpe_event_info) {
    320
    321		/* Mark the GPE as a possible wake event */
    322
    323		gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
    324		status = AE_OK;
    325	}
    326
    327	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    328	return_ACPI_STATUS(status);
    329}
    330
    331ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
    332
    333/*******************************************************************************
    334 *
    335 * FUNCTION:    acpi_setup_gpe_for_wake
    336 *
    337 * PARAMETERS:  wake_device         - Device associated with the GPE (via _PRW)
    338 *              gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
    339 *              gpe_number          - GPE level within the GPE block
    340 *
    341 * RETURN:      Status
    342 *
    343 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
    344 *              interface is intended to be used as the host executes the
    345 *              _PRW methods (Power Resources for Wake) in the system tables.
    346 *              Each _PRW appears under a Device Object (The wake_device), and
    347 *              contains the info for the wake GPE associated with the
    348 *              wake_device.
    349 *
    350 ******************************************************************************/
    351acpi_status
    352acpi_setup_gpe_for_wake(acpi_handle wake_device,
    353			acpi_handle gpe_device, u32 gpe_number)
    354{
    355	acpi_status status;
    356	struct acpi_gpe_event_info *gpe_event_info;
    357	struct acpi_namespace_node *device_node;
    358	struct acpi_gpe_notify_info *notify;
    359	struct acpi_gpe_notify_info *new_notify;
    360	acpi_cpu_flags flags;
    361
    362	ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
    363
    364	/* Parameter Validation */
    365
    366	if (!wake_device) {
    367		/*
    368		 * By forcing wake_device to be valid, we automatically enable the
    369		 * implicit notify feature on all hosts.
    370		 */
    371		return_ACPI_STATUS(AE_BAD_PARAMETER);
    372	}
    373
    374	/* Handle root object case */
    375
    376	if (wake_device == ACPI_ROOT_OBJECT) {
    377		device_node = acpi_gbl_root_node;
    378	} else {
    379		device_node =
    380		    ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
    381	}
    382
    383	/* Validate wake_device is of type Device */
    384
    385	if (device_node->type != ACPI_TYPE_DEVICE) {
    386		return_ACPI_STATUS (AE_BAD_PARAMETER);
    387	}
    388
    389	/*
    390	 * Allocate a new notify object up front, in case it is needed.
    391	 * Memory allocation while holding a spinlock is a big no-no
    392	 * on some hosts.
    393	 */
    394	new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info));
    395	if (!new_notify) {
    396		return_ACPI_STATUS(AE_NO_MEMORY);
    397	}
    398
    399	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    400
    401	/* Ensure that we have a valid GPE number */
    402
    403	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    404	if (!gpe_event_info) {
    405		status = AE_BAD_PARAMETER;
    406		goto unlock_and_exit;
    407	}
    408
    409	/*
    410	 * If there is no method or handler for this GPE, then the
    411	 * wake_device will be notified whenever this GPE fires. This is
    412	 * known as an "implicit notify". Note: The GPE is assumed to be
    413	 * level-triggered (for windows compatibility).
    414	 */
    415	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
    416	    ACPI_GPE_DISPATCH_NONE) {
    417		/*
    418		 * This is the first device for implicit notify on this GPE.
    419		 * Just set the flags here, and enter the NOTIFY block below.
    420		 */
    421		gpe_event_info->flags =
    422		    (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
    423	} else if (gpe_event_info->flags & ACPI_GPE_AUTO_ENABLED) {
    424		/*
    425		 * A reference to this GPE has been added during the GPE block
    426		 * initialization, so drop it now to prevent the GPE from being
    427		 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
    428		 */
    429		(void)acpi_ev_remove_gpe_reference(gpe_event_info);
    430		gpe_event_info->flags &= ~ACPI_GPE_AUTO_ENABLED;
    431	}
    432
    433	/*
    434	 * If we already have an implicit notify on this GPE, add
    435	 * this device to the notify list.
    436	 */
    437	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
    438	    ACPI_GPE_DISPATCH_NOTIFY) {
    439
    440		/* Ensure that the device is not already in the list */
    441
    442		notify = gpe_event_info->dispatch.notify_list;
    443		while (notify) {
    444			if (notify->device_node == device_node) {
    445				status = AE_ALREADY_EXISTS;
    446				goto unlock_and_exit;
    447			}
    448			notify = notify->next;
    449		}
    450
    451		/* Add this device to the notify list for this GPE */
    452
    453		new_notify->device_node = device_node;
    454		new_notify->next = gpe_event_info->dispatch.notify_list;
    455		gpe_event_info->dispatch.notify_list = new_notify;
    456		new_notify = NULL;
    457	}
    458
    459	/* Mark the GPE as a possible wake event */
    460
    461	gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
    462	status = AE_OK;
    463
    464unlock_and_exit:
    465	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    466
    467	/* Delete the notify object if it was not used above */
    468
    469	if (new_notify) {
    470		ACPI_FREE(new_notify);
    471	}
    472	return_ACPI_STATUS(status);
    473}
    474ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
    475
    476/*******************************************************************************
    477 *
    478 * FUNCTION:    acpi_set_gpe_wake_mask
    479 *
    480 * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
    481 *              gpe_number      - GPE level within the GPE block
    482 *              action              - Enable or Disable
    483 *
    484 * RETURN:      Status
    485 *
    486 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
    487 *              already be marked as a WAKE GPE.
    488 *
    489 ******************************************************************************/
    490
    491acpi_status
    492acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
    493{
    494	acpi_status status = AE_OK;
    495	struct acpi_gpe_event_info *gpe_event_info;
    496	struct acpi_gpe_register_info *gpe_register_info;
    497	acpi_cpu_flags flags;
    498	u32 register_bit;
    499
    500	ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
    501
    502	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    503
    504	/*
    505	 * Ensure that we have a valid GPE number and that this GPE is in
    506	 * fact a wake GPE
    507	 */
    508	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    509	if (!gpe_event_info) {
    510		status = AE_BAD_PARAMETER;
    511		goto unlock_and_exit;
    512	}
    513
    514	if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
    515		status = AE_TYPE;
    516		goto unlock_and_exit;
    517	}
    518
    519	gpe_register_info = gpe_event_info->register_info;
    520	if (!gpe_register_info) {
    521		status = AE_NOT_EXIST;
    522		goto unlock_and_exit;
    523	}
    524
    525	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
    526
    527	/* Perform the action */
    528
    529	switch (action) {
    530	case ACPI_GPE_ENABLE:
    531
    532		ACPI_SET_BIT(gpe_register_info->enable_for_wake,
    533			     (u8)register_bit);
    534		break;
    535
    536	case ACPI_GPE_DISABLE:
    537
    538		ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
    539			       (u8)register_bit);
    540		break;
    541
    542	default:
    543
    544		ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
    545		status = AE_BAD_PARAMETER;
    546		break;
    547	}
    548
    549unlock_and_exit:
    550	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    551	return_ACPI_STATUS(status);
    552}
    553
    554ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
    555
    556/*******************************************************************************
    557 *
    558 * FUNCTION:    acpi_clear_gpe
    559 *
    560 * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
    561 *              gpe_number      - GPE level within the GPE block
    562 *
    563 * RETURN:      Status
    564 *
    565 * DESCRIPTION: Clear an ACPI event (general purpose)
    566 *
    567 ******************************************************************************/
    568acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
    569{
    570	acpi_status status = AE_OK;
    571	struct acpi_gpe_event_info *gpe_event_info;
    572	acpi_cpu_flags flags;
    573
    574	ACPI_FUNCTION_TRACE(acpi_clear_gpe);
    575
    576	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    577
    578	/* Ensure that we have a valid GPE number */
    579
    580	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    581	if (!gpe_event_info) {
    582		status = AE_BAD_PARAMETER;
    583		goto unlock_and_exit;
    584	}
    585
    586	status = acpi_hw_clear_gpe(gpe_event_info);
    587
    588      unlock_and_exit:
    589	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    590	return_ACPI_STATUS(status);
    591}
    592
    593ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
    594
    595/*******************************************************************************
    596 *
    597 * FUNCTION:    acpi_get_gpe_status
    598 *
    599 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
    600 *              gpe_number          - GPE level within the GPE block
    601 *              event_status        - Where the current status of the event
    602 *                                    will be returned
    603 *
    604 * RETURN:      Status
    605 *
    606 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
    607 *
    608 ******************************************************************************/
    609acpi_status
    610acpi_get_gpe_status(acpi_handle gpe_device,
    611		    u32 gpe_number, acpi_event_status *event_status)
    612{
    613	acpi_status status = AE_OK;
    614	struct acpi_gpe_event_info *gpe_event_info;
    615	acpi_cpu_flags flags;
    616
    617	ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
    618
    619	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    620
    621	/* Ensure that we have a valid GPE number */
    622
    623	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    624	if (!gpe_event_info) {
    625		status = AE_BAD_PARAMETER;
    626		goto unlock_and_exit;
    627	}
    628
    629	/* Obtain status on the requested GPE number */
    630
    631	status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
    632
    633unlock_and_exit:
    634	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    635	return_ACPI_STATUS(status);
    636}
    637
    638ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
    639
    640/*******************************************************************************
    641 *
    642 * FUNCTION:    acpi_gispatch_gpe
    643 *
    644 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
    645 *              gpe_number          - GPE level within the GPE block
    646 *
    647 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
    648 *
    649 * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
    650 *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
    651 *
    652 ******************************************************************************/
    653u32 acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number)
    654{
    655	ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
    656
    657	return acpi_ev_detect_gpe(gpe_device, NULL, gpe_number);
    658}
    659
    660ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe)
    661
    662/*******************************************************************************
    663 *
    664 * FUNCTION:    acpi_finish_gpe
    665 *
    666 * PARAMETERS:  gpe_device          - Namespace node for the GPE Block
    667 *                                    (NULL for FADT defined GPEs)
    668 *              gpe_number          - GPE level within the GPE block
    669 *
    670 * RETURN:      Status
    671 *
    672 * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
    673 *              processing. Intended for use by asynchronous host-installed
    674 *              GPE handlers. The GPE is only re-enabled if the enable_for_run bit
    675 *              is set in the GPE info.
    676 *
    677 ******************************************************************************/
    678acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)
    679{
    680	struct acpi_gpe_event_info *gpe_event_info;
    681	acpi_status status;
    682	acpi_cpu_flags flags;
    683
    684	ACPI_FUNCTION_TRACE(acpi_finish_gpe);
    685
    686	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
    687
    688	/* Ensure that we have a valid GPE number */
    689
    690	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
    691	if (!gpe_event_info) {
    692		status = AE_BAD_PARAMETER;
    693		goto unlock_and_exit;
    694	}
    695
    696	status = acpi_ev_finish_gpe(gpe_event_info);
    697
    698unlock_and_exit:
    699	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    700	return_ACPI_STATUS(status);
    701}
    702
    703ACPI_EXPORT_SYMBOL(acpi_finish_gpe)
    704
    705/******************************************************************************
    706 *
    707 * FUNCTION:    acpi_disable_all_gpes
    708 *
    709 * PARAMETERS:  None
    710 *
    711 * RETURN:      Status
    712 *
    713 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
    714 *
    715 ******************************************************************************/
    716
    717acpi_status acpi_disable_all_gpes(void)
    718{
    719	acpi_status status;
    720
    721	ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
    722
    723	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
    724	if (ACPI_FAILURE(status)) {
    725		return_ACPI_STATUS(status);
    726	}
    727
    728	status = acpi_hw_disable_all_gpes();
    729	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
    730
    731	return_ACPI_STATUS(status);
    732}
    733
    734ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
    735
    736/******************************************************************************
    737 *
    738 * FUNCTION:    acpi_enable_all_runtime_gpes
    739 *
    740 * PARAMETERS:  None
    741 *
    742 * RETURN:      Status
    743 *
    744 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
    745 *
    746 ******************************************************************************/
    747
    748acpi_status acpi_enable_all_runtime_gpes(void)
    749{
    750	acpi_status status;
    751
    752	ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
    753
    754	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
    755	if (ACPI_FAILURE(status)) {
    756		return_ACPI_STATUS(status);
    757	}
    758
    759	status = acpi_hw_enable_all_runtime_gpes();
    760	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
    761
    762	return_ACPI_STATUS(status);
    763}
    764
    765ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
    766
    767/******************************************************************************
    768 *
    769 * FUNCTION:    acpi_enable_all_wakeup_gpes
    770 *
    771 * PARAMETERS:  None
    772 *
    773 * RETURN:      Status
    774 *
    775 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
    776 *              all GPE blocks.
    777 *
    778 ******************************************************************************/
    779acpi_status acpi_enable_all_wakeup_gpes(void)
    780{
    781	acpi_status status;
    782
    783	ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes);
    784
    785	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
    786	if (ACPI_FAILURE(status)) {
    787		return_ACPI_STATUS(status);
    788	}
    789
    790	status = acpi_hw_enable_all_wakeup_gpes();
    791	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
    792
    793	return_ACPI_STATUS(status);
    794}
    795
    796ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
    797
    798/******************************************************************************
    799 *
    800 * FUNCTION:    acpi_any_gpe_status_set
    801 *
    802 * PARAMETERS:  gpe_skip_number      - Number of the GPE to skip
    803 *
    804 * RETURN:      Whether or not the status bit is set for any GPE
    805 *
    806 * DESCRIPTION: Check the status bits of all enabled GPEs, except for the one
    807 *              represented by the "skip" argument, and return TRUE if any of
    808 *              them is set or FALSE otherwise.
    809 *
    810 ******************************************************************************/
    811u32 acpi_any_gpe_status_set(u32 gpe_skip_number)
    812{
    813	acpi_status status;
    814	acpi_handle gpe_device;
    815	u8 ret;
    816
    817	ACPI_FUNCTION_TRACE(acpi_any_gpe_status_set);
    818
    819	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
    820	if (ACPI_FAILURE(status)) {
    821		return (FALSE);
    822	}
    823
    824	status = acpi_get_gpe_device(gpe_skip_number, &gpe_device);
    825	if (ACPI_FAILURE(status)) {
    826		gpe_device = NULL;
    827	}
    828
    829	ret = acpi_hw_check_all_gpes(gpe_device, gpe_skip_number);
    830	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
    831
    832	return (ret);
    833}
    834
    835ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set)
    836
    837/*******************************************************************************
    838 *
    839 * FUNCTION:    acpi_install_gpe_block
    840 *
    841 * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
    842 *              gpe_block_address   - Address and space_ID
    843 *              register_count      - Number of GPE register pairs in the block
    844 *              interrupt_number    - H/W interrupt for the block
    845 *
    846 * RETURN:      Status
    847 *
    848 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
    849 *              enabled here.
    850 *
    851 ******************************************************************************/
    852acpi_status
    853acpi_install_gpe_block(acpi_handle gpe_device,
    854		       struct acpi_generic_address *gpe_block_address,
    855		       u32 register_count, u32 interrupt_number)
    856{
    857	acpi_status status;
    858	union acpi_operand_object *obj_desc;
    859	struct acpi_namespace_node *node;
    860	struct acpi_gpe_block_info *gpe_block;
    861
    862	ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
    863
    864	if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
    865		return_ACPI_STATUS(AE_BAD_PARAMETER);
    866	}
    867
    868	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    869	if (ACPI_FAILURE(status)) {
    870		return_ACPI_STATUS(status);
    871	}
    872
    873	node = acpi_ns_validate_handle(gpe_device);
    874	if (!node) {
    875		status = AE_BAD_PARAMETER;
    876		goto unlock_and_exit;
    877	}
    878
    879	/* Validate the parent device */
    880
    881	if (node->type != ACPI_TYPE_DEVICE) {
    882		status = AE_TYPE;
    883		goto unlock_and_exit;
    884	}
    885
    886	if (node->object) {
    887		status = AE_ALREADY_EXISTS;
    888		goto unlock_and_exit;
    889	}
    890
    891	/*
    892	 * For user-installed GPE Block Devices, the gpe_block_base_number
    893	 * is always zero
    894	 */
    895	status = acpi_ev_create_gpe_block(node, gpe_block_address->address,
    896					  gpe_block_address->space_id,
    897					  register_count, 0, interrupt_number,
    898					  &gpe_block);
    899	if (ACPI_FAILURE(status)) {
    900		goto unlock_and_exit;
    901	}
    902
    903	/* Install block in the device_object attached to the node */
    904
    905	obj_desc = acpi_ns_get_attached_object(node);
    906	if (!obj_desc) {
    907
    908		/*
    909		 * No object, create a new one (Device nodes do not always have
    910		 * an attached object)
    911		 */
    912		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
    913		if (!obj_desc) {
    914			status = AE_NO_MEMORY;
    915			goto unlock_and_exit;
    916		}
    917
    918		status =
    919		    acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
    920
    921		/* Remove local reference to the object */
    922
    923		acpi_ut_remove_reference(obj_desc);
    924
    925		if (ACPI_FAILURE(status)) {
    926			goto unlock_and_exit;
    927		}
    928	}
    929
    930	/* Now install the GPE block in the device_object */
    931
    932	obj_desc->device.gpe_block = gpe_block;
    933
    934unlock_and_exit:
    935	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    936	return_ACPI_STATUS(status);
    937}
    938
    939ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
    940
    941/*******************************************************************************
    942 *
    943 * FUNCTION:    acpi_remove_gpe_block
    944 *
    945 * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
    946 *
    947 * RETURN:      Status
    948 *
    949 * DESCRIPTION: Remove a previously installed block of GPE registers
    950 *
    951 ******************************************************************************/
    952acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
    953{
    954	union acpi_operand_object *obj_desc;
    955	acpi_status status;
    956	struct acpi_namespace_node *node;
    957
    958	ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
    959
    960	if (!gpe_device) {
    961		return_ACPI_STATUS(AE_BAD_PARAMETER);
    962	}
    963
    964	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    965	if (ACPI_FAILURE(status)) {
    966		return_ACPI_STATUS(status);
    967	}
    968
    969	node = acpi_ns_validate_handle(gpe_device);
    970	if (!node) {
    971		status = AE_BAD_PARAMETER;
    972		goto unlock_and_exit;
    973	}
    974
    975	/* Validate the parent device */
    976
    977	if (node->type != ACPI_TYPE_DEVICE) {
    978		status = AE_TYPE;
    979		goto unlock_and_exit;
    980	}
    981
    982	/* Get the device_object attached to the node */
    983
    984	obj_desc = acpi_ns_get_attached_object(node);
    985	if (!obj_desc || !obj_desc->device.gpe_block) {
    986		return_ACPI_STATUS(AE_NULL_OBJECT);
    987	}
    988
    989	/* Delete the GPE block (but not the device_object) */
    990
    991	status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
    992	if (ACPI_SUCCESS(status)) {
    993		obj_desc->device.gpe_block = NULL;
    994	}
    995
    996unlock_and_exit:
    997	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    998	return_ACPI_STATUS(status);
    999}
   1000
   1001ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
   1002
   1003/*******************************************************************************
   1004 *
   1005 * FUNCTION:    acpi_get_gpe_device
   1006 *
   1007 * PARAMETERS:  index               - System GPE index (0-current_gpe_count)
   1008 *              gpe_device          - Where the parent GPE Device is returned
   1009 *
   1010 * RETURN:      Status
   1011 *
   1012 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
   1013 *              gpe device indicates that the gpe number is contained in one of
   1014 *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
   1015 *
   1016 ******************************************************************************/
   1017acpi_status acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
   1018{
   1019	struct acpi_gpe_device_info info;
   1020	acpi_status status;
   1021
   1022	ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
   1023
   1024	if (!gpe_device) {
   1025		return_ACPI_STATUS(AE_BAD_PARAMETER);
   1026	}
   1027
   1028	if (index >= acpi_current_gpe_count) {
   1029		return_ACPI_STATUS(AE_NOT_EXIST);
   1030	}
   1031
   1032	/* Setup and walk the GPE list */
   1033
   1034	info.index = index;
   1035	info.status = AE_NOT_EXIST;
   1036	info.gpe_device = NULL;
   1037	info.next_block_base_index = 0;
   1038
   1039	status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
   1040	if (ACPI_FAILURE(status)) {
   1041		return_ACPI_STATUS(status);
   1042	}
   1043
   1044	*gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
   1045	return_ACPI_STATUS(info.status);
   1046}
   1047
   1048ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
   1049#endif				/* !ACPI_REDUCED_HARDWARE */