/*
 *  acpi_osl.c - OS-dependent functions ($Revision: 83 $)
 *
 *  Copyright (C) 2000       Andrew Henroid
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/nmi.h>
#include <acpi/acpi.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/processor.h>
#include <asm/uaccess.h>

#include <linux/efi.h>


#define _COMPONENT		ACPI_OS_SERVICES
ACPI_MODULE_NAME	("osl")

#define PREFIX		"ACPI: "

struct acpi_os_dpc
{
    acpi_osd_exec_callback  function;
    void		    *context;
};

#ifdef CONFIG_ACPI_CUSTOM_DSDT
#include CONFIG_ACPI_CUSTOM_DSDT_FILE
#endif

#ifdef ENABLE_DEBUGGER
#include <linux/kdb.h>

/* stuff for debugger support */
int acpi_in_debugger;
EXPORT_SYMBOL(acpi_in_debugger);

extern char line_buf[80];
#endif /*ENABLE_DEBUGGER*/

static unsigned int acpi_irq_irq;
static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
static struct workqueue_struct *kacpid_wq;

acpi_status
acpi_os_initialize(void)
{
	return AE_OK;
}

acpi_status
acpi_os_initialize1(void)
{
	/*
	 * Initialize PCI configuration space access, as we'll need to access
	 * it while walking the namespace (bus 0 and root bridges w/ _BBNs).
	 */
#ifdef CONFIG_ACPI_PCI
	if (!raw_pci_ops) {
		printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n");
		return AE_NULL_ENTRY;
	}
#endif
	kacpid_wq = create_singlethread_workqueue("kacpid");
	BUG_ON(!kacpid_wq);

	return AE_OK;
}

acpi_status
acpi_os_terminate(void)
{
	if (acpi_irq_handler) {
		acpi_os_remove_interrupt_handler(acpi_irq_irq,
						 acpi_irq_handler);
	}

	destroy_workqueue(kacpid_wq);

	return AE_OK;
}

void
acpi_os_printf(const char *fmt,...)
{
	va_list args;
	va_start(args, fmt);
	acpi_os_vprintf(fmt, args);
	va_end(args);
}
EXPORT_SYMBOL(acpi_os_printf);

void
acpi_os_vprintf(const char *fmt, va_list args)
{
	static char buffer[512];
	
	vsprintf(buffer, fmt, args);

#ifdef ENABLE_DEBUGGER
	if (acpi_in_debugger) {
		kdb_printf("%s", buffer);
	} else {
		printk("%s", buffer);
	}
#else
	printk("%s", buffer);
#endif
}

void *
acpi_os_allocate(acpi_size size)
{
	return kmalloc(size, GFP_KERNEL);
}

void
acpi_os_free(void *ptr)
{
	kfree(ptr);
}
EXPORT_SYMBOL(acpi_os_free);

acpi_status
acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
{
	if (efi_enabled) {
		addr->pointer_type = ACPI_PHYSICAL_POINTER;
		if (efi.acpi20)
			addr->pointer.physical =
				(acpi_physical_address) virt_to_phys(efi.acpi20);
		else if (efi.acpi)
			addr->pointer.physical =
				(acpi_physical_address) virt_to_phys(efi.acpi);
		else {
			printk(KERN_ERR PREFIX "System description tables not found\n");
			return AE_NOT_FOUND;
		}
	} else {
		if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) {
			printk(KERN_ERR PREFIX "System description tables not found\n");
			return AE_NOT_FOUND;
		}
	}

	return AE_OK;
}

acpi_status
acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void __iomem **virt)
{
	if (efi_enabled) {
		if (EFI_MEMORY_WB & efi_mem_attributes(phys)) {
			*virt = (void __iomem *) phys_to_virt(phys);
		} else {
			*virt = ioremap(phys, size);
		}
	} else {
		if (phys > ULONG_MAX) {
			printk(KERN_ERR PREFIX "Cannot map memory that high\n");
			return AE_BAD_PARAMETER;
		}
		/*
	 	 * ioremap checks to ensure this is in reserved space
	 	 */
		*virt = ioremap((unsigned long) phys, size);
	}

	if (!*virt)
		return AE_NO_MEMORY;

	return AE_OK;
}

void
acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
{
	iounmap(virt);
}

#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
{
	if(!phys || !virt)
		return AE_BAD_PARAMETER;

	*phys = virt_to_phys(virt);

	return AE_OK;
}
#endif

#define ACPI_MAX_OVERRIDE_LEN 100

static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];

acpi_status
acpi_os_predefined_override (const struct acpi_predefined_names *init_val,
		             acpi_string *new_val)
{
	if (!init_val || !new_val)
		return AE_BAD_PARAMETER;

	*new_val = NULL;
	if (!memcmp (init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
		printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
			acpi_os_name);
		*new_val = acpi_os_name;
	}

	return AE_OK;
}

acpi_status
acpi_os_table_override (struct acpi_table_header *existing_table,
			struct acpi_table_header **new_table)
{
	if (!existing_table || !new_table)
		return AE_BAD_PARAMETER;

#ifdef CONFIG_ACPI_CUSTOM_DSDT
	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
		*new_table = (struct acpi_table_header*)AmlCode;
	else
		*new_table = NULL;
#else
	*new_table = NULL;
#endif
	return AE_OK;
}

static irqreturn_t
acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
}

acpi_status
acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *context)
{
	unsigned int irq;

	/*
	 * Ignore the GSI from the core, and use the value in our copy of the
	 * FADT. It may not be the same if an interrupt source override exists
	 * for the SCI.
	 */
	gsi = acpi_fadt.sci_int;
	if (acpi_gsi_to_irq(gsi, &irq) < 0) {
		printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
		       gsi);
		return AE_OK;
	}

	acpi_irq_handler = handler;
	acpi_irq_context = context;
	if (request_irq(irq, acpi_irq, SA_SHIRQ, "acpi", acpi_irq)) {
		printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
		return AE_NOT_ACQUIRED;
	}
	acpi_irq_irq = irq;

	return AE_OK;
}

acpi_status
acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
{
	if (irq) {
		free_irq(irq, acpi_irq);
		acpi_irq_handler = NULL;
		acpi_irq_irq = 0;
	}

	return AE_OK;
}

/*
 * Running in interpreter thread context, safe to sleep
 */

void
acpi_os_sleep(acpi_integer ms)
{
	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(((signed long) ms * HZ) / 1000);
}
EXPORT_SYMBOL(acpi_os_sleep);

void
acpi_os_stall(u32 us)
{
	while (us) {
		u32 delay = 1000;

		if (delay > us)
			delay = us;
		udelay(delay);
		touch_nmi_watchdog();
		us -= delay;
	}
}
EXPORT_SYMBOL(acpi_os_stall);

/*
 * Support ACPI 3.0 AML Timer operand
 * Returns 64-bit free-running, monotonically increasing timer
 * with 100ns granularity
 */
u64
acpi_os_get_timer (void)
{
	static u64 t;

#ifdef	CONFIG_HPET
	/* TBD: use HPET if available */
#endif

#ifdef	CONFIG_X86_PM_TIMER
	/* TBD: default to PM timer if HPET was not available */
#endif
	if (!t)
		printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");

	return ++t;
}

acpi_status
acpi_os_read_port(
	acpi_io_address	port,
	u32		*value,
	u32		width)
{
	u32 dummy;

	if (!value)
		value = &dummy;

	switch (width)
	{
	case 8:
		*(u8*)  value = inb(port);
		break;
	case 16:
		*(u16*) value = inw(port);
		break;
	case 32:
		*(u32*) value = inl(port);
		break;
	default:
		BUG();
	}

	return AE_OK;
}
EXPORT_SYMBOL(acpi_os_read_port);

acpi_status
acpi_os_write_port(
	acpi_io_address	port,
	u32		value,
	u32		width)
{
	switch (width)
	{
	case 8:
		outb(value, port);
		break;
	case 16:
		outw(value, port);
		break;
	case 32:
		outl(value, port);
		break;
	default:
		BUG();
	}

	return AE_OK;
}
EXPORT_SYMBOL(acpi_os_write_port);

acpi_status
acpi_os_read_memory(
	acpi_physical_address	phys_addr,
	u32			*value,
	u32			width)
{
	u32			dummy;
	void __iomem		*virt_addr;
	int			iomem = 0;

	if (efi_enabled) {
		if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
			/* HACK ALERT! We can use readb/w/l on real memory too.. */
			virt_addr = (void __iomem *) phys_to_virt(phys_addr);
		} else {
			iomem = 1;
			virt_addr = ioremap(phys_addr, width);
		}
	} else
		virt_addr = (void __iomem *) phys_to_virt(phys_addr);
	if (!value)
		value = &dummy;

	switch (width) {
	case 8:
		*(u8*) value = readb(virt_addr);
		break;
	case 16:
		*(u16*) value = readw(virt_addr);
		break;
	case 32:
		*(u32*) value = readl(virt_addr);
		break;
	default:
		BUG();
	}

	if (efi_enabled) {
		if (iomem)
			iounmap(virt_addr);
	}

	return AE_OK;
}

acpi_status
acpi_os_write_memory(
	acpi_physical_address	phys_addr,
	u32			value,
	u32			width)
{
	void __iomem		*virt_addr;
	int			iomem = 0;

	if (efi_enabled) {
		if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
			/* HACK ALERT! We can use writeb/w/l on real memory too */
			virt_addr = (void __iomem *) phys_to_virt(phys_addr);
		} else {
			iomem = 1;
			virt_addr = ioremap(phys_addr, width);
		}
	} else
		virt_addr = (void __iomem *) phys_to_virt(phys_addr);

	switch (width) {
	case 8:
		writeb(value, virt_addr);
		break;
	case 16:
		writew(value, virt_addr);
		break;
	case 32:
		writel(value, virt_addr);
		break;
	default:
		BUG();
	}

	if (iomem)
		iounmap(virt_addr);

	return AE_OK;
}

#ifdef CONFIG_ACPI_PCI

acpi_status
acpi_os_read_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, void *value, u32 width)
{
	int result, size;

	if (!value)
		return AE_BAD_PARAMETER;

	switch (width) {
	case 8:
		size = 1;
		break;
	case 16:
		size = 2;
		break;
	case 32:
		size = 4;
		break;
	default:
		return AE_ERROR;
	}

	BUG_ON(!raw_pci_ops);

	result = raw_pci_ops->read(pci_id->segment, pci_id->bus,
				PCI_DEVFN(pci_id->device, pci_id->function),
				reg, size, value);

	return (result ? AE_ERROR : AE_OK);
}
EXPORT_SYMBOL(acpi_os_read_pci_configuration);

acpi_status
acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integer value, u32 width)
{
	int result, size;

	switch (width) {
	case 8:
		size = 1;
		break;
	case 16:
		size = 2;
		break;
	case 32:
		size = 4;
		break;
	default:
		return AE_ERROR;
	}

	BUG_ON(!raw_pci_ops);

	result = raw_pci_ops->write(pci_id->segment, pci_id->bus,
				PCI_DEVFN(pci_id->device, pci_id->function),
				reg, size, value);

	return (result ? AE_ERROR : AE_OK);
}

/* TODO: Change code to take advantage of driver model more */
static void
acpi_os_derive_pci_id_2 (
	acpi_handle		rhandle,        /* upper bound  */
	acpi_handle		chandle,        /* current node */
	struct acpi_pci_id	**id,
	int			*is_bridge,
	u8			*bus_number)
{
	acpi_handle		handle;
	struct acpi_pci_id	*pci_id = *id;
	acpi_status		status;
	unsigned long		temp;
	acpi_object_type	type;
	u8			tu8;

	acpi_get_parent(chandle, &handle);
	if (handle != rhandle) {
		acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, bus_number);

		status = acpi_get_type(handle, &type);
		if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) )
			return;

		status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &temp);
		if (ACPI_SUCCESS(status)) {
			pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (temp));
			pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));

			if (*is_bridge)
				pci_id->bus = *bus_number;

			/* any nicer way to get bus number of bridge ? */
			status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8);
			if (ACPI_SUCCESS(status) &&
			    ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
				status = acpi_os_read_pci_configuration(pci_id, 0x18, &tu8, 8);
				if (!ACPI_SUCCESS(status)) {
					/* Certainly broken...  FIX ME */
					return;
				}
				*is_bridge = 1;
				pci_id->bus = tu8;
				status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8);
				if (ACPI_SUCCESS(status)) {
					*bus_number = tu8;
				}
			} else
				*is_bridge = 0;
		}
	}
}

void
acpi_os_derive_pci_id (
	acpi_handle		rhandle,        /* upper bound  */
	acpi_handle		chandle,        /* current node */
	struct acpi_pci_id	**id)
{
	int is_bridge = 1;
	u8 bus_number = (*id)->bus;

	acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
}

#else /*!CONFIG_ACPI_PCI*/

acpi_status
acpi_os_write_pci_configuration (
	struct acpi_pci_id	*pci_id,
	u32			reg,
	acpi_integer		value,
	u32			width)
{
	return AE_SUPPORT;
}

acpi_status
acpi_os_read_pci_configuration (
	struct acpi_pci_id	*pci_id,
	u32			reg,
	void			*value,
	u32			width)
{
	return AE_SUPPORT;
}

void
acpi_os_derive_pci_id (
	acpi_handle		rhandle,        /* upper bound  */
	acpi_handle		chandle,        /* current node */
	struct acpi_pci_id	**id)
{
}

#endif /*CONFIG_ACPI_PCI*/

static void
acpi_os_execute_deferred (
	void *context)
{
	struct acpi_os_dpc	*dpc = NULL;

	ACPI_FUNCTION_TRACE ("os_execute_deferred");

	dpc = (struct acpi_os_dpc *) context;
	if (!dpc) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
		return_VOID;
	}

	dpc->function(dpc->context);

	kfree(dpc);

	return_VOID;
}

acpi_status
acpi_os_queue_for_execution(
	u32			priority,
	acpi_osd_exec_callback	function,
	void			*context)
{
	acpi_status 		status = AE_OK;
	struct acpi_os_dpc	*dpc;
	struct work_struct	*task;

	ACPI_FUNCTION_TRACE ("os_queue_for_execution");

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context));

	if (!function)
		return_ACPI_STATUS (AE_BAD_PARAMETER);

	/*
	 * Allocate/initialize DPC structure.  Note that this memory will be
	 * freed by the callee.  The kernel handles the tq_struct list  in a
	 * way that allows us to also free its memory inside the callee.
	 * Because we may want to schedule several tasks with different
	 * parameters we can't use the approach some kernel code uses of
	 * having a static tq_struct.
	 * We can save time and code by allocating the DPC and tq_structs
	 * from the same memory.
	 */

	dpc = kmalloc(sizeof(struct acpi_os_dpc)+sizeof(struct work_struct), GFP_ATOMIC);
	if (!dpc)
		return_ACPI_STATUS (AE_NO_MEMORY);

	dpc->function = function;
	dpc->context = context;

	task = (void *)(dpc+1);
	INIT_WORK(task, acpi_os_execute_deferred, (void*)dpc);

	if (!queue_work(kacpid_wq, task)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to queue_work() failed.\n"));
		kfree(dpc);
		status = AE_ERROR;
	}

	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_os_queue_for_execution);

void
acpi_os_wait_events_complete(
	void *context)
{
	flush_workqueue(kacpid_wq);
}
EXPORT_SYMBOL(acpi_os_wait_events_complete);

/*
 * Allocate the memory for a spinlock and initialize it.
 */
acpi_status
acpi_os_create_lock (
	acpi_handle	*out_handle)
{
	spinlock_t *lock_ptr;

	ACPI_FUNCTION_TRACE ("os_create_lock");

	lock_ptr = acpi_os_allocate(sizeof(spinlock_t));

	spin_lock_init(lock_ptr);

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr));

	*out_handle = lock_ptr;

	return_ACPI_STATUS (AE_OK);
}


/*
 * Deallocate the memory for a spinlock.
 */
void
acpi_os_delete_lock (
	acpi_handle	handle)
{
	ACPI_FUNCTION_TRACE ("os_create_lock");

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle));

	acpi_os_free(handle);

	return_VOID;
}

/*
 * Acquire a spinlock.
 *
 * handle is a pointer to the spinlock_t.
 * flags is *not* the result of save_flags - it is an ACPI-specific flag variable
 *   that indicates whether we are at interrupt level.
 */
void
acpi_os_acquire_lock (
	acpi_handle	handle,
	u32		flags)
{
	ACPI_FUNCTION_TRACE ("os_acquire_lock");

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquiring spinlock[%p] from %s level\n", handle,
		((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));

	if (flags & ACPI_NOT_ISR)
		ACPI_DISABLE_IRQS();

	spin_lock((spinlock_t *)handle);

	return_VOID;
}


/*
 * Release a spinlock. See above.
 */
void
acpi_os_release_lock (
	acpi_handle	handle,
	u32		flags)
{
	ACPI_FUNCTION_TRACE ("os_release_lock");

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Releasing spinlock[%p] from %s level\n", handle,
		((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));

	spin_unlock((spinlock_t *)handle);

	if (flags & ACPI_NOT_ISR)
		ACPI_ENABLE_IRQS();

	return_VOID;
}


acpi_status
acpi_os_create_semaphore(
	u32		max_units,
	u32		initial_units,
	acpi_handle	*handle)
{
	struct semaphore	*sem = NULL;

	ACPI_FUNCTION_TRACE ("os_create_semaphore");

	sem = acpi_os_allocate(sizeof(struct semaphore));
	if (!sem)
		return_ACPI_STATUS (AE_NO_MEMORY);
	memset(sem, 0, sizeof(struct semaphore));

	sema_init(sem, initial_units);

	*handle = (acpi_handle*)sem;

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n", *handle, initial_units));

	return_ACPI_STATUS (AE_OK);
}
EXPORT_SYMBOL(acpi_os_create_semaphore);


/*
 * TODO: A better way to delete semaphores?  Linux doesn't have a
 * 'delete_semaphore()' function -- may result in an invalid
 * pointer dereference for non-synchronized consumers.	Should
 * we at least check for blocked threads and signal/cancel them?
 */

acpi_status
acpi_os_delete_semaphore(
	acpi_handle	handle)
{
	struct semaphore *sem = (struct semaphore*) handle;

	ACPI_FUNCTION_TRACE ("os_delete_semaphore");

	if (!sem)
		return_ACPI_STATUS (AE_BAD_PARAMETER);

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));

	acpi_os_free(sem); sem =  NULL;

	return_ACPI_STATUS (AE_OK);
}
EXPORT_SYMBOL(acpi_os_delete_semaphore);


/*
 * TODO: The kernel doesn't have a 'down_timeout' function -- had to
 * improvise.  The process is to sleep for one scheduler quantum
 * until the semaphore becomes available.  Downside is that this
 * may result in starvation for timeout-based waits when there's
 * lots of semaphore activity.
 *
 * TODO: Support for units > 1?
 */
acpi_status
acpi_os_wait_semaphore(
	acpi_handle		handle,
	u32			units,
	u16			timeout)
{
	acpi_status		status = AE_OK;
	struct semaphore	*sem = (struct semaphore*)handle;
	int			ret = 0;

	ACPI_FUNCTION_TRACE ("os_wait_semaphore");

	if (!sem || (units < 1))
		return_ACPI_STATUS (AE_BAD_PARAMETER);

	if (units > 1)
		return_ACPI_STATUS (AE_SUPPORT);

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));

	if (in_atomic())
		timeout = 0;

	switch (timeout)
	{
		/*
		 * No Wait:
		 * --------
		 * A zero timeout value indicates that we shouldn't wait - just
		 * acquire the semaphore if available otherwise return AE_TIME
		 * (a.k.a. 'would block').
		 */
		case 0:
		if(down_trylock(sem))
			status = AE_TIME;
		break;

		/*
		 * Wait Indefinitely:
		 * ------------------
		 */
		case ACPI_WAIT_FOREVER:
		down(sem);
		break;

		/*
		 * Wait w/ Timeout:
		 * ----------------
		 */
		default:
		// TODO: A better timeout algorithm?
		{
			int i = 0;
			static const int quantum_ms = 1000/HZ;

			ret = down_trylock(sem);
			for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
				current->state = TASK_INTERRUPTIBLE;
				schedule_timeout(1);
				ret = down_trylock(sem);
			}
	
			if (ret != 0)
				status = AE_TIME;
		}
		break;
	}

	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Failed to acquire semaphore[%p|%d|%d], %s\n", 
			handle, units, timeout, acpi_format_exception(status)));
	}
	else {
		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout));
	}

	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_os_wait_semaphore);


/*
 * TODO: Support for units > 1?
 */
acpi_status
acpi_os_signal_semaphore(
    acpi_handle 	    handle,
    u32 		    units)
{
	struct semaphore *sem = (struct semaphore *) handle;

	ACPI_FUNCTION_TRACE ("os_signal_semaphore");

	if (!sem || (units < 1))
		return_ACPI_STATUS (AE_BAD_PARAMETER);

	if (units > 1)
		return_ACPI_STATUS (AE_SUPPORT);

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle, units));

	up(sem);

	return_ACPI_STATUS (AE_OK);
}
EXPORT_SYMBOL(acpi_os_signal_semaphore);

#ifdef ACPI_FUTURE_USAGE
u32
acpi_os_get_line(char *buffer)
{

#ifdef ENABLE_DEBUGGER
	if (acpi_in_debugger) {
		u32 chars;

		kdb_read(buffer, sizeof(line_buf));

		/* remove the CR kdb includes */
		chars = strlen(buffer) - 1;
		buffer[chars] = '\0';
	}
#endif

	return 0;
}
#endif  /*  ACPI_FUTURE_USAGE  */

/* Assumes no unreadable holes inbetween */
u8
acpi_os_readable(void *ptr, acpi_size len)
{
#if defined(__i386__) || defined(__x86_64__) 
	char tmp;
	return !__get_user(tmp, (char __user *)ptr) && !__get_user(tmp, (char __user *)ptr + len - 1);
#endif
	return 1;
}

#ifdef ACPI_FUTURE_USAGE
u8
acpi_os_writable(void *ptr, acpi_size len)
{
	/* could do dummy write (racy) or a kernel page table lookup.
	   The later may be difficult at early boot when kmap doesn't work yet. */
	return 1;
}
#endif

u32
acpi_os_get_thread_id (void)
{
	if (!in_atomic())
		return current->pid;

	return 0;
}

acpi_status
acpi_os_signal (
    u32		function,
    void	*info)
{
	switch (function)
	{
	case ACPI_SIGNAL_FATAL:
		printk(KERN_ERR PREFIX "Fatal opcode executed\n");
		break;
	case ACPI_SIGNAL_BREAKPOINT:
		/*
		 * AML Breakpoint
		 * ACPI spec. says to treat it as a NOP unless
		 * you are debugging.  So if/when we integrate
		 * AML debugger into the kernel debugger its
		 * hook will go here.  But until then it is
		 * not useful to print anything on breakpoints.
		 */
		break;
	default:
		break;
	}

	return AE_OK;
}
EXPORT_SYMBOL(acpi_os_signal);

static int __init
acpi_os_name_setup(char *str)
{
	char *p = acpi_os_name;
	int count = ACPI_MAX_OVERRIDE_LEN-1;

	if (!str || !*str)
		return 0;

	for (; count-- && str && *str; str++) {
		if (isalnum(*str) || *str == ' ' || *str == ':')
			*p++ = *str;
		else if (*str == '\'' || *str == '"')
			continue;
		else
			break;
	}
	*p = 0;

	return 1;
		
}

__setup("acpi_os_name=", acpi_os_name_setup);

/*
 * _OSI control
 * empty string disables _OSI
 * TBD additional string adds to _OSI
 */
static int __init
acpi_osi_setup(char *str)
{
	if (str == NULL || *str == '\0') {
		printk(KERN_INFO PREFIX "_OSI method disabled\n");
		acpi_gbl_create_osi_method = FALSE;
	} else
	{
		/* TBD */
		printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n", str);
	}

	return 1;
}

__setup("acpi_osi=", acpi_osi_setup);

/* enable serialization to combat AE_ALREADY_EXISTS errors */
static int __init
acpi_serialize_setup(char *str)
{
	printk(KERN_INFO PREFIX "serialize enabled\n");

	acpi_gbl_all_methods_serialized = TRUE;

	return 1;
}

__setup("acpi_serialize", acpi_serialize_setup);

/*
 * Wake and Run-Time GPES are expected to be separate.
 * We disable wake-GPEs at run-time to prevent spurious
 * interrupts.
 *
 * However, if a system exists that shares Wake and
 * Run-time events on the same GPE this flag is available
 * to tell Linux to keep the wake-time GPEs enabled at run-time.
 */
static int __init
acpi_wake_gpes_always_on_setup(char *str)
{
	printk(KERN_INFO PREFIX "wake GPEs not disabled\n");

	acpi_gbl_leave_wake_gpes_disabled = FALSE;

	return 1;
}

__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);

/*
 * max_cstate is defined in the base kernel so modules can
 * change it w/o depending on the state of the processor module.
 */
unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;


EXPORT_SYMBOL(max_cstate);
