brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 28d18ef Raw
135 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2#include <linux/types.h>3#include <linux/errno.h>4#include <linux/kernel.h>5#include <linux/delay.h>6#include <linux/pm_qos.h>7#include <linux/slab.h>8#include <linux/init.h>9#include <linux/wait.h>10#include <linux/cpu.h>11#include <linux/cpufreq.h>12 13#include "windfarm.h"14 15#define VERSION "0.3"16 17static int clamped;18static struct wf_control *clamp_control;19static struct freq_qos_request qos_req;20static unsigned int min_freq, max_freq;21 22static int clamp_set(struct wf_control *ct, s32 value)23{24	unsigned int freq;25 26	if (value) {27		freq = min_freq;28		printk(KERN_INFO "windfarm: Clamping CPU frequency to "29		       "minimum !\n");30	} else {31		freq = max_freq;32		printk(KERN_INFO "windfarm: CPU frequency unclamped !\n");33	}34	clamped = value;35 36	return freq_qos_update_request(&qos_req, freq);37}38 39static int clamp_get(struct wf_control *ct, s32 *value)40{41	*value = clamped;42	return 0;43}44 45static s32 clamp_min(struct wf_control *ct)46{47	return 0;48}49 50static s32 clamp_max(struct wf_control *ct)51{52	return 1;53}54 55static const struct wf_control_ops clamp_ops = {56	.set_value	= clamp_set,57	.get_value	= clamp_get,58	.get_min	= clamp_min,59	.get_max	= clamp_max,60	.owner		= THIS_MODULE,61};62 63static int __init wf_cpufreq_clamp_init(void)64{65	struct cpufreq_policy *policy;66	struct wf_control *clamp;67	struct device *dev;68	int ret;69 70	policy = cpufreq_cpu_get(0);71	if (!policy) {72		pr_warn("%s: cpufreq policy not found cpu0\n", __func__);73		return -EPROBE_DEFER;74	}75 76	min_freq = policy->cpuinfo.min_freq;77	max_freq = policy->cpuinfo.max_freq;78 79	ret = freq_qos_add_request(&policy->constraints, &qos_req, FREQ_QOS_MAX,80				   max_freq);81 82	cpufreq_cpu_put(policy);83 84	if (ret < 0) {85		pr_err("%s: Failed to add freq constraint (%d)\n", __func__,86		       ret);87		return ret;88	}89 90	dev = get_cpu_device(0);91	if (unlikely(!dev)) {92		pr_warn("%s: No cpu device for cpu0\n", __func__);93		ret = -ENODEV;94		goto fail;95	}96 97	clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);98	if (clamp == NULL) {99		ret = -ENOMEM;100		goto fail;101	}102 103	clamp->ops = &clamp_ops;104	clamp->name = "cpufreq-clamp";105	ret = wf_register_control(clamp);106	if (ret)107		goto free;108 109	clamp_control = clamp;110	return 0;111 112 free:113	kfree(clamp);114 fail:115	freq_qos_remove_request(&qos_req);116	return ret;117}118 119static void __exit wf_cpufreq_clamp_exit(void)120{121	if (clamp_control) {122		wf_unregister_control(clamp_control);123		freq_qos_remove_request(&qos_req);124	}125}126 127 128module_init(wf_cpufreq_clamp_init);129module_exit(wf_cpufreq_clamp_exit);130 131MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");132MODULE_DESCRIPTION("CPU frequency clamp for PowerMacs thermal control");133MODULE_LICENSE("GPL");134 135