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