/*
 * Copyright (c) 2014-2015, 2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 */

#define pr_fmt(fmt) "dev-cpufreq: " fmt

#include <linux/devfreq.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/module.h>
#include "governor.h"

struct cpu_state {
	unsigned int freq;
	unsigned int min_freq;
	unsigned int max_freq;
	bool on;
	unsigned int first_cpu;
};
static struct cpu_state *state[NR_CPUS];
static int cpufreq_cnt;

struct freq_map {
	unsigned int cpu_khz;
	unsigned int target_freq;
};

struct devfreq_node {
	struct devfreq *df;
	void *orig_data;
	struct device *dev;
	struct device_node *of_node;
	struct list_head list;
	struct freq_map **map;
	struct freq_map *common_map;
	unsigned int timeout;
	struct delayed_work dwork;
	bool drop;
	unsigned long prev_tgt;
};
static LIST_HEAD(devfreq_list);
static DEFINE_MUTEX(state_lock);
static DEFINE_MUTEX(cpufreq_reg_lock);

#define show_attr(name) \
static ssize_t show_##name(struct device *dev,				\
			struct device_attribute *attr, char *buf)	\
{									\
	struct devfreq *df = to_devfreq(dev);				\
	struct devfreq_node *n = df->data;				\
	return snprintf(buf, PAGE_SIZE, "%u\n", n->name);		\
}

#define store_attr(name, _min, _max) \
static ssize_t store_##name(struct device *dev,				\
			struct device_attribute *attr, const char *buf,	\
			size_t count)					\
{									\
	struct devfreq *df = to_devfreq(dev);				\
	struct devfreq_node *n = df->data;				\
	int ret;							\
	unsigned int val;						\
	ret = kstrtoint(buf, 10, &val);					\
	if (ret)							\
		return ret;						\
	val = max(val, _min);						\
	val = min(val, _max);						\
	n->name = val;							\
	return count;							\
}

#define gov_attr(__attr, min, max)	\
show_attr(__attr)			\
store_attr(__attr, (min), (max))	\
static DEVICE_ATTR(__attr, 0644, show_##__attr, store_##__attr)

static int update_node(struct devfreq_node *node)
{
	int ret;
	struct devfreq *df = node->df;

	if (!df)
		return 0;

	cancel_delayed_work_sync(&node->dwork);

	mutex_lock(&df->lock);
	node->drop = false;
	ret = update_devfreq(df);
	if (ret) {
		dev_err(df->dev.parent, "Unable to update frequency\n");
		goto out;
	}

	if (!node->timeout)
		goto out;

	if (df->previous_freq <= df->min_freq)
		goto out;

	schedule_delayed_work(&node->dwork,
			      msecs_to_jiffies(node->timeout));
out:
	mutex_unlock(&df->lock);
	return ret;
}

static void update_all_devfreqs(void)
{
	struct devfreq_node *node;

	list_for_each_entry(node, &devfreq_list, list) {
		update_node(node);
	}
}

static void do_timeout(struct work_struct *work)
{
	struct devfreq_node *node = container_of(to_delayed_work(work),
						struct devfreq_node, dwork);
	struct devfreq *df = node->df;

	mutex_lock(&df->lock);
	node->drop = true;
	update_devfreq(df);
	mutex_unlock(&df->lock);
}

static struct devfreq_node *find_devfreq_node(struct device *dev)
{
	struct devfreq_node *node;

	list_for_each_entry(node, &devfreq_list, list)
		if (node->dev == dev || node->of_node == dev->of_node)
			return node;

	return NULL;
}

/* ==================== cpufreq part ==================== */
static void add_policy(struct cpufreq_policy *policy)
{
	struct cpu_state *new_state;
	unsigned int cpu, first_cpu;

	if (state[policy->cpu]) {
		state[policy->cpu]->freq = policy->cur;
		state[policy->cpu]->on = true;
	} else {
		new_state = kzalloc(sizeof(struct cpu_state), GFP_KERNEL);
		if (!new_state)
			return;

		first_cpu = cpumask_first(policy->related_cpus);
		new_state->first_cpu = first_cpu;
		new_state->freq = policy->cur;
		new_state->min_freq = policy->cpuinfo.min_freq;
		new_state->max_freq = policy->cpuinfo.max_freq;
		new_state->on = true;

		for_each_cpu(cpu, policy->related_cpus)
			state[cpu] = new_state;
	}
}

static int cpufreq_policy_notifier(struct notifier_block *nb,
		unsigned long event, void *data)
{
	struct cpufreq_policy *policy = data;

	switch (event) {
	case CPUFREQ_START:
		mutex_lock(&state_lock);
		add_policy(policy);
		update_all_devfreqs();
		mutex_unlock(&state_lock);
		break;

	case CPUFREQ_STOP:
		mutex_lock(&state_lock);
		if (state[policy->cpu]) {
			state[policy->cpu]->on = false;
			update_all_devfreqs();
		}
		mutex_unlock(&state_lock);
		break;
	}

	return 0;
}

static struct notifier_block cpufreq_policy_nb = {
	.notifier_call = cpufreq_policy_notifier
};

static int cpufreq_trans_notifier(struct notifier_block *nb,
		unsigned long event, void *data)
{
	struct cpufreq_freqs *freq = data;
	struct cpu_state *s;

	if (event != CPUFREQ_POSTCHANGE)
		return 0;

	mutex_lock(&state_lock);

	s = state[freq->cpu];
	if (!s)
		goto out;

	if (s->freq != freq->new) {
		s->freq = freq->new;
		update_all_devfreqs();
	}

out:
	mutex_unlock(&state_lock);
	return 0;
}

static struct notifier_block cpufreq_trans_nb = {
	.notifier_call = cpufreq_trans_notifier
};

static int register_cpufreq(void)
{
	int ret = 0;
	unsigned int cpu;
	struct cpufreq_policy *policy;

	mutex_lock(&cpufreq_reg_lock);

	if (cpufreq_cnt)
		goto cnt_not_zero;

	get_online_cpus();
	ret = cpufreq_register_notifier(&cpufreq_policy_nb,
				CPUFREQ_POLICY_NOTIFIER);
	if (ret)
		goto out;

	ret = cpufreq_register_notifier(&cpufreq_trans_nb,
				CPUFREQ_TRANSITION_NOTIFIER);
	if (ret) {
		cpufreq_unregister_notifier(&cpufreq_policy_nb,
				CPUFREQ_POLICY_NOTIFIER);
		goto out;
	}

	for_each_online_cpu(cpu) {
		policy = cpufreq_cpu_get(cpu);
		if (policy) {
			add_policy(policy);
			cpufreq_cpu_put(policy);
		}
	}
out:
	put_online_cpus();
cnt_not_zero:
	if (!ret)
		cpufreq_cnt++;
	mutex_unlock(&cpufreq_reg_lock);
	return ret;
}

static int unregister_cpufreq(void)
{
	int ret = 0;
	int cpu;

	mutex_lock(&cpufreq_reg_lock);

	if (cpufreq_cnt > 1)
		goto out;

	cpufreq_unregister_notifier(&cpufreq_policy_nb,
				CPUFREQ_POLICY_NOTIFIER);
	cpufreq_unregister_notifier(&cpufreq_trans_nb,
				CPUFREQ_TRANSITION_NOTIFIER);

	for (cpu = ARRAY_SIZE(state) - 1; cpu >= 0; cpu--) {
		if (!state[cpu])
			continue;
		if (state[cpu]->first_cpu == cpu)
			kfree(state[cpu]);
		state[cpu] = NULL;
	}

out:
	cpufreq_cnt--;
	mutex_unlock(&cpufreq_reg_lock);
	return ret;
}

/* ==================== devfreq part ==================== */

static unsigned int interpolate_freq(struct devfreq *df, unsigned int cpu)
{
	unsigned long *freq_table = df->profile->freq_table;
	unsigned int cpu_min = state[cpu]->min_freq;
	unsigned int cpu_max = state[cpu]->max_freq;
	unsigned int cpu_freq = state[cpu]->freq;
	unsigned int dev_min, dev_max, cpu_percent;

	if (freq_table) {
		dev_min = freq_table[0];
		dev_max = freq_table[df->profile->max_state - 1];
	} else {
		if (df->max_freq <= df->min_freq)
			return 0;
		dev_min = df->min_freq;
		dev_max = df->max_freq;
	}

	cpu_percent = ((cpu_freq - cpu_min) * 100) / (cpu_max - cpu_min);
	return dev_min + mult_frac(dev_max - dev_min, cpu_percent, 100);
}

static unsigned int cpu_to_dev_freq(struct devfreq *df, unsigned int cpu)
{
	struct freq_map *map = NULL;
	unsigned int cpu_khz = 0, freq;
	struct devfreq_node *n = df->data;

	if (!state[cpu] || !state[cpu]->on || state[cpu]->first_cpu != cpu) {
		freq = 0;
		goto out;
	}

	if (n->common_map)
		map = n->common_map;
	else if (n->map)
		map = n->map[cpu];

	cpu_khz = state[cpu]->freq;

	if (!map) {
		freq = interpolate_freq(df, cpu);
		goto out;
	}

	while (map->cpu_khz && map->cpu_khz < cpu_khz)
		map++;
	if (!map->cpu_khz)
		map--;
	freq = map->target_freq;

out:
	dev_dbg(df->dev.parent, "CPU%u: %d -> dev: %u\n", cpu, cpu_khz, freq);
	return freq;
}

static int devfreq_cpufreq_get_freq(struct devfreq *df,
					unsigned long *freq)
{
	unsigned int cpu, tgt_freq = 0;
	struct devfreq_node *node;

	node = df->data;
	if (!node) {
		pr_err("Unable to find devfreq node!\n");
		return -ENODEV;
	}

	if (node->drop) {
		*freq = 0;
		return 0;
	}

	for_each_possible_cpu(cpu)
		tgt_freq = max(tgt_freq, cpu_to_dev_freq(df, cpu));

	if (node->timeout && tgt_freq < node->prev_tgt)
		*freq = 0;
	else
		*freq = tgt_freq;

	node->prev_tgt = tgt_freq;

	return 0;
}

static unsigned int show_table(char *buf, unsigned int len,
				struct freq_map *map)
{
	unsigned int cnt = 0;

	cnt += snprintf(buf + cnt, len - cnt, "CPU freq\tDevice freq\n");

	while (map->cpu_khz && cnt < len) {
		cnt += snprintf(buf + cnt, len - cnt, "%8u\t%11u\n",
				map->cpu_khz, map->target_freq);
		map++;
	}
	if (cnt < len)
		cnt += snprintf(buf + cnt, len - cnt, "\n");

	return cnt;
}

static ssize_t show_map(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	struct devfreq_node *n = df->data;
	struct freq_map *map;
	unsigned int cnt = 0, cpu;

	mutex_lock(&state_lock);
	if (n->common_map) {
		map = n->common_map;
		cnt += snprintf(buf + cnt, PAGE_SIZE - cnt,
				"Common table for all CPUs:\n");
		cnt += show_table(buf + cnt, PAGE_SIZE - cnt, map);
	} else if (n->map) {
		for_each_possible_cpu(cpu) {
			map = n->map[cpu];
			if (!map)
				continue;
			cnt += snprintf(buf + cnt, PAGE_SIZE - cnt,
					"CPU %u:\n", cpu);
			if (cnt >= PAGE_SIZE)
				break;
			cnt += show_table(buf + cnt, PAGE_SIZE - cnt, map);
			if (cnt >= PAGE_SIZE)
				break;
		}
	} else {
		cnt += snprintf(buf + cnt, PAGE_SIZE - cnt,
				"Device freq interpolated based on CPU freq\n");
	}
	mutex_unlock(&state_lock);

	return cnt;
}

static DEVICE_ATTR(freq_map, 0444, show_map, NULL);
gov_attr(timeout, 0U, 100U);

static struct attribute *dev_attr[] = {
	&dev_attr_freq_map.attr,
	&dev_attr_timeout.attr,
	NULL,
};

static struct attribute_group dev_attr_group = {
	.name = "cpufreq",
	.attrs = dev_attr,
};

static int devfreq_cpufreq_gov_start(struct devfreq *devfreq)
{
	int ret = 0;
	struct devfreq_node *node;
	bool alloc = false;

	ret = register_cpufreq();
	if (ret)
		return ret;

	ret = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group);
	if (ret) {
		unregister_cpufreq();
		return ret;
	}

	mutex_lock(&state_lock);

	node = find_devfreq_node(devfreq->dev.parent);
	if (node == NULL) {
		node = kzalloc(sizeof(struct devfreq_node), GFP_KERNEL);
		if (!node) {
			pr_err("Out of memory!\n");
			ret = -ENOMEM;
			goto alloc_fail;
		}
		alloc = true;
		node->dev = devfreq->dev.parent;
		list_add_tail(&node->list, &devfreq_list);
	}

	INIT_DELAYED_WORK(&node->dwork, do_timeout);

	node->df = devfreq;
	node->orig_data = devfreq->data;
	devfreq->data = node;

	ret = update_node(node);
	if (ret)
		goto update_fail;

	mutex_unlock(&state_lock);
	return 0;

update_fail:
	devfreq->data = node->orig_data;
	if (alloc) {
		list_del(&node->list);
		kfree(node);
	}
alloc_fail:
	mutex_unlock(&state_lock);
	sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
	unregister_cpufreq();
	return ret;
}

static void devfreq_cpufreq_gov_stop(struct devfreq *devfreq)
{
	struct devfreq_node *node = devfreq->data;

	cancel_delayed_work_sync(&node->dwork);

	mutex_lock(&state_lock);
	devfreq->data = node->orig_data;
	if (node->map || node->common_map) {
		node->df = NULL;
	} else {
		list_del(&node->list);
		kfree(node);
	}
	mutex_unlock(&state_lock);

	sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
	unregister_cpufreq();
}

static int devfreq_cpufreq_ev_handler(struct devfreq *devfreq,
					unsigned int event, void *data)
{
	int ret;

	switch (event) {
	case DEVFREQ_GOV_START:

		ret = devfreq_cpufreq_gov_start(devfreq);
		if (ret) {
			pr_err("Governor start failed!\n");
			return ret;
		}
		pr_debug("Enabled dev CPUfreq governor\n");
		break;

	case DEVFREQ_GOV_STOP:

		devfreq_cpufreq_gov_stop(devfreq);
		pr_debug("Disabled dev CPUfreq governor\n");
		break;
	}

	return 0;
}

static struct devfreq_governor devfreq_cpufreq = {
	.name = "cpufreq",
	.get_target_freq = devfreq_cpufreq_get_freq,
	.event_handler = devfreq_cpufreq_ev_handler,
};

#define NUM_COLS	2
static struct freq_map *read_tbl(struct device_node *of_node, char *prop_name)
{
	int len, nf, i, j;
	u32 data;
	struct freq_map *tbl;

	if (!of_find_property(of_node, prop_name, &len))
		return NULL;
	len /= sizeof(data);

	if (len % NUM_COLS || len == 0)
		return NULL;
	nf = len / NUM_COLS;

	tbl = kzalloc((nf + 1) * sizeof(*tbl), GFP_KERNEL);
	if (!tbl)
		return NULL;

	for (i = 0, j = 0; i < nf; i++, j += 2) {
		of_property_read_u32_index(of_node, prop_name, j, &data);
		tbl[i].cpu_khz = data;

		of_property_read_u32_index(of_node, prop_name, j + 1, &data);
		tbl[i].target_freq = data;
	}
	tbl[i].cpu_khz = 0;

	return tbl;
}

#define PROP_TARGET "target-dev"
#define PROP_TABLE "cpu-to-dev-map"
static int add_table_from_of(struct device_node *of_node)
{
	struct device_node *target_of_node;
	struct devfreq_node *node;
	struct freq_map *common_tbl;
	struct freq_map **tbl_list = NULL;
	static char prop_name[] = PROP_TABLE "-999999";
	int cpu, ret, cnt = 0, prop_sz = ARRAY_SIZE(prop_name);

	target_of_node = of_parse_phandle(of_node, PROP_TARGET, 0);
	if (!target_of_node)
		return -EINVAL;

	node = kzalloc(sizeof(struct devfreq_node), GFP_KERNEL);
	if (!node)
		return -ENOMEM;

	common_tbl = read_tbl(of_node, PROP_TABLE);
	if (!common_tbl) {
		tbl_list = kzalloc(sizeof(*tbl_list) * NR_CPUS, GFP_KERNEL);
		if (!tbl_list) {
			ret = -ENOMEM;
			goto err_list;
		}

		for_each_possible_cpu(cpu) {
			ret = snprintf(prop_name, prop_sz, "%s-%d",
					PROP_TABLE, cpu);
			if (ret >= prop_sz) {
				pr_warn("More CPUs than I can handle!\n");
				pr_warn("Skipping rest of the tables!\n");
				break;
			}
			tbl_list[cpu] = read_tbl(of_node, prop_name);
			if (tbl_list[cpu])
				cnt++;
		}
	}
	if (!common_tbl && !cnt) {
		ret = -EINVAL;
		goto err_tbl;
	}

	mutex_lock(&state_lock);
	node->of_node = target_of_node;
	node->map = tbl_list;
	node->common_map = common_tbl;
	list_add_tail(&node->list, &devfreq_list);
	mutex_unlock(&state_lock);

	return 0;
err_tbl:
	kfree(tbl_list);
err_list:
	kfree(node);
	return ret;
}

static int __init devfreq_cpufreq_init(void)
{
	int ret;
	struct device_node *of_par, *of_child;

	of_par = of_find_node_by_name(NULL, "devfreq-cpufreq");
	if (of_par) {
		for_each_child_of_node(of_par, of_child) {
			ret = add_table_from_of(of_child);
			if (ret)
				pr_err("Parsing %s failed!\n", of_child->name);
			else
				pr_debug("Parsed %s.\n", of_child->name);
		}
		of_node_put(of_par);
	} else {
		pr_info("No tables parsed from DT.\n");
	}

	ret = devfreq_add_governor(&devfreq_cpufreq);
	if (ret) {
		pr_err("Governor add failed!\n");
		return ret;
	}

	return 0;
}
subsys_initcall(devfreq_cpufreq_init);

static void __exit devfreq_cpufreq_exit(void)
{
	int ret, cpu;
	struct devfreq_node *node, *tmp;

	ret = devfreq_remove_governor(&devfreq_cpufreq);
	if (ret)
		pr_err("Governor remove failed!\n");

	mutex_lock(&state_lock);
	list_for_each_entry_safe(node, tmp, &devfreq_list, list) {
		kfree(node->common_map);
		for_each_possible_cpu(cpu)
			kfree(node->map[cpu]);
		kfree(node->map);
		list_del(&node->list);
		kfree(node);
	}
	mutex_unlock(&state_lock);
}
module_exit(devfreq_cpufreq_exit);

MODULE_DESCRIPTION("CPU freq based generic governor for devfreq devices");
MODULE_LICENSE("GPL v2");
