/******************************************************************************
 *
 * Module Name: evxface - External interfaces for ACPI events
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2005, R. Byron Moore
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <linux/module.h>

#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/acinterp.h>

#define _COMPONENT          ACPI_EVENTS
	 ACPI_MODULE_NAME    ("evxface")


/*******************************************************************************
 *
 * FUNCTION:    acpi_install_exception_handler
 *
 * PARAMETERS:  Handler         - Pointer to the handler function for the
 *                                event
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Saves the pointer to the handler function
 *
 ******************************************************************************/

#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_install_exception_handler (
	acpi_exception_handler          handler)
{
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_install_exception_handler");


	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Don't allow two handlers. */

	if (acpi_gbl_exception_handler) {
		status = AE_ALREADY_EXISTS;
		goto cleanup;
	}

	/* Install the handler */

	acpi_gbl_exception_handler = handler;

cleanup:
	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	return_ACPI_STATUS (status);
}
#endif  /*  ACPI_FUTURE_USAGE  */


/*******************************************************************************
 *
 * FUNCTION:    acpi_install_fixed_event_handler
 *
 * PARAMETERS:  Event           - Event type to enable.
 *              Handler         - Pointer to the handler function for the
 *                                event
 *              Context         - Value passed to the handler on each GPE
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Saves the pointer to the handler function and then enables the
 *              event.
 *
 ******************************************************************************/

acpi_status
acpi_install_fixed_event_handler (
	u32                             event,
	acpi_event_handler              handler,
	void                            *context)
{
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler");


	/* Parameter validation */

	if (event > ACPI_EVENT_MAX) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Don't allow two handlers. */

	if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
		status = AE_ALREADY_EXISTS;
		goto cleanup;
	}

	/* Install the handler before enabling the event */

	acpi_gbl_fixed_event_handlers[event].handler = handler;
	acpi_gbl_fixed_event_handlers[event].context = context;

	status = acpi_clear_event (event);
	if (ACPI_SUCCESS(status))
		status = acpi_enable_event (event, 0);
	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));

		/* Remove the handler */

		acpi_gbl_fixed_event_handlers[event].handler = NULL;
		acpi_gbl_fixed_event_handlers[event].context = NULL;
	}
	else {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"Enabled fixed event %X, Handler=%p\n", event, handler));
	}


cleanup:
	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_install_fixed_event_handler);


/*******************************************************************************
 *
 * FUNCTION:    acpi_remove_fixed_event_handler
 *
 * PARAMETERS:  Event           - Event type to disable.
 *              Handler         - Address of the handler
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Disables the event and unregisters the event handler.
 *
 ******************************************************************************/

acpi_status
acpi_remove_fixed_event_handler (
	u32                             event,
	acpi_event_handler              handler)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("acpi_remove_fixed_event_handler");


	/* Parameter validation */

	if (event > ACPI_EVENT_MAX) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Disable the event before removing the handler */

	status = acpi_disable_event (event, 0);

	/* Always Remove the handler */

	acpi_gbl_fixed_event_handlers[event].handler = NULL;
	acpi_gbl_fixed_event_handlers[event].context = NULL;

	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
			"Could not write to fixed event enable register.\n"));
	}
	else {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", event));
	}

	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_remove_fixed_event_handler);


/*******************************************************************************
 *
 * FUNCTION:    acpi_install_notify_handler
 *
 * PARAMETERS:  Device          - The device for which notifies will be handled
 *              handler_type    - The type of handler:
 *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
 *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
 *                                  ACPI_ALL_NOTIFY:  both system and device
 *              Handler         - Address of the handler
 *              Context         - Value passed to the handler on each GPE
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Install a handler for notifies on an ACPI device
 *
 ******************************************************************************/

acpi_status
acpi_install_notify_handler (
	acpi_handle                     device,
	u32                             handler_type,
	acpi_notify_handler             handler,
	void                            *context)
{
	union acpi_operand_object       *obj_desc;
	union acpi_operand_object       *notify_obj;
	struct acpi_namespace_node      *node;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_install_notify_handler");


	/* Parameter validation */

	if ((!device)  ||
		(!handler) ||
		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Convert and validate the device handle */

	node = acpi_ns_map_handle_to_node (device);
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

	/*
	 * Root Object:
	 * Registering a notify handler on the root object indicates that the
	 * caller wishes to receive notifications for all objects.  Note that
	 * only one <external> global handler can be regsitered (per notify type).
	 */
	if (device == ACPI_ROOT_OBJECT) {
		/* Make sure the handler is not already installed */

		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
				acpi_gbl_system_notify.handler)     ||
			((handler_type & ACPI_DEVICE_NOTIFY) &&
				acpi_gbl_device_notify.handler)) {
			status = AE_ALREADY_EXISTS;
			goto unlock_and_exit;
		}

		if (handler_type & ACPI_SYSTEM_NOTIFY) {
			acpi_gbl_system_notify.node  = node;
			acpi_gbl_system_notify.handler = handler;
			acpi_gbl_system_notify.context = context;
		}

		if (handler_type & ACPI_DEVICE_NOTIFY) {
			acpi_gbl_device_notify.node  = node;
			acpi_gbl_device_notify.handler = handler;
			acpi_gbl_device_notify.context = context;
		}

		/* Global notify handler installed */
	}

	/*
	 * All Other Objects:
	 * Caller will only receive notifications specific to the target object.
	 * Note that only certain object types can receive notifications.
	 */
	else {
		/* Notifies allowed on this object? */

		if (!acpi_ev_is_notify_object (node)) {
			status = AE_TYPE;
			goto unlock_and_exit;
		}

		/* Check for an existing internal object */

		obj_desc = acpi_ns_get_attached_object (node);
		if (obj_desc) {
			/* Object exists - make sure there's no handler */

			if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
					obj_desc->common_notify.system_notify) ||
				((handler_type & ACPI_DEVICE_NOTIFY) &&
					obj_desc->common_notify.device_notify)) {
				status = AE_ALREADY_EXISTS;
				goto unlock_and_exit;
			}
		}
		else {
			/* Create a new object */

			obj_desc = acpi_ut_create_internal_object (node->type);
			if (!obj_desc) {
				status = AE_NO_MEMORY;
				goto unlock_and_exit;
			}

			/* Attach new object to the Node */

			status = acpi_ns_attach_object (device, obj_desc, node->type);

			/* Remove local reference to the object */

			acpi_ut_remove_reference (obj_desc);
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}
		}

		/* Install the handler */

		notify_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_NOTIFY);
		if (!notify_obj) {
			status = AE_NO_MEMORY;
			goto unlock_and_exit;
		}

		notify_obj->notify.node   = node;
		notify_obj->notify.handler = handler;
		notify_obj->notify.context = context;

		if (handler_type & ACPI_SYSTEM_NOTIFY) {
			obj_desc->common_notify.system_notify = notify_obj;
		}

		if (handler_type & ACPI_DEVICE_NOTIFY) {
			obj_desc->common_notify.device_notify = notify_obj;
		}

		if (handler_type == ACPI_ALL_NOTIFY) {
			/* Extra ref if installed in both */

			acpi_ut_add_reference (notify_obj);
		}
	}


unlock_and_exit:
	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_install_notify_handler);


/*******************************************************************************
 *
 * FUNCTION:    acpi_remove_notify_handler
 *
 * PARAMETERS:  Device          - The device for which notifies will be handled
 *              handler_type    - The type of handler:
 *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
 *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
 *                                  ACPI_ALL_NOTIFY:  both system and device
 *              Handler         - Address of the handler
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Remove a handler for notifies on an ACPI device
 *
 ******************************************************************************/

acpi_status
acpi_remove_notify_handler (
	acpi_handle                     device,
	u32                             handler_type,
	acpi_notify_handler             handler)
{
	union acpi_operand_object       *notify_obj;
	union acpi_operand_object       *obj_desc;
	struct acpi_namespace_node      *node;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_remove_notify_handler");


	/* Parameter validation */

	if ((!device)  ||
		(!handler) ||
		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Convert and validate the device handle */

	node = acpi_ns_map_handle_to_node (device);
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

	/* Root Object */

	if (device == ACPI_ROOT_OBJECT) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"Removing notify handler for ROOT object.\n"));

		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
			  !acpi_gbl_system_notify.handler)      ||
			((handler_type & ACPI_DEVICE_NOTIFY) &&
			  !acpi_gbl_device_notify.handler)) {
			status = AE_NOT_EXIST;
			goto unlock_and_exit;
		}

		/* Make sure all deferred tasks are completed */

		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
		acpi_os_wait_events_complete(NULL);
		status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
 		}

		if (handler_type & ACPI_SYSTEM_NOTIFY) {
			acpi_gbl_system_notify.node  = NULL;
			acpi_gbl_system_notify.handler = NULL;
			acpi_gbl_system_notify.context = NULL;
		}

		if (handler_type & ACPI_DEVICE_NOTIFY) {
			acpi_gbl_device_notify.node  = NULL;
			acpi_gbl_device_notify.handler = NULL;
			acpi_gbl_device_notify.context = NULL;
		}
	}

	/* All Other Objects */

	else {
		/* Notifies allowed on this object? */

		if (!acpi_ev_is_notify_object (node)) {
			status = AE_TYPE;
			goto unlock_and_exit;
		}

		/* Check for an existing internal object */

		obj_desc = acpi_ns_get_attached_object (node);
		if (!obj_desc) {
			status = AE_NOT_EXIST;
			goto unlock_and_exit;
		}

		/* Object exists - make sure there's an existing handler */

		if (handler_type & ACPI_SYSTEM_NOTIFY) {
			notify_obj = obj_desc->common_notify.system_notify;
			if ((!notify_obj) ||
				 (notify_obj->notify.handler != handler)) {
				status = AE_BAD_PARAMETER;
				goto unlock_and_exit;
			}
			/* Make sure all deferred tasks are completed */

			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
			acpi_os_wait_events_complete(NULL);
			status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
			if (ACPI_FAILURE (status)) {
				return_ACPI_STATUS (status);
 			}

			/* Remove the handler */
			obj_desc->common_notify.system_notify = NULL;
			acpi_ut_remove_reference (notify_obj);
		}

		if (handler_type & ACPI_DEVICE_NOTIFY) {
			notify_obj = obj_desc->common_notify.device_notify;
			if ((!notify_obj) ||
				 (notify_obj->notify.handler != handler)) {
				status = AE_BAD_PARAMETER;
				goto unlock_and_exit;
			}
			/* Make sure all deferred tasks are completed */

			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
			acpi_os_wait_events_complete(NULL);
			status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
			if (ACPI_FAILURE (status)) {
				return_ACPI_STATUS (status);
 			}

			/* Remove the handler */
			obj_desc->common_notify.device_notify = NULL;
			acpi_ut_remove_reference (notify_obj);
		}
	}


unlock_and_exit:
	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_remove_notify_handler);


/*******************************************************************************
 *
 * FUNCTION:    acpi_install_gpe_handler
 *
 * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
 *                                defined GPEs)
 *              gpe_number      - The GPE number within the GPE block
 *              Type            - Whether this GPE should be treated as an
 *                                edge- or level-triggered interrupt.
 *              Address         - Address of the handler
 *              Context         - Value passed to the handler on each GPE
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Install a handler for a General Purpose Event.
 *
 ******************************************************************************/

acpi_status
acpi_install_gpe_handler (
	acpi_handle                     gpe_device,
	u32                             gpe_number,
	u32                             type,
	acpi_event_handler              address,
	void                            *context)
{
	struct acpi_gpe_event_info      *gpe_event_info;
	struct acpi_handler_info        *handler;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");


	/* Parameter validation */

	if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Ensure that we have a valid GPE number */

	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
	if (!gpe_event_info) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

	/* Make sure that there isn't a handler there already */

	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
		status = AE_ALREADY_EXISTS;
		goto unlock_and_exit;
	}

	/* Allocate and init handler object */

	handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info));
	if (!handler) {
		status = AE_NO_MEMORY;
		goto unlock_and_exit;
	}

	handler->address    = address;
	handler->context    = context;
	handler->method_node = gpe_event_info->dispatch.method_node;

	/* Disable the GPE before installing the handler */

	status = acpi_ev_disable_gpe (gpe_event_info);
	if (ACPI_FAILURE (status)) {
		goto unlock_and_exit;
	}

	/* Install the handler */

	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
	gpe_event_info->dispatch.handler = handler;

	/* Setup up dispatch flags to indicate handler (vs. method) */

	gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
	gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);

	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);


unlock_and_exit:
	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_install_gpe_handler);


/*******************************************************************************
 *
 * FUNCTION:    acpi_remove_gpe_handler
 *
 * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
 *                                defined GPEs)
 *              gpe_number      - The event to remove a handler
 *              Address         - Address of the handler
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
 *
 ******************************************************************************/

acpi_status
acpi_remove_gpe_handler (
	acpi_handle                     gpe_device,
	u32                             gpe_number,
	acpi_event_handler              address)
{
	struct acpi_gpe_event_info      *gpe_event_info;
	struct acpi_handler_info        *handler;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");


	/* Parameter validation */

	if (!address) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Ensure that we have a valid GPE number */

	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
	if (!gpe_event_info) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

	/* Make sure that a handler is indeed installed */

	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
		status = AE_NOT_EXIST;
		goto unlock_and_exit;
	}

	/* Make sure that the installed handler is the same */

	if (gpe_event_info->dispatch.handler->address != address) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

	/* Disable the GPE before removing the handler */

	status = acpi_ev_disable_gpe (gpe_event_info);
	if (ACPI_FAILURE (status)) {
		goto unlock_and_exit;
	}

	/* Make sure all deferred tasks are completed */

	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	acpi_os_wait_events_complete(NULL);
	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
 	}

	/* Remove the handler */

	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
	handler = gpe_event_info->dispatch.handler;

	/* Restore Method node (if any), set dispatch flags */

	gpe_event_info->dispatch.method_node = handler->method_node;
	gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
	if (handler->method_node) {
		gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
	}
	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);

	/* Now we can free the handler object */

	ACPI_MEM_FREE (handler);


unlock_and_exit:
	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_remove_gpe_handler);


/*******************************************************************************
 *
 * FUNCTION:    acpi_acquire_global_lock
 *
 * PARAMETERS:  Timeout         - How long the caller is willing to wait
 *              Handle          - Where the handle to the lock is returned
 *                                (if acquired)
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Acquire the ACPI Global Lock
 *
 ******************************************************************************/

acpi_status
acpi_acquire_global_lock (
	u16                             timeout,
	u32                             *handle)
{
	acpi_status                     status;


	if (!handle) {
		return (AE_BAD_PARAMETER);
	}

	status = acpi_ex_enter_interpreter ();
	if (ACPI_FAILURE (status)) {
		return (status);
	}

	status = acpi_ev_acquire_global_lock (timeout);
	acpi_ex_exit_interpreter ();

	if (ACPI_SUCCESS (status)) {
		acpi_gbl_global_lock_handle++;
		*handle = acpi_gbl_global_lock_handle;
	}

	return (status);
}
EXPORT_SYMBOL(acpi_acquire_global_lock);


/*******************************************************************************
 *
 * FUNCTION:    acpi_release_global_lock
 *
 * PARAMETERS:  Handle      - Returned from acpi_acquire_global_lock
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
 *
 ******************************************************************************/

acpi_status
acpi_release_global_lock (
	u32                             handle)
{
	acpi_status                     status;


	if (handle != acpi_gbl_global_lock_handle) {
		return (AE_NOT_ACQUIRED);
	}

	status = acpi_ev_release_global_lock ();
	return (status);
}
EXPORT_SYMBOL(acpi_release_global_lock);

