1#!/bin/sh 2# 3# Modify the power profile based on AC line state. This script is 4# usually called from devd(8). 5# 6# Arguments: 0x00 (AC offline, economy) or 0x01 (AC online, performance) 7# 8# $FreeBSD$ 9# 10 11# PROVIDE: power_profile 12# REQUIRE: FILESYSTEMS syslogd 13# KEYWORD: nojail nostart 14 15. /etc/rc.subr 16 17name="power_profile" 18desc="Modify the power profile based on AC line state" 19stop_cmd=':' 20LOGGER="logger -t power_profile -p daemon.notice" 21 22# Set a given sysctl node to a value. 23# 24# Variables: 25# $node: sysctl node to set with the new value 26# $value: HIGH for the highest performance value, LOW for the best 27# economy value, or the value itself. 28# $highest_value: maximum value for this sysctl, when $value is "HIGH" 29# $lowest_value: minimum value for this sysctl, when $value is "LOW" 30# 31sysctl_set() 32{ 33 # Check if the node exists 34 if [ -z "$(sysctl -n ${node} 2> /dev/null)" ]; then 35 return 36 fi 37 38 # Get the new value, checking for special types HIGH or LOW 39 case ${value} in 40 [Hh][Ii][Gg][Hh]) 41 value=${highest_value} 42 ;; 43 [Ll][Oo][Ww]) 44 value=${lowest_value} 45 ;; 46 [Nn][Oo][Nn][Ee]) 47 return 48 ;; 49 *) 50 ;; 51 esac 52 53 # Set the desired value 54 if [ -n "${value}" ]; then 55 if ! sysctl ${node}=${value} > /dev/null 2>&1; then 56 warn "unable to set ${node}=${value}" 57 fi 58 fi 59} 60 61if [ $# -ne 1 ]; then 62 err 1 "Usage: $0 [0x00|0x01]" 63fi 64load_rc_config $name 65 66# Find the next state (performance or economy). 67state=$1 68case ${state} in 690x01 | '') 70 ${LOGGER} "changed to 'performance'" 71 profile="performance" 72 ;; 730x00) 74 ${LOGGER} "changed to 'economy'" 75 profile="economy" 76 ;; 77*) 78 echo "Usage: $0 [0x00|0x01]" 79 exit 1 80esac 81 82# Set the various sysctls based on the profile's values. 83node="hw.acpi.cpu.cx_lowest" 84highest_value="C1" 85lowest_value="Cmax" 86eval value=\$${profile}_cx_lowest 87sysctl_set 88 89node="dev.cpu.0.freq" 90highest_value="`(sysctl -n dev.cpu.0.freq_levels | \ 91 awk '{ split($0, a, "[/ ]"); print a[1] }' -) 2> /dev/null`" 92lowest_value="`(sysctl -n dev.cpu.0.freq_levels | \ 93 awk '{ split($0, a, "[/ ]"); print a[length(a) - 1] }' -) 2> /dev/null`" 94eval value=\$${profile}_cpu_freq 95sysctl_set 96 97exit 0 98