/*
 *  acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 38 $)
 *
 *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
 *  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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/actypes.h>

#define _COMPONENT		ACPI_EC_COMPONENT
ACPI_MODULE_NAME		("acpi_ec")

#define ACPI_EC_COMPONENT		0x00100000
#define ACPI_EC_CLASS			"embedded_controller"
#define ACPI_EC_HID			"PNP0C09"
#define ACPI_EC_DRIVER_NAME		"ACPI Embedded Controller Driver"
#define ACPI_EC_DEVICE_NAME		"Embedded Controller"
#define ACPI_EC_FILE_INFO		"info"


#define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
#define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
#define ACPI_EC_FLAG_BURST	0x10	/* burst mode */
#define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */

#define ACPI_EC_EVENT_OBF	0x01	/* Output buffer full */
#define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */

#define ACPI_EC_DELAY		50	/* Wait 50ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */

#define ACPI_EC_UDELAY         100     /* Poll @ 100us increments */
#define ACPI_EC_UDELAY_COUNT   1000    /* Wait 10ms max. during EC ops */

#define ACPI_EC_COMMAND_READ	0x80
#define ACPI_EC_COMMAND_WRITE	0x81
#define ACPI_EC_BURST_ENABLE	0x82
#define ACPI_EC_BURST_DISABLE	0x83
#define ACPI_EC_COMMAND_QUERY	0x84

#define EC_POLLING		0xFF
#define EC_BURST		0x00


static int acpi_ec_remove (struct acpi_device *device, int type);
static int acpi_ec_start (struct acpi_device *device);
static int acpi_ec_stop (struct acpi_device *device, int type);
static int acpi_ec_burst_add ( struct acpi_device *device);

static struct acpi_driver acpi_ec_driver = {
	.name =		ACPI_EC_DRIVER_NAME,
	.class =	ACPI_EC_CLASS,
	.ids =		ACPI_EC_HID,
	.ops =		{
				.add =		acpi_ec_burst_add,
				.remove =	acpi_ec_remove,
				.start =	acpi_ec_start,
				.stop =		acpi_ec_stop,
			},
};
union acpi_ec {
	struct {
		u32				mode;
		acpi_handle			handle;
		unsigned long			uid;
		unsigned long			gpe_bit;
		struct acpi_generic_address	status_addr;
		struct acpi_generic_address	command_addr;
		struct acpi_generic_address	data_addr;
		unsigned long			global_lock;
	} common;

	struct {
		u32				mode;
		acpi_handle			handle;
		unsigned long			uid;
		unsigned long			gpe_bit;
		struct acpi_generic_address	status_addr;
		struct acpi_generic_address	command_addr;
		struct acpi_generic_address	data_addr;
		unsigned long			global_lock;
		unsigned int			expect_event;
		atomic_t			leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
		atomic_t			pending_gpe;
		struct semaphore		sem;
		wait_queue_head_t		wait;
	}burst;

	struct {
		u32				mode;
		acpi_handle			handle;
		unsigned long			uid;
		unsigned long			gpe_bit;
		struct acpi_generic_address	status_addr;
		struct acpi_generic_address	command_addr;
		struct acpi_generic_address	data_addr;
		unsigned long			global_lock;
       		spinlock_t                      lock;
	}polling;
};

static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event); 
static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event);
static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data);
static int acpi_ec_burst_read( union acpi_ec *ec, u8 address, u32 *data);
static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data);
static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data);
static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data);
static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data);
static void acpi_ec_gpe_polling_query ( void *ec_cxt);
static void acpi_ec_gpe_burst_query ( void *ec_cxt);
static u32 acpi_ec_gpe_polling_handler ( void *data);
static u32 acpi_ec_gpe_burst_handler ( void *data);
static acpi_status __init
acpi_fake_ecdt_polling_callback (
	acpi_handle	handle,
	u32		Level,
	void		*context,
	void		**retval);

static acpi_status __init
acpi_fake_ecdt_burst_callback (
	acpi_handle	handle,
	u32		Level,
	void		*context,
	void		**retval);

static int __init
acpi_ec_polling_get_real_ecdt(void);
static int __init
acpi_ec_burst_get_real_ecdt(void);
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
static union acpi_ec	*ec_ecdt;

/* External interfaces use first EC only, so remember */
static struct acpi_device *first_ec;
static int acpi_ec_polling_mode;

/* --------------------------------------------------------------------------
                             Transaction Management
   -------------------------------------------------------------------------- */

static inline u32 acpi_ec_read_status(union acpi_ec *ec)
{
	u32	status = 0;

	acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
	return status;
}

static int
acpi_ec_wait (
	union acpi_ec		*ec,
	u8			event)
{
	if (acpi_ec_polling_mode) 
		return acpi_ec_polling_wait (ec, event);
	else
		return acpi_ec_burst_wait (ec, event);
}

static int
acpi_ec_polling_wait (
	union acpi_ec		*ec,
	u8			event)
{
	u32			acpi_ec_status = 0;
	u32			i = ACPI_EC_UDELAY_COUNT;

	if (!ec)
		return -EINVAL;

	/* Poll the EC status register waiting for the event to occur. */
	switch (event) {
	case ACPI_EC_EVENT_OBF:
		do {
			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
				return 0;
			udelay(ACPI_EC_UDELAY);
		} while (--i>0);
		break;
	case ACPI_EC_EVENT_IBE:
		do {
			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
				return 0;
			udelay(ACPI_EC_UDELAY);
		} while (--i>0);
		break;
	default:
		return -EINVAL;
	}

	return -ETIME;
}
static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
{
	int	result = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_wait");

	ec->burst.expect_event = event;
	smp_mb();

	result = wait_event_interruptible_timeout(ec->burst.wait,
					!ec->burst.expect_event,
					msecs_to_jiffies(ACPI_EC_DELAY));
	
	ec->burst.expect_event = 0;
	smp_mb();

	if (result < 0){
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result  = %d ", result));
		return_VALUE(result);
	}

	/*
	 * Verify that the event in question has actually happened by
	 * querying EC status. Do the check even if operation timed-out
	 * to make sure that we did not miss interrupt.
	 */
	switch (event) {
	case ACPI_EC_EVENT_OBF:
		if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
			return_VALUE(0);
		break;

	case ACPI_EC_EVENT_IBE:
		if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
			return_VALUE(0);
		break;
	}

	return_VALUE(-ETIME);
}



static int
acpi_ec_enter_burst_mode (
	union acpi_ec		*ec)
{
	u32			tmp = 0;
	int			status = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode");

	status = acpi_ec_read_status(ec);
	if (status != -EINVAL &&
		!(status & ACPI_EC_FLAG_BURST)){
		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
		if (status){
			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
			return_VALUE(-EINVAL);
		}
		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		if(tmp != 0x90 ) {/* Burst ACK byte*/
			return_VALUE(-EINVAL);
		}
	}

	atomic_set(&ec->burst.leaving_burst , 0);
	return_VALUE(0);
}

static int
acpi_ec_leave_burst_mode (
	union acpi_ec		*ec)
{
	int			status =0;

	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");

	atomic_set(&ec->burst.leaving_burst , 1);
	status = acpi_ec_read_status(ec);
	if (status != -EINVAL &&
		(status & ACPI_EC_FLAG_BURST)){
		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
		if (status){
			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
			return_VALUE(-EINVAL);
		}
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		status = acpi_ec_read_status(ec);
	}

	return_VALUE(0);
}

static int
acpi_ec_read (
	union acpi_ec		*ec,
	u8			address,
	u32			*data)
{
	if (acpi_ec_polling_mode) 
		return acpi_ec_polling_read(ec, address, data);
	else
		return acpi_ec_burst_read(ec, address, data);
}
static int
acpi_ec_write (
	union acpi_ec		*ec,
	u8			address,
	u8			data)
{
	if (acpi_ec_polling_mode) 
		return acpi_ec_polling_write(ec, address, data);
	else
		return acpi_ec_burst_write(ec, address, data);
}
static int
acpi_ec_polling_read (
	union acpi_ec		*ec,
	u8			address,
	u32			*data)
{
	acpi_status		status = AE_OK;
	int			result = 0;
	unsigned long		flags = 0;
	u32			glk = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_read");

	if (!ec || !data)
		return_VALUE(-EINVAL);

	*data = 0;

	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
			return_VALUE(-ENODEV);
	}

	spin_lock_irqsave(&ec->polling.lock, flags);

	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (result)
		goto end;

	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
	if (result)
		goto end;

	acpi_hw_low_level_read(8, data, &ec->common.data_addr);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
		*data, address));
	
end:
	spin_unlock_irqrestore(&ec->polling.lock, flags);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	return_VALUE(result);
}


static int
acpi_ec_polling_write (
	union acpi_ec		*ec,
	u8			address,
	u8			data)
{
	int			result = 0;
	acpi_status		status = AE_OK;
	unsigned long		flags = 0;
	u32			glk = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_write");

	if (!ec)
		return_VALUE(-EINVAL);

	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
			return_VALUE(-ENODEV);
	}

	spin_lock_irqsave(&ec->polling.lock, flags);

	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (result)
		goto end;

	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (result)
		goto end;

	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (result)
		goto end;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
		data, address));

end:
	spin_unlock_irqrestore(&ec->polling.lock, flags);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	return_VALUE(result);
}

static int
acpi_ec_burst_read (
	union acpi_ec		*ec,
	u8			address,
	u32			*data)
{
	int			status = 0;
	u32			glk;

	ACPI_FUNCTION_TRACE("acpi_ec_read");

	if (!ec || !data)
		return_VALUE(-EINVAL);

retry:
	*data = 0;

	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
			return_VALUE(-ENODEV);
	}

	WARN_ON(in_interrupt());
	down(&ec->burst.sem);

	if(acpi_ec_enter_burst_mode(ec))
		goto end;

	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (status) {
		goto end;
	}

	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
	if (status){
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto end;
	}

	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
		*data, address));
	
end:
	acpi_ec_leave_burst_mode(ec);
	up(&ec->burst.sem);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	if(atomic_read(&ec->burst.leaving_burst) == 2){
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
		while(atomic_read(&ec->burst.pending_gpe)){
			msleep(1);	
		}
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto retry;
	}

	return_VALUE(status);
}


static int
acpi_ec_burst_write (
	union acpi_ec		*ec,
	u8			address,
	u8			data)
{
	int			status = 0;
	u32			glk;
	u32			tmp;

	ACPI_FUNCTION_TRACE("acpi_ec_write");

	if (!ec)
		return_VALUE(-EINVAL);
retry:
	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
			return_VALUE(-ENODEV);
	}

	WARN_ON(in_interrupt());
	down(&ec->burst.sem);

	if(acpi_ec_enter_burst_mode(ec))
		goto end;

	status = acpi_ec_read_status(ec);
	if (status != -EINVAL &&
		!(status & ACPI_EC_FLAG_BURST)){
		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
		if (status)
			goto end;
		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
		if(tmp != 0x90 ) /* Burst ACK byte*/
			goto end;
	}
	/*Now we are in burst mode*/

	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (status){
		goto end;
	}

	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (status){
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto end;
	}

	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (status)
		goto end;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
		data, address));

end:
	acpi_ec_leave_burst_mode(ec);
	up(&ec->burst.sem);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	if(atomic_read(&ec->burst.leaving_burst) == 2){
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
		while(atomic_read(&ec->burst.pending_gpe)){
			msleep(1);	
		}
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto retry;
	}

	return_VALUE(status);
}

/*
 * Externally callable EC access functions. For now, assume 1 EC only
 */
int
ec_read(u8 addr, u8 *val)
{
	union acpi_ec *ec;
	int err;
	u32 temp_data;

	if (!first_ec)
		return -ENODEV;

	ec = acpi_driver_data(first_ec);

	err = acpi_ec_read(ec, addr, &temp_data);

	if (!err) {
		*val = temp_data;
		return 0;
	}
	else
		return err;
}
EXPORT_SYMBOL(ec_read);

int
ec_write(u8 addr, u8 val)
{
	union acpi_ec *ec;
	int err;

	if (!first_ec)
		return -ENODEV;

	ec = acpi_driver_data(first_ec);

	err = acpi_ec_write(ec, addr, val);

	return err;
}
EXPORT_SYMBOL(ec_write);

static int
acpi_ec_query (
	union acpi_ec		*ec,
	u32			*data)
{
	if (acpi_ec_polling_mode) 
		return acpi_ec_polling_query(ec, data);
	else
		return acpi_ec_burst_query(ec, data);
}
static int
acpi_ec_polling_query (
	union acpi_ec		*ec,
	u32			*data)
{
	int			result = 0;
	acpi_status		status = AE_OK;
	unsigned long		flags = 0;
	u32			glk = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_query");

	if (!ec || !data)
		return_VALUE(-EINVAL);

	*data = 0;

	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
			return_VALUE(-ENODEV);
	}

	/*
	 * Query the EC to find out which _Qxx method we need to evaluate.
	 * Note that successful completion of the query causes the ACPI_EC_SCI
	 * bit to be cleared (and thus clearing the interrupt source).
	 */
	spin_lock_irqsave(&ec->polling.lock, flags);

	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
	if (result)
		goto end;

	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
	if (!*data)
		result = -ENODATA;

end:
	spin_unlock_irqrestore(&ec->polling.lock, flags);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	return_VALUE(result);
}
static int
acpi_ec_burst_query (
	union acpi_ec		*ec,
	u32			*data)
{
	int			status = 0;
	u32			glk;

	ACPI_FUNCTION_TRACE("acpi_ec_query");

	if (!ec || !data)
		return_VALUE(-EINVAL);
	*data = 0;

	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
			return_VALUE(-ENODEV);
	}

	down(&ec->burst.sem);
	if(acpi_ec_enter_burst_mode(ec))
		goto end;
	/*
	 * Query the EC to find out which _Qxx method we need to evaluate.
	 * Note that successful completion of the query causes the ACPI_EC_SCI
	 * bit to be cleared (and thus clearing the interrupt source).
	 */
	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
	if (status){
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto end;
	}

	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (!*data)
		status = -ENODATA;

end:
	acpi_ec_leave_burst_mode(ec);
	up(&ec->burst.sem);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	if(atomic_read(&ec->burst.leaving_burst) == 2){
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		status = -ENODATA;
	}
	return_VALUE(status);
}


/* --------------------------------------------------------------------------
                                Event Management
   -------------------------------------------------------------------------- */

union acpi_ec_query_data {
	acpi_handle		handle;
	u8			data;
};

static void
acpi_ec_gpe_query (
	void			*ec_cxt)
{
	if (acpi_ec_polling_mode) 
		acpi_ec_gpe_polling_query(ec_cxt);
	else
		acpi_ec_gpe_burst_query(ec_cxt);
}

static void
acpi_ec_gpe_polling_query (
	void			*ec_cxt)
{
	union acpi_ec		*ec = (union acpi_ec *) ec_cxt;
	u32			value = 0;
	unsigned long		flags = 0;
	static char		object_name[5] = {'_','Q','0','0','\0'};
	const char		hex[] = {'0','1','2','3','4','5','6','7',
				         '8','9','A','B','C','D','E','F'};

	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");

	if (!ec_cxt)
		goto end;

	spin_lock_irqsave(&ec->polling.lock, flags);
	acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
	spin_unlock_irqrestore(&ec->polling.lock, flags);

	/* TBD: Implement asynch events!
	 * NOTE: All we care about are EC-SCI's.  Other EC events are
	 * handled via polling (yuck!).  This is because some systems
	 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
	 *  a purely interrupt-driven approach (grumble, grumble).
	 */
	if (!(value & ACPI_EC_FLAG_SCI))
		goto end;

	if (acpi_ec_query(ec, &value))
		goto end;

	object_name[2] = hex[((value >> 4) & 0x0F)];
	object_name[3] = hex[(value & 0x0F)];

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));

	acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);

end:	
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
}
static void
acpi_ec_gpe_burst_query (
	void			*ec_cxt)
{
	union acpi_ec		*ec = (union acpi_ec *) ec_cxt;
	u32			value;
	int			result = -ENODATA;
	static char		object_name[5] = {'_','Q','0','0','\0'};
	const char		hex[] = {'0','1','2','3','4','5','6','7',
				         '8','9','A','B','C','D','E','F'};

	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");

	if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
		result = acpi_ec_query(ec, &value);

	if (result)
		goto end;

	object_name[2] = hex[((value >> 4) & 0x0F)];
	object_name[3] = hex[(value & 0x0F)];

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));

	acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
end:	
	atomic_dec(&ec->burst.pending_gpe);
	return;
}

static u32
acpi_ec_gpe_handler (
	void			*data)
{
	if (acpi_ec_polling_mode) 
		return acpi_ec_gpe_polling_handler(data);
	else
		return acpi_ec_gpe_burst_handler(data);	
}
static u32
acpi_ec_gpe_polling_handler (
	void			*data)
{
	acpi_status		status = AE_OK;
	union acpi_ec		*ec = (union acpi_ec *) data;

	if (!ec)
		return ACPI_INTERRUPT_NOT_HANDLED;

	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);

	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
		acpi_ec_gpe_query, ec);

	if (status == AE_OK)
		return ACPI_INTERRUPT_HANDLED;
	else
		return ACPI_INTERRUPT_NOT_HANDLED;
}
static u32
acpi_ec_gpe_burst_handler (
	void			*data)
{
	acpi_status		status = AE_OK;
	u32			value;
	union acpi_ec		*ec = (union acpi_ec *) data;

	if (!ec)
		return ACPI_INTERRUPT_NOT_HANDLED;

	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);

	value = acpi_ec_read_status(ec);

	if((value & ACPI_EC_FLAG_IBF) &&
		!(value & ACPI_EC_FLAG_BURST) &&
			(atomic_read(&ec->burst.leaving_burst) == 0)) { 
	/*
	 * the embedded controller disables 
	 * burst mode for any reason other 
	 * than the burst disable command
	 * to process critical event.
	 */
		atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
					and retry */
		wake_up(&ec->burst.wait);
	}else {
		if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
				(value & ACPI_EC_FLAG_OBF)) ||
	    			(ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
				!(value & ACPI_EC_FLAG_IBF))) {
			ec->burst.expect_event = 0;
			wake_up(&ec->burst.wait);
			return ACPI_INTERRUPT_HANDLED;
		}
	}

	if (value & ACPI_EC_FLAG_SCI){
		atomic_add(1, &ec->burst.pending_gpe) ;
		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
						acpi_ec_gpe_query, ec);
		return status == AE_OK ?
		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
	} 
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
	return status == AE_OK ?
		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
}

/* --------------------------------------------------------------------------
                             Address Space Management
   -------------------------------------------------------------------------- */

static acpi_status
acpi_ec_space_setup (
	acpi_handle		region_handle,
	u32			function,
	void			*handler_context,
	void			**return_context)
{
	/*
	 * The EC object is in the handler context and is needed
	 * when calling the acpi_ec_space_handler.
	 */
	*return_context  = (function != ACPI_REGION_DEACTIVATE) ?
						handler_context : NULL;

	return AE_OK;
}


static acpi_status
acpi_ec_space_handler (
	u32			function,
	acpi_physical_address	address,
	u32			bit_width,
	acpi_integer		*value,
	void			*handler_context,
	void			*region_context)
{
	int			result = 0;
	union acpi_ec		*ec = NULL;
	u64			temp = *value;
	acpi_integer		f_v = 0;
	int 			i = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_space_handler");

	if ((address > 0xFF) || !value || !handler_context)
		return_VALUE(AE_BAD_PARAMETER);

	if (bit_width != 8 && acpi_strict) {
		printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
		return_VALUE(AE_BAD_PARAMETER);
	}

	ec = (union acpi_ec *) handler_context;

next_byte:
	switch (function) {
	case ACPI_READ:
		temp = 0;
		result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);
		break;
	case ACPI_WRITE:
		result = acpi_ec_write(ec, (u8) address, (u8) temp);
		break;
	default:
		result = -EINVAL;
		goto out;
		break;
	}

	bit_width -= 8;
	if (bit_width) {
		if (function == ACPI_READ)
			f_v |= temp << 8 * i;
		if (function == ACPI_WRITE)
			temp >>= 8;
		i++;
		address++;
		goto next_byte;
	}

	if (function == ACPI_READ) {
		f_v |= temp << 8 * i;
		*value = f_v;
	}

		
out:
	switch (result) {
	case -EINVAL:
		return_VALUE(AE_BAD_PARAMETER);
		break;
	case -ENODEV:
		return_VALUE(AE_NOT_FOUND);
		break;
	case -ETIME:
		return_VALUE(AE_TIME);
		break;
	default:
		return_VALUE(AE_OK);
	}
}


/* --------------------------------------------------------------------------
                              FS Interface (/proc)
   -------------------------------------------------------------------------- */

static struct proc_dir_entry	*acpi_ec_dir;


static int
acpi_ec_read_info (struct seq_file *seq, void *offset)
{
	union acpi_ec		*ec = (union acpi_ec *) seq->private;

	ACPI_FUNCTION_TRACE("acpi_ec_read_info");

	if (!ec)
		goto end;

	seq_printf(seq, "gpe bit:                 0x%02x\n",
		(u32) ec->common.gpe_bit);
	seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
		(u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address);
	seq_printf(seq, "use global lock:         %s\n",
		ec->common.global_lock?"yes":"no");
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);

end:
	return_VALUE(0);
}

static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}

static struct file_operations acpi_ec_info_ops = {
	.open		= acpi_ec_info_open_fs,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.owner = THIS_MODULE,
};

static int
acpi_ec_add_fs (
	struct acpi_device	*device)
{
	struct proc_dir_entry	*entry = NULL;

	ACPI_FUNCTION_TRACE("acpi_ec_add_fs");

	if (!acpi_device_dir(device)) {
		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
			acpi_ec_dir);
		if (!acpi_device_dir(device))
			return_VALUE(-ENODEV);
	}

	entry = create_proc_entry(ACPI_EC_FILE_INFO, S_IRUGO,
		acpi_device_dir(device));
	if (!entry)
		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
			"Unable to create '%s' fs entry\n",
			ACPI_EC_FILE_INFO));
	else {
		entry->proc_fops = &acpi_ec_info_ops;
		entry->data = acpi_driver_data(device);
		entry->owner = THIS_MODULE;
	}

	return_VALUE(0);
}


static int
acpi_ec_remove_fs (
	struct acpi_device	*device)
{
	ACPI_FUNCTION_TRACE("acpi_ec_remove_fs");

	if (acpi_device_dir(device)) {
		remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
		remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
		acpi_device_dir(device) = NULL;
	}

	return_VALUE(0);
}


/* --------------------------------------------------------------------------
                               Driver Interface
   -------------------------------------------------------------------------- */


static int
acpi_ec_polling_add (
	struct acpi_device	*device)
{
	int			result = 0;
	acpi_status		status = AE_OK;
	union acpi_ec		*ec = NULL;
	unsigned long		uid;

	ACPI_FUNCTION_TRACE("acpi_ec_add");

	if (!device)
		return_VALUE(-EINVAL);

	ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
	if (!ec)
		return_VALUE(-ENOMEM);
	memset(ec, 0, sizeof(union acpi_ec));

	ec->common.handle = device->handle;
	ec->common.uid = -1;
	spin_lock_init(&ec->polling.lock);
	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
	acpi_driver_data(device) = ec;

	/* Use the global lock for all EC transactions? */
	acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);

	/* If our UID matches the UID for the ECDT-enumerated EC,
	   we now have the *real* EC info, so kill the makeshift one.*/
	acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
	if (ec_ecdt && ec_ecdt->common.uid == uid) {
		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
	
		acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);

		kfree(ec_ecdt);
	}

	/* Get GPE bit assignment (EC events). */
	/* TODO: Add support for _GPE returning a package */
	status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			"Error obtaining GPE bit assignment\n"));
		result = -ENODEV;
		goto end;
	}

	result = acpi_ec_add_fs(device);
	if (result)
		goto end;

	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
		acpi_device_name(device), acpi_device_bid(device),
		(u32) ec->common.gpe_bit);

	if (!first_ec)
		first_ec = device;

end:
	if (result)
		kfree(ec);

	return_VALUE(result);
}
static int
acpi_ec_burst_add (
	struct acpi_device	*device)
{
	int			result = 0;
	acpi_status		status = AE_OK;
	union acpi_ec		*ec = NULL;
	unsigned long		uid;

	ACPI_FUNCTION_TRACE("acpi_ec_add");

	if (!device)
		return_VALUE(-EINVAL);

	ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
	if (!ec)
		return_VALUE(-ENOMEM);
	memset(ec, 0, sizeof(union acpi_ec));

	ec->common.handle = device->handle;
	ec->common.uid = -1;
 	atomic_set(&ec->burst.pending_gpe, 0);
 	atomic_set(&ec->burst.leaving_burst , 1);
 	init_MUTEX(&ec->burst.sem);
 	init_waitqueue_head(&ec->burst.wait);
	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
	acpi_driver_data(device) = ec;

	/* Use the global lock for all EC transactions? */
	acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);

	/* If our UID matches the UID for the ECDT-enumerated EC,
	   we now have the *real* EC info, so kill the makeshift one.*/
	acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
	if (ec_ecdt && ec_ecdt->common.uid == uid) {
		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);

		acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);

		kfree(ec_ecdt);
	}

	/* Get GPE bit assignment (EC events). */
	/* TODO: Add support for _GPE returning a package */
	status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			"Error obtaining GPE bit assignment\n"));
		result = -ENODEV;
		goto end;
	}

	result = acpi_ec_add_fs(device);
	if (result)
		goto end;

	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
		acpi_device_name(device), acpi_device_bid(device),
		(u32) ec->common.gpe_bit);

	if (!first_ec)
		first_ec = device;

end:
	if (result)
		kfree(ec);

	return_VALUE(result);
}


static int
acpi_ec_remove (
	struct acpi_device	*device,
	int			type)
{
	union acpi_ec		*ec = NULL;

	ACPI_FUNCTION_TRACE("acpi_ec_remove");

	if (!device)
		return_VALUE(-EINVAL);

	ec = acpi_driver_data(device);

	acpi_ec_remove_fs(device);

	kfree(ec);

	return_VALUE(0);
}


static acpi_status
acpi_ec_io_ports (
	struct acpi_resource	*resource,
	void			*context)
{
	union acpi_ec		*ec = (union acpi_ec *) context;
	struct acpi_generic_address *addr;

	if (resource->id != ACPI_RSTYPE_IO) {
		return AE_OK;
	}

	/*
	 * The first address region returned is the data port, and
	 * the second address region returned is the status/command
	 * port.
	 */
	if (ec->common.data_addr.register_bit_width == 0) {
		addr = &ec->common.data_addr;
	} else if (ec->common.command_addr.register_bit_width == 0) {
		addr = &ec->common.command_addr;
	} else {
		return AE_CTRL_TERMINATE;
	}

	addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
	addr->register_bit_width = 8;
	addr->register_bit_offset = 0;
	addr->address = resource->data.io.min_base_address;

	return AE_OK;
}


static int
acpi_ec_start (
	struct acpi_device	*device)
{
	acpi_status		status = AE_OK;
	union acpi_ec		*ec = NULL;

	ACPI_FUNCTION_TRACE("acpi_ec_start");

	if (!device)
		return_VALUE(-EINVAL);

	ec = acpi_driver_data(device);

	if (!ec)
		return_VALUE(-EINVAL);

	/*
	 * Get I/O port addresses. Convert to GAS format.
	 */
	status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
		acpi_ec_io_ports, ec);
	if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
		return_VALUE(-ENODEV);
	}

	ec->common.status_addr = ec->common.command_addr;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
		(u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address,
		(u32) ec->common.data_addr.address));


	/*
	 * Install GPE handler
	 */
	status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
	if (ACPI_FAILURE(status)) {
		return_VALUE(-ENODEV);
	}
	acpi_set_gpe_type (NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
	acpi_enable_gpe (NULL, ec->common.gpe_bit, ACPI_NOT_ISR);

	status = acpi_install_address_space_handler (ec->common.handle,
			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
			&acpi_ec_space_setup, ec);
	if (ACPI_FAILURE(status)) {
		acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
		return_VALUE(-ENODEV);
	}

	return_VALUE(AE_OK);
}


static int
acpi_ec_stop (
	struct acpi_device	*device,
	int			type)
{
	acpi_status		status = AE_OK;
	union acpi_ec		*ec = NULL;

	ACPI_FUNCTION_TRACE("acpi_ec_stop");

	if (!device)
		return_VALUE(-EINVAL);

	ec = acpi_driver_data(device);

	status = acpi_remove_address_space_handler(ec->common.handle,
		ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
	if (ACPI_FAILURE(status))
		return_VALUE(-ENODEV);

	status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
	if (ACPI_FAILURE(status))
		return_VALUE(-ENODEV);

	return_VALUE(0);
}

static acpi_status __init
acpi_fake_ecdt_callback (
	acpi_handle	handle,
	u32		Level,
	void		*context,
	void		**retval)
{

	if (acpi_ec_polling_mode)
		return acpi_fake_ecdt_polling_callback(handle,
			Level, context, retval);
	else
		return acpi_fake_ecdt_burst_callback(handle,
			Level, context, retval);
}

static acpi_status __init
acpi_fake_ecdt_polling_callback (
	acpi_handle	handle,
	u32		Level,
	void		*context,
	void		**retval)
{
	acpi_status	status;

	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
		acpi_ec_io_ports, ec_ecdt);
	if (ACPI_FAILURE(status))
		return status;
	ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;

	ec_ecdt->common.uid = -1;
	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);

	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
	if (ACPI_FAILURE(status))
		return status;
	spin_lock_init(&ec_ecdt->polling.lock);
	ec_ecdt->common.global_lock = TRUE;
	ec_ecdt->common.handle = handle;

	printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
		(u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
		(u32) ec_ecdt->common.data_addr.address);

	return AE_CTRL_TERMINATE;
}

static acpi_status __init
acpi_fake_ecdt_burst_callback (
	acpi_handle	handle,
	u32		Level,
	void		*context,
	void		**retval)
{
	acpi_status	status;

	init_MUTEX(&ec_ecdt->burst.sem);
	init_waitqueue_head(&ec_ecdt->burst.wait);
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
		acpi_ec_io_ports, ec_ecdt);
	if (ACPI_FAILURE(status))
		return status;
	ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;

	ec_ecdt->common.uid = -1;
	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);

	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
	if (ACPI_FAILURE(status))
		return status;
	ec_ecdt->common.global_lock = TRUE;
	ec_ecdt->common.handle = handle;

	printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
		(u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
		(u32) ec_ecdt->common.data_addr.address);

	return AE_CTRL_TERMINATE;
}

/*
 * Some BIOS (such as some from Gateway laptops) access EC region very early
 * such as in BAT0._INI or EC._INI before an EC device is found and
 * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
 * required, but if EC regison is accessed early, it is required.
 * The routine tries to workaround the BIOS bug by pre-scan EC device
 * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
 * op region (since _REG isn't invoked yet). The assumption is true for
 * all systems found.
 */
static int __init
acpi_ec_fake_ecdt(void)
{
	acpi_status	status;
	int		ret = 0;

	printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");

	ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
	if (!ec_ecdt) {
		ret = -ENOMEM;
		goto error;
	}
	memset(ec_ecdt, 0, sizeof(union acpi_ec));

	status = acpi_get_devices (ACPI_EC_HID,
				acpi_fake_ecdt_callback,
				NULL,
				NULL);
	if (ACPI_FAILURE(status)) {
		kfree(ec_ecdt);
		ec_ecdt = NULL;
		ret = -ENODEV;
		goto error;
	}
	return 0;
error:
	printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
	return ret;
}

static int __init
acpi_ec_get_real_ecdt(void)
{
	if (acpi_ec_polling_mode)
		return acpi_ec_polling_get_real_ecdt();
	else
		return acpi_ec_burst_get_real_ecdt();
}

static int __init
acpi_ec_polling_get_real_ecdt(void)
{
	acpi_status		status;
	struct acpi_table_ecdt 	*ecdt_ptr;

	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
		(struct acpi_table_header **) &ecdt_ptr);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	printk(KERN_INFO PREFIX "Found ECDT\n");

	/*
	 * Generate a temporary ec context to use until the namespace is scanned
	 */
	ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
	if (!ec_ecdt)
		return -ENOMEM;
	memset(ec_ecdt, 0, sizeof(union acpi_ec));

	ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
	ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
	ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
	ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
	spin_lock_init(&ec_ecdt->polling.lock);
	/* use the GL just to be safe */
	ec_ecdt->common.global_lock = TRUE;
	ec_ecdt->common.uid = ecdt_ptr->uid;

	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
	if (ACPI_FAILURE(status)) {
		goto error;
	}

	return 0;
error:
	printk(KERN_ERR PREFIX "Could not use ECDT\n");
	kfree(ec_ecdt);
	ec_ecdt = NULL;

	return -ENODEV;
}


static int __init
acpi_ec_burst_get_real_ecdt(void)
{
	acpi_status		status;
	struct acpi_table_ecdt 	*ecdt_ptr;

	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
		(struct acpi_table_header **) &ecdt_ptr);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	printk(KERN_INFO PREFIX "Found ECDT\n");

	/*
	 * Generate a temporary ec context to use until the namespace is scanned
	 */
	ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
	if (!ec_ecdt)
		return -ENOMEM;
	memset(ec_ecdt, 0, sizeof(union acpi_ec));

 	init_MUTEX(&ec_ecdt->burst.sem);
 	init_waitqueue_head(&ec_ecdt->burst.wait);
	ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
	ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
	ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
	ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
	/* use the GL just to be safe */
	ec_ecdt->common.global_lock = TRUE;
	ec_ecdt->common.uid = ecdt_ptr->uid;

	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
	if (ACPI_FAILURE(status)) {
		goto error;
	}

	return 0;
error:
	printk(KERN_ERR PREFIX "Could not use ECDT\n");
	kfree(ec_ecdt);
	ec_ecdt = NULL;

	return -ENODEV;
}

static int __initdata acpi_fake_ecdt_enabled;
int __init
acpi_ec_ecdt_probe (void)
{
	acpi_status		status;
	int			ret;

	ret = acpi_ec_get_real_ecdt();
	/* Try to make a fake ECDT */
	if (ret && acpi_fake_ecdt_enabled) {
		ret = acpi_ec_fake_ecdt();
	}

	if (ret)
		return 0;

	/*
	 * Install GPE handler
	 */
	status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
		ec_ecdt);
	if (ACPI_FAILURE(status)) {
		goto error;
	}
	acpi_set_gpe_type (NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
	acpi_enable_gpe (NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);

	status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
			&acpi_ec_space_setup, ec_ecdt);
	if (ACPI_FAILURE(status)) {
		acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
			&acpi_ec_gpe_handler);
		goto error;
	}

	return 0;

error:
	printk(KERN_ERR PREFIX "Could not use ECDT\n");
	kfree(ec_ecdt);
	ec_ecdt = NULL;

	return -ENODEV;
}


static int __init acpi_ec_init (void)
{
	int			result = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_init");

	if (acpi_disabled)
		return_VALUE(0);

	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
	if (!acpi_ec_dir)
		return_VALUE(-ENODEV);

	/* Now register the driver for the EC */
	result = acpi_bus_register_driver(&acpi_ec_driver);
	if (result < 0) {
		remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
		return_VALUE(-ENODEV);
	}

	return_VALUE(result);
}

subsys_initcall(acpi_ec_init);

/* EC driver currently not unloadable */
#if 0
static void __exit
acpi_ec_exit (void)
{
	ACPI_FUNCTION_TRACE("acpi_ec_exit");

	acpi_bus_unregister_driver(&acpi_ec_driver);

	remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);

	return_VOID;
}
#endif /* 0 */

static int __init acpi_fake_ecdt_setup(char *str)
{
	acpi_fake_ecdt_enabled = 1;
	return 0;
}
__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
static int __init acpi_ec_set_polling_mode(char *str)
{
	acpi_ec_polling_mode = EC_POLLING;
	acpi_ec_driver.ops.add = acpi_ec_polling_add;
	return 0;
}
__setup("ec_polling", acpi_ec_set_polling_mode);
