/*
 * Copyright (C) 2007-2009 Luca Tettamanti <kronos.it@gmail.com>
 *
 * This file is released under the GPLv2
 * See COPYING in the top level directory of the kernel tree.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/hwmon.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/dmi.h>

#include <acpi/acpi.h>
#include <acpi/acpixf.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>


#define ATK_HID "ATK0110"

static bool new_if;
module_param(new_if, bool, 0);
MODULE_PARM_DESC(new_if, "Override detection heuristic and force the use of the new ATK0110 interface");

static const struct dmi_system_id __initconst atk_force_new_if[] = {
	{
		/* Old interface has broken MCH temp monitoring */
		.ident = "Asus Sabertooth X58",
		.matches = {
			DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58")
		}
	},
	{ }
};

/* Minimum time between readings, enforced in order to avoid
 * hogging the CPU.
 */
#define CACHE_TIME		HZ

#define BOARD_ID		"MBIF"
#define METHOD_ENUMERATE	"GGRP"
#define METHOD_READ		"GITM"
#define METHOD_WRITE		"SITM"
#define METHOD_OLD_READ_TMP	"RTMP"
#define METHOD_OLD_READ_VLT	"RVLT"
#define METHOD_OLD_READ_FAN	"RFAN"
#define METHOD_OLD_ENUM_TMP	"TSIF"
#define METHOD_OLD_ENUM_VLT	"VSIF"
#define METHOD_OLD_ENUM_FAN	"FSIF"

#define ATK_MUX_HWMON		0x00000006ULL
#define ATK_MUX_MGMT		0x00000011ULL

#define ATK_CLASS_MASK		0xff000000ULL
#define ATK_CLASS_FREQ_CTL	0x03000000ULL
#define ATK_CLASS_FAN_CTL	0x04000000ULL
#define ATK_CLASS_HWMON		0x06000000ULL
#define ATK_CLASS_MGMT		0x11000000ULL

#define ATK_TYPE_MASK		0x00ff0000ULL
#define HWMON_TYPE_VOLT		0x00020000ULL
#define HWMON_TYPE_TEMP		0x00030000ULL
#define HWMON_TYPE_FAN		0x00040000ULL

#define ATK_ELEMENT_ID_MASK	0x0000ffffULL

#define ATK_EC_ID		0x11060004ULL

enum atk_pack_member {
	HWMON_PACK_FLAGS,
	HWMON_PACK_NAME,
	HWMON_PACK_LIMIT1,
	HWMON_PACK_LIMIT2,
	HWMON_PACK_ENABLE
};

/* New package format */
#define _HWMON_NEW_PACK_SIZE	7
#define _HWMON_NEW_PACK_FLAGS	0
#define _HWMON_NEW_PACK_NAME	1
#define _HWMON_NEW_PACK_UNK1	2
#define _HWMON_NEW_PACK_UNK2	3
#define _HWMON_NEW_PACK_LIMIT1	4
#define _HWMON_NEW_PACK_LIMIT2	5
#define _HWMON_NEW_PACK_ENABLE	6

/* Old package format */
#define _HWMON_OLD_PACK_SIZE	5
#define _HWMON_OLD_PACK_FLAGS	0
#define _HWMON_OLD_PACK_NAME	1
#define _HWMON_OLD_PACK_LIMIT1	2
#define _HWMON_OLD_PACK_LIMIT2	3
#define _HWMON_OLD_PACK_ENABLE	4


struct atk_data {
	struct device *hwmon_dev;
	acpi_handle atk_handle;
	struct acpi_device *acpi_dev;

	bool old_interface;

	/* old interface */
	acpi_handle rtmp_handle;
	acpi_handle rvlt_handle;
	acpi_handle rfan_handle;
	/* new inteface */
	acpi_handle enumerate_handle;
	acpi_handle read_handle;
	acpi_handle write_handle;

	bool disable_ec;

	int voltage_count;
	int temperature_count;
	int fan_count;
	struct list_head sensor_list;

	struct {
		struct dentry *root;
		u32 id;
	} debugfs;
};


typedef ssize_t (*sysfs_show_func)(struct device *dev,
			struct device_attribute *attr, char *buf);

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

#define ATTR_NAME_SIZE 16 /* Worst case is "tempN_input" */

struct atk_sensor_data {
	struct list_head list;
	struct atk_data *data;
	struct device_attribute label_attr;
	struct device_attribute input_attr;
	struct device_attribute limit1_attr;
	struct device_attribute limit2_attr;
	char label_attr_name[ATTR_NAME_SIZE];
	char input_attr_name[ATTR_NAME_SIZE];
	char limit1_attr_name[ATTR_NAME_SIZE];
	char limit2_attr_name[ATTR_NAME_SIZE];
	u64 id;
	u64 type;
	u64 limit1;
	u64 limit2;
	u64 cached_value;
	unsigned long last_updated; /* in jiffies */
	bool is_valid;
	char const *acpi_name;
};

/* Return buffer format:
 * [0-3] "value" is valid flag
 * [4-7] value
 * [8- ] unknown stuff on newer mobos
 */
struct atk_acpi_ret_buffer {
	u32 flags;
	u32 value;
	u8 data[];
};

/* Input buffer used for GITM and SITM methods */
struct atk_acpi_input_buf {
	u32 id;
	u32 param1;
	u32 param2;
};

static int atk_add(struct acpi_device *device);
static int atk_remove(struct acpi_device *device, int type);
static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
static void atk_free_sensors(struct atk_data *data);

static struct acpi_driver atk_driver = {
	.name	= ATK_HID,
	.class	= "hwmon",
	.ids	= atk_ids,
	.ops	= {
		.add	= atk_add,
		.remove	= atk_remove,
	},
};

#define input_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, input_attr)

#define label_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, label_attr)

#define limit1_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, limit1_attr)

#define limit2_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, limit2_attr)

static ssize_t atk_input_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = input_to_atk_sensor(attr);
	u64 value;
	int err;

	err = atk_read_value(s, &value);
	if (err)
		return err;

	if (s->type == HWMON_TYPE_TEMP)
		/* ACPI returns decidegree */
		value *= 100;

	return sprintf(buf, "%llu\n", value);
}

static ssize_t atk_label_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = label_to_atk_sensor(attr);

	return sprintf(buf, "%s\n", s->acpi_name);
}

static ssize_t atk_limit1_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit1_to_atk_sensor(attr);
	u64 value = s->limit1;

	if (s->type == HWMON_TYPE_TEMP)
		value *= 100;

	return sprintf(buf, "%lld\n", value);
}

static ssize_t atk_limit2_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit2_to_atk_sensor(attr);
	u64 value = s->limit2;

	if (s->type == HWMON_TYPE_TEMP)
		value *= 100;

	return sprintf(buf, "%lld\n", value);
}

static ssize_t atk_name_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "atk0110\n");
}
static struct device_attribute atk_name_attr =
		__ATTR(name, 0444, atk_name_show, NULL);

static void atk_init_attribute(struct device_attribute *attr, char *name,
		sysfs_show_func show)
{
	sysfs_attr_init(&attr->attr);
	attr->attr.name = name;
	attr->attr.mode = 0444;
	attr->show = show;
	attr->store = NULL;
}


static union acpi_object *atk_get_pack_member(struct atk_data *data,
						union acpi_object *pack,
						enum atk_pack_member m)
{
	bool old_if = data->old_interface;
	int offset;

	switch (m) {
	case HWMON_PACK_FLAGS:
		offset = old_if ? _HWMON_OLD_PACK_FLAGS : _HWMON_NEW_PACK_FLAGS;
		break;
	case HWMON_PACK_NAME:
		offset = old_if ? _HWMON_OLD_PACK_NAME : _HWMON_NEW_PACK_NAME;
		break;
	case HWMON_PACK_LIMIT1:
		offset = old_if ? _HWMON_OLD_PACK_LIMIT1 :
				  _HWMON_NEW_PACK_LIMIT1;
		break;
	case HWMON_PACK_LIMIT2:
		offset = old_if ? _HWMON_OLD_PACK_LIMIT2 :
				  _HWMON_NEW_PACK_LIMIT2;
		break;
	case HWMON_PACK_ENABLE:
		offset = old_if ? _HWMON_OLD_PACK_ENABLE :
				  _HWMON_NEW_PACK_ENABLE;
		break;
	default:
		return NULL;
	}

	return &pack->package.elements[offset];
}


/* New package format is:
 * - flag (int)
 *	class - used for de-muxing the request to the correct GITn
 *	type (volt, temp, fan)
 *	sensor id |
 *	sensor id - used for de-muxing the request _inside_ the GITn
 * - name (str)
 * - unknown (int)
 * - unknown (int)
 * - limit1 (int)
 * - limit2 (int)
 * - enable (int)
 *
 * The old package has the same format but it's missing the two unknown fields.
 */
static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *tmp;
	bool old_if = data->old_interface;
	int const expected_size = old_if ? _HWMON_OLD_PACK_SIZE :
					   _HWMON_NEW_PACK_SIZE;

	if (obj->type != ACPI_TYPE_PACKAGE) {
		dev_warn(dev, "Invalid type: %d\n", obj->type);
		return -EINVAL;
	}

	if (obj->package.count != expected_size) {
		dev_warn(dev, "Invalid package size: %d, expected: %d\n",
				obj->package.count, expected_size);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (flag): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	if (tmp->type != ACPI_TYPE_STRING) {
		dev_warn(dev, "Invalid type (name): %d\n", tmp->type);
		return -EINVAL;
	}

	/* Don't check... we don't know what they're useful for anyway */
#if 0
	tmp = &obj->package.elements[HWMON_PACK_UNK1];
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (unk1): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = &obj->package.elements[HWMON_PACK_UNK2];
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (unk2): %d\n", tmp->type);
		return -EINVAL;
	}
#endif

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (limit1): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (limit2): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (enable): %d\n", tmp->type);
		return -EINVAL;
	}

	atk_print_sensor(data, obj);

	return 0;
}

#ifdef DEBUG
static char const *atk_sensor_type(union acpi_object *flags)
{
	u64 type = flags->integer.value & ATK_TYPE_MASK;
	char const *what;

	switch (type) {
	case HWMON_TYPE_VOLT:
		what = "voltage";
		break;
	case HWMON_TYPE_TEMP:
		what = "temperature";
		break;
	case HWMON_TYPE_FAN:
		what = "fan";
		break;
	default:
		what = "unknown";
		break;
	}

	return what;
}
#endif

static void atk_print_sensor(struct atk_data *data, union acpi_object *obj)
{
#ifdef DEBUG
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *flags;
	union acpi_object *name;
	union acpi_object *limit1;
	union acpi_object *limit2;
	union acpi_object *enable;
	char const *what;

	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);

	what = atk_sensor_type(flags);

	dev_dbg(dev, "%s: %#llx %s [%llu-%llu] %s\n", what,
			flags->integer.value,
			name->string.pointer,
			limit1->integer.value, limit2->integer.value,
			enable->integer.value ? "enabled" : "disabled");
#endif
}

static int atk_read_value_old(struct atk_sensor_data *sensor, u64 *value)
{
	struct atk_data *data = sensor->data;
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_object_list params;
	union acpi_object id;
	acpi_status status;
	acpi_handle method;

	switch (sensor->type) {
	case HWMON_TYPE_VOLT:
		method = data->rvlt_handle;
		break;
	case HWMON_TYPE_TEMP:
		method = data->rtmp_handle;
		break;
	case HWMON_TYPE_FAN:
		method = data->rfan_handle;
		break;
	default:
		return -EINVAL;
	}

	id.type = ACPI_TYPE_INTEGER;
	id.integer.value = sensor->id;

	params.count = 1;
	params.pointer = &id;

	status = acpi_evaluate_integer(method, NULL, &params, value);
	if (status != AE_OK) {
		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
				acpi_format_exception(status));
		return -EIO;
	}

	return 0;
}

static union acpi_object *atk_ggrp(struct atk_data *data, u16 mux)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_buffer buf;
	acpi_status ret;
	struct acpi_object_list params;
	union acpi_object id;
	union acpi_object *pack;

	id.type = ACPI_TYPE_INTEGER;
	id.integer.value = mux;
	params.count = 1;
	params.pointer = &id;

	buf.length = ACPI_ALLOCATE_BUFFER;
	ret = acpi_evaluate_object(data->enumerate_handle, NULL, &params, &buf);
	if (ret != AE_OK) {
		dev_err(dev, "GGRP[%#x] ACPI exception: %s\n", mux,
				acpi_format_exception(ret));
		return ERR_PTR(-EIO);
	}
	pack = buf.pointer;
	if (pack->type != ACPI_TYPE_PACKAGE) {
		/* Execution was successful, but the id was not found */
		ACPI_FREE(pack);
		return ERR_PTR(-ENOENT);
	}

	if (pack->package.count < 1) {
		dev_err(dev, "GGRP[%#x] package is too small\n", mux);
		ACPI_FREE(pack);
		return ERR_PTR(-EIO);
	}
	return pack;
}

static union acpi_object *atk_gitm(struct atk_data *data, u64 id)
{
	struct device *dev = &data->acpi_dev->dev;
	struct atk_acpi_input_buf buf;
	union acpi_object tmp;
	struct acpi_object_list params;
	struct acpi_buffer ret;
	union acpi_object *obj;
	acpi_status status;

	buf.id = id;
	buf.param1 = 0;
	buf.param2 = 0;

	tmp.type = ACPI_TYPE_BUFFER;
	tmp.buffer.pointer = (u8 *)&buf;
	tmp.buffer.length = sizeof(buf);

	params.count = 1;
	params.pointer = (void *)&tmp;

	ret.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
			&ret, ACPI_TYPE_BUFFER);
	if (status != AE_OK) {
		dev_warn(dev, "GITM[%#llx] ACPI exception: %s\n", id,
				acpi_format_exception(status));
		return ERR_PTR(-EIO);
	}
	obj = ret.pointer;

	/* Sanity check */
	if (obj->buffer.length < 8) {
		dev_warn(dev, "Unexpected ASBF length: %u\n",
				obj->buffer.length);
		ACPI_FREE(obj);
		return ERR_PTR(-EIO);
	}
	return obj;
}

static union acpi_object *atk_sitm(struct atk_data *data,
		struct atk_acpi_input_buf *buf)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_object_list params;
	union acpi_object tmp;
	struct acpi_buffer ret;
	union acpi_object *obj;
	acpi_status status;

	tmp.type = ACPI_TYPE_BUFFER;
	tmp.buffer.pointer = (u8 *)buf;
	tmp.buffer.length = sizeof(*buf);

	params.count = 1;
	params.pointer = &tmp;

	ret.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->write_handle, NULL, &params,
			&ret, ACPI_TYPE_BUFFER);
	if (status != AE_OK) {
		dev_warn(dev, "SITM[%#x] ACPI exception: %s\n", buf->id,
				acpi_format_exception(status));
		return ERR_PTR(-EIO);
	}
	obj = ret.pointer;

	/* Sanity check */
	if (obj->buffer.length < 8) {
		dev_warn(dev, "Unexpected ASBF length: %u\n",
				obj->buffer.length);
		ACPI_FREE(obj);
		return ERR_PTR(-EIO);
	}
	return obj;
}

static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
{
	struct atk_data *data = sensor->data;
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *obj;
	struct atk_acpi_ret_buffer *buf;
	int err = 0;

	obj = atk_gitm(data, sensor->id);
	if (IS_ERR(obj))
		return PTR_ERR(obj);

	buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
	if (buf->flags == 0) {
		/* The reading is not valid, possible causes:
		 * - sensor failure
		 * - enumeration was FUBAR (and we didn't notice)
		 */
		dev_warn(dev, "Read failed, sensor = %#llx\n", sensor->id);
		err = -EIO;
		goto out;
	}

	*value = buf->value;
out:
	ACPI_FREE(obj);
	return err;
}

static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
{
	int err;

	if (!sensor->is_valid ||
	    time_after(jiffies, sensor->last_updated + CACHE_TIME)) {
		if (sensor->data->old_interface)
			err = atk_read_value_old(sensor, value);
		else
			err = atk_read_value_new(sensor, value);

		sensor->is_valid = true;
		sensor->last_updated = jiffies;
		sensor->cached_value = *value;
	} else {
		*value = sensor->cached_value;
		err = 0;
	}

	return err;
}

#ifdef CONFIG_DEBUG_FS
static int atk_debugfs_gitm_get(void *p, u64 *val)
{
	struct atk_data *data = p;
	union acpi_object *ret;
	struct atk_acpi_ret_buffer *buf;
	int err = 0;

	if (!data->read_handle)
		return -ENODEV;

	if (!data->debugfs.id)
		return -EINVAL;

	ret = atk_gitm(data, data->debugfs.id);
	if (IS_ERR(ret))
		return PTR_ERR(ret);

	buf = (struct atk_acpi_ret_buffer *)ret->buffer.pointer;
	if (buf->flags)
		*val = buf->value;
	else
		err = -EIO;

	ACPI_FREE(ret);
	return err;
}

DEFINE_SIMPLE_ATTRIBUTE(atk_debugfs_gitm,
			atk_debugfs_gitm_get,
			NULL,
			"0x%08llx\n")

static int atk_acpi_print(char *buf, size_t sz, union acpi_object *obj)
{
	int ret = 0;

	switch (obj->type) {
	case ACPI_TYPE_INTEGER:
		ret = snprintf(buf, sz, "0x%08llx\n", obj->integer.value);
		break;
	case ACPI_TYPE_STRING:
		ret = snprintf(buf, sz, "%s\n", obj->string.pointer);
		break;
	}

	return ret;
}

static void atk_pack_print(char *buf, size_t sz, union acpi_object *pack)
{
	int ret;
	int i;

	for (i = 0; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_acpi_print(buf, sz, obj);
		if (ret >= sz)
			break;
		buf += ret;
		sz -= ret;
	}
}

static int atk_debugfs_ggrp_open(struct inode *inode, struct file *file)
{
	struct atk_data *data = inode->i_private;
	char *buf = NULL;
	union acpi_object *ret;
	u8 cls;
	int i;

	if (!data->enumerate_handle)
		return -ENODEV;
	if (!data->debugfs.id)
		return -EINVAL;

	cls = (data->debugfs.id & 0xff000000) >> 24;
	ret = atk_ggrp(data, cls);
	if (IS_ERR(ret))
		return PTR_ERR(ret);

	for (i = 0; i < ret->package.count; i++) {
		union acpi_object *pack = &ret->package.elements[i];
		union acpi_object *id;

		if (pack->type != ACPI_TYPE_PACKAGE)
			continue;
		if (!pack->package.count)
			continue;
		id = &pack->package.elements[0];
		if (id->integer.value == data->debugfs.id) {
			/* Print the package */
			buf = kzalloc(512, GFP_KERNEL);
			if (!buf) {
				ACPI_FREE(ret);
				return -ENOMEM;
			}
			atk_pack_print(buf, 512, pack);
			break;
		}
	}
	ACPI_FREE(ret);

	if (!buf)
		return -EINVAL;

	file->private_data = buf;

	return nonseekable_open(inode, file);
}

static ssize_t atk_debugfs_ggrp_read(struct file *file, char __user *buf,
		size_t count, loff_t *pos)
{
	char *str = file->private_data;
	size_t len = strlen(str);

	return simple_read_from_buffer(buf, count, pos, str, len);
}

static int atk_debugfs_ggrp_release(struct inode *inode, struct file *file)
{
	kfree(file->private_data);
	return 0;
}

static const struct file_operations atk_debugfs_ggrp_fops = {
	.read		= atk_debugfs_ggrp_read,
	.open		= atk_debugfs_ggrp_open,
	.release	= atk_debugfs_ggrp_release,
	.llseek		= no_llseek,
};

static void atk_debugfs_init(struct atk_data *data)
{
	struct dentry *d;
	struct dentry *f;

	data->debugfs.id = 0;

	d = debugfs_create_dir("asus_atk0110", NULL);
	if (!d || IS_ERR(d))
		return;

	f = debugfs_create_x32("id", S_IRUSR | S_IWUSR, d, &data->debugfs.id);
	if (!f || IS_ERR(f))
		goto cleanup;

	f = debugfs_create_file("gitm", S_IRUSR, d, data,
			&atk_debugfs_gitm);
	if (!f || IS_ERR(f))
		goto cleanup;

	f = debugfs_create_file("ggrp", S_IRUSR, d, data,
			&atk_debugfs_ggrp_fops);
	if (!f || IS_ERR(f))
		goto cleanup;

	data->debugfs.root = d;

	return;
cleanup:
	debugfs_remove_recursive(d);
}

static void atk_debugfs_cleanup(struct atk_data *data)
{
	debugfs_remove_recursive(data->debugfs.root);
}

#else /* CONFIG_DEBUG_FS */

static void atk_debugfs_init(struct atk_data *data)
{
}

static void atk_debugfs_cleanup(struct atk_data *data)
{
}
#endif

static int atk_add_sensor(struct atk_data *data, union acpi_object *obj)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *flags;
	union acpi_object *name;
	union acpi_object *limit1;
	union acpi_object *limit2;
	union acpi_object *enable;
	struct atk_sensor_data *sensor;
	char const *base_name;
	char const *limit1_name;
	char const *limit2_name;
	u64 type;
	int err;
	int *num;
	int start;

	if (obj->type != ACPI_TYPE_PACKAGE) {
		/* wft is this? */
		dev_warn(dev, "Unknown type for ACPI object: (%d)\n",
				obj->type);
		return -EINVAL;
	}

	err = validate_hwmon_pack(data, obj);
	if (err)
		return err;

	/* Ok, we have a valid hwmon package */
	type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value
	       & ATK_TYPE_MASK;

	switch (type) {
	case HWMON_TYPE_VOLT:
		base_name = "in";
		limit1_name = "min";
		limit2_name = "max";
		num = &data->voltage_count;
		start = 0;
		break;
	case HWMON_TYPE_TEMP:
		base_name = "temp";
		limit1_name = "max";
		limit2_name = "crit";
		num = &data->temperature_count;
		start = 1;
		break;
	case HWMON_TYPE_FAN:
		base_name = "fan";
		limit1_name = "min";
		limit2_name = "max";
		num = &data->fan_count;
		start = 1;
		break;
	default:
		dev_warn(dev, "Unknown sensor type: %#llx\n", type);
		return -EINVAL;
	}

	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
	if (!enable->integer.value)
		/* sensor is disabled */
		return 0;

	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (!sensor)
		return -ENOMEM;

	sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL);
	if (!sensor->acpi_name) {
		err = -ENOMEM;
		goto out;
	}

	INIT_LIST_HEAD(&sensor->list);
	sensor->type = type;
	sensor->data = data;
	sensor->id = flags->integer.value;
	sensor->limit1 = limit1->integer.value;
	if (data->old_interface)
		sensor->limit2 = limit2->integer.value;
	else
		/* The upper limit is expressed as delta from lower limit */
		sensor->limit2 = sensor->limit1 + limit2->integer.value;

	snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
			"%s%d_input", base_name, start + *num);
	atk_init_attribute(&sensor->input_attr,
			sensor->input_attr_name,
			atk_input_show);

	snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
			"%s%d_label", base_name, start + *num);
	atk_init_attribute(&sensor->label_attr,
			sensor->label_attr_name,
			atk_label_show);

	snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
			"%s%d_%s", base_name, start + *num, limit1_name);
	atk_init_attribute(&sensor->limit1_attr,
			sensor->limit1_attr_name,
			atk_limit1_show);

	snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
			"%s%d_%s", base_name, start + *num, limit2_name);
	atk_init_attribute(&sensor->limit2_attr,
			sensor->limit2_attr_name,
			atk_limit2_show);

	list_add(&sensor->list, &data->sensor_list);
	(*num)++;

	return 1;
out:
	kfree(sensor->acpi_name);
	kfree(sensor);
	return err;
}

static int atk_enumerate_old_hwmon(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_buffer buf;
	union acpi_object *pack;
	acpi_status status;
	int i, ret;
	int count = 0;

	/* Voltages */
	buf.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->atk_handle,
			METHOD_OLD_ENUM_VLT, NULL, &buf, ACPI_TYPE_PACKAGE);
	if (status != AE_OK) {
		dev_warn(dev, METHOD_OLD_ENUM_VLT ": ACPI exception: %s\n",
				acpi_format_exception(status));

		return -ENODEV;
	}

	pack = buf.pointer;
	for (i = 1; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_add_sensor(data, obj);
		if (ret > 0)
			count++;
	}
	ACPI_FREE(buf.pointer);

	/* Temperatures */
	buf.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->atk_handle,
			METHOD_OLD_ENUM_TMP, NULL, &buf, ACPI_TYPE_PACKAGE);
	if (status != AE_OK) {
		dev_warn(dev, METHOD_OLD_ENUM_TMP ": ACPI exception: %s\n",
				acpi_format_exception(status));

		ret = -ENODEV;
		goto cleanup;
	}

	pack = buf.pointer;
	for (i = 1; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_add_sensor(data, obj);
		if (ret > 0)
			count++;
	}
	ACPI_FREE(buf.pointer);

	/* Fans */
	buf.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->atk_handle,
			METHOD_OLD_ENUM_FAN, NULL, &buf, ACPI_TYPE_PACKAGE);
	if (status != AE_OK) {
		dev_warn(dev, METHOD_OLD_ENUM_FAN ": ACPI exception: %s\n",
				acpi_format_exception(status));

		ret = -ENODEV;
		goto cleanup;
	}

	pack = buf.pointer;
	for (i = 1; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_add_sensor(data, obj);
		if (ret > 0)
			count++;
	}
	ACPI_FREE(buf.pointer);

	return count;
cleanup:
	atk_free_sensors(data);
	return ret;
}

static int atk_ec_present(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *pack;
	union acpi_object *ec;
	int ret;
	int i;

	pack = atk_ggrp(data, ATK_MUX_MGMT);
	if (IS_ERR(pack)) {
		if (PTR_ERR(pack) == -ENOENT) {
			/* The MGMT class does not exists - that's ok */
			dev_dbg(dev, "Class %#llx not found\n", ATK_MUX_MGMT);
			return 0;
		}
		return PTR_ERR(pack);
	}

	/* Search the EC */
	ec = NULL;
	for (i = 0; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];
		union acpi_object *id;

		if (obj->type != ACPI_TYPE_PACKAGE)
			continue;

		id = &obj->package.elements[0];
		if (id->type != ACPI_TYPE_INTEGER)
			continue;

		if (id->integer.value == ATK_EC_ID) {
			ec = obj;
			break;
		}
	}

	ret = (ec != NULL);
	if (!ret)
		/* The system has no EC */
		dev_dbg(dev, "EC not found\n");

	ACPI_FREE(pack);
	return ret;
}

static int atk_ec_enabled(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *obj;
	struct atk_acpi_ret_buffer *buf;
	int err;

	obj = atk_gitm(data, ATK_EC_ID);
	if (IS_ERR(obj)) {
		dev_err(dev, "Unable to query EC status\n");
		return PTR_ERR(obj);
	}
	buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;

	if (buf->flags == 0) {
		dev_err(dev, "Unable to query EC status\n");
		err = -EIO;
	} else {
		err = (buf->value != 0);
		dev_dbg(dev, "EC is %sabled\n",
				err ? "en" : "dis");
	}

	ACPI_FREE(obj);
	return err;
}

static int atk_ec_ctl(struct atk_data *data, int enable)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *obj;
	struct atk_acpi_input_buf sitm;
	struct atk_acpi_ret_buffer *ec_ret;
	int err = 0;

	sitm.id = ATK_EC_ID;
	sitm.param1 = enable;
	sitm.param2 = 0;

	obj = atk_sitm(data, &sitm);
	if (IS_ERR(obj)) {
		dev_err(dev, "Failed to %sable the EC\n",
				enable ? "en" : "dis");
		return PTR_ERR(obj);
	}
	ec_ret = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
	if (ec_ret->flags == 0) {
		dev_err(dev, "Failed to %sable the EC\n",
				enable ? "en" : "dis");
		err = -EIO;
	} else {
		dev_info(dev, "EC %sabled\n",
				enable ? "en" : "dis");
	}

	ACPI_FREE(obj);
	return err;
}

static int atk_enumerate_new_hwmon(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *pack;
	int err;
	int i;

	err = atk_ec_present(data);
	if (err < 0)
		return err;
	if (err) {
		err = atk_ec_enabled(data);
		if (err < 0)
			return err;
		/* If the EC was disabled we will disable it again on unload */
		data->disable_ec = err;

		err = atk_ec_ctl(data, 1);
		if (err) {
			data->disable_ec = false;
			return err;
		}
	}

	dev_dbg(dev, "Enumerating hwmon sensors\n");

	pack = atk_ggrp(data, ATK_MUX_HWMON);
	if (IS_ERR(pack))
		return PTR_ERR(pack);

	for (i = 0; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		atk_add_sensor(data, obj);
	}

	err = data->voltage_count + data->temperature_count + data->fan_count;

	ACPI_FREE(pack);
	return err;
}

static int atk_create_files(struct atk_data *data)
{
	struct atk_sensor_data *s;
	int err;

	list_for_each_entry(s, &data->sensor_list, list) {
		err = device_create_file(data->hwmon_dev, &s->input_attr);
		if (err)
			return err;
		err = device_create_file(data->hwmon_dev, &s->label_attr);
		if (err)
			return err;
		err = device_create_file(data->hwmon_dev, &s->limit1_attr);
		if (err)
			return err;
		err = device_create_file(data->hwmon_dev, &s->limit2_attr);
		if (err)
			return err;
	}

	err = device_create_file(data->hwmon_dev, &atk_name_attr);

	return err;
}

static void atk_remove_files(struct atk_data *data)
{
	struct atk_sensor_data *s;

	list_for_each_entry(s, &data->sensor_list, list) {
		device_remove_file(data->hwmon_dev, &s->input_attr);
		device_remove_file(data->hwmon_dev, &s->label_attr);
		device_remove_file(data->hwmon_dev, &s->limit1_attr);
		device_remove_file(data->hwmon_dev, &s->limit2_attr);
	}
	device_remove_file(data->hwmon_dev, &atk_name_attr);
}

static void atk_free_sensors(struct atk_data *data)
{
	struct list_head *head = &data->sensor_list;
	struct atk_sensor_data *s, *tmp;

	list_for_each_entry_safe(s, tmp, head, list) {
		kfree(s->acpi_name);
		kfree(s);
	}
}

static int atk_register_hwmon(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	int err;

	dev_dbg(dev, "registering hwmon device\n");
	data->hwmon_dev = hwmon_device_register(dev);
	if (IS_ERR(data->hwmon_dev))
		return PTR_ERR(data->hwmon_dev);

	dev_dbg(dev, "populating sysfs directory\n");
	err = atk_create_files(data);
	if (err)
		goto remove;

	return 0;
remove:
	/* Cleanup the registered files */
	atk_remove_files(data);
	hwmon_device_unregister(data->hwmon_dev);
	return err;
}

static int atk_probe_if(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	acpi_handle ret;
	acpi_status status;
	int err = 0;

	/* RTMP: read temperature */
	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret);
	if (ACPI_SUCCESS(status))
		data->rtmp_handle = ret;
	else
		dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n",
				acpi_format_exception(status));

	/* RVLT: read voltage */
	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret);
	if (ACPI_SUCCESS(status))
		data->rvlt_handle = ret;
	else
		dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n",
				acpi_format_exception(status));

	/* RFAN: read fan status */
	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret);
	if (ACPI_SUCCESS(status))
		data->rfan_handle = ret;
	else
		dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n",
				acpi_format_exception(status));

	/* Enumeration */
	status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret);
	if (ACPI_SUCCESS(status))
		data->enumerate_handle = ret;
	else
		dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n",
				acpi_format_exception(status));

	/* De-multiplexer (read) */
	status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret);
	if (ACPI_SUCCESS(status))
		data->read_handle = ret;
	else
		dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
				acpi_format_exception(status));

	/* De-multiplexer (write) */
	status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret);
	if (ACPI_SUCCESS(status))
		data->write_handle = ret;
	else
		dev_dbg(dev, "method " METHOD_WRITE " not found: %s\n",
				 acpi_format_exception(status));

	/* Check for hwmon methods: first check "old" style methods; note that
	 * both may be present: in this case we stick to the old interface;
	 * analysis of multiple DSDTs indicates that when both interfaces
	 * are present the new one (GGRP/GITM) is not functional.
	 */
	if (new_if)
		dev_info(dev, "Overriding interface detection\n");
	if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle && !new_if)
		data->old_interface = true;
	else if (data->enumerate_handle && data->read_handle &&
			data->write_handle)
		data->old_interface = false;
	else
		err = -ENODEV;

	return err;
}

static int atk_add(struct acpi_device *device)
{
	acpi_status ret;
	int err;
	struct acpi_buffer buf;
	union acpi_object *obj;
	struct atk_data *data;

	dev_dbg(&device->dev, "adding...\n");

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->acpi_dev = device;
	data->atk_handle = device->handle;
	INIT_LIST_HEAD(&data->sensor_list);
	data->disable_ec = false;

	buf.length = ACPI_ALLOCATE_BUFFER;
	ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL,
			&buf, ACPI_TYPE_PACKAGE);
	if (ret != AE_OK) {
		dev_dbg(&device->dev, "atk: method MBIF not found\n");
	} else {
		obj = buf.pointer;
		if (obj->package.count >= 2) {
			union acpi_object *id = &obj->package.elements[1];
			if (id->type == ACPI_TYPE_STRING)
				dev_dbg(&device->dev, "board ID = %s\n",
					id->string.pointer);
		}
		ACPI_FREE(buf.pointer);
	}

	err = atk_probe_if(data);
	if (err) {
		dev_err(&device->dev, "No usable hwmon interface detected\n");
		goto out;
	}

	if (data->old_interface) {
		dev_dbg(&device->dev, "Using old hwmon interface\n");
		err = atk_enumerate_old_hwmon(data);
	} else {
		dev_dbg(&device->dev, "Using new hwmon interface\n");
		err = atk_enumerate_new_hwmon(data);
	}
	if (err < 0)
		goto out;
	if (err == 0) {
		dev_info(&device->dev,
			 "No usable sensor detected, bailing out\n");
		err = -ENODEV;
		goto out;
	}

	err = atk_register_hwmon(data);
	if (err)
		goto cleanup;

	atk_debugfs_init(data);

	device->driver_data = data;
	return 0;
cleanup:
	atk_free_sensors(data);
out:
	if (data->disable_ec)
		atk_ec_ctl(data, 0);
	kfree(data);
	return err;
}

static int atk_remove(struct acpi_device *device, int type)
{
	struct atk_data *data = device->driver_data;
	dev_dbg(&device->dev, "removing...\n");

	device->driver_data = NULL;

	atk_debugfs_cleanup(data);

	atk_remove_files(data);
	atk_free_sensors(data);
	hwmon_device_unregister(data->hwmon_dev);

	if (data->disable_ec) {
		if (atk_ec_ctl(data, 0))
			dev_err(&device->dev, "Failed to disable EC\n");
	}

	kfree(data);

	return 0;
}

static int __init atk0110_init(void)
{
	int ret;

	/* Make sure it's safe to access the device through ACPI */
	if (!acpi_resources_are_enforced()) {
		pr_err("Resources not safely usable due to acpi_enforce_resources kernel parameter\n");
		return -EBUSY;
	}

	if (dmi_check_system(atk_force_new_if))
		new_if = true;

	ret = acpi_bus_register_driver(&atk_driver);
	if (ret)
		pr_info("acpi_bus_register_driver failed: %d\n", ret);

	return ret;
}

static void __exit atk0110_exit(void)
{
	acpi_bus_unregister_driver(&atk_driver);
}

module_init(atk0110_init);
module_exit(atk0110_exit);

MODULE_LICENSE("GPL");
