#!/bin/sh # kernel configuration script for power user kernel # (c) Copyright 2010 by Thomas Tanner # licensed under GPLv3 # version 0.3 (16. May 2010) if test $# -eq 0; then echo "$0 command [options]" echo "commands:" echo " show - show current settings" echo " load - load settings from file" echo " save - save settings to file (abs. path or filename in /home/user/.kernel)" echo " default [] - set file or the current settings as default settings" echo " limits min max - set the frequency limits ('-' keeps the current setting)" echo " lock freq [volt] [dsp] - lock CPU at frequency with specific settings" echo " unlock - unlock CPU frequency" echo "filenames: absolute path or filename in search path or none=defaults" echo "search path: .,/home/user/.kernel,/usr/share/kernel-power-settings/" exit 1 fi if test "`id -u`" -ne 0; then sudo $0 $* # run as root exit $? fi cfr=/sys/devices/system/cpu/cpu0/cpufreq cfd=$cfr/ondemand cfc=$cfr/conservative pwr=/sys/power if test -f $pwr/vdd1_opps_vsel -a -f $pwr/dsp_opps_rate; then : else echo This kernel version `uname -r` is not supported echo Please make sure that kernel-power is installed and running. echo If you have just installed the kernel, you need to shutdown and boot to activate it. echo To reinstall the power user kernel run: echo \'apt-get install --reinstall kernel-power kernel-power-flasher\' exit 1 fi allfreq= for f in `cat $cfr/scaling_available_frequencies`; do allfreq="$f $allfreq" done vsel=`cat $pwr/vdd1_opps_vsel` rate=`cat $pwr/dsp_opps_rate` cmd=$1 test "$cmd" = setdefault && cmd=default # old name case " show load save default limits lock unlock " in *" $cmd "*) ;; *) echo "invalid command $cmd"; exit 1 ;; esac arg= shift if test "$cmd" = unlock; then echo 'unlocking frequency. reset to defaults' cmd=loaddef fi if test "$cmd" = default && test $# -eq 0; then echo 'saving current settings as defaults' arg=/etc/default/kernel-power cmd=savedef fi popvsel() { curvsel=$1; shift; vsel="$*"; } poprate() { currate=$1; shift; rate="$*"; } case $cmd in show|save|savedef) minfreq=$((`cat $cfr/scaling_min_freq`/1000)) maxfreq=$((`cat $cfr/scaling_max_freq`/1000)) test $maxfreq = 599 && maxfreq=600 gov=`cat $cfr/scaling_governor` avoid= test $gov = ondemand && avoid=`cat $cfd/avoid_frequencies` freqs= for f in 0 $allfreq; do popvsel $vsel poprate $rate case " $avoid " in *" $f "*) ;; *) freqs="$freqs$((f/1000)):$curvsel,$currate " ;; esac done if test $cmd = show; then echo "current kernel configuration:" echo "current frequency:" $((`cat $cfr/scaling_cur_freq`/1000)) echo -n "supported frequencies: " for f in $allfreq; do echo -n "$((f/1000)) "; done echo echo "min. frequency:" $minfreq echo "max. frequency:" $maxfreq echo -n "avoid frequencies: " for f in $avoid; do echo -n "$((f/1000)) "; done echo echo "active frequencies: $freqs" echo "SmartReflex" "VDD1=`cat $pwr/sr_vdd1_autocomp`, VDD2=`cat $pwr/sr_vdd2_autocomp`" echo -n "governor $gov:" if test $gov = ondemand; then echo -n " ignore nice load=" `cat $cfd/ignore_nice_load` echo -n ", up threshold=" `cat $cfd/up_threshold` echo -n ", sampling rate=" `cat $cfd/sampling_rate` echo ", powersave bias=" `cat $cfd/powersave_bias` else echo fi else test $cmd = save && arg=$1 if test -z "$arg"; then echo "filename argument is mssing" exit 1 fi if test `basename $arg` = $arg; then u=/home/user/.kernel arg=$u/$arg if test ! -d $u; then mkdir -p $u chown user.users $u fi touch $arg chown user.users $arg fi rm -f $arg echo "saving to $arg" echo "# kernel configuration file generated by $0" > $arg echo "MINFREQ=$minfreq" >> $arg echo "MAXFREQ=$maxfreq" >> $arg echo "FREQS=\"$freqs\"" >> $arg echo "SMARTREFLEX_VDD1=`cat $pwr/sr_vdd1_autocomp`" >> $arg echo "SMARTREFLEX_VDD2=`cat $pwr/sr_vdd2_autocomp`" >> $arg echo "GOVERNOR=$gov" >> $arg if test $gov = ondemand; then echo "IGNORE_NICE_LOAD=`cat $cfd/ignore_nice_load`" >> $arg echo "UP_THRESHOLD=`cat $cfd/up_threshold`" >> $arg echo "SAMPLING_RATE=`cat $cfd/sampling_rate`" >> $arg echo "POWERSAVE_BIAS=`cat $cfd/powersave_bias`" >> $arg fi fi ;; load|loaddef) test $cmd = loaddef || arg=$1 if test -z "$arg"; then arg=/etc/default/kernel-power test -f $arg || arg=/usr/share/kernel-power-settings/default fi if test `basename $arg` = $arg; then # not absolute for p in . /home/user/.kernel /usr/share/kernel-power-settings; do test -f $p/$arg && arg=$p/$arg && break done fi if test ! -f "$arg"; then echo "file not found $arg" exit 1 fi echo "loading $arg" source $arg if test -n "$VDD1_OPPS_VSEL" -o -n "$DSP_OPPS_RATE"; then echo "warning: old configuration format detected. please save in the new format." if test -n "$MAX_FREQ"; then test $MAX_FREQ = 600000 && MAX_FREQ=599000 echo $MAX_FREQ > $cfr/scaling_max_freq fi test -n "$MIN_FREQ" && echo $MIN_FREQ > $cfr/scaling_min_freq test -n "$MAX_FREQ" && echo $MAX_FREQ > $cfr/scaling_max_freq test -n "$VDD1_OPPS_VSEL" && echo $VDD1_OPPS_VSEL > $pwr/vdd1_opps_vsel test -n "$DSP_OPPS_RATE" && echo $DSP_OPPS_RATE > $pwr/dsp_opps_rate test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate exit 1 fi active= minfreq= maxfreq= for f in $FREQS; do freq=`echo $f | cut -d: -f1` f=`echo $f | cut -d: -f2` volt=`echo $f | cut -d, -f1` dsp=`echo $f | cut -d, -f2` if test ! $freq = 0; then test -z "$minfreq" -o "$freq" -lt "$minfreq" && minfreq=$freq test -z "$maxfreq" -o "$freq" -gt "$maxfreq" && maxfreq=$freq freq=$((freq*1000)) case " $allfreq " in *" $freq "*) ;; *) echo warning: $freq not supported; continue ;; esac active="$active $freq" fi test -z "$volt" && test -z "$dsp" && continue tvsel= trate= for fr in 0 $allfreq; do if test $fr = $freq; then popvsel $vsel poprate $rate test -z "$volt" && volt=$curvsel test -z "$dsp" && dsp=$currate tvsel="$tvsel $volt $vsel" trate="$trate $dsp $rate" break fi popvsel $vsel tvsel="$tvsel $curvsel" poprate $rate trate="$trate $currate" done vsel=$tvsel rate=$trate done test -z "$GOVERNOR" && GOVERNOR=ondemand test -n "$MINFREQ" && minfreq=$MINFREQ test -n "$MAXFREQ" && maxfreq=$MAXFREQ test "$minfreq" -gt 100000 && minfreq=$((minfreq/1000)) test "$maxfreq" -gt 100000 && maxfreq=$((maxfreq/1000)) avoid= for f in $allfreq; do if test "$f" -lt $((minfreq*1000)); then avoid="$avoid $f" continue fi case " $active " in *" $f "*) ;; *) avoid="$avoid $f" ;; esac done echo $GOVERNOR > $cfr/scaling_governor if test $GOVERNOR = ondemand; then echo $avoid > $cfd/avoid_frequencies test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate test -n "$POWERSAVE_BIAS" && echo $POWERSAVE_BIAS > $cfd/powersave_bias fi echo $vsel > $pwr/vdd1_opps_vsel echo $rate > $pwr/dsp_opps_rate test $maxfreq = 600 && maxfreq=599 echo $((maxfreq*1000)) > $cfr/scaling_max_freq echo $((minfreq*1000)) > $cfr/scaling_min_freq echo $((maxfreq*1000)) > $cfr/scaling_max_freq test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp echo "successfully loaded." ;; default) arg=$1 if test -z "$arg"; then echo "filename missing" exit 1 fi if test `basename $arg` = $arg; then # not absolute for p in . /home/user/.kernel /usr/share/kernel-power-settings; do test -f $p/$arg && arg=$p/$arg && break done fi def=/etc/default/kernel-power rm -f $def case $arg in /usr/share/kernel-power-settings/*) ln -s $arg $def ;; *) cp $arg $def ;; esac echo "defaults set to $arg" ;; limits) minfreq=$1 maxfreq=$2 if test "x$minfreq" = x -o "x$maxfreq" = x; then echo "frequency limit arguments missing" exit 1 fi test "x$minfreq" = "x-" && minfreq=$((`cat $cfr/scaling_min_freq`/1000)) test "x$maxfreq" = "x-" && maxfreq=$((`cat $cfr/scaling_max_freq`/1000)) limits="$minfreq,$maxfreq" minfreq=$((minfreq*1000)) maxfreq=$((maxfreq*1000)) case " $allfreq " in *" $minfreq "*) ;; *) echo "invalid lower limit $1"; exit 1; ;; esac case " $allfreq " in *" $maxfreq "*) ;; *) echo "invalid upper limit $2"; exit 1; ;; esac if test $minfreq -gt $maxfreq; then echo "minimum must not be greater than maximum: $limits" exit 1 fi test $maxfreq = 600000 && maxfreq=599000 echo $maxfreq > $cfr/scaling_max_freq echo $minfreq > $cfr/scaling_min_freq echo $maxfreq > $cfr/scaling_max_freq echo "the limits were set to [$limits]" ;; lock) arg=$1 altfreq= for f in $allfreq; do test "$f" = "$arg" && continue altfreq=$f break done vsel= dsp= freq=$((arg*1000)) ifreq= i=1 avoid= for f in $allfreq; do i=$((i+1)) if test $f = $freq; then ifreq=$i break fi avoid="$avoid $f" done if test -z "ifreq"; then echo invalid frequency $freq exit 1 fi echo userspace > $cfr/scaling_governor echo $altfreq > $cfr/scaling_setspeed # temporarily set alternative frequencies volt=$2 if test -n "$volt"; then i=0 vsel= for v in `cat $pwr/vdd1_opps_vsel`; do i=$((i+1)) test $i = $ifreq && v=$volt vsel="$vsel $v" done echo $vsel > $pwr/vdd1_opps_vsel fi dsp=$3 if test -n "$dsp"; then i=0 dsp= for r in `cat $pwr/dsp_opps_rate`; do i=$((i+1)) test $i = $ifreq && r=$dsp dsp="$dsp $r" done echo $dsp > $pwr/dsp_opps_rate fi echo locking frequency $freq echo ondemand > $cfr/scaling_governor echo $avoid > $cfd/avoid_frequencies # avoid all other freqs maxfreq=$freq test $maxfreq = 600000 && maxfreq=599000 # min after max? kernel docs are wrong? echo $maxfreq > $cfr/scaling_max_freq echo $freq > $cfr/scaling_min_freq echo $maxfreq > $cfr/scaling_max_freq ;; esac exit 0