#!/bin/bash

# determine actual governor
if [ -a /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then
    actual_gov=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`
elif [ -a /proc/cpufreq ]; then
    actual_gov=`tail -1 /proc/cpufreq | sed 's/.*\ //'`
fi

# exit if no interface available
if [ "$actual_gov" == "" ]; then
    exit
fi

# determine available governors
if [ -a /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ]; then
    avail_gov=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors`
else
    # default guess
    avail_gov="powersave userspace performance"
fi

avail_gov1=`echo $avail_gov | sed "s/.*$actual_gov//"`
avail_gov2=`echo $avail_gov | sed "s/$actual_gov.*//"`
avail_gov="$avail_gov1 $avail_gov2"

success="false"
if [ -a /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then
    for candidate_gov in $avail_gov; do
        for cpu in `ls --color=none /sys/devices/system/cpu/`; do
            echo $candidate_gov > /sys/devices/system/cpu/$cpu/cpufreq/scaling_governor
            if [ `cat /sys/devices/system/cpu/$cpu/cpufreq/scaling_governor` == "$candidate_gov" ]; then
                success="true"
            fi
        done
        if [ "$success" == "true" ]; then
            exit
        fi
    done
elif [ -a /proc/cpufreq ]; then
    for candidate_gov in $avail_gov; do
        if [ -a /proc/sys/cpu/0/speed ]; then
            for cpu in `ls --color=none /proc/sys/cpu/`; do
                echo "$cpu%0%100%$candidate_gov" > /proc/cpufreq
                if [  `tail -1 /proc/cpufreq | sed 's/.*\ //'` == "$candidate_gov" ]; then
                    success="true"
                fi
            done
        fi
    done
    if [ "$success" == "true" ]; then
        exit
    fi
fi