| #!/bin/sh |
| |
| # Copyright 2017 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Configures cpufreq if /etc/cpufreq.conf exists and contains valid |
| # configuration data. |
| |
| # Convenience variables with sysfs paths. |
| CPU_BASE_DIR=/sys/devices/system/cpu |
| CPUFREQ_DIR="${CPU_BASE_DIR}/cpufreq" |
| |
| ############################################## |
| # Sets the cpufreq governor for all CPUs. |
| # Globals: |
| # CPU_BASE_DIR |
| # Arguments: |
| # Name of the cpufreq governor |
| # Returns: |
| # nothing |
| ############################################## |
| cpufreq_set_governor() { |
| local governor="$1" |
| local cpu |
| |
| for cpu in "${CPU_BASE_DIR}"/cpu[0-9]*; do |
| if [ -e "${cpu}/cpufreq" ]; then |
| echo "${governor}" > "${cpu}/cpufreq/scaling_governor" |
| fi |
| done |
| } |
| |
| ########################################################################### |
| # Gets the value of a configuration setting for the cpufreq governor. |
| # The settings are specified in the configuration file. |
| # Arguments: |
| # Name of the sysfs attribute of the setting |
| # Number of the cpufreq policy, empty for systems with a single policy |
| # for all CPUs |
| # Returns: |
| # Value of the requested setting, or an empty string if the setting is |
| # not specified in the configuration file. |
| ########################################################################### |
| governor_get_config_value() { |
| local setting="$1" |
| local policy="$2" |
| local conf_var |
| |
| conf_var="CPUFREQ_$(echo "${setting}" | tr "[:lower:]" "[:upper:]")" |
| if [ -n "${policy}" ]; then |
| conf_var="${conf_var}_POLICY_${policy}" |
| fi |
| |
| echo "$(eval "echo \$$conf_var")" |
| } |
| |
| ############################################################################# |
| # Configures a setting of the cpufreq governor on systems with a single |
| # cpufreq policy. Does nothing if the setting is not specified in the |
| # configuration file. |
| # Globals: |
| # GOVERNOR_DIR |
| # Arguments: |
| # Name of the sysfs attribute of the setting |
| # Returns: |
| # nothing |
| ########################################################################### |
| governor_set_optional() { |
| local setting="$1" |
| local sysfs_attr |
| |
| sysfs_attr="${GOVERNOR_DIR}/${setting}" |
| if [ ! -f "${sysfs_attr}" ]; then |
| return |
| fi |
| |
| local value="$(governor_get_config_value "${setting}")" |
| if [ -z "${value}" ]; then |
| return |
| fi |
| |
| echo "${value}" > "${sysfs_attr}" |
| } |
| |
| ###################################################################### |
| # |
| # Interactive governor |
| # |
| ############################################################################# |
| # Configures a setting of the interactive cpufreq governor on systems with |
| # multiple cpufreq policies. Does nothing if the setting is not specified |
| # in the configuration file. |
| # Globals: |
| # CPUFREQ_DIR |
| # Arguments: |
| # Number of the cpufreq policy |
| # Name of the sysfs attribute of the setting |
| # Returns: |
| # nothing |
| ########################################################################### |
| interactive_policy_set_optional() { |
| local policy="$1" |
| local setting="$2" |
| local sysfs_attr="${CPUFREQ_DIR}/policy${policy}/interactive/${setting}" |
| |
| if [ ! -f "${sysfs_attr}" ]; then |
| return |
| fi |
| |
| local value="$(governor_get_config_value "${setting}" "${policy}")" |
| if [ -z "${value}" ]; then |
| return |
| fi |
| |
| echo "${value}" > "${sysfs_attr}" |
| } |
| |
| ######################################################################### |
| # Configures the interactive cpufreq governor according to the values |
| # from the configuration file. |
| # Globals: |
| # GOVERNOR_DIR |
| # CPUFREQ_DIR |
| # Arguments: |
| # None |
| # Returns: |
| # nothing |
| ######################################################################### |
| cpufreq_config_interactive() { |
| local setting |
| |
| GOVERNOR_DIR="${CPUFREQ_DIR}/interactive" |
| if [ -d "${GOVERNOR_DIR}" ]; then |
| for setting in input_boost above_hispeed_delay go_hispeed_load \ |
| hispeed_freq min_sample_time target_loads timer_rate; do |
| governor_set_optional "${setting}" |
| done |
| else |
| local p |
| for p in "${CPUFREQ_DIR}"/policy[0-9]*; do |
| local policy="${p##*/policy}" |
| |
| for setting in input_boost above_hispeed_delay go_hispeed_load \ |
| hispeed_freq min_sample_time target_loads timer_rate; do |
| interactive_policy_set_optional "${policy}" "${setting}" |
| done |
| done |
| fi |
| } |
| |
| |
| ###################################################################### |
| # |
| # Ondemand governor |
| # |
| ######################################################################### |
| # Configures the ondemand cpufreq governor according to the values |
| # from the configuration file. |
| # Globals: |
| # GOVERNOR_DIR |
| # Arguments: |
| # None |
| # Returns: |
| # nothing |
| ######################################################################### |
| cpufreq_config_ondemand() { |
| local setting |
| |
| GOVERNOR_DIR="${CPUFREQ_DIR}/ondemand" |
| for setting in sampling_rate up_threshold ignore_nice_load \ |
| io_is_busy sampling_down_factor powersave_bias; do |
| governor_set_optional "${setting}" |
| done |
| } |
| |
| ###################################################################### |
| |
| if [ ! -f /etc/cpufreq.conf ]; then |
| exit 0 |
| fi |
| . /etc/cpufreq.conf |
| |
| if [ -z "${CPUFREQ_GOVERNOR}" ]; then |
| exit 0 |
| fi |
| |
| cpufreq_set_governor "${CPUFREQ_GOVERNOR}" |
| |
| if [ "${CPUFREQ_GOVERNOR}" = "interactive" ]; then |
| cpufreq_config_interactive |
| elif [ "${CPUFREQ_GOVERNOR}" = "ondemand" ]; then |
| cpufreq_config_ondemand |
| fi |