/*
 *  intel_menlow.c - Intel menlow Driver for thermal management extension
 *
 *  Copyright (C) 2008 Intel Corp
 *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
 *  Copyright (C) 2008 Zhang Rui <rui.zhang@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; version 2 of the License.
 *
 *  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.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This driver creates the sys I/F for programming the sensors.
 *  It also implements the driver for intel menlow memory controller (hardware
 *  id is INT0002) which makes use of the platform specific ACPI methods
 *  to get/set bandwidth.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pm.h>

#include <linux/thermal.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>

MODULE_AUTHOR("Thomas Sujith");
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Intel Menlow platform specific driver");
MODULE_LICENSE("GPL");

/*
 * Memory controller device control
 */

#define MEMORY_GET_BANDWIDTH "GTHS"
#define MEMORY_SET_BANDWIDTH "STHS"
#define MEMORY_ARG_CUR_BANDWIDTH 1
#define MEMORY_ARG_MAX_BANDWIDTH 0

static void intel_menlow_unregister_sensor(void);

/*
 * GTHS returning 'n' would mean that [0,n-1] states are supported
 * In that case max_cstate would be n-1
 * GTHS returning '0' would mean that no bandwidth control states are supported
 */
static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
				    unsigned long *max_state)
{
	struct acpi_device *device = cdev->devdata;
	acpi_handle handle = device->handle;
	unsigned long long value;
	struct acpi_object_list arg_list;
	union acpi_object arg;
	acpi_status status = AE_OK;

	arg_list.count = 1;
	arg_list.pointer = &arg;
	arg.type = ACPI_TYPE_INTEGER;
	arg.integer.value = MEMORY_ARG_MAX_BANDWIDTH;
	status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
				       &arg_list, &value);
	if (ACPI_FAILURE(status))
		return -EFAULT;

	if (!value)
		return -EINVAL;

	*max_state = value - 1;
	return 0;
}

static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
				    unsigned long *value)
{
	struct acpi_device *device = cdev->devdata;
	acpi_handle handle = device->handle;
	unsigned long long result;
	struct acpi_object_list arg_list;
	union acpi_object arg;
	acpi_status status = AE_OK;

	arg_list.count = 1;
	arg_list.pointer = &arg;
	arg.type = ACPI_TYPE_INTEGER;
	arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
	status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
				       &arg_list, &result);
	if (ACPI_FAILURE(status))
		return -EFAULT;

	*value = result;
	return 0;
}

static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
				    unsigned long state)
{
	struct acpi_device *device = cdev->devdata;
	acpi_handle handle = device->handle;
	struct acpi_object_list arg_list;
	union acpi_object arg;
	acpi_status status;
	unsigned long long temp;
	unsigned long max_state;

	if (memory_get_max_bandwidth(cdev, &max_state))
		return -EFAULT;

	if (state > max_state)
		return -EINVAL;

	arg_list.count = 1;
	arg_list.pointer = &arg;
	arg.type = ACPI_TYPE_INTEGER;
	arg.integer.value = state;

	status =
	    acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list,
				  &temp);

	pr_info("Bandwidth value was %ld: status is %d\n", state, status);
	if (ACPI_FAILURE(status))
		return -EFAULT;

	return 0;
}

static struct thermal_cooling_device_ops memory_cooling_ops = {
	.get_max_state = memory_get_max_bandwidth,
	.get_cur_state = memory_get_cur_bandwidth,
	.set_cur_state = memory_set_cur_bandwidth,
};

/*
 * Memory Device Management
 */
static int intel_menlow_memory_add(struct acpi_device *device)
{
	int result = -ENODEV;
	struct thermal_cooling_device *cdev;

	if (!device)
		return -EINVAL;

	if (!acpi_has_method(device->handle, MEMORY_GET_BANDWIDTH))
		goto end;

	if (!acpi_has_method(device->handle, MEMORY_SET_BANDWIDTH))
		goto end;

	cdev = thermal_cooling_device_register("Memory controller", device,
					       &memory_cooling_ops);
	if (IS_ERR(cdev)) {
		result = PTR_ERR(cdev);
		goto end;
	}

	device->driver_data = cdev;
	result = sysfs_create_link(&device->dev.kobj,
				&cdev->device.kobj, "thermal_cooling");
	if (result)
		goto unregister;

	result = sysfs_create_link(&cdev->device.kobj,
				&device->dev.kobj, "device");
	if (result) {
		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
		goto unregister;
	}

 end:
	return result;

 unregister:
	thermal_cooling_device_unregister(cdev);
	return result;

}

static int intel_menlow_memory_remove(struct acpi_device *device)
{
	struct thermal_cooling_device *cdev = acpi_driver_data(device);

	if (!device || !cdev)
		return -EINVAL;

	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
	sysfs_remove_link(&cdev->device.kobj, "device");
	thermal_cooling_device_unregister(cdev);

	return 0;
}

static const struct acpi_device_id intel_menlow_memory_ids[] = {
	{"INT0002", 0},
	{"", 0},
};

static struct acpi_driver intel_menlow_memory_driver = {
	.name = "intel_menlow_thermal_control",
	.ids = intel_menlow_memory_ids,
	.ops = {
		.add = intel_menlow_memory_add,
		.remove = intel_menlow_memory_remove,
		},
};

/*
 * Sensor control on menlow platform
 */

#define THERMAL_AUX0 0
#define THERMAL_AUX1 1
#define GET_AUX0 "GAX0"
#define GET_AUX1 "GAX1"
#define SET_AUX0 "SAX0"
#define SET_AUX1 "SAX1"

struct intel_menlow_attribute {
	struct device_attribute attr;
	struct device *device;
	acpi_handle handle;
	struct list_head node;
};

static LIST_HEAD(intel_menlow_attr_list);
static DEFINE_MUTEX(intel_menlow_attr_lock);

/*
 * sensor_get_auxtrip - get the current auxtrip value from sensor
 * @name: Thermalzone name
 * @auxtype : AUX0/AUX1
 * @buf: syfs buffer
 */
static int sensor_get_auxtrip(acpi_handle handle, int index,
							unsigned long long *value)
{
	acpi_status status;

	if ((index != 0 && index != 1) || !value)
		return -EINVAL;

	status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0,
				       NULL, value);
	if (ACPI_FAILURE(status))
		return -EIO;

	return 0;
}

/*
 * sensor_set_auxtrip - set the new auxtrip value to sensor
 * @name: Thermalzone name
 * @auxtype : AUX0/AUX1
 * @buf: syfs buffer
 */
static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
{
	acpi_status status;
	union acpi_object arg = {
		ACPI_TYPE_INTEGER
	};
	struct acpi_object_list args = {
		1, &arg
	};
	unsigned long long temp;

	if (index != 0 && index != 1)
		return -EINVAL;

	status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1,
				       NULL, &temp);
	if (ACPI_FAILURE(status))
		return -EIO;
	if ((index && value < temp) || (!index && value > temp))
		return -EINVAL;

	arg.integer.value = value;
	status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0,
				       &args, &temp);
	if (ACPI_FAILURE(status))
		return -EIO;

	/* do we need to check the return value of SAX0/SAX1 ? */

	return 0;
}

#define to_intel_menlow_attr(_attr)	\
	container_of(_attr, struct intel_menlow_attribute, attr)

static ssize_t aux0_show(struct device *dev,
			 struct device_attribute *dev_attr, char *buf)
{
	struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
	unsigned long long value;
	int result;

	result = sensor_get_auxtrip(attr->handle, 0, &value);

	return result ? result : sprintf(buf, "%lu", KELVIN_TO_CELSIUS(value));
}

static ssize_t aux1_show(struct device *dev,
			 struct device_attribute *dev_attr, char *buf)
{
	struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
	unsigned long long value;
	int result;

	result = sensor_get_auxtrip(attr->handle, 1, &value);

	return result ? result : sprintf(buf, "%lu", KELVIN_TO_CELSIUS(value));
}

static ssize_t aux0_store(struct device *dev,
			  struct device_attribute *dev_attr,
			  const char *buf, size_t count)
{
	struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
	int value;
	int result;

	/*Sanity check; should be a positive integer */
	if (!sscanf(buf, "%d", &value))
		return -EINVAL;

	if (value < 0)
		return -EINVAL;

	result = sensor_set_auxtrip(attr->handle, 0, CELSIUS_TO_KELVIN(value));
	return result ? result : count;
}

static ssize_t aux1_store(struct device *dev,
			  struct device_attribute *dev_attr,
			  const char *buf, size_t count)
{
	struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
	int value;
	int result;

	/*Sanity check; should be a positive integer */
	if (!sscanf(buf, "%d", &value))
		return -EINVAL;

	if (value < 0)
		return -EINVAL;

	result = sensor_set_auxtrip(attr->handle, 1, CELSIUS_TO_KELVIN(value));
	return result ? result : count;
}

/* BIOS can enable/disable the thermal user application in dabney platform */
#define BIOS_ENABLED "\\_TZ.GSTS"
static ssize_t bios_enabled_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	acpi_status status;
	unsigned long long bios_enabled;

	status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	return sprintf(buf, "%s\n", bios_enabled ? "enabled" : "disabled");
}

static int intel_menlow_add_one_attribute(char *name, umode_t mode, void *show,
					  void *store, struct device *dev,
					  acpi_handle handle)
{
	struct intel_menlow_attribute *attr;
	int result;

	attr = kzalloc(sizeof(struct intel_menlow_attribute), GFP_KERNEL);
	if (!attr)
		return -ENOMEM;

	sysfs_attr_init(&attr->attr.attr); /* That is consistent naming :D */
	attr->attr.attr.name = name;
	attr->attr.attr.mode = mode;
	attr->attr.show = show;
	attr->attr.store = store;
	attr->device = dev;
	attr->handle = handle;

	result = device_create_file(dev, &attr->attr);
	if (result) {
		kfree(attr);
		return result;
	}

	mutex_lock(&intel_menlow_attr_lock);
	list_add_tail(&attr->node, &intel_menlow_attr_list);
	mutex_unlock(&intel_menlow_attr_lock);

	return 0;
}

static acpi_status intel_menlow_register_sensor(acpi_handle handle, u32 lvl,
						void *context, void **rv)
{
	acpi_status status;
	acpi_handle dummy;
	struct thermal_zone_device *thermal;
	int result;

	result = acpi_bus_get_private_data(handle, (void **)&thermal);
	if (result)
		return 0;

	/* _TZ must have the AUX0/1 methods */
	status = acpi_get_handle(handle, GET_AUX0, &dummy);
	if (ACPI_FAILURE(status))
		return (status == AE_NOT_FOUND) ? AE_OK : status;

	status = acpi_get_handle(handle, SET_AUX0, &dummy);
	if (ACPI_FAILURE(status))
		return (status == AE_NOT_FOUND) ? AE_OK : status;

	result = intel_menlow_add_one_attribute("aux0", 0644,
						aux0_show, aux0_store,
						&thermal->device, handle);
	if (result)
		return AE_ERROR;

	status = acpi_get_handle(handle, GET_AUX1, &dummy);
	if (ACPI_FAILURE(status))
		goto aux1_not_found;

	status = acpi_get_handle(handle, SET_AUX1, &dummy);
	if (ACPI_FAILURE(status))
		goto aux1_not_found;

	result = intel_menlow_add_one_attribute("aux1", 0644,
						aux1_show, aux1_store,
						&thermal->device, handle);
	if (result) {
		intel_menlow_unregister_sensor();
		return AE_ERROR;
	}

	/*
	 * create the "dabney_enabled" attribute which means the user app
	 * should be loaded or not
	 */

	result = intel_menlow_add_one_attribute("bios_enabled", 0444,
						bios_enabled_show, NULL,
						&thermal->device, handle);
	if (result) {
		intel_menlow_unregister_sensor();
		return AE_ERROR;
	}

	return AE_OK;

 aux1_not_found:
	if (status == AE_NOT_FOUND)
		return AE_OK;

	intel_menlow_unregister_sensor();
	return status;
}

static void intel_menlow_unregister_sensor(void)
{
	struct intel_menlow_attribute *pos, *next;

	mutex_lock(&intel_menlow_attr_lock);
	list_for_each_entry_safe(pos, next, &intel_menlow_attr_list, node) {
		list_del(&pos->node);
		device_remove_file(pos->device, &pos->attr);
		kfree(pos);
	}
	mutex_unlock(&intel_menlow_attr_lock);

	return;
}

static int __init intel_menlow_module_init(void)
{
	int result = -ENODEV;
	acpi_status status;
	unsigned long long enable;

	if (acpi_disabled)
		return result;

	/* Looking for the \_TZ.GSTS method */
	status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &enable);
	if (ACPI_FAILURE(status) || !enable)
		return -ENODEV;

	/* Looking for ACPI device MEM0 with hardware id INT0002 */
	result = acpi_bus_register_driver(&intel_menlow_memory_driver);
	if (result)
		return result;

	/* Looking for sensors in each ACPI thermal zone */
	status = acpi_walk_namespace(ACPI_TYPE_THERMAL, ACPI_ROOT_OBJECT,
				     ACPI_UINT32_MAX,
				     intel_menlow_register_sensor, NULL, NULL, NULL);
	if (ACPI_FAILURE(status)) {
		acpi_bus_unregister_driver(&intel_menlow_memory_driver);
		return -ENODEV;
	}

	return 0;
}

static void __exit intel_menlow_module_exit(void)
{
	acpi_bus_unregister_driver(&intel_menlow_memory_driver);
	intel_menlow_unregister_sensor();
}

module_init(intel_menlow_module_init);
module_exit(intel_menlow_module_exit);
