root/drivers/cpufreq/cpufreq_userspace.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cpufreq_set
  2. show_speed
  3. cpufreq_userspace_policy_init
  4. cpufreq_userspace_policy_exit
  5. cpufreq_userspace_policy_start
  6. cpufreq_userspace_policy_stop
  7. cpufreq_userspace_policy_limits
  8. cpufreq_gov_userspace_init
  9. cpufreq_gov_userspace_exit
  10. cpufreq_default_governor

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 
   3 /*
   4  *  linux/drivers/cpufreq/cpufreq_userspace.c
   5  *
   6  *  Copyright (C)  2001 Russell King
   7  *            (C)  2002 - 2004 Dominik Brodowski <linux@brodo.de>
   8  */
   9 
  10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11 
  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>
  17 
  18 static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
  19 static DEFINE_MUTEX(userspace_mutex);
  20 
  21 /**
  22  * cpufreq_set - set the CPU frequency
  23  * @policy: pointer to policy struct where freq is being set
  24  * @freq: target frequency in kHz
  25  *
  26  * Sets the CPU frequency to freq.
  27  */
  28 static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
  29 {
  30         int ret = -EINVAL;
  31         unsigned int *setspeed = policy->governor_data;
  32 
  33         pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
  34 
  35         mutex_lock(&userspace_mutex);
  36         if (!per_cpu(cpu_is_managed, policy->cpu))
  37                 goto err;
  38 
  39         *setspeed = freq;
  40 
  41         ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
  42  err:
  43         mutex_unlock(&userspace_mutex);
  44         return ret;
  45 }
  46 
  47 static ssize_t show_speed(struct cpufreq_policy *policy, char *buf)
  48 {
  49         return sprintf(buf, "%u\n", policy->cur);
  50 }
  51 
  52 static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy)
  53 {
  54         unsigned int *setspeed;
  55 
  56         setspeed = kzalloc(sizeof(*setspeed), GFP_KERNEL);
  57         if (!setspeed)
  58                 return -ENOMEM;
  59 
  60         policy->governor_data = setspeed;
  61         return 0;
  62 }
  63 
  64 static void cpufreq_userspace_policy_exit(struct cpufreq_policy *policy)
  65 {
  66         mutex_lock(&userspace_mutex);
  67         kfree(policy->governor_data);
  68         policy->governor_data = NULL;
  69         mutex_unlock(&userspace_mutex);
  70 }
  71 
  72 static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy)
  73 {
  74         unsigned int *setspeed = policy->governor_data;
  75 
  76         BUG_ON(!policy->cur);
  77         pr_debug("started managing cpu %u\n", policy->cpu);
  78 
  79         mutex_lock(&userspace_mutex);
  80         per_cpu(cpu_is_managed, policy->cpu) = 1;
  81         *setspeed = policy->cur;
  82         mutex_unlock(&userspace_mutex);
  83         return 0;
  84 }
  85 
  86 static void cpufreq_userspace_policy_stop(struct cpufreq_policy *policy)
  87 {
  88         unsigned int *setspeed = policy->governor_data;
  89 
  90         pr_debug("managing cpu %u stopped\n", policy->cpu);
  91 
  92         mutex_lock(&userspace_mutex);
  93         per_cpu(cpu_is_managed, policy->cpu) = 0;
  94         *setspeed = 0;
  95         mutex_unlock(&userspace_mutex);
  96 }
  97 
  98 static void cpufreq_userspace_policy_limits(struct cpufreq_policy *policy)
  99 {
 100         unsigned int *setspeed = policy->governor_data;
 101 
 102         mutex_lock(&userspace_mutex);
 103 
 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);
 106 
 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);
 111         else
 112                 __cpufreq_driver_target(policy, *setspeed, CPUFREQ_RELATION_L);
 113 
 114         mutex_unlock(&userspace_mutex);
 115 }
 116 
 117 static struct cpufreq_governor cpufreq_gov_userspace = {
 118         .name           = "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,
 127 };
 128 
 129 static int __init cpufreq_gov_userspace_init(void)
 130 {
 131         return cpufreq_register_governor(&cpufreq_gov_userspace);
 132 }
 133 
 134 static void __exit cpufreq_gov_userspace_exit(void)
 135 {
 136         cpufreq_unregister_governor(&cpufreq_gov_userspace);
 137 }
 138 
 139 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
 140                 "Russell King <rmk@arm.linux.org.uk>");
 141 MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
 142 MODULE_LICENSE("GPL");
 143 
 144 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
 145 struct cpufreq_governor *cpufreq_default_governor(void)
 146 {
 147         return &cpufreq_gov_userspace;
 148 }
 149 
 150 fs_initcall(cpufreq_gov_userspace_init);
 151 #else
 152 module_init(cpufreq_gov_userspace_init);
 153 #endif
 154 module_exit(cpufreq_gov_userspace_exit);

/* [<][>][^][v][top][bottom][index][help] */