/*
 * Windfarm PowerMac thermal control. Core
 *
 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
 *                    <benh@kernel.crashing.org>
 *
 * Released under the term of the GNU GPL v2.
 *
 * This core code tracks the list of sensors & controls, register
 * clients, and holds the kernel thread used for control.
 *
 * TODO:
 *
 * Add some information about sensor/control type and data format to
 * sensors/controls, and have the sysfs attribute stuff be moved
 * generically here instead of hard coded in the platform specific
 * driver as it us currently
 *
 * This however requires solving some annoying lifetime issues with
 * sysfs which doesn't seem to have lifetime rules for struct attribute,
 * I may have to create full features kobjects for every sensor/control
 * instead which is a bit of an overkill imho
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/jiffies.h>
#include <linux/reboot.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/freezer.h>

#include <asm/prom.h>

#include "windfarm.h"

#define VERSION "0.2"

#undef DEBUG

#ifdef DEBUG
#define DBG(args...)	printk(args)
#else
#define DBG(args...)	do { } while(0)
#endif

static LIST_HEAD(wf_controls);
static LIST_HEAD(wf_sensors);
static DEFINE_MUTEX(wf_lock);
static BLOCKING_NOTIFIER_HEAD(wf_client_list);
static int wf_client_count;
static unsigned int wf_overtemp;
static unsigned int wf_overtemp_counter;
struct task_struct *wf_thread;

static struct platform_device wf_platform_device = {
	.name	= "windfarm",
};

/*
 * Utilities & tick thread
 */

static inline void wf_notify(int event, void *param)
{
	blocking_notifier_call_chain(&wf_client_list, event, param);
}

int wf_critical_overtemp(void)
{
	static char * critical_overtemp_path = "/sbin/critical_overtemp";
	char *argv[] = { critical_overtemp_path, NULL };
	static char *envp[] = { "HOME=/",
				"TERM=linux",
				"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
				NULL };

	return call_usermodehelper(critical_overtemp_path,
				   argv, envp, UMH_WAIT_EXEC);
}
EXPORT_SYMBOL_GPL(wf_critical_overtemp);

static int wf_thread_func(void *data)
{
	unsigned long next, delay;

	next = jiffies;

	DBG("wf: thread started\n");

	set_freezable();
	while (!kthread_should_stop()) {
		try_to_freeze();

		if (time_after_eq(jiffies, next)) {
			wf_notify(WF_EVENT_TICK, NULL);
			if (wf_overtemp) {
				wf_overtemp_counter++;
				/* 10 seconds overtemp, notify userland */
				if (wf_overtemp_counter > 10)
					wf_critical_overtemp();
				/* 30 seconds, shutdown */
				if (wf_overtemp_counter > 30) {
					printk(KERN_ERR "windfarm: Overtemp "
					       "for more than 30"
					       " seconds, shutting down\n");
					machine_power_off();
				}
			}
			next += HZ;
		}

		delay = next - jiffies;
		if (delay <= HZ)
			schedule_timeout_interruptible(delay);
	}

	DBG("wf: thread stopped\n");

	return 0;
}

static void wf_start_thread(void)
{
	wf_thread = kthread_run(wf_thread_func, NULL, "kwindfarm");
	if (IS_ERR(wf_thread)) {
		printk(KERN_ERR "windfarm: failed to create thread,err %ld\n",
		       PTR_ERR(wf_thread));
		wf_thread = NULL;
	}
}


static void wf_stop_thread(void)
{
	if (wf_thread)
		kthread_stop(wf_thread);
	wf_thread = NULL;
}

/*
 * Controls
 */

static void wf_control_release(struct kref *kref)
{
	struct wf_control *ct = container_of(kref, struct wf_control, ref);

	DBG("wf: Deleting control %s\n", ct->name);

	if (ct->ops && ct->ops->release)
		ct->ops->release(ct);
	else
		kfree(ct);
}

static ssize_t wf_show_control(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
	const char *typestr;
	s32 val = 0;
	int err;

	err = ctrl->ops->get_value(ctrl, &val);
	if (err < 0) {
		if (err == -EFAULT)
			return sprintf(buf, "<HW FAULT>\n");
		return err;
	}
	switch(ctrl->type) {
	case WF_CONTROL_RPM_FAN:
		typestr = " RPM";
		break;
	case WF_CONTROL_PWM_FAN:
		typestr = " %";
		break;
	default:
		typestr = "";
	}
	return sprintf(buf, "%d%s\n", val, typestr);
}

/* This is really only for debugging... */
static ssize_t wf_store_control(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
	int val;
	int err;
	char *endp;

	val = simple_strtoul(buf, &endp, 0);
	while (endp < buf + count && (*endp == ' ' || *endp == '\n'))
		++endp;
	if (endp - buf < count)
		return -EINVAL;
	err = ctrl->ops->set_value(ctrl, val);
	if (err < 0)
		return err;
	return count;
}

int wf_register_control(struct wf_control *new_ct)
{
	struct wf_control *ct;

	mutex_lock(&wf_lock);
	list_for_each_entry(ct, &wf_controls, link) {
		if (!strcmp(ct->name, new_ct->name)) {
			printk(KERN_WARNING "windfarm: trying to register"
			       " duplicate control %s\n", ct->name);
			mutex_unlock(&wf_lock);
			return -EEXIST;
		}
	}
	kref_init(&new_ct->ref);
	list_add(&new_ct->link, &wf_controls);

	sysfs_attr_init(&new_ct->attr.attr);
	new_ct->attr.attr.name = new_ct->name;
	new_ct->attr.attr.mode = 0644;
	new_ct->attr.show = wf_show_control;
	new_ct->attr.store = wf_store_control;
	if (device_create_file(&wf_platform_device.dev, &new_ct->attr))
		printk(KERN_WARNING "windfarm: device_create_file failed"
			" for %s\n", new_ct->name);
		/* the subsystem still does useful work without the file */

	DBG("wf: Registered control %s\n", new_ct->name);

	wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
	mutex_unlock(&wf_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(wf_register_control);

void wf_unregister_control(struct wf_control *ct)
{
	mutex_lock(&wf_lock);
	list_del(&ct->link);
	mutex_unlock(&wf_lock);

	DBG("wf: Unregistered control %s\n", ct->name);

	kref_put(&ct->ref, wf_control_release);
}
EXPORT_SYMBOL_GPL(wf_unregister_control);

struct wf_control * wf_find_control(const char *name)
{
	struct wf_control *ct;

	mutex_lock(&wf_lock);
	list_for_each_entry(ct, &wf_controls, link) {
		if (!strcmp(ct->name, name)) {
			if (wf_get_control(ct))
				ct = NULL;
			mutex_unlock(&wf_lock);
			return ct;
		}
	}
	mutex_unlock(&wf_lock);
	return NULL;
}
EXPORT_SYMBOL_GPL(wf_find_control);

int wf_get_control(struct wf_control *ct)
{
	if (!try_module_get(ct->ops->owner))
		return -ENODEV;
	kref_get(&ct->ref);
	return 0;
}
EXPORT_SYMBOL_GPL(wf_get_control);

void wf_put_control(struct wf_control *ct)
{
	struct module *mod = ct->ops->owner;
	kref_put(&ct->ref, wf_control_release);
	module_put(mod);
}
EXPORT_SYMBOL_GPL(wf_put_control);


/*
 * Sensors
 */


static void wf_sensor_release(struct kref *kref)
{
	struct wf_sensor *sr = container_of(kref, struct wf_sensor, ref);

	DBG("wf: Deleting sensor %s\n", sr->name);

	if (sr->ops && sr->ops->release)
		sr->ops->release(sr);
	else
		kfree(sr);
}

static ssize_t wf_show_sensor(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr);
	s32 val = 0;
	int err;

	err = sens->ops->get_value(sens, &val);
	if (err < 0)
		return err;
	return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val));
}

int wf_register_sensor(struct wf_sensor *new_sr)
{
	struct wf_sensor *sr;

	mutex_lock(&wf_lock);
	list_for_each_entry(sr, &wf_sensors, link) {
		if (!strcmp(sr->name, new_sr->name)) {
			printk(KERN_WARNING "windfarm: trying to register"
			       " duplicate sensor %s\n", sr->name);
			mutex_unlock(&wf_lock);
			return -EEXIST;
		}
	}
	kref_init(&new_sr->ref);
	list_add(&new_sr->link, &wf_sensors);

	sysfs_attr_init(&new_sr->attr.attr);
	new_sr->attr.attr.name = new_sr->name;
	new_sr->attr.attr.mode = 0444;
	new_sr->attr.show = wf_show_sensor;
	new_sr->attr.store = NULL;
	if (device_create_file(&wf_platform_device.dev, &new_sr->attr))
		printk(KERN_WARNING "windfarm: device_create_file failed"
			" for %s\n", new_sr->name);
		/* the subsystem still does useful work without the file */

	DBG("wf: Registered sensor %s\n", new_sr->name);

	wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
	mutex_unlock(&wf_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(wf_register_sensor);

void wf_unregister_sensor(struct wf_sensor *sr)
{
	mutex_lock(&wf_lock);
	list_del(&sr->link);
	mutex_unlock(&wf_lock);

	DBG("wf: Unregistered sensor %s\n", sr->name);

	wf_put_sensor(sr);
}
EXPORT_SYMBOL_GPL(wf_unregister_sensor);

struct wf_sensor * wf_find_sensor(const char *name)
{
	struct wf_sensor *sr;

	mutex_lock(&wf_lock);
	list_for_each_entry(sr, &wf_sensors, link) {
		if (!strcmp(sr->name, name)) {
			if (wf_get_sensor(sr))
				sr = NULL;
			mutex_unlock(&wf_lock);
			return sr;
		}
	}
	mutex_unlock(&wf_lock);
	return NULL;
}
EXPORT_SYMBOL_GPL(wf_find_sensor);

int wf_get_sensor(struct wf_sensor *sr)
{
	if (!try_module_get(sr->ops->owner))
		return -ENODEV;
	kref_get(&sr->ref);
	return 0;
}
EXPORT_SYMBOL_GPL(wf_get_sensor);

void wf_put_sensor(struct wf_sensor *sr)
{
	struct module *mod = sr->ops->owner;
	kref_put(&sr->ref, wf_sensor_release);
	module_put(mod);
}
EXPORT_SYMBOL_GPL(wf_put_sensor);


/*
 * Client & notification
 */

int wf_register_client(struct notifier_block *nb)
{
	int rc;
	struct wf_control *ct;
	struct wf_sensor *sr;

	mutex_lock(&wf_lock);
	rc = blocking_notifier_chain_register(&wf_client_list, nb);
	if (rc != 0)
		goto bail;
	wf_client_count++;
	list_for_each_entry(ct, &wf_controls, link)
		wf_notify(WF_EVENT_NEW_CONTROL, ct);
	list_for_each_entry(sr, &wf_sensors, link)
		wf_notify(WF_EVENT_NEW_SENSOR, sr);
	if (wf_client_count == 1)
		wf_start_thread();
 bail:
	mutex_unlock(&wf_lock);
	return rc;
}
EXPORT_SYMBOL_GPL(wf_register_client);

int wf_unregister_client(struct notifier_block *nb)
{
	mutex_lock(&wf_lock);
	blocking_notifier_chain_unregister(&wf_client_list, nb);
	wf_client_count++;
	if (wf_client_count == 0)
		wf_stop_thread();
	mutex_unlock(&wf_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(wf_unregister_client);

void wf_set_overtemp(void)
{
	mutex_lock(&wf_lock);
	wf_overtemp++;
	if (wf_overtemp == 1) {
		printk(KERN_WARNING "windfarm: Overtemp condition detected !\n");
		wf_overtemp_counter = 0;
		wf_notify(WF_EVENT_OVERTEMP, NULL);
	}
	mutex_unlock(&wf_lock);
}
EXPORT_SYMBOL_GPL(wf_set_overtemp);

void wf_clear_overtemp(void)
{
	mutex_lock(&wf_lock);
	WARN_ON(wf_overtemp == 0);
	if (wf_overtemp == 0) {
		mutex_unlock(&wf_lock);
		return;
	}
	wf_overtemp--;
	if (wf_overtemp == 0) {
		printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n");
		wf_notify(WF_EVENT_NORMALTEMP, NULL);
	}
	mutex_unlock(&wf_lock);
}
EXPORT_SYMBOL_GPL(wf_clear_overtemp);

int wf_is_overtemp(void)
{
	return (wf_overtemp != 0);
}
EXPORT_SYMBOL_GPL(wf_is_overtemp);

static int __init windfarm_core_init(void)
{
	DBG("wf: core loaded\n");

	platform_device_register(&wf_platform_device);
	return 0;
}

static void __exit windfarm_core_exit(void)
{
	BUG_ON(wf_client_count != 0);

	DBG("wf: core unloaded\n");

	platform_device_unregister(&wf_platform_device);
}


module_init(windfarm_core_init);
module_exit(windfarm_core_exit);

MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Core component of PowerMac thermal control");
MODULE_LICENSE("GPL");

