/*
 *  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 int acpi_ec_polling_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_polling_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 = EC_POLLING;

/* --------------------------------------------------------------------------
                             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)
{
	int burst;

	if (!get_option(&str, &burst))
		return 0;

	if (burst) {
		acpi_ec_polling_mode = EC_BURST;
		acpi_ec_driver.ops.add = acpi_ec_burst_add;
	} else {
		acpi_ec_polling_mode = EC_POLLING;
		acpi_ec_driver.ops.add = acpi_ec_polling_add;
	}
	printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst" : "polling");
	return 0;
}

__setup("ec_burst=", acpi_ec_set_polling_mode);
