// SPDX-License-Identifier: GPL-2.0-only
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>

#include <asm/prom.h>

#include "windfarm.h"

#define VERSION "0.3"

static int clamped;
static struct wf_control *clamp_control;
static struct dev_pm_qos_request qos_req;
static unsigned int min_freq, max_freq;

static int clamp_set(struct wf_control *ct, s32 value)
{
	unsigned int freq;

	if (value) {
		freq = min_freq;
		printk(KERN_INFO "windfarm: Clamping CPU frequency to "
		       "minimum !\n");
	} else {
		freq = max_freq;
		printk(KERN_INFO "windfarm: CPU frequency unclamped !\n");
	}
	clamped = value;

	return dev_pm_qos_update_request(&qos_req, freq);
}

static int clamp_get(struct wf_control *ct, s32 *value)
{
	*value = clamped;
	return 0;
}

static s32 clamp_min(struct wf_control *ct)
{
	return 0;
}

static s32 clamp_max(struct wf_control *ct)
{
	return 1;
}

static const struct wf_control_ops clamp_ops = {
	.set_value	= clamp_set,
	.get_value	= clamp_get,
	.get_min	= clamp_min,
	.get_max	= clamp_max,
	.owner		= THIS_MODULE,
};

static int __init wf_cpufreq_clamp_init(void)
{
	struct cpufreq_policy *policy;
	struct wf_control *clamp;
	struct device *dev;
	int ret;

	policy = cpufreq_cpu_get(0);
	if (!policy) {
		pr_warn("%s: cpufreq policy not found cpu0\n", __func__);
		return -EPROBE_DEFER;
	}

	min_freq = policy->cpuinfo.min_freq;
	max_freq = policy->cpuinfo.max_freq;
	cpufreq_cpu_put(policy);

	dev = get_cpu_device(0);
	if (unlikely(!dev)) {
		pr_warn("%s: No cpu device for cpu0\n", __func__);
		return -ENODEV;
	}

	clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
	if (clamp == NULL)
		return -ENOMEM;

	ret = dev_pm_qos_add_request(dev, &qos_req, DEV_PM_QOS_MAX_FREQUENCY,
				     max_freq);
	if (ret < 0) {
		pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
		       ret);
		goto free;
	}

	clamp->ops = &clamp_ops;
	clamp->name = "cpufreq-clamp";
	ret = wf_register_control(clamp);
	if (ret)
		goto fail;
	clamp_control = clamp;
	return 0;
 fail:
	dev_pm_qos_remove_request(&qos_req);

 free:
	kfree(clamp);
	return ret;
}

static void __exit wf_cpufreq_clamp_exit(void)
{
	if (clamp_control) {
		wf_unregister_control(clamp_control);
		dev_pm_qos_remove_request(&qos_req);
	}
}


module_init(wf_cpufreq_clamp_init);
module_exit(wf_cpufreq_clamp_exit);

MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("CPU frequency clamp for PowerMacs thermal control");
MODULE_LICENSE("GPL");

