/*
 * A hwmon driver for the IBM System Director Active Energy Manager (AEM)
 * temperature/power/energy sensors and capping functionality.
 * Copyright (C) 2008 IBM
 *
 * Author: Darrick J. Wong <djwong@us.ibm.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
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/ipmi.h>
#include <linux/module.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/kdev_t.h>
#include <linux/spinlock.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/math64.h>
#include <linux/time.h>
#include <linux/err.h>

#define REFRESH_INTERVAL	(HZ)
#define IPMI_TIMEOUT		(30 * HZ)
#define DRVNAME			"aem"

#define AEM_NETFN		0x2E

#define AEM_FIND_FW_CMD		0x80
#define AEM_ELEMENT_CMD		0x81
#define AEM_FW_INSTANCE_CMD	0x82

#define AEM_READ_ELEMENT_CFG	0x80
#define AEM_READ_BUFFER		0x81
#define AEM_READ_REGISTER	0x82
#define AEM_WRITE_REGISTER	0x83
#define AEM_SET_REG_MASK	0x84
#define AEM_CLEAR_REG_MASK	0x85
#define AEM_READ_ELEMENT_CFG2	0x86

#define AEM_CONTROL_ELEMENT	0
#define AEM_ENERGY_ELEMENT	1
#define AEM_CLOCK_ELEMENT	4
#define AEM_POWER_CAP_ELEMENT	7
#define AEM_EXHAUST_ELEMENT	9
#define AEM_POWER_ELEMENT	10

#define AEM_MODULE_TYPE_ID	0x0001

#define AEM2_NUM_ENERGY_REGS	2
#define AEM2_NUM_PCAP_REGS	6
#define AEM2_NUM_TEMP_REGS	2
#define AEM2_NUM_SENSORS	14

#define AEM1_NUM_ENERGY_REGS	1
#define AEM1_NUM_SENSORS	3

/* AEM 2.x has more energy registers */
#define AEM_NUM_ENERGY_REGS	AEM2_NUM_ENERGY_REGS
/* AEM 2.x needs more sensor files */
#define AEM_NUM_SENSORS		AEM2_NUM_SENSORS

#define POWER_CAP		0
#define POWER_CAP_MAX_HOTPLUG	1
#define POWER_CAP_MAX		2
#define	POWER_CAP_MIN_WARNING	3
#define POWER_CAP_MIN		4
#define	POWER_AUX		5

#define AEM_DEFAULT_POWER_INTERVAL 1000
#define AEM_MIN_POWER_INTERVAL	200
#define UJ_PER_MJ		1000L

static DEFINE_IDA(aem_ida);

static struct platform_driver aem_driver = {
	.driver = {
		.name = DRVNAME,
		.bus = &platform_bus_type,
	}
};

struct aem_ipmi_data {
	struct completion	read_complete;
	struct ipmi_addr	address;
	ipmi_user_t		user;
	int			interface;

	struct kernel_ipmi_msg	tx_message;
	long			tx_msgid;

	void			*rx_msg_data;
	unsigned short		rx_msg_len;
	unsigned char		rx_result;
	int			rx_recv_type;

	struct device		*bmc_device;
};

struct aem_ro_sensor_template {
	char *label;
	ssize_t (*show)(struct device *dev,
			struct device_attribute *devattr,
			char *buf);
	int index;
};

struct aem_rw_sensor_template {
	char *label;
	ssize_t (*show)(struct device *dev,
			struct device_attribute *devattr,
			char *buf);
	ssize_t (*set)(struct device *dev,
		       struct device_attribute *devattr,
		       const char *buf, size_t count);
	int index;
};

struct aem_data {
	struct list_head	list;

	struct device		*hwmon_dev;
	struct platform_device	*pdev;
	struct mutex		lock;
	char			valid;
	unsigned long		last_updated;	/* In jiffies */
	u8			ver_major;
	u8			ver_minor;
	u8			module_handle;
	int			id;
	struct aem_ipmi_data	ipmi;

	/* Function and buffer to update sensors */
	void (*update)(struct aem_data *data);
	struct aem_read_sensor_resp *rs_resp;

	/*
	 * AEM 1.x sensors:
	 * Available sensors:
	 * Energy meter
	 * Power meter
	 *
	 * AEM 2.x sensors:
	 * Two energy meters
	 * Two power meters
	 * Two temperature sensors
	 * Six power cap registers
	 */

	/* sysfs attrs */
	struct sensor_device_attribute	sensors[AEM_NUM_SENSORS];

	/* energy use in mJ */
	u64			energy[AEM_NUM_ENERGY_REGS];

	/* power sampling interval in ms */
	unsigned long		power_period[AEM_NUM_ENERGY_REGS];

	/* Everything past here is for AEM2 only */

	/* power caps in dW */
	u16			pcap[AEM2_NUM_PCAP_REGS];

	/* exhaust temperature in C */
	u8			temp[AEM2_NUM_TEMP_REGS];
};

/* Data structures returned by the AEM firmware */
struct aem_iana_id {
	u8			bytes[3];
};
static struct aem_iana_id system_x_id = {
	.bytes = {0x4D, 0x4F, 0x00}
};

/* These are used to find AEM1 instances */
struct aem_find_firmware_req {
	struct aem_iana_id	id;
	u8			rsvd;
	__be16			index;
	__be16			module_type_id;
} __packed;

struct aem_find_firmware_resp {
	struct aem_iana_id	id;
	u8			num_instances;
} __packed;

/* These are used to find AEM2 instances */
struct aem_find_instance_req {
	struct aem_iana_id	id;
	u8			instance_number;
	__be16			module_type_id;
} __packed;

struct aem_find_instance_resp {
	struct aem_iana_id	id;
	u8			num_instances;
	u8			major;
	u8			minor;
	u8			module_handle;
	u16			record_id;
} __packed;

/* These are used to query sensors */
struct aem_read_sensor_req {
	struct aem_iana_id	id;
	u8			module_handle;
	u8			element;
	u8			subcommand;
	u8			reg;
	u8			rx_buf_size;
} __packed;

struct aem_read_sensor_resp {
	struct aem_iana_id	id;
	u8			bytes[0];
} __packed;

/* Data structures to talk to the IPMI layer */
struct aem_driver_data {
	struct list_head	aem_devices;
	struct ipmi_smi_watcher	bmc_events;
	struct ipmi_user_hndl	ipmi_hndlrs;
};

static void aem_register_bmc(int iface, struct device *dev);
static void aem_bmc_gone(int iface);
static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);

static void aem_remove_sensors(struct aem_data *data);
static int aem1_find_sensors(struct aem_data *data);
static int aem2_find_sensors(struct aem_data *data);
static void update_aem1_sensors(struct aem_data *data);
static void update_aem2_sensors(struct aem_data *data);

static struct aem_driver_data driver_data = {
	.aem_devices = LIST_HEAD_INIT(driver_data.aem_devices),
	.bmc_events = {
		.owner = THIS_MODULE,
		.new_smi = aem_register_bmc,
		.smi_gone = aem_bmc_gone,
	},
	.ipmi_hndlrs = {
		.ipmi_recv_hndl = aem_msg_handler,
	},
};

/* Functions to talk to the IPMI layer */

/* Initialize IPMI address, message buffers and user data */
static int aem_init_ipmi_data(struct aem_ipmi_data *data, int iface,
			      struct device *bmc)
{
	int err;

	init_completion(&data->read_complete);
	data->bmc_device = bmc;

	/* Initialize IPMI address */
	data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	data->address.channel = IPMI_BMC_CHANNEL;
	data->address.data[0] = 0;
	data->interface = iface;

	/* Initialize message buffers */
	data->tx_msgid = 0;
	data->tx_message.netfn = AEM_NETFN;

	/* Create IPMI messaging interface user */
	err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs,
			       data, &data->user);
	if (err < 0) {
		dev_err(bmc,
			"Unable to register user with IPMI interface %d\n",
			data->interface);
		return -EACCES;
	}

	return 0;
}

/* Send an IPMI command */
static int aem_send_message(struct aem_ipmi_data *data)
{
	int err;

	err = ipmi_validate_addr(&data->address, sizeof(data->address));
	if (err)
		goto out;

	data->tx_msgid++;
	err = ipmi_request_settime(data->user, &data->address, data->tx_msgid,
				   &data->tx_message, data, 0, 0, 0);
	if (err)
		goto out1;

	return 0;
out1:
	dev_err(data->bmc_device, "request_settime=%x\n", err);
	return err;
out:
	dev_err(data->bmc_device, "validate_addr=%x\n", err);
	return err;
}

/* Dispatch IPMI messages to callers */
static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
{
	unsigned short rx_len;
	struct aem_ipmi_data *data = user_msg_data;

	if (msg->msgid != data->tx_msgid) {
		dev_err(data->bmc_device,
			"Mismatch between received msgid (%02x) and transmitted msgid (%02x)!\n",
			(int)msg->msgid,
			(int)data->tx_msgid);
		ipmi_free_recv_msg(msg);
		return;
	}

	data->rx_recv_type = msg->recv_type;
	if (msg->msg.data_len > 0)
		data->rx_result = msg->msg.data[0];
	else
		data->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE;

	if (msg->msg.data_len > 1) {
		rx_len = msg->msg.data_len - 1;
		if (data->rx_msg_len < rx_len)
			rx_len = data->rx_msg_len;
		data->rx_msg_len = rx_len;
		memcpy(data->rx_msg_data, msg->msg.data + 1, data->rx_msg_len);
	} else
		data->rx_msg_len = 0;

	ipmi_free_recv_msg(msg);
	complete(&data->read_complete);
}

/* Sensor support functions */

/* Read a sensor value; must be called with data->lock held */
static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
			   void *buf, size_t size)
{
	int rs_size, res;
	struct aem_read_sensor_req rs_req;
	/* Use preallocated rx buffer */
	struct aem_read_sensor_resp *rs_resp = data->rs_resp;
	struct aem_ipmi_data *ipmi = &data->ipmi;

	/* AEM registers are 1, 2, 4 or 8 bytes */
	switch (size) {
	case 1:
	case 2:
	case 4:
	case 8:
		break;
	default:
		return -EINVAL;
	}

	rs_req.id = system_x_id;
	rs_req.module_handle = data->module_handle;
	rs_req.element = elt;
	rs_req.subcommand = AEM_READ_REGISTER;
	rs_req.reg = reg;
	rs_req.rx_buf_size = size;

	ipmi->tx_message.cmd = AEM_ELEMENT_CMD;
	ipmi->tx_message.data = (char *)&rs_req;
	ipmi->tx_message.data_len = sizeof(rs_req);

	rs_size = sizeof(*rs_resp) + size;
	ipmi->rx_msg_data = rs_resp;
	ipmi->rx_msg_len = rs_size;

	aem_send_message(ipmi);

	res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT);
	if (!res) {
		res = -ETIMEDOUT;
		goto out;
	}

	if (ipmi->rx_result || ipmi->rx_msg_len != rs_size ||
	    memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) {
		res = -ENOENT;
		goto out;
	}

	switch (size) {
	case 1: {
		u8 *x = buf;
		*x = rs_resp->bytes[0];
		break;
	}
	case 2: {
		u16 *x = buf;
		*x = be16_to_cpup((__be16 *)rs_resp->bytes);
		break;
	}
	case 4: {
		u32 *x = buf;
		*x = be32_to_cpup((__be32 *)rs_resp->bytes);
		break;
	}
	case 8: {
		u64 *x = buf;
		*x = be64_to_cpup((__be64 *)rs_resp->bytes);
		break;
	}
	}
	res = 0;

out:
	return res;
}

/* Update AEM energy registers */
static void update_aem_energy_one(struct aem_data *data, int which)
{
	aem_read_sensor(data, AEM_ENERGY_ELEMENT, which,
			&data->energy[which], 8);
}

static void update_aem_energy(struct aem_data *data)
{
	update_aem_energy_one(data, 0);
	if (data->ver_major < 2)
		return;
	update_aem_energy_one(data, 1);
}

/* Update all AEM1 sensors */
static void update_aem1_sensors(struct aem_data *data)
{
	mutex_lock(&data->lock);
	if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) &&
	    data->valid)
		goto out;

	update_aem_energy(data);
out:
	mutex_unlock(&data->lock);
}

/* Update all AEM2 sensors */
static void update_aem2_sensors(struct aem_data *data)
{
	int i;

	mutex_lock(&data->lock);
	if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) &&
	    data->valid)
		goto out;

	update_aem_energy(data);
	aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 0, &data->temp[0], 1);
	aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 1, &data->temp[1], 1);

	for (i = POWER_CAP; i <= POWER_AUX; i++)
		aem_read_sensor(data, AEM_POWER_CAP_ELEMENT, i,
				&data->pcap[i], 2);
out:
	mutex_unlock(&data->lock);
}

/* Delete an AEM instance */
static void aem_delete(struct aem_data *data)
{
	list_del(&data->list);
	aem_remove_sensors(data);
	kfree(data->rs_resp);
	hwmon_device_unregister(data->hwmon_dev);
	ipmi_destroy_user(data->ipmi.user);
	platform_set_drvdata(data->pdev, NULL);
	platform_device_unregister(data->pdev);
	ida_simple_remove(&aem_ida, data->id);
	kfree(data);
}

/* Probe functions for AEM1 devices */

/* Retrieve version and module handle for an AEM1 instance */
static int aem_find_aem1_count(struct aem_ipmi_data *data)
{
	int res;
	struct aem_find_firmware_req	ff_req;
	struct aem_find_firmware_resp	ff_resp;

	ff_req.id = system_x_id;
	ff_req.index = 0;
	ff_req.module_type_id = cpu_to_be16(AEM_MODULE_TYPE_ID);

	data->tx_message.cmd = AEM_FIND_FW_CMD;
	data->tx_message.data = (char *)&ff_req;
	data->tx_message.data_len = sizeof(ff_req);

	data->rx_msg_data = &ff_resp;
	data->rx_msg_len = sizeof(ff_resp);

	aem_send_message(data);

	res = wait_for_completion_timeout(&data->read_complete, IPMI_TIMEOUT);
	if (!res)
		return -ETIMEDOUT;

	if (data->rx_result || data->rx_msg_len != sizeof(ff_resp) ||
	    memcmp(&ff_resp.id, &system_x_id, sizeof(system_x_id)))
		return -ENOENT;

	return ff_resp.num_instances;
}

/* Find and initialize one AEM1 instance */
static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
{
	struct aem_data *data;
	int i;
	int res = -ENOMEM;

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return res;
	mutex_init(&data->lock);

	/* Copy instance data */
	data->ver_major = 1;
	data->ver_minor = 0;
	data->module_handle = module_handle;
	for (i = 0; i < AEM1_NUM_ENERGY_REGS; i++)
		data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL;

	/* Create sub-device for this fw instance */
	data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL);
	if (data->id < 0)
		goto id_err;

	data->pdev = platform_device_alloc(DRVNAME, data->id);
	if (!data->pdev)
		goto dev_err;
	data->pdev->dev.driver = &aem_driver.driver;

	res = platform_device_add(data->pdev);
	if (res)
		goto ipmi_err;

	platform_set_drvdata(data->pdev, data);

	/* Set up IPMI interface */
	res = aem_init_ipmi_data(&data->ipmi, probe->interface,
				 probe->bmc_device);
	if (res)
		goto ipmi_err;

	/* Register with hwmon */
	data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
	if (IS_ERR(data->hwmon_dev)) {
		dev_err(&data->pdev->dev,
			"Unable to register hwmon device for IPMI interface %d\n",
			probe->interface);
		res = PTR_ERR(data->hwmon_dev);
		goto hwmon_reg_err;
	}

	data->update = update_aem1_sensors;
	data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
	if (!data->rs_resp) {
		res = -ENOMEM;
		goto alloc_resp_err;
	}

	/* Find sensors */
	res = aem1_find_sensors(data);
	if (res)
		goto sensor_err;

	/* Add to our list of AEM devices */
	list_add_tail(&data->list, &driver_data.aem_devices);

	dev_info(data->ipmi.bmc_device, "Found AEM v%d.%d at 0x%X\n",
		 data->ver_major, data->ver_minor,
		 data->module_handle);
	return 0;

sensor_err:
	kfree(data->rs_resp);
alloc_resp_err:
	hwmon_device_unregister(data->hwmon_dev);
hwmon_reg_err:
	ipmi_destroy_user(data->ipmi.user);
ipmi_err:
	platform_set_drvdata(data->pdev, NULL);
	platform_device_unregister(data->pdev);
dev_err:
	ida_simple_remove(&aem_ida, data->id);
id_err:
	kfree(data);

	return res;
}

/* Find and initialize all AEM1 instances */
static void aem_init_aem1(struct aem_ipmi_data *probe)
{
	int num, i, err;

	num = aem_find_aem1_count(probe);
	for (i = 0; i < num; i++) {
		err = aem_init_aem1_inst(probe, i);
		if (err) {
			dev_err(probe->bmc_device,
				"Error %d initializing AEM1 0x%X\n",
				err, i);
		}
	}
}

/* Probe functions for AEM2 devices */

/* Retrieve version and module handle for an AEM2 instance */
static int aem_find_aem2(struct aem_ipmi_data *data,
			    struct aem_find_instance_resp *fi_resp,
			    int instance_num)
{
	int res;
	struct aem_find_instance_req fi_req;

	fi_req.id = system_x_id;
	fi_req.instance_number = instance_num;
	fi_req.module_type_id = cpu_to_be16(AEM_MODULE_TYPE_ID);

	data->tx_message.cmd = AEM_FW_INSTANCE_CMD;
	data->tx_message.data = (char *)&fi_req;
	data->tx_message.data_len = sizeof(fi_req);

	data->rx_msg_data = fi_resp;
	data->rx_msg_len = sizeof(*fi_resp);

	aem_send_message(data);

	res = wait_for_completion_timeout(&data->read_complete, IPMI_TIMEOUT);
	if (!res)
		return -ETIMEDOUT;

	if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) ||
	    memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id)) ||
	    fi_resp->num_instances <= instance_num)
		return -ENOENT;

	return 0;
}

/* Find and initialize one AEM2 instance */
static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
			      struct aem_find_instance_resp *fi_resp)
{
	struct aem_data *data;
	int i;
	int res = -ENOMEM;

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return res;
	mutex_init(&data->lock);

	/* Copy instance data */
	data->ver_major = fi_resp->major;
	data->ver_minor = fi_resp->minor;
	data->module_handle = fi_resp->module_handle;
	for (i = 0; i < AEM2_NUM_ENERGY_REGS; i++)
		data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL;

	/* Create sub-device for this fw instance */
	data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL);
	if (data->id < 0)
		goto id_err;

	data->pdev = platform_device_alloc(DRVNAME, data->id);
	if (!data->pdev)
		goto dev_err;
	data->pdev->dev.driver = &aem_driver.driver;

	res = platform_device_add(data->pdev);
	if (res)
		goto ipmi_err;

	platform_set_drvdata(data->pdev, data);

	/* Set up IPMI interface */
	res = aem_init_ipmi_data(&data->ipmi, probe->interface,
				 probe->bmc_device);
	if (res)
		goto ipmi_err;

	/* Register with hwmon */
	data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
	if (IS_ERR(data->hwmon_dev)) {
		dev_err(&data->pdev->dev,
			"Unable to register hwmon device for IPMI interface %d\n",
			probe->interface);
		res = PTR_ERR(data->hwmon_dev);
		goto hwmon_reg_err;
	}

	data->update = update_aem2_sensors;
	data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
	if (!data->rs_resp) {
		res = -ENOMEM;
		goto alloc_resp_err;
	}

	/* Find sensors */
	res = aem2_find_sensors(data);
	if (res)
		goto sensor_err;

	/* Add to our list of AEM devices */
	list_add_tail(&data->list, &driver_data.aem_devices);

	dev_info(data->ipmi.bmc_device, "Found AEM v%d.%d at 0x%X\n",
		 data->ver_major, data->ver_minor,
		 data->module_handle);
	return 0;

sensor_err:
	kfree(data->rs_resp);
alloc_resp_err:
	hwmon_device_unregister(data->hwmon_dev);
hwmon_reg_err:
	ipmi_destroy_user(data->ipmi.user);
ipmi_err:
	platform_set_drvdata(data->pdev, NULL);
	platform_device_unregister(data->pdev);
dev_err:
	ida_simple_remove(&aem_ida, data->id);
id_err:
	kfree(data);

	return res;
}

/* Find and initialize all AEM2 instances */
static void aem_init_aem2(struct aem_ipmi_data *probe)
{
	struct aem_find_instance_resp fi_resp;
	int err;
	int i = 0;

	while (!aem_find_aem2(probe, &fi_resp, i)) {
		if (fi_resp.major != 2) {
			dev_err(probe->bmc_device,
				"Unknown AEM v%d; please report this to the maintainer.\n",
				fi_resp.major);
			i++;
			continue;
		}
		err = aem_init_aem2_inst(probe, &fi_resp);
		if (err) {
			dev_err(probe->bmc_device,
				"Error %d initializing AEM2 0x%X\n",
				err, fi_resp.module_handle);
		}
		i++;
	}
}

/* Probe a BMC for AEM firmware instances */
static void aem_register_bmc(int iface, struct device *dev)
{
	struct aem_ipmi_data probe;

	if (aem_init_ipmi_data(&probe, iface, dev))
		return;

	/* Ignore probe errors; they won't cause problems */
	aem_init_aem1(&probe);
	aem_init_aem2(&probe);

	ipmi_destroy_user(probe.user);
}

/* Handle BMC deletion */
static void aem_bmc_gone(int iface)
{
	struct aem_data *p1, *next1;

	list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list)
		if (p1->ipmi.interface == iface)
			aem_delete(p1);
}

/* sysfs support functions */

/* AEM device name */
static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
			 char *buf)
{
	struct aem_data *data = dev_get_drvdata(dev);

	return sprintf(buf, "%s%d\n", DRVNAME, data->ver_major);
}
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);

/* AEM device version */
static ssize_t show_version(struct device *dev,
			    struct device_attribute *devattr,
			    char *buf)
{
	struct aem_data *data = dev_get_drvdata(dev);

	return sprintf(buf, "%d.%d\n", data->ver_major, data->ver_minor);
}
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, 0);

/* Display power use */
static ssize_t aem_show_power(struct device *dev,
			      struct device_attribute *devattr,
			      char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct aem_data *data = dev_get_drvdata(dev);
	u64 before, after, delta, time;
	signed long leftover;
	struct timespec b, a;

	mutex_lock(&data->lock);
	update_aem_energy_one(data, attr->index);
	getnstimeofday(&b);
	before = data->energy[attr->index];

	leftover = schedule_timeout_interruptible(
			msecs_to_jiffies(data->power_period[attr->index])
		   );
	if (leftover) {
		mutex_unlock(&data->lock);
		return 0;
	}

	update_aem_energy_one(data, attr->index);
	getnstimeofday(&a);
	after = data->energy[attr->index];
	mutex_unlock(&data->lock);

	time = timespec_to_ns(&a) - timespec_to_ns(&b);
	delta = (after - before) * UJ_PER_MJ;

	return sprintf(buf, "%llu\n",
		(unsigned long long)div64_u64(delta * NSEC_PER_SEC, time));
}

/* Display energy use */
static ssize_t aem_show_energy(struct device *dev,
			       struct device_attribute *devattr,
			       char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct aem_data *a = dev_get_drvdata(dev);
	mutex_lock(&a->lock);
	update_aem_energy_one(a, attr->index);
	mutex_unlock(&a->lock);

	return sprintf(buf, "%llu\n",
			(unsigned long long)a->energy[attr->index] * 1000);
}

/* Display power interval registers */
static ssize_t aem_show_power_period(struct device *dev,
				     struct device_attribute *devattr,
				     char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct aem_data *a = dev_get_drvdata(dev);
	a->update(a);

	return sprintf(buf, "%lu\n", a->power_period[attr->index]);
}

/* Set power interval registers */
static ssize_t aem_set_power_period(struct device *dev,
				    struct device_attribute *devattr,
				    const char *buf, size_t count)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct aem_data *a = dev_get_drvdata(dev);
	unsigned long temp;
	int res;

	res = kstrtoul(buf, 10, &temp);
	if (res)
		return res;

	if (temp < AEM_MIN_POWER_INTERVAL)
		return -EINVAL;

	mutex_lock(&a->lock);
	a->power_period[attr->index] = temp;
	mutex_unlock(&a->lock);

	return count;
}

/* Discover sensors on an AEM device */
static int aem_register_sensors(struct aem_data *data,
				struct aem_ro_sensor_template *ro,
				struct aem_rw_sensor_template *rw)
{
	struct device *dev = &data->pdev->dev;
	struct sensor_device_attribute *sensors = data->sensors;
	int err;

	/* Set up read-only sensors */
	while (ro->label) {
		sysfs_attr_init(&sensors->dev_attr.attr);
		sensors->dev_attr.attr.name = ro->label;
		sensors->dev_attr.attr.mode = S_IRUGO;
		sensors->dev_attr.show = ro->show;
		sensors->index = ro->index;

		err = device_create_file(dev, &sensors->dev_attr);
		if (err) {
			sensors->dev_attr.attr.name = NULL;
			goto error;
		}
		sensors++;
		ro++;
	}

	/* Set up read-write sensors */
	while (rw->label) {
		sysfs_attr_init(&sensors->dev_attr.attr);
		sensors->dev_attr.attr.name = rw->label;
		sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
		sensors->dev_attr.show = rw->show;
		sensors->dev_attr.store = rw->set;
		sensors->index = rw->index;

		err = device_create_file(dev, &sensors->dev_attr);
		if (err) {
			sensors->dev_attr.attr.name = NULL;
			goto error;
		}
		sensors++;
		rw++;
	}

	err = device_create_file(dev, &sensor_dev_attr_name.dev_attr);
	if (err)
		goto error;
	err = device_create_file(dev, &sensor_dev_attr_version.dev_attr);
	return err;

error:
	aem_remove_sensors(data);
	return err;
}

/* sysfs support functions for AEM2 sensors */

/* Display temperature use */
static ssize_t aem2_show_temp(struct device *dev,
			      struct device_attribute *devattr,
			      char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct aem_data *a = dev_get_drvdata(dev);
	a->update(a);

	return sprintf(buf, "%u\n", a->temp[attr->index] * 1000);
}

/* Display power-capping registers */
static ssize_t aem2_show_pcap_value(struct device *dev,
				    struct device_attribute *devattr,
				    char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct aem_data *a = dev_get_drvdata(dev);
	a->update(a);

	return sprintf(buf, "%u\n", a->pcap[attr->index] * 100000);
}

/* Remove sensors attached to an AEM device */
static void aem_remove_sensors(struct aem_data *data)
{
	int i;

	for (i = 0; i < AEM_NUM_SENSORS; i++) {
		if (!data->sensors[i].dev_attr.attr.name)
			continue;
		device_remove_file(&data->pdev->dev,
				   &data->sensors[i].dev_attr);
	}

	device_remove_file(&data->pdev->dev,
			   &sensor_dev_attr_name.dev_attr);
	device_remove_file(&data->pdev->dev,
			   &sensor_dev_attr_version.dev_attr);
}

/* Sensor probe functions */

/* Description of AEM1 sensors */
static struct aem_ro_sensor_template aem1_ro_sensors[] = {
{"energy1_input",  aem_show_energy, 0},
{"power1_average", aem_show_power,  0},
{NULL,		   NULL,	    0},
};

static struct aem_rw_sensor_template aem1_rw_sensors[] = {
{"power1_average_interval", aem_show_power_period, aem_set_power_period, 0},
{NULL,			    NULL,                  NULL,                 0},
};

/* Description of AEM2 sensors */
static struct aem_ro_sensor_template aem2_ro_sensors[] = {
{"energy1_input",	  aem_show_energy,	0},
{"energy2_input",	  aem_show_energy,	1},
{"power1_average",	  aem_show_power,	0},
{"power2_average",	  aem_show_power,	1},
{"temp1_input",		  aem2_show_temp,	0},
{"temp2_input",		  aem2_show_temp,	1},

{"power4_average",	  aem2_show_pcap_value,	POWER_CAP_MAX_HOTPLUG},
{"power5_average",	  aem2_show_pcap_value,	POWER_CAP_MAX},
{"power6_average",	  aem2_show_pcap_value,	POWER_CAP_MIN_WARNING},
{"power7_average",	  aem2_show_pcap_value,	POWER_CAP_MIN},

{"power3_average",	  aem2_show_pcap_value,	POWER_AUX},
{"power_cap",		  aem2_show_pcap_value,	POWER_CAP},
{NULL,                    NULL,                 0},
};

static struct aem_rw_sensor_template aem2_rw_sensors[] = {
{"power1_average_interval", aem_show_power_period, aem_set_power_period, 0},
{"power2_average_interval", aem_show_power_period, aem_set_power_period, 1},
{NULL,			    NULL,                  NULL,                 0},
};

/* Set up AEM1 sensor attrs */
static int aem1_find_sensors(struct aem_data *data)
{
	return aem_register_sensors(data, aem1_ro_sensors, aem1_rw_sensors);
}

/* Set up AEM2 sensor attrs */
static int aem2_find_sensors(struct aem_data *data)
{
	return aem_register_sensors(data, aem2_ro_sensors, aem2_rw_sensors);
}

/* Module init/exit routines */

static int __init aem_init(void)
{
	int res;

	res = driver_register(&aem_driver.driver);
	if (res) {
		pr_err("Can't register aem driver\n");
		return res;
	}

	res = ipmi_smi_watcher_register(&driver_data.bmc_events);
	if (res)
		goto ipmi_reg_err;
	return 0;

ipmi_reg_err:
	driver_unregister(&aem_driver.driver);
	return res;

}

static void __exit aem_exit(void)
{
	struct aem_data *p1, *next1;

	ipmi_smi_watcher_unregister(&driver_data.bmc_events);
	driver_unregister(&aem_driver.driver);
	list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list)
		aem_delete(p1);
}

MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
MODULE_DESCRIPTION("IBM AEM power/temp/energy sensor driver");
MODULE_LICENSE("GPL");

module_init(aem_init);
module_exit(aem_exit);

MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3350-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMBladeHC10-*");
