#!/bin/bash
#
# cpu_ondemand.sh v1.0 2005/04
#
# script for tuning centrino cpu frequency ondemand performance
# when cpu power is needed, speed is upped; when cpu is idle, speed
# is lowered into more powersaving values.
# this is the kernel method, using cpufreq_ondemand
#
# requires kernel modules: cpufreq, speedstep_centrino and cpufreq_ondemand
#
# Copyright (C) 2005 < pjvenda (at) pjvenda org >
#
# Distributed under the terms of the GNU Public License Agreement (GPLv2)
# http://www.fsf.org/licensing/licenses/gpl.html or
# http://www.fsf.org/licensing/licenses/gpl.txt
#
# Changelog
# =========
#
# v1.0 - 2005/04/09
# - first version
#

# CONFIGURABLE VARIABLES
CPUFREQ_MODULE="speedstep_centrino"

# NON-CONFIGURABLE VARIABLES
# these should be standard for 99% of linux systems
CPUFREQ_DIR="/sys/devices/system/cpu/cpu0/cpufreq" # cpufreq directory
ACPI_DIR="/proc/acpi" # acpi directory
ONDEMAND_MODULE="cpufreq_ondemand" # name of ondemand governor module
THERMAL_MODULE="thermal" # name of thermal module
THERMAL_DIR="/proc/acpi/thermal_zone/THRM" # acpi thermal information dir

# state variables
# these define detection results. only thermal_monitor is optional!
# initialized to 0, detection routines below will set them otherwise if
# support for respective feature is found
THERMAL_MONITOR=0
CPUFREQ=0
ONDEMAND=0

# check for cpufreq driver
echo -n "checking for cpufreq driver ... "
# look for the directory
if [ ! -d "${CPUFREQ_DIR}" ]; then
	echo -n "modprobing ${CPUFREQ_MODULE} ... "
	/sbin/modprobe ${CPUFREQ_MODULE}
	if [ $? = "0" ]; then
		echo "done"
		CPUFREQ=1
	else
		echo "failed"
		CPUFREQ=0
	fi
else
	echo "ok"
	CPUFREQ=1
fi

# if cpufreq is not found, there's nothing we can do. exit
if [ ${CPUFREQ} = "0" ]; then
	echo "no cpufreq driver available"
	exit 1
fi

# check for cpufreq ondemand governor
echo -n "checking for ondemand governor ... "
# grep for it from the available governors list
if [ -z "$(grep ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)" ]; then

	echo -n "modprobing ${ONDEMAND_MODULE} ... "
	/sbin/modprobe ${ONDEMAND_MODULE}
	if [ $? = "0" ]; then
		if [ -z "$(grep ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)" ]; then
			echo "module loaded but still no available ondemand governor"
			ONDEMAND=0
		else
			echo "done"
			ONDEMAND=1
		fi
		echo "done"
		ONDEMAND=1
	else
		echo "failed"
		ONDEMAND=0
	fi
else
	echo "ok"
	ONDEMAND=1
fi					 

# if there is no cpufreq ondemand governor, we can't do our work. exit
if [ ${ONDEMAND} = "0" ]; then
	echo "ondemand governor is not available. cpu frequency cannot be set to minimum"
	exit 1
fi

# check for acpi thermal monitor
echo -n "checking for thermal monitor ... "
# look for file
if [ ! -f "${THERMAL_DIR}/temperature" ]; then
	# ondemand governor exists: carry on
	echo -n "modprobing ${THERMAL_MODULE} ... "
	/sbin/modprobe ${THERMAL_MODULE}
	if [ $? = "0" ]; then	
		if [ ! -f "${THERMAL_DIR}/temperature" ]; then
			echo "module loaded but still no acpi temperature reading available"
			THERMAL_MONITOR=0
		else
			echo "done"
			THERMAL_MONITOR=1
		fi
		echo "done"
		THERMAL_MONITOR=1
	else
		echo "failed (not fatal, just no temperature info available)"
		THERMAL_MONITOR=0
	fi
else
	echo "ok"
	THERMAL_MONITOR=1
fi

# see if there is anything to do
if [ "ondemand" = "$(cat ${CPUFREQ_DIR}/scaling_governor)" ]; then
	echo "governor already set to ondemand"
	exit 1
fi

# all checks done. everything needed is available (hopefully)
# set the scaling_governor to ondemand
echo -n "ondemand" > ${CPUFREQ_DIR}/scaling_governor

echo ""
echo "dinamically setting frequency according to load demand"
echo ""

# give status information
echo "current frequency: 	$(cat ${CPUFREQ_DIR}/cpuinfo_cur_freq) kHz"
if [ ${THERMAL_MONITOR} = "1" ]; then
	echo "temperature:		$(cat ${THERMAL_DIR}/temperature| tr -s " "| cut -f 2 -d ' ') C"
fi
echo "governor: 		$(cat ${CPUFREQ_DIR}/scaling_governor)"

