1 // SPDX-License-Identifier: GPL-2.0-only
4 * linux/drivers/cpufreq/cpufreq_userspace.c
6 * Copyright (C) 2001 Russell King
7 * (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/cpufreq.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/slab.h>
18 static DEFINE_PER_CPU(unsigned int, cpu_is_managed
);
19 static DEFINE_MUTEX(userspace_mutex
);
22 * cpufreq_set - set the CPU frequency
23 * @policy: pointer to policy struct where freq is being set
24 * @freq: target frequency in kHz
26 * Sets the CPU frequency to freq.
28 static int cpufreq_set(struct cpufreq_policy
*policy
, unsigned int freq
)
31 unsigned int *setspeed
= policy
->governor_data
;
33 pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy
->cpu
, freq
);
35 mutex_lock(&userspace_mutex
);
36 if (!per_cpu(cpu_is_managed
, policy
->cpu
))
41 ret
= __cpufreq_driver_target(policy
, freq
, CPUFREQ_RELATION_L
);
43 mutex_unlock(&userspace_mutex
);
47 static ssize_t
show_speed(struct cpufreq_policy
*policy
, char *buf
)
49 return sprintf(buf
, "%u\n", policy
->cur
);
52 static int cpufreq_userspace_policy_init(struct cpufreq_policy
*policy
)
54 unsigned int *setspeed
;
56 setspeed
= kzalloc(sizeof(*setspeed
), GFP_KERNEL
);
60 policy
->governor_data
= setspeed
;
64 static void cpufreq_userspace_policy_exit(struct cpufreq_policy
*policy
)
66 mutex_lock(&userspace_mutex
);
67 kfree(policy
->governor_data
);
68 policy
->governor_data
= NULL
;
69 mutex_unlock(&userspace_mutex
);
72 static int cpufreq_userspace_policy_start(struct cpufreq_policy
*policy
)
74 unsigned int *setspeed
= policy
->governor_data
;
77 pr_debug("started managing cpu %u\n", policy
->cpu
);
79 mutex_lock(&userspace_mutex
);
80 per_cpu(cpu_is_managed
, policy
->cpu
) = 1;
81 *setspeed
= policy
->cur
;
82 mutex_unlock(&userspace_mutex
);
86 static void cpufreq_userspace_policy_stop(struct cpufreq_policy
*policy
)
88 unsigned int *setspeed
= policy
->governor_data
;
90 pr_debug("managing cpu %u stopped\n", policy
->cpu
);
92 mutex_lock(&userspace_mutex
);
93 per_cpu(cpu_is_managed
, policy
->cpu
) = 0;
95 mutex_unlock(&userspace_mutex
);
98 static void cpufreq_userspace_policy_limits(struct cpufreq_policy
*policy
)
100 unsigned int *setspeed
= policy
->governor_data
;
102 mutex_lock(&userspace_mutex
);
104 pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
105 policy
->cpu
, policy
->min
, policy
->max
, policy
->cur
, *setspeed
);
107 if (policy
->max
< *setspeed
)
108 __cpufreq_driver_target(policy
, policy
->max
, CPUFREQ_RELATION_H
);
109 else if (policy
->min
> *setspeed
)
110 __cpufreq_driver_target(policy
, policy
->min
, CPUFREQ_RELATION_L
);
112 __cpufreq_driver_target(policy
, *setspeed
, CPUFREQ_RELATION_L
);
114 mutex_unlock(&userspace_mutex
);
117 static struct cpufreq_governor cpufreq_gov_userspace
= {
119 .init
= cpufreq_userspace_policy_init
,
120 .exit
= cpufreq_userspace_policy_exit
,
121 .start
= cpufreq_userspace_policy_start
,
122 .stop
= cpufreq_userspace_policy_stop
,
123 .limits
= cpufreq_userspace_policy_limits
,
124 .store_setspeed
= cpufreq_set
,
125 .show_setspeed
= show_speed
,
126 .owner
= THIS_MODULE
,
129 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
130 "Russell King <rmk@arm.linux.org.uk>");
131 MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
132 MODULE_LICENSE("GPL");
134 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
135 struct cpufreq_governor
*cpufreq_default_governor(void)
137 return &cpufreq_gov_userspace
;
141 cpufreq_governor_init(cpufreq_gov_userspace
);
142 cpufreq_governor_exit(cpufreq_gov_userspace
);