/*
 * OMAP thermal driver interface
 *
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 * Contact:
 *   Eduardo Valentin <eduardo.valentin@ti.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <linux/thermal.h>
#include <linux/cpufreq.h>
#include <linux/cpu_cooling.h>

#include "omap-thermal.h"
#include "omap-bandgap.h"

/* common data structures */
struct omap_thermal_data {
	struct thermal_zone_device *omap_thermal;
	struct thermal_cooling_device *cool_dev;
	struct omap_bandgap *bg_ptr;
	enum thermal_device_mode mode;
	struct work_struct thermal_wq;
	int sensor_id;
};

static void omap_thermal_work(struct work_struct *work)
{
	struct omap_thermal_data *data = container_of(work,
					struct omap_thermal_data, thermal_wq);

	thermal_zone_device_update(data->omap_thermal);

	dev_dbg(&data->omap_thermal->device, "updated thermal zone %s\n",
		data->omap_thermal->type);
}

/**
 * omap_thermal_hotspot_temperature - returns sensor extrapolated temperature
 * @t:	omap sensor temperature
 * @s:	omap sensor slope value
 * @c:	omap sensor const value
 */
static inline int omap_thermal_hotspot_temperature(int t, int s, int c)
{
	int delta = t * s / 1000 + c;

	if (delta < 0)
		delta = 0;

	return t + delta;
}

/* thermal zone ops */
/* Get temperature callback function for thermal zone*/
static inline int omap_thermal_get_temp(struct thermal_zone_device *thermal,
					 unsigned long *temp)
{
	struct omap_thermal_data *data = thermal->devdata;
	struct omap_bandgap *bg_ptr = data->bg_ptr;
	struct omap_temp_sensor *s = &bg_ptr->conf->sensors[data->sensor_id];
	int ret, tmp, pcb_temp, slope, constant;

	ret = omap_bandgap_read_temperature(bg_ptr, data->sensor_id, &tmp);
	if (ret)
		return ret;

	pcb_temp = 0;
	/* TODO: Introduce pcb temperature lookup */
	/* In case pcb zone is available, use the extrapolation rule with it */
	if (pcb_temp) {
		tmp -= pcb_temp;
		slope = s->slope_pcb;
		constant = s->constant_pcb;
	} else {
		slope = s->slope;
		constant = s->constant;
	}
	*temp = omap_thermal_hotspot_temperature(tmp, slope, constant);

	return ret;
}

/* Bind callback functions for thermal zone */
static int omap_thermal_bind(struct thermal_zone_device *thermal,
			      struct thermal_cooling_device *cdev)
{
	struct omap_thermal_data *data = thermal->devdata;
	int max, id;

	if (IS_ERR_OR_NULL(data))
		return -ENODEV;

	/* check if this is the cooling device we registered */
	if (data->cool_dev != cdev)
		return 0;

	id = data->sensor_id;
	max = data->bg_ptr->conf->sensors[id].cooling_data.freq_clip_count;

	/* TODO: bind with min and max states */
	/* Simple thing, two trips, one passive another critical */
	return thermal_zone_bind_cooling_device(thermal, 0, cdev);
}

/* Unbind callback functions for thermal zone */
static int omap_thermal_unbind(struct thermal_zone_device *thermal,
				struct thermal_cooling_device *cdev)
{
	struct omap_thermal_data *data = thermal->devdata;

	if (IS_ERR_OR_NULL(data))
		return -ENODEV;

	/* check if this is the cooling device we registered */
	if (data->cool_dev != cdev)
		return 0;

	/* Simple thing, two trips, one passive another critical */
	return thermal_zone_unbind_cooling_device(thermal, 0, cdev);
}

/* Get mode callback functions for thermal zone */
static int omap_thermal_get_mode(struct thermal_zone_device *thermal,
				  enum thermal_device_mode *mode)
{
	struct omap_thermal_data *data = thermal->devdata;

	if (data)
		*mode = data->mode;

	return 0;
}

/* Set mode callback functions for thermal zone */
static int omap_thermal_set_mode(struct thermal_zone_device *thermal,
				  enum thermal_device_mode mode)
{
	struct omap_thermal_data *data = thermal->devdata;

	if (!data->omap_thermal) {
		dev_notice(&thermal->device, "thermal zone not registered\n");
		return 0;
	}

	mutex_lock(&data->omap_thermal->lock);

	if (mode == THERMAL_DEVICE_ENABLED)
		data->omap_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
	else
		data->omap_thermal->polling_delay = 0;

	mutex_unlock(&data->omap_thermal->lock);

	data->mode = mode;
	thermal_zone_device_update(data->omap_thermal);
	dev_dbg(&thermal->device, "thermal polling set for duration=%d msec\n",
		data->omap_thermal->polling_delay);

	return 0;
}

/* Get trip type callback functions for thermal zone */
static int omap_thermal_get_trip_type(struct thermal_zone_device *thermal,
				       int trip, enum thermal_trip_type *type)
{
	if (!omap_thermal_is_valid_trip(trip))
		return -EINVAL;

	if (trip + 1 == OMAP_TRIP_NUMBER)
		*type = THERMAL_TRIP_CRITICAL;
	else
		*type = THERMAL_TRIP_PASSIVE;

	return 0;
}

/* Get trip temperature callback functions for thermal zone */
static int omap_thermal_get_trip_temp(struct thermal_zone_device *thermal,
				       int trip, unsigned long *temp)
{
	if (!omap_thermal_is_valid_trip(trip))
		return -EINVAL;

	*temp = omap_thermal_get_trip_value(trip);

	return 0;
}

/* Get critical temperature callback functions for thermal zone */
static int omap_thermal_get_crit_temp(struct thermal_zone_device *thermal,
				       unsigned long *temp)
{
	/* shutdown zone */
	return omap_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp);
}

static struct thermal_zone_device_ops omap_thermal_ops = {
	.get_temp = omap_thermal_get_temp,
	/* TODO: add .get_trend */
	.bind = omap_thermal_bind,
	.unbind = omap_thermal_unbind,
	.get_mode = omap_thermal_get_mode,
	.set_mode = omap_thermal_set_mode,
	.get_trip_type = omap_thermal_get_trip_type,
	.get_trip_temp = omap_thermal_get_trip_temp,
	.get_crit_temp = omap_thermal_get_crit_temp,
};

int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id,
			       char *domain)
{
	struct omap_thermal_data *data;

	data = devm_kzalloc(bg_ptr->dev, sizeof(*data), GFP_KERNEL);
	if (!data) {
		dev_err(bg_ptr->dev, "kzalloc fail\n");
		return -ENOMEM;
	}
	data->sensor_id = id;
	data->bg_ptr = bg_ptr;
	data->mode = THERMAL_DEVICE_ENABLED;
	INIT_WORK(&data->thermal_wq, omap_thermal_work);

	/* TODO: remove TC1 TC2 */
	/* Create thermal zone */
	data->omap_thermal = thermal_zone_device_register(domain,
				OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
				0, FAST_TEMP_MONITORING_RATE, 0, 0);
	if (IS_ERR_OR_NULL(data->omap_thermal)) {
		dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
		return PTR_ERR(data->omap_thermal);
	}
	data->omap_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
	omap_bandgap_set_sensor_data(bg_ptr, id, data);

	return 0;
}

int omap_thermal_remove_sensor(struct omap_bandgap *bg_ptr, int id)
{
	struct omap_thermal_data *data;

	data = omap_bandgap_get_sensor_data(bg_ptr, id);

	thermal_zone_device_unregister(data->omap_thermal);

	return 0;
}

int omap_thermal_report_sensor_temperature(struct omap_bandgap *bg_ptr, int id)
{
	struct omap_thermal_data *data;

	data = omap_bandgap_get_sensor_data(bg_ptr, id);

	schedule_work(&data->thermal_wq);

	return 0;
}

static int omap_thermal_build_cpufreq_clip(struct omap_bandgap *bg_ptr,
					   struct freq_clip_table **tab_ptr,
					   int *tab_size)
{
	struct cpufreq_frequency_table *freq_table;
	struct freq_clip_table *tab;
	int i, count = 0;

	freq_table = cpufreq_frequency_get_table(0);
	if (IS_ERR_OR_NULL(freq_table)) {
		dev_err(bg_ptr->dev,
			"%s: failed to get cpufreq table (%p)\n",
			__func__, freq_table);
		return -EINVAL;
	}

	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
		unsigned int freq = freq_table[i].frequency;
		if (freq == CPUFREQ_ENTRY_INVALID)
			continue;
		count++;
	}

	tab = devm_kzalloc(bg_ptr->dev, sizeof(*tab) * count, GFP_KERNEL);
	if (!tab) {
		dev_err(bg_ptr->dev,
			"%s: no memory available\n", __func__);
		return -ENOMEM;
	}

	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
		unsigned int freq = freq_table[i].frequency;

		if (freq == CPUFREQ_ENTRY_INVALID)
			continue;

		tab[count - i - 1].freq_clip_max = freq;
		tab[count - i - 1].temp_level = OMAP_TRIP_HOT;
		tab[count - i - 1].mask_val = cpumask_of(0);
	}

	*tab_ptr = tab;
	*tab_size = count;

	return 0;
}

int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id)
{
	struct omap_thermal_data *data;
	struct freq_clip_table *tab_ptr;
	int tab_size, ret;

	data = omap_bandgap_get_sensor_data(bg_ptr, id);

	ret = omap_thermal_build_cpufreq_clip(bg_ptr, &tab_ptr, &tab_size);
	if (ret < 0) {
		dev_err(bg_ptr->dev,
			"%s: failed to build cpufreq clip table\n", __func__);
		return ret;
	}

	/* Register cooling device */
	data->cool_dev = cpufreq_cooling_register(tab_ptr, tab_size);
	if (IS_ERR_OR_NULL(data->cool_dev)) {
		dev_err(bg_ptr->dev,
			"Failed to register cpufreq cooling device\n");
		return PTR_ERR(data->cool_dev);
	}
	bg_ptr->conf->sensors[id].cooling_data.freq_clip_count = tab_size;

	return 0;
}

int omap_thermal_unregister_cpu_cooling(struct omap_bandgap *bg_ptr, int id)
{
	struct omap_thermal_data *data;

	data = omap_bandgap_get_sensor_data(bg_ptr, id);
	cpufreq_cooling_unregister(data->cool_dev);

	return 0;
}
