LCOV - code coverage report
Current view: top level - drivers/cpufreq - cpufreq_ondemand.c (source / functions) Hit Total Coverage
Test: Real Lines: 73 172 42.4 %
Date: 2020-10-17 15:46:16 Functions: 8 25 32.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  *  drivers/cpufreq/cpufreq_ondemand.c
       4                 :            :  *
       5                 :            :  *  Copyright (C)  2001 Russell King
       6                 :            :  *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
       7                 :            :  *                      Jun Nakajima <jun.nakajima@intel.com>
       8                 :            :  */
       9                 :            : 
      10                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      11                 :            : 
      12                 :            : #include <linux/cpu.h>
      13                 :            : #include <linux/percpu-defs.h>
      14                 :            : #include <linux/slab.h>
      15                 :            : #include <linux/tick.h>
      16                 :            : #include <linux/sched/cpufreq.h>
      17                 :            : 
      18                 :            : #include "cpufreq_ondemand.h"
      19                 :            : 
      20                 :            : /* On-demand governor macros */
      21                 :            : #define DEF_FREQUENCY_UP_THRESHOLD              (80)
      22                 :            : #define DEF_SAMPLING_DOWN_FACTOR                (1)
      23                 :            : #define MAX_SAMPLING_DOWN_FACTOR                (100000)
      24                 :            : #define MICRO_FREQUENCY_UP_THRESHOLD            (95)
      25                 :            : #define MICRO_FREQUENCY_MIN_SAMPLE_RATE         (10000)
      26                 :            : #define MIN_FREQUENCY_UP_THRESHOLD              (1)
      27                 :            : #define MAX_FREQUENCY_UP_THRESHOLD              (100)
      28                 :            : 
      29                 :            : static struct od_ops od_ops;
      30                 :            : 
      31                 :            : static unsigned int default_powersave_bias;
      32                 :            : 
      33                 :            : /*
      34                 :            :  * Not all CPUs want IO time to be accounted as busy; this depends on how
      35                 :            :  * efficient idling at a higher frequency/voltage is.
      36                 :            :  * Pavel Machek says this is not so for various generations of AMD and old
      37                 :            :  * Intel systems.
      38                 :            :  * Mike Chan (android.com) claims this is also not true for ARM.
      39                 :            :  * Because of this, whitelist specific known (series) of CPUs by default, and
      40                 :            :  * leave all others up to the user.
      41                 :            :  */
      42                 :            : static int should_io_be_busy(void)
      43                 :            : {
      44                 :            : #if defined(CONFIG_X86)
      45                 :            :         /*
      46                 :            :          * For Intel, Core 2 (model 15) and later have an efficient idle.
      47                 :            :          */
      48                 :            :         if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
      49                 :            :                         boot_cpu_data.x86 == 6 &&
      50                 :            :                         boot_cpu_data.x86_model >= 15)
      51                 :            :                 return 1;
      52                 :            : #endif
      53                 :            :         return 0;
      54                 :            : }
      55                 :            : 
      56                 :            : /*
      57                 :            :  * Find right freq to be set now with powersave_bias on.
      58                 :            :  * Returns the freq_hi to be used right now and will set freq_hi_delay_us,
      59                 :            :  * freq_lo, and freq_lo_delay_us in percpu area for averaging freqs.
      60                 :            :  */
      61                 :          0 : static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy,
      62                 :            :                 unsigned int freq_next, unsigned int relation)
      63                 :            : {
      64                 :            :         unsigned int freq_req, freq_reduc, freq_avg;
      65                 :            :         unsigned int freq_hi, freq_lo;
      66                 :            :         unsigned int index;
      67                 :            :         unsigned int delay_hi_us;
      68                 :          0 :         struct policy_dbs_info *policy_dbs = policy->governor_data;
      69                 :            :         struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
      70                 :          0 :         struct dbs_data *dbs_data = policy_dbs->dbs_data;
      71                 :          0 :         struct od_dbs_tuners *od_tuners = dbs_data->tuners;
      72                 :          0 :         struct cpufreq_frequency_table *freq_table = policy->freq_table;
      73                 :            : 
      74                 :          0 :         if (!freq_table) {
      75                 :          0 :                 dbs_info->freq_lo = 0;
      76                 :          0 :                 dbs_info->freq_lo_delay_us = 0;
      77                 :          0 :                 return freq_next;
      78                 :            :         }
      79                 :            : 
      80                 :          0 :         index = cpufreq_frequency_table_target(policy, freq_next, relation);
      81                 :          0 :         freq_req = freq_table[index].frequency;
      82                 :          0 :         freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
      83                 :          0 :         freq_avg = freq_req - freq_reduc;
      84                 :            : 
      85                 :            :         /* Find freq bounds for freq_avg in freq_table */
      86                 :          0 :         index = cpufreq_table_find_index_h(policy, freq_avg);
      87                 :          0 :         freq_lo = freq_table[index].frequency;
      88                 :          0 :         index = cpufreq_table_find_index_l(policy, freq_avg);
      89                 :          0 :         freq_hi = freq_table[index].frequency;
      90                 :            : 
      91                 :            :         /* Find out how long we have to be in hi and lo freqs */
      92                 :          0 :         if (freq_hi == freq_lo) {
      93                 :          0 :                 dbs_info->freq_lo = 0;
      94                 :          0 :                 dbs_info->freq_lo_delay_us = 0;
      95                 :          0 :                 return freq_lo;
      96                 :            :         }
      97                 :          0 :         delay_hi_us = (freq_avg - freq_lo) * dbs_data->sampling_rate;
      98                 :          0 :         delay_hi_us += (freq_hi - freq_lo) / 2;
      99                 :          0 :         delay_hi_us /= freq_hi - freq_lo;
     100                 :          0 :         dbs_info->freq_hi_delay_us = delay_hi_us;
     101                 :          0 :         dbs_info->freq_lo = freq_lo;
     102                 :          0 :         dbs_info->freq_lo_delay_us = dbs_data->sampling_rate - delay_hi_us;
     103                 :          0 :         return freq_hi;
     104                 :            : }
     105                 :            : 
     106                 :            : static void ondemand_powersave_bias_init(struct cpufreq_policy *policy)
     107                 :            : {
     108                 :          2 :         struct od_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);
     109                 :            : 
     110                 :          2 :         dbs_info->freq_lo = 0;
     111                 :            : }
     112                 :            : 
     113                 :          2 : static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq)
     114                 :            : {
     115                 :          2 :         struct policy_dbs_info *policy_dbs = policy->governor_data;
     116                 :          2 :         struct dbs_data *dbs_data = policy_dbs->dbs_data;
     117                 :          2 :         struct od_dbs_tuners *od_tuners = dbs_data->tuners;
     118                 :            : 
     119                 :          2 :         if (od_tuners->powersave_bias)
     120                 :          0 :                 freq = od_ops.powersave_bias_target(policy, freq,
     121                 :            :                                 CPUFREQ_RELATION_H);
     122                 :          2 :         else if (policy->cur == policy->max)
     123                 :          2 :                 return;
     124                 :            : 
     125                 :          2 :         __cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ?
     126                 :            :                         CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
     127                 :            : }
     128                 :            : 
     129                 :            : /*
     130                 :            :  * Every sampling_rate, we check, if current idle time is less than 20%
     131                 :            :  * (default), then we try to increase frequency. Else, we adjust the frequency
     132                 :            :  * proportional to load.
     133                 :            :  */
     134                 :          2 : static void od_update(struct cpufreq_policy *policy)
     135                 :            : {
     136                 :          2 :         struct policy_dbs_info *policy_dbs = policy->governor_data;
     137                 :            :         struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
     138                 :          2 :         struct dbs_data *dbs_data = policy_dbs->dbs_data;
     139                 :          2 :         struct od_dbs_tuners *od_tuners = dbs_data->tuners;
     140                 :          2 :         unsigned int load = dbs_update(policy);
     141                 :            : 
     142                 :          2 :         dbs_info->freq_lo = 0;
     143                 :            : 
     144                 :            :         /* Check for frequency increase */
     145                 :          2 :         if (load > dbs_data->up_threshold) {
     146                 :            :                 /* If switching to max speed, apply sampling_down_factor */
     147                 :          2 :                 if (policy->cur < policy->max)
     148                 :          2 :                         policy_dbs->rate_mult = dbs_data->sampling_down_factor;
     149                 :          2 :                 dbs_freq_increase(policy, policy->max);
     150                 :            :         } else {
     151                 :            :                 /* Calculate the next frequency proportional to load */
     152                 :            :                 unsigned int freq_next, min_f, max_f;
     153                 :            : 
     154                 :          2 :                 min_f = policy->cpuinfo.min_freq;
     155                 :          2 :                 max_f = policy->cpuinfo.max_freq;
     156                 :          2 :                 freq_next = min_f + load * (max_f - min_f) / 100;
     157                 :            : 
     158                 :            :                 /* No longer fully busy, reset rate_mult */
     159                 :          2 :                 policy_dbs->rate_mult = 1;
     160                 :            : 
     161                 :          2 :                 if (od_tuners->powersave_bias)
     162                 :          0 :                         freq_next = od_ops.powersave_bias_target(policy,
     163                 :            :                                                                  freq_next,
     164                 :            :                                                                  CPUFREQ_RELATION_L);
     165                 :            : 
     166                 :          2 :                 __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
     167                 :            :         }
     168                 :          2 : }
     169                 :            : 
     170                 :          2 : static unsigned int od_dbs_update(struct cpufreq_policy *policy)
     171                 :            : {
     172                 :          2 :         struct policy_dbs_info *policy_dbs = policy->governor_data;
     173                 :          2 :         struct dbs_data *dbs_data = policy_dbs->dbs_data;
     174                 :            :         struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
     175                 :          2 :         int sample_type = dbs_info->sample_type;
     176                 :            : 
     177                 :            :         /* Common NORMAL_SAMPLE setup */
     178                 :          2 :         dbs_info->sample_type = OD_NORMAL_SAMPLE;
     179                 :            :         /*
     180                 :            :          * OD_SUB_SAMPLE doesn't make sense if sample_delay_ns is 0, so ignore
     181                 :            :          * it then.
     182                 :            :          */
     183                 :          2 :         if (sample_type == OD_SUB_SAMPLE && policy_dbs->sample_delay_ns > 0) {
     184                 :          0 :                 __cpufreq_driver_target(policy, dbs_info->freq_lo,
     185                 :            :                                         CPUFREQ_RELATION_H);
     186                 :          0 :                 return dbs_info->freq_lo_delay_us;
     187                 :            :         }
     188                 :            : 
     189                 :          2 :         od_update(policy);
     190                 :            : 
     191                 :          2 :         if (dbs_info->freq_lo) {
     192                 :            :                 /* Setup SUB_SAMPLE */
     193                 :          0 :                 dbs_info->sample_type = OD_SUB_SAMPLE;
     194                 :          0 :                 return dbs_info->freq_hi_delay_us;
     195                 :            :         }
     196                 :            : 
     197                 :          2 :         return dbs_data->sampling_rate * policy_dbs->rate_mult;
     198                 :            : }
     199                 :            : 
     200                 :            : /************************** sysfs interface ************************/
     201                 :            : static struct dbs_governor od_dbs_gov;
     202                 :            : 
     203                 :          0 : static ssize_t store_io_is_busy(struct gov_attr_set *attr_set, const char *buf,
     204                 :            :                                 size_t count)
     205                 :            : {
     206                 :            :         struct dbs_data *dbs_data = to_dbs_data(attr_set);
     207                 :            :         unsigned int input;
     208                 :            :         int ret;
     209                 :            : 
     210                 :          0 :         ret = sscanf(buf, "%u", &input);
     211                 :          0 :         if (ret != 1)
     212                 :            :                 return -EINVAL;
     213                 :          0 :         dbs_data->io_is_busy = !!input;
     214                 :            : 
     215                 :            :         /* we need to re-evaluate prev_cpu_idle */
     216                 :          0 :         gov_update_cpu_data(dbs_data);
     217                 :            : 
     218                 :          0 :         return count;
     219                 :            : }
     220                 :            : 
     221                 :          2 : static ssize_t store_up_threshold(struct gov_attr_set *attr_set,
     222                 :            :                                   const char *buf, size_t count)
     223                 :            : {
     224                 :            :         struct dbs_data *dbs_data = to_dbs_data(attr_set);
     225                 :            :         unsigned int input;
     226                 :            :         int ret;
     227                 :          2 :         ret = sscanf(buf, "%u", &input);
     228                 :            : 
     229                 :          2 :         if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
     230                 :            :                         input < MIN_FREQUENCY_UP_THRESHOLD) {
     231                 :            :                 return -EINVAL;
     232                 :            :         }
     233                 :            : 
     234                 :          2 :         dbs_data->up_threshold = input;
     235                 :          2 :         return count;
     236                 :            : }
     237                 :            : 
     238                 :          2 : static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
     239                 :            :                                           const char *buf, size_t count)
     240                 :            : {
     241                 :            :         struct dbs_data *dbs_data = to_dbs_data(attr_set);
     242                 :            :         struct policy_dbs_info *policy_dbs;
     243                 :            :         unsigned int input;
     244                 :            :         int ret;
     245                 :          2 :         ret = sscanf(buf, "%u", &input);
     246                 :            : 
     247                 :          2 :         if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
     248                 :            :                 return -EINVAL;
     249                 :            : 
     250                 :          2 :         dbs_data->sampling_down_factor = input;
     251                 :            : 
     252                 :            :         /* Reset down sampling multiplier in case it was active */
     253                 :          2 :         list_for_each_entry(policy_dbs, &attr_set->policy_list, list) {
     254                 :            :                 /*
     255                 :            :                  * Doing this without locking might lead to using different
     256                 :            :                  * rate_mult values in od_update() and od_dbs_update().
     257                 :            :                  */
     258                 :          2 :                 mutex_lock(&policy_dbs->update_mutex);
     259                 :          2 :                 policy_dbs->rate_mult = 1;
     260                 :          2 :                 mutex_unlock(&policy_dbs->update_mutex);
     261                 :            :         }
     262                 :            : 
     263                 :          2 :         return count;
     264                 :            : }
     265                 :            : 
     266                 :          0 : static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
     267                 :            :                                       const char *buf, size_t count)
     268                 :            : {
     269                 :            :         struct dbs_data *dbs_data = to_dbs_data(attr_set);
     270                 :            :         unsigned int input;
     271                 :            :         int ret;
     272                 :            : 
     273                 :          0 :         ret = sscanf(buf, "%u", &input);
     274                 :          0 :         if (ret != 1)
     275                 :            :                 return -EINVAL;
     276                 :            : 
     277                 :          0 :         if (input > 1)
     278                 :          0 :                 input = 1;
     279                 :            : 
     280                 :          0 :         if (input == dbs_data->ignore_nice_load) { /* nothing to do */
     281                 :          0 :                 return count;
     282                 :            :         }
     283                 :          0 :         dbs_data->ignore_nice_load = input;
     284                 :            : 
     285                 :            :         /* we need to re-evaluate prev_cpu_idle */
     286                 :          0 :         gov_update_cpu_data(dbs_data);
     287                 :            : 
     288                 :          0 :         return count;
     289                 :            : }
     290                 :            : 
     291                 :          0 : static ssize_t store_powersave_bias(struct gov_attr_set *attr_set,
     292                 :            :                                     const char *buf, size_t count)
     293                 :            : {
     294                 :            :         struct dbs_data *dbs_data = to_dbs_data(attr_set);
     295                 :          0 :         struct od_dbs_tuners *od_tuners = dbs_data->tuners;
     296                 :            :         struct policy_dbs_info *policy_dbs;
     297                 :            :         unsigned int input;
     298                 :            :         int ret;
     299                 :          0 :         ret = sscanf(buf, "%u", &input);
     300                 :            : 
     301                 :          0 :         if (ret != 1)
     302                 :            :                 return -EINVAL;
     303                 :            : 
     304                 :          0 :         if (input > 1000)
     305                 :          0 :                 input = 1000;
     306                 :            : 
     307                 :          0 :         od_tuners->powersave_bias = input;
     308                 :            : 
     309                 :          0 :         list_for_each_entry(policy_dbs, &attr_set->policy_list, list)
     310                 :          0 :                 ondemand_powersave_bias_init(policy_dbs->policy);
     311                 :            : 
     312                 :          0 :         return count;
     313                 :            : }
     314                 :            : 
     315                 :          0 : gov_show_one_common(sampling_rate);
     316                 :          0 : gov_show_one_common(up_threshold);
     317                 :          0 : gov_show_one_common(sampling_down_factor);
     318                 :          0 : gov_show_one_common(ignore_nice_load);
     319                 :          0 : gov_show_one_common(io_is_busy);
     320                 :          0 : gov_show_one(od, powersave_bias);
     321                 :            : 
     322                 :            : gov_attr_rw(sampling_rate);
     323                 :            : gov_attr_rw(io_is_busy);
     324                 :            : gov_attr_rw(up_threshold);
     325                 :            : gov_attr_rw(sampling_down_factor);
     326                 :            : gov_attr_rw(ignore_nice_load);
     327                 :            : gov_attr_rw(powersave_bias);
     328                 :            : 
     329                 :            : static struct attribute *od_attributes[] = {
     330                 :            :         &sampling_rate.attr,
     331                 :            :         &up_threshold.attr,
     332                 :            :         &sampling_down_factor.attr,
     333                 :            :         &ignore_nice_load.attr,
     334                 :            :         &powersave_bias.attr,
     335                 :            :         &io_is_busy.attr,
     336                 :            :         NULL
     337                 :            : };
     338                 :            : 
     339                 :            : /************************** sysfs end ************************/
     340                 :            : 
     341                 :          2 : static struct policy_dbs_info *od_alloc(void)
     342                 :            : {
     343                 :            :         struct od_policy_dbs_info *dbs_info;
     344                 :            : 
     345                 :          2 :         dbs_info = kzalloc(sizeof(*dbs_info), GFP_KERNEL);
     346                 :          2 :         return dbs_info ? &dbs_info->policy_dbs : NULL;
     347                 :            : }
     348                 :            : 
     349                 :          0 : static void od_free(struct policy_dbs_info *policy_dbs)
     350                 :            : {
     351                 :          0 :         kfree(to_dbs_info(policy_dbs));
     352                 :          0 : }
     353                 :            : 
     354                 :          2 : static int od_init(struct dbs_data *dbs_data)
     355                 :            : {
     356                 :            :         struct od_dbs_tuners *tuners;
     357                 :            :         u64 idle_time;
     358                 :            :         int cpu;
     359                 :            : 
     360                 :          2 :         tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
     361                 :          2 :         if (!tuners)
     362                 :            :                 return -ENOMEM;
     363                 :            : 
     364                 :          2 :         cpu = get_cpu();
     365                 :          2 :         idle_time = get_cpu_idle_time_us(cpu, NULL);
     366                 :          2 :         put_cpu();
     367                 :          2 :         if (idle_time != -1ULL) {
     368                 :            :                 /* Idle micro accounting is supported. Use finer thresholds */
     369                 :          2 :                 dbs_data->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
     370                 :            :         } else {
     371                 :          0 :                 dbs_data->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
     372                 :            :         }
     373                 :            : 
     374                 :          2 :         dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
     375                 :          2 :         dbs_data->ignore_nice_load = 0;
     376                 :          2 :         tuners->powersave_bias = default_powersave_bias;
     377                 :          2 :         dbs_data->io_is_busy = should_io_be_busy();
     378                 :            : 
     379                 :          2 :         dbs_data->tuners = tuners;
     380                 :          2 :         return 0;
     381                 :            : }
     382                 :            : 
     383                 :          0 : static void od_exit(struct dbs_data *dbs_data)
     384                 :            : {
     385                 :          0 :         kfree(dbs_data->tuners);
     386                 :          0 : }
     387                 :            : 
     388                 :          2 : static void od_start(struct cpufreq_policy *policy)
     389                 :            : {
     390                 :          2 :         struct od_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);
     391                 :            : 
     392                 :          2 :         dbs_info->sample_type = OD_NORMAL_SAMPLE;
     393                 :            :         ondemand_powersave_bias_init(policy);
     394                 :          2 : }
     395                 :            : 
     396                 :            : static struct od_ops od_ops = {
     397                 :            :         .powersave_bias_target = generic_powersave_bias_target,
     398                 :            : };
     399                 :            : 
     400                 :            : static struct dbs_governor od_dbs_gov = {
     401                 :            :         .gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("ondemand"),
     402                 :            :         .kobj_type = { .default_attrs = od_attributes },
     403                 :            :         .gov_dbs_update = od_dbs_update,
     404                 :            :         .alloc = od_alloc,
     405                 :            :         .free = od_free,
     406                 :            :         .init = od_init,
     407                 :            :         .exit = od_exit,
     408                 :            :         .start = od_start,
     409                 :            : };
     410                 :            : 
     411                 :            : #define CPU_FREQ_GOV_ONDEMAND   (&od_dbs_gov.gov)
     412                 :            : 
     413                 :          0 : static void od_set_powersave_bias(unsigned int powersave_bias)
     414                 :            : {
     415                 :            :         unsigned int cpu;
     416                 :            :         cpumask_t done;
     417                 :            : 
     418                 :          0 :         default_powersave_bias = powersave_bias;
     419                 :            :         cpumask_clear(&done);
     420                 :            : 
     421                 :            :         get_online_cpus();
     422                 :          0 :         for_each_online_cpu(cpu) {
     423                 :            :                 struct cpufreq_policy *policy;
     424                 :            :                 struct policy_dbs_info *policy_dbs;
     425                 :            :                 struct dbs_data *dbs_data;
     426                 :            :                 struct od_dbs_tuners *od_tuners;
     427                 :            : 
     428                 :          0 :                 if (cpumask_test_cpu(cpu, &done))
     429                 :          0 :                         continue;
     430                 :            : 
     431                 :          0 :                 policy = cpufreq_cpu_get_raw(cpu);
     432                 :          0 :                 if (!policy || policy->governor != CPU_FREQ_GOV_ONDEMAND)
     433                 :          0 :                         continue;
     434                 :            : 
     435                 :          0 :                 policy_dbs = policy->governor_data;
     436                 :          0 :                 if (!policy_dbs)
     437                 :          0 :                         continue;
     438                 :            : 
     439                 :            :                 cpumask_or(&done, &done, policy->cpus);
     440                 :            : 
     441                 :          0 :                 dbs_data = policy_dbs->dbs_data;
     442                 :          0 :                 od_tuners = dbs_data->tuners;
     443                 :          0 :                 od_tuners->powersave_bias = default_powersave_bias;
     444                 :            :         }
     445                 :            :         put_online_cpus();
     446                 :          0 : }
     447                 :            : 
     448                 :          0 : void od_register_powersave_bias_handler(unsigned int (*f)
     449                 :            :                 (struct cpufreq_policy *, unsigned int, unsigned int),
     450                 :            :                 unsigned int powersave_bias)
     451                 :            : {
     452                 :          0 :         od_ops.powersave_bias_target = f;
     453                 :          0 :         od_set_powersave_bias(powersave_bias);
     454                 :          0 : }
     455                 :            : EXPORT_SYMBOL_GPL(od_register_powersave_bias_handler);
     456                 :            : 
     457                 :          0 : void od_unregister_powersave_bias_handler(void)
     458                 :            : {
     459                 :          0 :         od_ops.powersave_bias_target = generic_powersave_bias_target;
     460                 :          0 :         od_set_powersave_bias(0);
     461                 :          0 : }
     462                 :            : EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler);
     463                 :            : 
     464                 :          3 : static int __init cpufreq_gov_dbs_init(void)
     465                 :            : {
     466                 :          3 :         return cpufreq_register_governor(CPU_FREQ_GOV_ONDEMAND);
     467                 :            : }
     468                 :            : 
     469                 :          0 : static void __exit cpufreq_gov_dbs_exit(void)
     470                 :            : {
     471                 :          0 :         cpufreq_unregister_governor(CPU_FREQ_GOV_ONDEMAND);
     472                 :          0 : }
     473                 :            : 
     474                 :            : MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
     475                 :            : MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
     476                 :            : MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
     477                 :            :         "Low Latency Frequency Transition capable processors");
     478                 :            : MODULE_LICENSE("GPL");
     479                 :            : 
     480                 :            : #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
     481                 :            : struct cpufreq_governor *cpufreq_default_governor(void)
     482                 :            : {
     483                 :            :         return CPU_FREQ_GOV_ONDEMAND;
     484                 :            : }
     485                 :            : 
     486                 :            : fs_initcall(cpufreq_gov_dbs_init);
     487                 :            : #else
     488                 :            : module_init(cpufreq_gov_dbs_init);
     489                 :            : #endif
     490                 :            : module_exit(cpufreq_gov_dbs_exit);
    

Generated by: LCOV version 1.14