/*
 *  hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
 *
 *  Copyright (C) 2004 Luming Yu <luming.yu@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/proc_fs.h>
#include <linux/sched.h>
#include <linux/kmod.h>
#include <linux/seq_file.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>

#define HOTKEY_ACPI_VERSION "0.1"

#define HOTKEY_PROC "hotkey"
#define HOTKEY_EV_CONFIG    "event_config"
#define HOTKEY_PL_CONFIG    "poll_config"
#define HOTKEY_ACTION   "action"
#define HOTKEY_INFO "info"

#define ACPI_HOTK_NAME          "Generic Hotkey Driver"
#define ACPI_HOTK_CLASS         "Hotkey"
#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
#define ACPI_HOTK_HID           "Unknown?"
#define ACPI_HOTKEY_COMPONENT   0x20000000

#define ACPI_HOTKEY_EVENT   0x1
#define ACPI_HOTKEY_POLLING 0x2
#define ACPI_UNDEFINED_EVENT    0xf

#define RESULT_STR_LEN	    80

#define ACTION_METHOD	0
#define POLL_METHOD	1

#define IS_EVENT(e)       	((e) <= 10000 && (e) >0)
#define IS_POLL(e)      	((e) > 10000)
#define IS_OTHERS(e)		((e)<=0 || (e)>=20000)
#define _COMPONENT              ACPI_HOTKEY_COMPONENT
ACPI_MODULE_NAME("acpi_hotkey")

    MODULE_AUTHOR("luming.yu@intel.com");
MODULE_DESCRIPTION(ACPI_HOTK_NAME);
MODULE_LICENSE("GPL");

/*  standardized internal hotkey number/event  */
enum {
	/* Video Extension event */
	HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
	HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
	HK_EVENT_CYCLE_DISPLAY_OUTPUT,
	HK_EVENT_NEXT_DISPLAY_OUTPUT,
	HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
	HK_EVENT_CYCLE_BRIGHTNESS,
	HK_EVENT_INCREASE_BRIGHTNESS,
	HK_EVENT_DECREASE_BRIGHTNESS,
	HK_EVENT_ZERO_BRIGHTNESS,
	HK_EVENT_DISPLAY_DEVICE_OFF,

	/* Snd Card event */
	HK_EVENT_VOLUME_MUTE,
	HK_EVENT_VOLUME_INCLREASE,
	HK_EVENT_VOLUME_DECREASE,

	/* running state control */
	HK_EVENT_ENTERRING_S3,
	HK_EVENT_ENTERRING_S4,
	HK_EVENT_ENTERRING_S5,
};

/*  procdir we use */
static struct proc_dir_entry *hotkey_proc_dir;
static struct proc_dir_entry *hotkey_config;
static struct proc_dir_entry *hotkey_poll_config;
static struct proc_dir_entry *hotkey_action;
static struct proc_dir_entry *hotkey_info;

/* linkage for all type of hotkey */
struct acpi_hotkey_link {
	struct list_head entries;
	int hotkey_type;	/* event or polling based hotkey  */
	int hotkey_standard_num;	/* standardized hotkey(event) number */
};

/* event based hotkey */
struct acpi_event_hotkey {
	struct acpi_hotkey_link hotkey_link;
	int flag;
	acpi_handle bus_handle;	/* bus to install notify handler */
	int external_hotkey_num;	/* external hotkey/event number */
	acpi_handle action_handle;	/* acpi handle attached aml action method */
	char *action_method;	/* action method */
};

/*
 * There are two ways to poll status
 * 1. directy call read_xxx method, without any arguments passed in
 * 2. call write_xxx method, with arguments passed in, you need
 * the result is saved in acpi_polling_hotkey.poll_result.
 * anthoer read command through polling interface.
 *
 */

/* polling based hotkey */
struct acpi_polling_hotkey {
	struct acpi_hotkey_link hotkey_link;
	int flag;
	acpi_handle poll_handle;	/* acpi handle attached polling method */
	char *poll_method;	/* poll method */
	acpi_handle action_handle;	/* acpi handle attached action method */
	char *action_method;	/* action method */
	union acpi_object *poll_result;	/* polling_result */
	struct proc_dir_entry *proc;
};

/* hotkey object union */
union acpi_hotkey {
	struct list_head entries;
	struct acpi_hotkey_link link;
	struct acpi_event_hotkey event_hotkey;
	struct acpi_polling_hotkey poll_hotkey;
};

/* hotkey object list */
struct acpi_hotkey_list {
	struct list_head *entries;
	int count;
};

static int auto_hotkey_add(struct acpi_device *device);
static int auto_hotkey_remove(struct acpi_device *device, int type);

static struct acpi_driver hotkey_driver = {
	.name = ACPI_HOTK_NAME,
	.class = ACPI_HOTK_CLASS,
	.ids = ACPI_HOTK_HID,
	.ops = {
		.add = auto_hotkey_add,
		.remove = auto_hotkey_remove,
		},
};

static void free_hotkey_device(union acpi_hotkey *key);
static void free_hotkey_buffer(union acpi_hotkey *key);
static void free_poll_hotkey_buffer(union acpi_hotkey *key);
static int hotkey_open_config(struct inode *inode, struct file *file);
static int hotkey_poll_open_config(struct inode *inode, struct file *file);
static ssize_t hotkey_write_config(struct file *file,
				   const char __user * buffer,
				   size_t count, loff_t * data);
static int hotkey_info_open_fs(struct inode *inode, struct file *file);
static int hotkey_action_open_fs(struct inode *inode, struct file *file);
static ssize_t hotkey_execute_aml_method(struct file *file,
					 const char __user * buffer,
					 size_t count, loff_t * data);
static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
static union acpi_hotkey *get_hotkey_by_event(struct
					      acpi_hotkey_list
					      *hotkey_list, int event);

/* event based config */
static struct file_operations hotkey_config_fops = {
	.open = hotkey_open_config,
	.read = seq_read,
	.write = hotkey_write_config,
	.llseek = seq_lseek,
	.release = single_release,
};

/* polling based config */
static struct file_operations hotkey_poll_config_fops = {
	.open = hotkey_poll_open_config,
	.read = seq_read,
	.write = hotkey_write_config,
	.llseek = seq_lseek,
	.release = single_release,
};

/* hotkey driver info */
static struct file_operations hotkey_info_fops = {
	.open = hotkey_info_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

/* action */
static struct file_operations hotkey_action_fops = {
	.open = hotkey_action_open_fs,
	.read = seq_read,
	.write = hotkey_execute_aml_method,
	.llseek = seq_lseek,
	.release = single_release,
};

/* polling results */
static struct file_operations hotkey_polling_fops = {
	.open = hotkey_polling_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

struct acpi_hotkey_list global_hotkey_list;	/* link all ev or pl hotkey  */
struct list_head hotkey_entries;	/* head of the list of hotkey_list */

static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
{
	ACPI_FUNCTION_TRACE("hotkey_info_seq_show");

	seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);

	return_VALUE(0);
}

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

static char *format_result(union acpi_object *object)
{
	char *buf = NULL;

	buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
	if (buf)
		memset(buf, 0, RESULT_STR_LEN);
	else
		goto do_fail;

	/* Now, just support integer type */
	if (object->type == ACPI_TYPE_INTEGER)
		sprintf(buf, "%d\n", (u32) object->integer.value);
      do_fail:
	return (buf);
}

static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
{
	struct acpi_polling_hotkey *poll_hotkey =
	    (struct acpi_polling_hotkey *)seq->private;
	char *buf;

	ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");

	if (poll_hotkey->poll_result) {
		buf = format_result(poll_hotkey->poll_result);
		if (buf)
			seq_printf(seq, "%s", buf);
		kfree(buf);
	}
	return_VALUE(0);
}

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

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

/* Mapping external hotkey number to standardized hotkey event num */
static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
{
	struct list_head *entries;
	int val = -1;

	ACPI_FUNCTION_TRACE("hotkey_get_internal_event");

	list_for_each(entries, list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
		    && key->event_hotkey.external_hotkey_num == event) {
			val = key->link.hotkey_standard_num;
			break;
		}
	}

	return_VALUE(val);
}

static void
acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
{
	struct acpi_device *device = NULL;
	u32 internal_event;

	ACPI_FUNCTION_TRACE("acpi_hotkey_notify_handler");

	if (acpi_bus_get_device(handle, &device))
		return_VOID;

	internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
	acpi_bus_generate_event(device, internal_event, 0);

	return_VOID;
}

/* Need to invent automatically hotkey add method */
static int auto_hotkey_add(struct acpi_device *device)
{
	/* Implement me */
	return 0;
}

/* Need to invent automatically hotkey remove method */
static int auto_hotkey_remove(struct acpi_device *device, int type)
{
	/* Implement me */
	return 0;
}

/* Create a proc file for each polling method */
static int create_polling_proc(union acpi_hotkey *device)
{
	struct proc_dir_entry *proc;
	char proc_name[80];
	mode_t mode;

	ACPI_FUNCTION_TRACE("create_polling_proc");
	mode = S_IFREG | S_IRUGO | S_IWUGO;

	sprintf(proc_name, "%d", device->link.hotkey_standard_num);
	/*
	   strcat(proc_name, device->poll_hotkey.poll_method);
	 */
	proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);

	if (!proc) {
		return_VALUE(-ENODEV);
	} else {
		proc->proc_fops = &hotkey_polling_fops;
		proc->owner = THIS_MODULE;
		proc->data = device;
		proc->uid = 0;
		proc->gid = 0;
		device->poll_hotkey.proc = proc;
	}
	return_VALUE(0);
}

static int hotkey_add(union acpi_hotkey *device)
{
	int status = 0;
	struct acpi_device *dev = NULL;

	ACPI_FUNCTION_TRACE("hotkey_add");

	if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
		acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
		status = acpi_install_notify_handler(dev->handle,
						     ACPI_DEVICE_NOTIFY,
						     acpi_hotkey_notify_handler,
						     dev);
	} else			/* Add polling hotkey */
		create_polling_proc(device);

	global_hotkey_list.count++;

	list_add_tail(&device->link.entries, global_hotkey_list.entries);

	return_VALUE(status);
}

static int hotkey_remove(union acpi_hotkey *device)
{
	struct list_head *entries, *next;

	ACPI_FUNCTION_TRACE("hotkey_remove");

	list_for_each_safe(entries, next, global_hotkey_list.entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_standard_num ==
		    device->link.hotkey_standard_num) {
			list_del(&key->link.entries);
			free_hotkey_device(key);
			global_hotkey_list.count--;
			break;
		}
	}
	kfree(device);
	return_VALUE(0);
}

static int hotkey_update(union acpi_hotkey *key)
{
	struct list_head *entries;

	ACPI_FUNCTION_TRACE("hotkey_update");

	list_for_each(entries, global_hotkey_list.entries) {
		union acpi_hotkey *tmp =
		    container_of(entries, union acpi_hotkey, entries);
		if (tmp->link.hotkey_standard_num ==
		    key->link.hotkey_standard_num) {
			if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
				free_hotkey_buffer(tmp);
				tmp->event_hotkey.bus_handle =
				    key->event_hotkey.bus_handle;
				tmp->event_hotkey.external_hotkey_num =
				    key->event_hotkey.external_hotkey_num;
				tmp->event_hotkey.action_handle =
				    key->event_hotkey.action_handle;
				tmp->event_hotkey.action_method =
				    key->event_hotkey.action_method;
				kfree(key);
			} else {
				/*
				   char  proc_name[80];

				   sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
				   strcat(proc_name, tmp->poll_hotkey.poll_method);
				   remove_proc_entry(proc_name,hotkey_proc_dir);
				 */
				free_poll_hotkey_buffer(tmp);
				tmp->poll_hotkey.poll_handle =
				    key->poll_hotkey.poll_handle;
				tmp->poll_hotkey.poll_method =
				    key->poll_hotkey.poll_method;
				tmp->poll_hotkey.action_handle =
				    key->poll_hotkey.action_handle;
				tmp->poll_hotkey.action_method =
				    key->poll_hotkey.action_method;
				tmp->poll_hotkey.poll_result =
				    key->poll_hotkey.poll_result;
				/*
				   create_polling_proc(tmp);
				 */
				kfree(key);
			}
			return_VALUE(0);
			break;
		}
	}

	return_VALUE(-ENODEV);
}

static void free_hotkey_device(union acpi_hotkey *key)
{
	struct acpi_device *dev;

	ACPI_FUNCTION_TRACE("free_hotkey_device");

	if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
		acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
		if (dev->handle)
			acpi_remove_notify_handler(dev->handle,
						   ACPI_DEVICE_NOTIFY,
						   acpi_hotkey_notify_handler);
		free_hotkey_buffer(key);
	} else {
		char proc_name[80];

		sprintf(proc_name, "%d", key->link.hotkey_standard_num);
		/*
		   strcat(proc_name, key->poll_hotkey.poll_method);
		 */
		remove_proc_entry(proc_name, hotkey_proc_dir);
		free_poll_hotkey_buffer(key);
	}
	kfree(key);
	return_VOID;
}

static void free_hotkey_buffer(union acpi_hotkey *key)
{
	kfree(key->event_hotkey.action_method);
}

static void free_poll_hotkey_buffer(union acpi_hotkey *key)
{
	kfree(key->poll_hotkey.action_method);
	kfree(key->poll_hotkey.poll_method);
	kfree(key->poll_hotkey.poll_result);
}
static int
init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
		   char *method, int std_num, int external_num)
{
	acpi_handle tmp_handle;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE("init_hotkey_device");

	if (std_num < 0 || IS_POLL(std_num) || !key)
		goto do_fail;

	if (!bus_str || !action_str || !method)
		goto do_fail;

	key->link.hotkey_type = ACPI_HOTKEY_EVENT;
	key->link.hotkey_standard_num = std_num;
	key->event_hotkey.flag = 0;
	key->event_hotkey.action_method = method;

	status =
	    acpi_get_handle(NULL, bus_str, &(key->event_hotkey.bus_handle));
	if (ACPI_FAILURE(status))
		goto do_fail;
	key->event_hotkey.external_hotkey_num = external_num;
	status =
	    acpi_get_handle(NULL, action_str,
			    &(key->event_hotkey.action_handle));
	if (ACPI_FAILURE(status))
		goto do_fail;
	status = acpi_get_handle(key->event_hotkey.action_handle,
				 method, &tmp_handle);
	if (ACPI_FAILURE(status))
		goto do_fail;
	return_VALUE(AE_OK);
      do_fail:
	return_VALUE(-ENODEV);
}

static int
init_poll_hotkey_device(union acpi_hotkey *key,
			char *poll_str,
			char *poll_method,
			char *action_str, char *action_method, int std_num)
{
	acpi_status status = AE_OK;
	acpi_handle tmp_handle;

	ACPI_FUNCTION_TRACE("init_poll_hotkey_device");

	if (std_num < 0 || IS_EVENT(std_num) || !key)
		goto do_fail;

	if (!poll_str || !poll_method || !action_str || !action_method)
		goto do_fail;

	key->link.hotkey_type = ACPI_HOTKEY_POLLING;
	key->link.hotkey_standard_num = std_num;
	key->poll_hotkey.flag = 0;
	key->poll_hotkey.poll_method = poll_method;
	key->poll_hotkey.action_method = action_method;

	status =
	    acpi_get_handle(NULL, poll_str, &(key->poll_hotkey.poll_handle));
	if (ACPI_FAILURE(status))
		goto do_fail;
	status = acpi_get_handle(key->poll_hotkey.poll_handle,
				 poll_method, &tmp_handle);
	if (ACPI_FAILURE(status))
		goto do_fail;
	status =
	    acpi_get_handle(NULL, action_str,
			    &(key->poll_hotkey.action_handle));
	if (ACPI_FAILURE(status))
		goto do_fail;
	status = acpi_get_handle(key->poll_hotkey.action_handle,
				 action_method, &tmp_handle);
	if (ACPI_FAILURE(status))
		goto do_fail;
	key->poll_hotkey.poll_result =
	    (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
	if (!key->poll_hotkey.poll_result)
		goto do_fail;
	return_VALUE(AE_OK);
      do_fail:
	return_VALUE(-ENODEV);
}

static int hotkey_open_config(struct inode *inode, struct file *file)
{
	ACPI_FUNCTION_TRACE("hotkey_open_config");
	return_VALUE(single_open
		     (file, hotkey_config_seq_show, PDE(inode)->data));
}

static int hotkey_poll_open_config(struct inode *inode, struct file *file)
{
	ACPI_FUNCTION_TRACE("hotkey_poll_open_config");
	return_VALUE(single_open
		     (file, hotkey_poll_config_seq_show, PDE(inode)->data));
}

static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
{
	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
	struct list_head *entries;
	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
	char action_name[ACPI_PATHNAME_MAX] = { 0 };
	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };

	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));

	list_for_each(entries, hotkey_list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
			acpi_get_name(key->event_hotkey.bus_handle,
				      ACPI_NAME_TYPE_MAX, &bus);
			acpi_get_name(key->event_hotkey.action_handle,
				      ACPI_NAME_TYPE_MAX, &act);
			seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
				   action_name,
				   key->event_hotkey.action_method,
				   key->link.hotkey_standard_num,
				   key->event_hotkey.external_hotkey_num);
		}
	}
	seq_puts(seq, "\n");
	return_VALUE(0);
}

static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
{
	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
	struct list_head *entries;
	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
	char action_name[ACPI_PATHNAME_MAX] = { 0 };
	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };

	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));

	list_for_each(entries, hotkey_list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
			acpi_get_name(key->poll_hotkey.poll_handle,
				      ACPI_NAME_TYPE_MAX, &bus);
			acpi_get_name(key->poll_hotkey.action_handle,
				      ACPI_NAME_TYPE_MAX, &act);
			seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
				   key->poll_hotkey.poll_method,
				   action_name,
				   key->poll_hotkey.action_method,
				   key->link.hotkey_standard_num);
		}
	}
	seq_puts(seq, "\n");
	return_VALUE(0);
}

static int
get_parms(char *config_record,
	  int *cmd,
	  char **bus_handle,
	  char **bus_method,
	  char **action_handle,
	  char **method, int *internal_event_num, int *external_event_num)
{
	char *tmp, *tmp1, count;
	ACPI_FUNCTION_TRACE(("get_parms"));

	sscanf(config_record, "%d", cmd);

	if (*cmd == 1) {
		if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
		    2)
			goto do_fail;
		else
			return (6);
	}
	tmp = strchr(config_record, ':');
	if (!tmp)
		goto do_fail;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;

	count = tmp1 - tmp;
	*bus_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
	if (!*bus_handle)
		goto do_fail;
	strncpy(*bus_handle, tmp, count);
	*(*bus_handle + count) = 0;

	tmp = tmp1;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;
	count = tmp1 - tmp;
	*bus_method = (char *)kmalloc(count + 1, GFP_KERNEL);
	if (!*bus_method)
		goto do_fail;
	strncpy(*bus_method, tmp, count);
	*(*bus_method + count) = 0;

	tmp = tmp1;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;
	count = tmp1 - tmp;
	*action_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
	if (!*action_handle)
		goto do_fail;
	strncpy(*action_handle, tmp, count);
	*(*action_handle + count) = 0;

	tmp = tmp1;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;
	count = tmp1 - tmp;
	*method = (char *)kmalloc(count + 1, GFP_KERNEL);
	if (!*method)
		goto do_fail;
	strncpy(*method, tmp, count);
	*(*method + count) = 0;

	if (sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num) <=
	    0)
		goto do_fail;

	return_VALUE(6);
      do_fail:
	return_VALUE(-1);
}

/*  count is length for one input record */
static ssize_t hotkey_write_config(struct file *file,
				   const char __user * buffer,
				   size_t count, loff_t * data)
{
	char *config_record = NULL;
	char *bus_handle = NULL;
	char *bus_method = NULL;
	char *action_handle = NULL;
	char *method = NULL;
	int cmd, internal_event_num, external_event_num;
	int ret = 0;
	union acpi_hotkey *key = NULL;

	ACPI_FUNCTION_TRACE(("hotkey_write_config"));

	config_record = (char *)kmalloc(count + 1, GFP_KERNEL);
	if (!config_record)
		return_VALUE(-ENOMEM);

	if (copy_from_user(config_record, buffer, count)) {
		kfree(config_record);
		ACPI_ERROR((AE_INFO, "Invalid data"));
		return_VALUE(-EINVAL);
	}
	config_record[count] = 0;

	ret = get_parms(config_record,
			&cmd,
			&bus_handle,
			&bus_method,
			&action_handle,
			&method, &internal_event_num, &external_event_num);

	kfree(config_record);
	if (IS_OTHERS(internal_event_num))
		goto do_fail;
	if (ret != 6) {
	      do_fail:
		kfree(bus_handle);
		kfree(bus_method);
		kfree(action_handle);
		kfree(method);
		ACPI_ERROR((AE_INFO, "Invalid data format ret=%d", ret));
		return_VALUE(-EINVAL);
	}

	key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
	if (!key)
		goto do_fail;
	memset(key, 0, sizeof(union acpi_hotkey));
	if (cmd == 1) {
		union acpi_hotkey *tmp = NULL;
		tmp = get_hotkey_by_event(&global_hotkey_list,
					  internal_event_num);
		if (!tmp)
			ACPI_ERROR((AE_INFO, "Invalid key"));
		else
			memcpy(key, tmp, sizeof(union acpi_hotkey));
		goto cont_cmd;
	}
	if (IS_EVENT(internal_event_num)) {
		kfree(bus_method);
		ret = init_hotkey_device(key, bus_handle, action_handle, method,
					 internal_event_num,
					 external_event_num);
	} else
		ret = init_poll_hotkey_device(key, bus_handle, bus_method,
					      action_handle, method,
					      internal_event_num);
	if (ret) {
		kfree(bus_handle);
		kfree(action_handle);
		if (IS_EVENT(internal_event_num))
			free_hotkey_buffer(key);
		else
			free_poll_hotkey_buffer(key);
		kfree(key);
		ACPI_ERROR((AE_INFO, "Invalid hotkey"));
		return_VALUE(-EINVAL);
	}

      cont_cmd:
	kfree(bus_handle);
	kfree(action_handle);

	switch (cmd) {
	case 0:
		if (get_hotkey_by_event
		    (&global_hotkey_list, key->link.hotkey_standard_num))
			goto fail_out;
		else
			hotkey_add(key);
		break;
	case 1:
		hotkey_remove(key);
		break;
	case 2:
		if (hotkey_update(key))
			goto fail_out;
		break;
	default:
		goto fail_out;
		break;
	}
	return_VALUE(count);
      fail_out:
	if (IS_EVENT(internal_event_num))
		free_hotkey_buffer(key);
	else
		free_poll_hotkey_buffer(key);
	kfree(key);
	ACPI_ERROR((AE_INFO, "invalid key"));
	return_VALUE(-EINVAL);
}

/*
 * This function evaluates an ACPI method, given an int as parameter, the
 * method is searched within the scope of the handle, can be NULL. The output
 * of the method is written is output, which can also be NULL
 *
 * returns 1 if write is successful, 0 else.
 */
static int write_acpi_int(acpi_handle handle, const char *method, int val,
			  struct acpi_buffer *output)
{
	struct acpi_object_list params;	/* list of input parameters (an int here) */
	union acpi_object in_obj;	/* the only param we use */
	acpi_status status;

	ACPI_FUNCTION_TRACE("write_acpi_int");
	params.count = 1;
	params.pointer = &in_obj;
	in_obj.type = ACPI_TYPE_INTEGER;
	in_obj.integer.value = val;

	status = acpi_evaluate_object(handle, (char *)method, &params, output);

	return_VALUE(status == AE_OK);
}

static int read_acpi_int(acpi_handle handle, const char *method,
			 union acpi_object *val)
{
	struct acpi_buffer output;
	union acpi_object out_obj;
	acpi_status status;

	ACPI_FUNCTION_TRACE("read_acpi_int");
	output.length = sizeof(out_obj);
	output.pointer = &out_obj;

	status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
	if (val) {
		val->integer.value = out_obj.integer.value;
		val->type = out_obj.type;
	} else
		ACPI_ERROR((AE_INFO, "null val pointer"));
	return_VALUE((status == AE_OK)
		     && (out_obj.type == ACPI_TYPE_INTEGER));
}

static union acpi_hotkey *get_hotkey_by_event(struct
					      acpi_hotkey_list
					      *hotkey_list, int event)
{
	struct list_head *entries;

	list_for_each(entries, hotkey_list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_standard_num == event) {
			return (key);
		}
	}
	return (NULL);
}

/*
 * user call AML method interface:
 * Call convention:
 * echo "event_num: arg type : value"
 * example: echo "1:1:30" > /proc/acpi/action
 * Just support 1 integer arg passing to AML method
 */

static ssize_t hotkey_execute_aml_method(struct file *file,
					 const char __user * buffer,
					 size_t count, loff_t * data)
{
	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
	char *arg;
	int event, method_type, type, value;
	union acpi_hotkey *key;

	ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");

	arg = (char *)kmalloc(count + 1, GFP_KERNEL);
	if (!arg)
		return_VALUE(-ENOMEM);
	arg[count] = 0;

	if (copy_from_user(arg, buffer, count)) {
		kfree(arg);
		ACPI_ERROR((AE_INFO, "Invalid argument 2"));
		return_VALUE(-EINVAL);
	}

	if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) !=
	    4) {
		kfree(arg);
		ACPI_ERROR((AE_INFO, "Invalid argument 3"));
		return_VALUE(-EINVAL);
	}
	kfree(arg);
	if (type == ACPI_TYPE_INTEGER) {
		key = get_hotkey_by_event(hotkey_list, event);
		if (!key)
			goto do_fail;
		if (IS_EVENT(event))
			write_acpi_int(key->event_hotkey.action_handle,
				       key->event_hotkey.action_method, value,
				       NULL);
		else if (IS_POLL(event)) {
			if (method_type == POLL_METHOD)
				read_acpi_int(key->poll_hotkey.poll_handle,
					      key->poll_hotkey.poll_method,
					      key->poll_hotkey.poll_result);
			else if (method_type == ACTION_METHOD)
				write_acpi_int(key->poll_hotkey.action_handle,
					       key->poll_hotkey.action_method,
					       value, NULL);
			else
				goto do_fail;

		}
	} else {
		printk(KERN_WARNING "Not supported\n");
		return_VALUE(-EINVAL);
	}
	return_VALUE(count);
      do_fail:
	return_VALUE(-EINVAL);

}

static int __init hotkey_init(void)
{
	int result;
	mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;

	ACPI_FUNCTION_TRACE("hotkey_init");

	if (acpi_disabled)
		return -ENODEV;

	if (acpi_specific_hotkey_enabled) {
		printk("Using specific hotkey driver\n");
		return -ENODEV;
	}

	hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
	if (!hotkey_proc_dir) {
		return (-ENODEV);
	}
	hotkey_proc_dir->owner = THIS_MODULE;

	hotkey_config =
	    create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
	if (!hotkey_config) {
		goto do_fail1;
	} else {
		hotkey_config->proc_fops = &hotkey_config_fops;
		hotkey_config->data = &global_hotkey_list;
		hotkey_config->owner = THIS_MODULE;
		hotkey_config->uid = 0;
		hotkey_config->gid = 0;
	}

	hotkey_poll_config =
	    create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
	if (!hotkey_poll_config) {
		goto do_fail2;
	} else {
		hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
		hotkey_poll_config->data = &global_hotkey_list;
		hotkey_poll_config->owner = THIS_MODULE;
		hotkey_poll_config->uid = 0;
		hotkey_poll_config->gid = 0;
	}

	hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
	if (!hotkey_action) {
		goto do_fail3;
	} else {
		hotkey_action->proc_fops = &hotkey_action_fops;
		hotkey_action->owner = THIS_MODULE;
		hotkey_action->uid = 0;
		hotkey_action->gid = 0;
	}

	hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
	if (!hotkey_info) {
		goto do_fail4;
	} else {
		hotkey_info->proc_fops = &hotkey_info_fops;
		hotkey_info->owner = THIS_MODULE;
		hotkey_info->uid = 0;
		hotkey_info->gid = 0;
	}

	result = acpi_bus_register_driver(&hotkey_driver);
	if (result < 0)
		goto do_fail5;
	global_hotkey_list.count = 0;
	global_hotkey_list.entries = &hotkey_entries;

	INIT_LIST_HEAD(&hotkey_entries);

	return (0);

      do_fail5:
	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
      do_fail4:
	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
      do_fail3:
	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
      do_fail2:
	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
      do_fail1:
	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
	return (-ENODEV);
}

static void __exit hotkey_exit(void)
{
	struct list_head *entries, *next;

	ACPI_FUNCTION_TRACE("hotkey_exit");

	list_for_each_safe(entries, next, global_hotkey_list.entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);

		acpi_os_wait_events_complete(NULL);
		list_del(&key->link.entries);
		global_hotkey_list.count--;
		free_hotkey_device(key);
	}
	acpi_bus_unregister_driver(&hotkey_driver);
	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
	return;
}

module_init(hotkey_init);
module_exit(hotkey_exit);
