/*
 *  eeepc-laptop.c - Asus Eee PC extras
 *
 *  Based on asus_acpi.c as patched for the Eee PC by Asus:
 *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
 *  Based on eee.c from eeepc-linux
 *
 *  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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/backlight.h>
#include <linux/fb.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/rfkill.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/leds.h>
#include <linux/dmi.h>

#define EEEPC_LAPTOP_VERSION	"0.1"
#define EEEPC_LAPTOP_NAME	"Eee PC Hotkey Driver"
#define EEEPC_LAPTOP_FILE	"eeepc"

#define EEEPC_ACPI_CLASS	"hotkey"
#define EEEPC_ACPI_DEVICE_NAME	"Hotkey"
#define EEEPC_ACPI_HID		"ASUS010"

MODULE_AUTHOR("Corentin Chary, Eric Cooper");
MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
MODULE_LICENSE("GPL");

static bool hotplug_disabled;

module_param(hotplug_disabled, bool, 0444);
MODULE_PARM_DESC(hotplug_disabled,
		 "Disable hotplug for wireless device. "
		 "If your laptop need that, please report to "
		 "acpi4asus-user@lists.sourceforge.net.");

/*
 * Definitions for Asus EeePC
 */
#define NOTIFY_BRN_MIN	0x20
#define NOTIFY_BRN_MAX	0x2f

enum {
	DISABLE_ASL_WLAN = 0x0001,
	DISABLE_ASL_BLUETOOTH = 0x0002,
	DISABLE_ASL_IRDA = 0x0004,
	DISABLE_ASL_CAMERA = 0x0008,
	DISABLE_ASL_TV = 0x0010,
	DISABLE_ASL_GPS = 0x0020,
	DISABLE_ASL_DISPLAYSWITCH = 0x0040,
	DISABLE_ASL_MODEM = 0x0080,
	DISABLE_ASL_CARDREADER = 0x0100,
	DISABLE_ASL_3G = 0x0200,
	DISABLE_ASL_WIMAX = 0x0400,
	DISABLE_ASL_HWCF = 0x0800
};

enum {
	CM_ASL_WLAN = 0,
	CM_ASL_BLUETOOTH,
	CM_ASL_IRDA,
	CM_ASL_1394,
	CM_ASL_CAMERA,
	CM_ASL_TV,
	CM_ASL_GPS,
	CM_ASL_DVDROM,
	CM_ASL_DISPLAYSWITCH,
	CM_ASL_PANELBRIGHT,
	CM_ASL_BIOSFLASH,
	CM_ASL_ACPIFLASH,
	CM_ASL_CPUFV,
	CM_ASL_CPUTEMPERATURE,
	CM_ASL_FANCPU,
	CM_ASL_FANCHASSIS,
	CM_ASL_USBPORT1,
	CM_ASL_USBPORT2,
	CM_ASL_USBPORT3,
	CM_ASL_MODEM,
	CM_ASL_CARDREADER,
	CM_ASL_3G,
	CM_ASL_WIMAX,
	CM_ASL_HWCF,
	CM_ASL_LID,
	CM_ASL_TYPE,
	CM_ASL_PANELPOWER,	/*P901*/
	CM_ASL_TPD
};

static const char *cm_getv[] = {
	"WLDG", "BTHG", NULL, NULL,
	"CAMG", NULL, NULL, NULL,
	NULL, "PBLG", NULL, NULL,
	"CFVG", NULL, NULL, NULL,
	"USBG", NULL, NULL, "MODG",
	"CRDG", "M3GG", "WIMG", "HWCF",
	"LIDG",	"TYPE", "PBPG",	"TPDG"
};

static const char *cm_setv[] = {
	"WLDS", "BTHS", NULL, NULL,
	"CAMS", NULL, NULL, NULL,
	"SDSP", "PBLS", "HDPS", NULL,
	"CFVS", NULL, NULL, NULL,
	"USBG", NULL, NULL, "MODS",
	"CRDS", "M3GS", "WIMS", NULL,
	NULL, NULL, "PBPS", "TPDS"
};

static const struct key_entry eeepc_keymap[] = {
	{ KE_KEY, 0x10, { KEY_WLAN } },
	{ KE_KEY, 0x11, { KEY_WLAN } },
	{ KE_KEY, 0x12, { KEY_PROG1 } },
	{ KE_KEY, 0x13, { KEY_MUTE } },
	{ KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
	{ KE_KEY, 0x15, { KEY_VOLUMEUP } },
	{ KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
	{ KE_KEY, 0x1a, { KEY_COFFEE } },
	{ KE_KEY, 0x1b, { KEY_ZOOM } },
	{ KE_KEY, 0x1c, { KEY_PROG2 } },
	{ KE_KEY, 0x1d, { KEY_PROG3 } },
	{ KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
	{ KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
	{ KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
	{ KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
	{ KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
	{ KE_KEY, 0x38, { KEY_F14 } },
	{ KE_END, 0 },
};

/*
 * This is the main structure, we can use it to store useful information
 */
struct eeepc_laptop {
	acpi_handle handle;		/* the handle of the acpi device */
	u32 cm_supported;		/* the control methods supported
					   by this BIOS */
	bool cpufv_disabled;
	bool hotplug_disabled;
	u16 event_count[128];		/* count for each event */

	struct platform_device *platform_device;
	struct acpi_device *device;		/* the device we are in */
	struct device *hwmon_device;
	struct backlight_device *backlight_device;

	struct input_dev *inputdev;

	struct rfkill *wlan_rfkill;
	struct rfkill *bluetooth_rfkill;
	struct rfkill *wwan3g_rfkill;
	struct rfkill *wimax_rfkill;

	struct hotplug_slot *hotplug_slot;
	struct mutex hotplug_lock;

	struct led_classdev tpd_led;
	int tpd_led_wk;
	struct workqueue_struct *led_workqueue;
	struct work_struct tpd_led_work;
};

/*
 * ACPI Helpers
 */
static int write_acpi_int(acpi_handle handle, const char *method, int val)
{
	acpi_status status;

	status = acpi_execute_simple_method(handle, (char *)method, val);

	return (status == AE_OK ? 0 : -1);
}

static int read_acpi_int(acpi_handle handle, const char *method, int *val)
{
	acpi_status status;
	unsigned long long result;

	status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
	if (ACPI_FAILURE(status)) {
		*val = -1;
		return -1;
	} else {
		*val = result;
		return 0;
	}
}

static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
{
	const char *method = cm_setv[cm];

	if (method == NULL)
		return -ENODEV;
	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
		return -ENODEV;

	if (write_acpi_int(eeepc->handle, method, value))
		pr_warn("Error writing %s\n", method);
	return 0;
}

static int get_acpi(struct eeepc_laptop *eeepc, int cm)
{
	const char *method = cm_getv[cm];
	int value;

	if (method == NULL)
		return -ENODEV;
	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
		return -ENODEV;

	if (read_acpi_int(eeepc->handle, method, &value))
		pr_warn("Error reading %s\n", method);
	return value;
}

static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
			      acpi_handle *handle)
{
	const char *method = cm_setv[cm];
	acpi_status status;

	if (method == NULL)
		return -ENODEV;
	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
		return -ENODEV;

	status = acpi_get_handle(eeepc->handle, (char *)method,
				 handle);
	if (status != AE_OK) {
		pr_warn("Error finding %s\n", method);
		return -ENODEV;
	}
	return 0;
}


/*
 * Sys helpers
 */
static int parse_arg(const char *buf, unsigned long count, int *val)
{
	if (!count)
		return 0;
	if (sscanf(buf, "%i", val) != 1)
		return -EINVAL;
	return count;
}

static ssize_t store_sys_acpi(struct device *dev, int cm,
			      const char *buf, size_t count)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
	int rv, value;

	rv = parse_arg(buf, count, &value);
	if (rv > 0)
		value = set_acpi(eeepc, cm, value);
	if (value < 0)
		return -EIO;
	return rv;
}

static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
	int value = get_acpi(eeepc, cm);

	if (value < 0)
		return -EIO;
	return sprintf(buf, "%d\n", value);
}

#define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm)			\
	static ssize_t show_##_name(struct device *dev,			\
				    struct device_attribute *attr,	\
				    char *buf)				\
	{								\
		return show_sys_acpi(dev, _cm, buf);			\
	}								\
	static ssize_t store_##_name(struct device *dev,		\
				     struct device_attribute *attr,	\
				     const char *buf, size_t count)	\
	{								\
		return store_sys_acpi(dev, _cm, buf, count);		\
	}								\
	static struct device_attribute dev_attr_##_name = {		\
		.attr = {						\
			.name = __stringify(_name),			\
			.mode = _mode },				\
		.show   = show_##_name,					\
		.store  = store_##_name,				\
	}

EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);

struct eeepc_cpufv {
	int num;
	int cur;
};

static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
{
	c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
	c->num = (c->cur >> 8) & 0xff;
	c->cur &= 0xff;
	if (c->cur < 0 || c->num <= 0 || c->num > 12)
		return -ENODEV;
	return 0;
}

static ssize_t show_available_cpufv(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
	struct eeepc_cpufv c;
	int i;
	ssize_t len = 0;

	if (get_cpufv(eeepc, &c))
		return -ENODEV;
	for (i = 0; i < c.num; i++)
		len += sprintf(buf + len, "%d ", i);
	len += sprintf(buf + len, "\n");
	return len;
}

static ssize_t show_cpufv(struct device *dev,
			  struct device_attribute *attr,
			  char *buf)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
	struct eeepc_cpufv c;

	if (get_cpufv(eeepc, &c))
		return -ENODEV;
	return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
}

static ssize_t store_cpufv(struct device *dev,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
	struct eeepc_cpufv c;
	int rv, value;

	if (eeepc->cpufv_disabled)
		return -EPERM;
	if (get_cpufv(eeepc, &c))
		return -ENODEV;
	rv = parse_arg(buf, count, &value);
	if (rv < 0)
		return rv;
	if (!rv || value < 0 || value >= c.num)
		return -EINVAL;
	set_acpi(eeepc, CM_ASL_CPUFV, value);
	return rv;
}

static ssize_t show_cpufv_disabled(struct device *dev,
			  struct device_attribute *attr,
			  char *buf)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);

	return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
}

static ssize_t store_cpufv_disabled(struct device *dev,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
	int rv, value;

	rv = parse_arg(buf, count, &value);
	if (rv < 0)
		return rv;

	switch (value) {
	case 0:
		if (eeepc->cpufv_disabled)
			pr_warn("cpufv enabled (not officially supported "
				"on this model)\n");
		eeepc->cpufv_disabled = false;
		return rv;
	case 1:
		return -EPERM;
	default:
		return -EINVAL;
	}
}


static struct device_attribute dev_attr_cpufv = {
	.attr = {
		.name = "cpufv",
		.mode = 0644 },
	.show   = show_cpufv,
	.store  = store_cpufv
};

static struct device_attribute dev_attr_available_cpufv = {
	.attr = {
		.name = "available_cpufv",
		.mode = 0444 },
	.show   = show_available_cpufv
};

static struct device_attribute dev_attr_cpufv_disabled = {
	.attr = {
		.name = "cpufv_disabled",
		.mode = 0644 },
	.show   = show_cpufv_disabled,
	.store  = store_cpufv_disabled
};


static struct attribute *platform_attributes[] = {
	&dev_attr_camera.attr,
	&dev_attr_cardr.attr,
	&dev_attr_disp.attr,
	&dev_attr_cpufv.attr,
	&dev_attr_available_cpufv.attr,
	&dev_attr_cpufv_disabled.attr,
	NULL
};

static struct attribute_group platform_attribute_group = {
	.attrs = platform_attributes
};

static int eeepc_platform_init(struct eeepc_laptop *eeepc)
{
	int result;

	eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
	if (!eeepc->platform_device)
		return -ENOMEM;
	platform_set_drvdata(eeepc->platform_device, eeepc);

	result = platform_device_add(eeepc->platform_device);
	if (result)
		goto fail_platform_device;

	result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
				    &platform_attribute_group);
	if (result)
		goto fail_sysfs;
	return 0;

fail_sysfs:
	platform_device_del(eeepc->platform_device);
fail_platform_device:
	platform_device_put(eeepc->platform_device);
	return result;
}

static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
{
	sysfs_remove_group(&eeepc->platform_device->dev.kobj,
			   &platform_attribute_group);
	platform_device_unregister(eeepc->platform_device);
}

/*
 * LEDs
 */
/*
 * These functions actually update the LED's, and are called from a
 * workqueue. By doing this as separate work rather than when the LED
 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
 * potentially bad time, such as a timer interrupt.
 */
static void tpd_led_update(struct work_struct *work)
 {
	struct eeepc_laptop *eeepc;

	eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);

	set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
}

static void tpd_led_set(struct led_classdev *led_cdev,
			enum led_brightness value)
{
	struct eeepc_laptop *eeepc;

	eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);

	eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
	queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
}

static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
{
	struct eeepc_laptop *eeepc;

	eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);

	return get_acpi(eeepc, CM_ASL_TPD);
}

static int eeepc_led_init(struct eeepc_laptop *eeepc)
{
	int rv;

	if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
		return 0;

	eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
	if (!eeepc->led_workqueue)
		return -ENOMEM;
	INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);

	eeepc->tpd_led.name = "eeepc::touchpad";
	eeepc->tpd_led.brightness_set = tpd_led_set;
	if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
	  eeepc->tpd_led.brightness_get = tpd_led_get;
	eeepc->tpd_led.max_brightness = 1;

	rv = led_classdev_register(&eeepc->platform_device->dev,
				   &eeepc->tpd_led);
	if (rv) {
		destroy_workqueue(eeepc->led_workqueue);
		return rv;
	}

	return 0;
}

static void eeepc_led_exit(struct eeepc_laptop *eeepc)
{
	if (!IS_ERR_OR_NULL(eeepc->tpd_led.dev))
		led_classdev_unregister(&eeepc->tpd_led);
	if (eeepc->led_workqueue)
		destroy_workqueue(eeepc->led_workqueue);
}


/*
 * PCI hotplug (for wlan rfkill)
 */
static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
{
	if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
		return false;
	return true;
}

static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
{
	struct pci_dev *port;
	struct pci_dev *dev;
	struct pci_bus *bus;
	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
	bool absent;
	u32 l;

	if (eeepc->wlan_rfkill)
		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);

	mutex_lock(&eeepc->hotplug_lock);

	if (eeepc->hotplug_slot) {
		port = acpi_get_pci_dev(handle);
		if (!port) {
			pr_warning("Unable to find port\n");
			goto out_unlock;
		}

		bus = port->subordinate;

		if (!bus) {
			pr_warn("Unable to find PCI bus 1?\n");
			goto out_put_dev;
		}

		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
			pr_err("Unable to read PCI config space?\n");
			goto out_put_dev;
		}

		absent = (l == 0xffffffff);

		if (blocked != absent) {
			pr_warn("BIOS says wireless lan is %s, "
				"but the pci device is %s\n",
				blocked ? "blocked" : "unblocked",
				absent ? "absent" : "present");
			pr_warn("skipped wireless hotplug as probably "
				"inappropriate for this model\n");
			goto out_put_dev;
		}

		if (!blocked) {
			dev = pci_get_slot(bus, 0);
			if (dev) {
				/* Device already present */
				pci_dev_put(dev);
				goto out_put_dev;
			}
			dev = pci_scan_single_device(bus, 0);
			if (dev) {
				pci_bus_assign_resources(bus);
				if (pci_bus_add_device(dev))
					pr_err("Unable to hotplug wifi\n");
			}
		} else {
			dev = pci_get_slot(bus, 0);
			if (dev) {
				pci_stop_and_remove_bus_device(dev);
				pci_dev_put(dev);
			}
		}
out_put_dev:
		pci_dev_put(port);
	}

out_unlock:
	mutex_unlock(&eeepc->hotplug_lock);
}

static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
{
	acpi_status status = AE_OK;
	acpi_handle handle;

	status = acpi_get_handle(NULL, node, &handle);

	if (ACPI_SUCCESS(status))
		eeepc_rfkill_hotplug(eeepc, handle);
}

static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
{
	struct eeepc_laptop *eeepc = data;

	if (event != ACPI_NOTIFY_BUS_CHECK)
		return;

	eeepc_rfkill_hotplug(eeepc, handle);
}

static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
					  char *node)
{
	acpi_status status;
	acpi_handle handle;

	status = acpi_get_handle(NULL, node, &handle);

	if (ACPI_SUCCESS(status)) {
		status = acpi_install_notify_handler(handle,
						     ACPI_SYSTEM_NOTIFY,
						     eeepc_rfkill_notify,
						     eeepc);
		if (ACPI_FAILURE(status))
			pr_warn("Failed to register notify on %s\n", node);

		/*
		 * Refresh pci hotplug in case the rfkill state was
		 * changed during setup.
		 */
		eeepc_rfkill_hotplug(eeepc, handle);
	} else
		return -ENODEV;

	return 0;
}

static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
					     char *node)
{
	acpi_status status = AE_OK;
	acpi_handle handle;

	status = acpi_get_handle(NULL, node, &handle);

	if (ACPI_SUCCESS(status)) {
		status = acpi_remove_notify_handler(handle,
						     ACPI_SYSTEM_NOTIFY,
						     eeepc_rfkill_notify);
		if (ACPI_FAILURE(status))
			pr_err("Error removing rfkill notify handler %s\n",
				node);
			/*
			 * Refresh pci hotplug in case the rfkill
			 * state was changed after
			 * eeepc_unregister_rfkill_notifier()
			 */
		eeepc_rfkill_hotplug(eeepc, handle);
	}
}

static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
				    u8 *value)
{
	struct eeepc_laptop *eeepc = hotplug_slot->private;
	int val = get_acpi(eeepc, CM_ASL_WLAN);

	if (val == 1 || val == 0)
		*value = val;
	else
		return -EINVAL;

	return 0;
}

static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
{
	kfree(hotplug_slot->info);
	kfree(hotplug_slot);
}

static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
	.owner = THIS_MODULE,
	.get_adapter_status = eeepc_get_adapter_status,
	.get_power_status = eeepc_get_adapter_status,
};

static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
{
	int ret = -ENOMEM;
	struct pci_bus *bus = pci_find_bus(0, 1);

	if (!bus) {
		pr_err("Unable to find wifi PCI bus\n");
		return -ENODEV;
	}

	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
	if (!eeepc->hotplug_slot)
		goto error_slot;

	eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
					    GFP_KERNEL);
	if (!eeepc->hotplug_slot->info)
		goto error_info;

	eeepc->hotplug_slot->private = eeepc;
	eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
	eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
	eeepc_get_adapter_status(eeepc->hotplug_slot,
				 &eeepc->hotplug_slot->info->adapter_status);

	ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
	if (ret) {
		pr_err("Unable to register hotplug slot - %d\n", ret);
		goto error_register;
	}

	return 0;

error_register:
	kfree(eeepc->hotplug_slot->info);
error_info:
	kfree(eeepc->hotplug_slot);
	eeepc->hotplug_slot = NULL;
error_slot:
	return ret;
}

/*
 * Rfkill devices
 */
static int eeepc_rfkill_set(void *data, bool blocked)
{
	acpi_handle handle = data;

	return write_acpi_int(handle, NULL, !blocked);
}

static const struct rfkill_ops eeepc_rfkill_ops = {
	.set_block = eeepc_rfkill_set,
};

static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
			    struct rfkill **rfkill,
			    const char *name,
			    enum rfkill_type type, int cm)
{
	acpi_handle handle;
	int result;

	result = acpi_setter_handle(eeepc, cm, &handle);
	if (result < 0)
		return result;

	*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
			       &eeepc_rfkill_ops, handle);

	if (!*rfkill)
		return -EINVAL;

	rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
	result = rfkill_register(*rfkill);
	if (result) {
		rfkill_destroy(*rfkill);
		*rfkill = NULL;
		return result;
	}
	return 0;
}

static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
{
	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
	if (eeepc->wlan_rfkill) {
		rfkill_unregister(eeepc->wlan_rfkill);
		rfkill_destroy(eeepc->wlan_rfkill);
		eeepc->wlan_rfkill = NULL;
	}

	if (eeepc->hotplug_slot)
		pci_hp_deregister(eeepc->hotplug_slot);

	if (eeepc->bluetooth_rfkill) {
		rfkill_unregister(eeepc->bluetooth_rfkill);
		rfkill_destroy(eeepc->bluetooth_rfkill);
		eeepc->bluetooth_rfkill = NULL;
	}
	if (eeepc->wwan3g_rfkill) {
		rfkill_unregister(eeepc->wwan3g_rfkill);
		rfkill_destroy(eeepc->wwan3g_rfkill);
		eeepc->wwan3g_rfkill = NULL;
	}
	if (eeepc->wimax_rfkill) {
		rfkill_unregister(eeepc->wimax_rfkill);
		rfkill_destroy(eeepc->wimax_rfkill);
		eeepc->wimax_rfkill = NULL;
	}
}

static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
{
	int result = 0;

	mutex_init(&eeepc->hotplug_lock);

	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
				  "eeepc-wlan", RFKILL_TYPE_WLAN,
				  CM_ASL_WLAN);

	if (result && result != -ENODEV)
		goto exit;

	result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
				  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
				  CM_ASL_BLUETOOTH);

	if (result && result != -ENODEV)
		goto exit;

	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
				  CM_ASL_3G);

	if (result && result != -ENODEV)
		goto exit;

	result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
				  "eeepc-wimax", RFKILL_TYPE_WIMAX,
				  CM_ASL_WIMAX);

	if (result && result != -ENODEV)
		goto exit;

	if (eeepc->hotplug_disabled)
		return 0;

	result = eeepc_setup_pci_hotplug(eeepc);
	/*
	 * If we get -EBUSY then something else is handling the PCI hotplug -
	 * don't fail in this case
	 */
	if (result == -EBUSY)
		result = 0;

	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");

exit:
	if (result && result != -ENODEV)
		eeepc_rfkill_exit(eeepc);
	return result;
}

/*
 * Platform driver - hibernate/resume callbacks
 */
static int eeepc_hotk_thaw(struct device *device)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(device);

	if (eeepc->wlan_rfkill) {
		bool wlan;

		/*
		 * Work around bios bug - acpi _PTS turns off the wireless led
		 * during suspend.  Normally it restores it on resume, but
		 * we should kick it ourselves in case hibernation is aborted.
		 */
		wlan = get_acpi(eeepc, CM_ASL_WLAN);
		set_acpi(eeepc, CM_ASL_WLAN, wlan);
	}

	return 0;
}

static int eeepc_hotk_restore(struct device *device)
{
	struct eeepc_laptop *eeepc = dev_get_drvdata(device);

	/* Refresh both wlan rfkill state and pci hotplug */
	if (eeepc->wlan_rfkill) {
		eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
		eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
		eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
	}

	if (eeepc->bluetooth_rfkill)
		rfkill_set_sw_state(eeepc->bluetooth_rfkill,
				    get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
	if (eeepc->wwan3g_rfkill)
		rfkill_set_sw_state(eeepc->wwan3g_rfkill,
				    get_acpi(eeepc, CM_ASL_3G) != 1);
	if (eeepc->wimax_rfkill)
		rfkill_set_sw_state(eeepc->wimax_rfkill,
				    get_acpi(eeepc, CM_ASL_WIMAX) != 1);

	return 0;
}

static const struct dev_pm_ops eeepc_pm_ops = {
	.thaw = eeepc_hotk_thaw,
	.restore = eeepc_hotk_restore,
};

static struct platform_driver platform_driver = {
	.driver = {
		.name = EEEPC_LAPTOP_FILE,
		.owner = THIS_MODULE,
		.pm = &eeepc_pm_ops,
	}
};

/*
 * Hwmon device
 */

#define EEEPC_EC_SC00      0x61
#define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
#define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
#define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */

#define EEEPC_EC_SFB0      0xD0
#define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */

static int eeepc_get_fan_pwm(void)
{
	u8 value = 0;

	ec_read(EEEPC_EC_FAN_PWM, &value);
	return value * 255 / 100;
}

static void eeepc_set_fan_pwm(int value)
{
	value = clamp_val(value, 0, 255);
	value = value * 100 / 255;
	ec_write(EEEPC_EC_FAN_PWM, value);
}

static int eeepc_get_fan_rpm(void)
{
	u8 high = 0;
	u8 low = 0;

	ec_read(EEEPC_EC_FAN_HRPM, &high);
	ec_read(EEEPC_EC_FAN_LRPM, &low);
	return high << 8 | low;
}

static int eeepc_get_fan_ctrl(void)
{
	u8 value = 0;

	ec_read(EEEPC_EC_FAN_CTRL, &value);
	if (value & 0x02)
		return 1; /* manual */
	else
		return 2; /* automatic */
}

static void eeepc_set_fan_ctrl(int manual)
{
	u8 value = 0;

	ec_read(EEEPC_EC_FAN_CTRL, &value);
	if (manual == 1)
		value |= 0x02;
	else
		value &= ~0x02;
	ec_write(EEEPC_EC_FAN_CTRL, value);
}

static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
{
	int rv, value;

	rv = parse_arg(buf, count, &value);
	if (rv > 0)
		set(value);
	return rv;
}

static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
{
	return sprintf(buf, "%d\n", get());
}

#define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)		\
	static ssize_t show_##_name(struct device *dev,			\
				    struct device_attribute *attr,	\
				    char *buf)				\
	{								\
		return show_sys_hwmon(_set, buf);			\
	}								\
	static ssize_t store_##_name(struct device *dev,		\
				     struct device_attribute *attr,	\
				     const char *buf, size_t count)	\
	{								\
		return store_sys_hwmon(_get, buf, count);		\
	}								\
	static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);

EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
			 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
			 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);

static ssize_t
show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "eeepc\n");
}
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);

static struct attribute *hwmon_attributes[] = {
	&sensor_dev_attr_pwm1.dev_attr.attr,
	&sensor_dev_attr_fan1_input.dev_attr.attr,
	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
	&sensor_dev_attr_name.dev_attr.attr,
	NULL
};

static struct attribute_group hwmon_attribute_group = {
	.attrs = hwmon_attributes
};

static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
{
	struct device *hwmon;

	hwmon = eeepc->hwmon_device;
	if (!hwmon)
		return;
	sysfs_remove_group(&hwmon->kobj,
			   &hwmon_attribute_group);
	hwmon_device_unregister(hwmon);
	eeepc->hwmon_device = NULL;
}

static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
{
	struct device *hwmon;
	int result;

	hwmon = hwmon_device_register(&eeepc->platform_device->dev);
	if (IS_ERR(hwmon)) {
		pr_err("Could not register eeepc hwmon device\n");
		eeepc->hwmon_device = NULL;
		return PTR_ERR(hwmon);
	}
	eeepc->hwmon_device = hwmon;
	result = sysfs_create_group(&hwmon->kobj,
				    &hwmon_attribute_group);
	if (result)
		eeepc_hwmon_exit(eeepc);
	return result;
}

/*
 * Backlight device
 */
static int read_brightness(struct backlight_device *bd)
{
	struct eeepc_laptop *eeepc = bl_get_data(bd);

	return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
}

static int set_brightness(struct backlight_device *bd, int value)
{
	struct eeepc_laptop *eeepc = bl_get_data(bd);

	return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
}

static int update_bl_status(struct backlight_device *bd)
{
	return set_brightness(bd, bd->props.brightness);
}

static const struct backlight_ops eeepcbl_ops = {
	.get_brightness = read_brightness,
	.update_status = update_bl_status,
};

static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
{
	struct backlight_device *bd = eeepc->backlight_device;
	int old = bd->props.brightness;

	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);

	return old;
}

static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
{
	struct backlight_properties props;
	struct backlight_device *bd;

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = 15;
	bd = backlight_device_register(EEEPC_LAPTOP_FILE,
				       &eeepc->platform_device->dev, eeepc,
				       &eeepcbl_ops, &props);
	if (IS_ERR(bd)) {
		pr_err("Could not register eeepc backlight device\n");
		eeepc->backlight_device = NULL;
		return PTR_ERR(bd);
	}
	eeepc->backlight_device = bd;
	bd->props.brightness = read_brightness(bd);
	bd->props.power = FB_BLANK_UNBLANK;
	backlight_update_status(bd);
	return 0;
}

static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
{
	if (eeepc->backlight_device)
		backlight_device_unregister(eeepc->backlight_device);
	eeepc->backlight_device = NULL;
}


/*
 * Input device (i.e. hotkeys)
 */
static int eeepc_input_init(struct eeepc_laptop *eeepc)
{
	struct input_dev *input;
	int error;

	input = input_allocate_device();
	if (!input) {
		pr_info("Unable to allocate input device\n");
		return -ENOMEM;
	}

	input->name = "Asus EeePC extra buttons";
	input->phys = EEEPC_LAPTOP_FILE "/input0";
	input->id.bustype = BUS_HOST;
	input->dev.parent = &eeepc->platform_device->dev;

	error = sparse_keymap_setup(input, eeepc_keymap, NULL);
	if (error) {
		pr_err("Unable to setup input device keymap\n");
		goto err_free_dev;
	}

	error = input_register_device(input);
	if (error) {
		pr_err("Unable to register input device\n");
		goto err_free_keymap;
	}

	eeepc->inputdev = input;
	return 0;

err_free_keymap:
	sparse_keymap_free(input);
err_free_dev:
	input_free_device(input);
	return error;
}

static void eeepc_input_exit(struct eeepc_laptop *eeepc)
{
	if (eeepc->inputdev) {
		sparse_keymap_free(eeepc->inputdev);
		input_unregister_device(eeepc->inputdev);
	}
	eeepc->inputdev = NULL;
}

/*
 * ACPI driver
 */
static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
{
	if (!eeepc->inputdev)
		return ;
	if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
		pr_info("Unknown key %x pressed\n", event);
}

static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
{
	struct eeepc_laptop *eeepc = acpi_driver_data(device);
	u16 count;

	if (event > ACPI_MAX_SYS_NOTIFY)
		return;
	count = eeepc->event_count[event % 128]++;
	acpi_bus_generate_netlink_event(device->pnp.device_class,
					dev_name(&device->dev), event,
					count);

	/* Brightness events are special */
	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {

		/* Ignore them completely if the acpi video driver is used */
		if (eeepc->backlight_device != NULL) {
			int old_brightness, new_brightness;

			/* Update the backlight device. */
			old_brightness = eeepc_backlight_notify(eeepc);

			/* Convert event to keypress (obsolescent hack) */
			new_brightness = event - NOTIFY_BRN_MIN;

			if (new_brightness < old_brightness) {
				event = NOTIFY_BRN_MIN; /* brightness down */
			} else if (new_brightness > old_brightness) {
				event = NOTIFY_BRN_MAX; /* brightness up */
			} else {
				/*
				* no change in brightness - already at min/max,
				* event will be desired value (or else ignored)
				*/
			}
			eeepc_input_notify(eeepc, event);
		}
	} else {
		/* Everything else is a bona-fide keypress event */
		eeepc_input_notify(eeepc, event);
	}
}

static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
{
	const char *model;

	model = dmi_get_system_info(DMI_PRODUCT_NAME);
	if (!model)
		return;

	/*
	 * Blacklist for setting cpufv (cpu speed).
	 *
	 * EeePC 4G ("701") implements CFVS, but it is not supported
	 * by the pre-installed OS, and the original option to change it
	 * in the BIOS setup screen was removed in later versions.
	 *
	 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
	 * this applies to all "701" models (4G/4G Surf/2G Surf).
	 *
	 * So Asus made a deliberate decision not to support it on this model.
	 * We have several reports that using it can cause the system to hang
	 *
	 * The hang has also been reported on a "702" (Model name "8G"?).
	 *
	 * We avoid dmi_check_system() / dmi_match(), because they use
	 * substring matching.  We don't want to affect the "701SD"
	 * and "701SDX" models, because they do support S.H.E.
	 */
	if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
		eeepc->cpufv_disabled = true;
		pr_info("model %s does not officially support setting cpu "
			"speed\n", model);
		pr_info("cpufv disabled to avoid instability\n");
	}

	/*
	 * Blacklist for wlan hotplug
	 *
	 * Eeepc 1005HA doesn't work like others models and don't need the
	 * hotplug code. In fact, current hotplug code seems to unplug another
	 * device...
	 */
	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
	    strcmp(model, "1005PE") == 0) {
		eeepc->hotplug_disabled = true;
		pr_info("wlan hotplug disabled\n");
	}
}

static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
{
	int dummy;

	/* Some BIOSes do not report cm although it is available.
	   Check if cm_getv[cm] works and, if yes, assume cm should be set. */
	if (!(eeepc->cm_supported & (1 << cm))
	    && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
		pr_info("%s (%x) not reported by BIOS,"
			" enabling anyway\n", name, 1 << cm);
		eeepc->cm_supported |= 1 << cm;
	}
}

static void cmsg_quirks(struct eeepc_laptop *eeepc)
{
	cmsg_quirk(eeepc, CM_ASL_LID, "LID");
	cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
	cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
	cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
}

static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
{
	unsigned int init_flags;
	int result;

	result = acpi_bus_get_status(eeepc->device);
	if (result)
		return result;
	if (!eeepc->device->status.present) {
		pr_err("Hotkey device not present, aborting\n");
		return -ENODEV;
	}

	init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
	pr_notice("Hotkey init flags 0x%x\n", init_flags);

	if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
		pr_err("Hotkey initialization failed\n");
		return -ENODEV;
	}

	/* get control methods supported */
	if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
		pr_err("Get control methods supported failed\n");
		return -ENODEV;
	}
	cmsg_quirks(eeepc);
	pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);

	return 0;
}

static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
{
	/*
	 * If the following call to set_acpi() fails, it's because there's no
	 * camera so we can ignore the error.
	 */
	if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
		set_acpi(eeepc, CM_ASL_CAMERA, 1);
}

static bool eeepc_device_present;

static int eeepc_acpi_add(struct acpi_device *device)
{
	struct eeepc_laptop *eeepc;
	int result;

	pr_notice(EEEPC_LAPTOP_NAME "\n");
	eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
	if (!eeepc)
		return -ENOMEM;
	eeepc->handle = device->handle;
	strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
	strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
	device->driver_data = eeepc;
	eeepc->device = device;

	eeepc->hotplug_disabled = hotplug_disabled;

	eeepc_dmi_check(eeepc);

	result = eeepc_acpi_init(eeepc);
	if (result)
		goto fail_platform;
	eeepc_enable_camera(eeepc);

	/*
	 * Register the platform device first.  It is used as a parent for the
	 * sub-devices below.
	 *
	 * Note that if there are multiple instances of this ACPI device it
	 * will bail out, because the platform device is registered with a
	 * fixed name.  Of course it doesn't make sense to have more than one,
	 * and machine-specific scripts find the fixed name convenient.  But
	 * It's also good for us to exclude multiple instances because both
	 * our hwmon and our wlan rfkill subdevice use global ACPI objects
	 * (the EC and the wlan PCI slot respectively).
	 */
	result = eeepc_platform_init(eeepc);
	if (result)
		goto fail_platform;

	if (!acpi_video_backlight_support()) {
		result = eeepc_backlight_init(eeepc);
		if (result)
			goto fail_backlight;
	} else
		pr_info("Backlight controlled by ACPI video driver\n");

	result = eeepc_input_init(eeepc);
	if (result)
		goto fail_input;

	result = eeepc_hwmon_init(eeepc);
	if (result)
		goto fail_hwmon;

	result = eeepc_led_init(eeepc);
	if (result)
		goto fail_led;

	result = eeepc_rfkill_init(eeepc);
	if (result)
		goto fail_rfkill;

	eeepc_device_present = true;
	return 0;

fail_rfkill:
	eeepc_led_exit(eeepc);
fail_led:
	eeepc_hwmon_exit(eeepc);
fail_hwmon:
	eeepc_input_exit(eeepc);
fail_input:
	eeepc_backlight_exit(eeepc);
fail_backlight:
	eeepc_platform_exit(eeepc);
fail_platform:
	kfree(eeepc);

	return result;
}

static int eeepc_acpi_remove(struct acpi_device *device)
{
	struct eeepc_laptop *eeepc = acpi_driver_data(device);

	eeepc_backlight_exit(eeepc);
	eeepc_rfkill_exit(eeepc);
	eeepc_input_exit(eeepc);
	eeepc_hwmon_exit(eeepc);
	eeepc_led_exit(eeepc);
	eeepc_platform_exit(eeepc);

	kfree(eeepc);
	return 0;
}


static const struct acpi_device_id eeepc_device_ids[] = {
	{EEEPC_ACPI_HID, 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);

static struct acpi_driver eeepc_acpi_driver = {
	.name = EEEPC_LAPTOP_NAME,
	.class = EEEPC_ACPI_CLASS,
	.owner = THIS_MODULE,
	.ids = eeepc_device_ids,
	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
	.ops = {
		.add = eeepc_acpi_add,
		.remove = eeepc_acpi_remove,
		.notify = eeepc_acpi_notify,
	},
};


static int __init eeepc_laptop_init(void)
{
	int result;

	result = platform_driver_register(&platform_driver);
	if (result < 0)
		return result;

	result = acpi_bus_register_driver(&eeepc_acpi_driver);
	if (result < 0)
		goto fail_acpi_driver;

	if (!eeepc_device_present) {
		result = -ENODEV;
		goto fail_no_device;
	}

	return 0;

fail_no_device:
	acpi_bus_unregister_driver(&eeepc_acpi_driver);
fail_acpi_driver:
	platform_driver_unregister(&platform_driver);
	return result;
}

static void __exit eeepc_laptop_exit(void)
{
	acpi_bus_unregister_driver(&eeepc_acpi_driver);
	platform_driver_unregister(&platform_driver);
}

module_init(eeepc_laptop_init);
module_exit(eeepc_laptop_exit);
