#!/bin/bash
#
# cpu_cool.sh v1.0 2005/04
#
# script for tuning centrino cpu frequency down for powersaving
# this is the ultimate powersaving method. frequency is statically
# set to minimum available.
#
# requires kernel modules: cpufreq, speedstep_centrino and cpufreq_powersave
#
# 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
POWERSAVE_MODULE="cpufreq_powersave" # name of powersave 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
POWERSAVE=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 powersave governor
echo -n "checking for powersave governor ... "
# grep for it from the available governors list
if [ -z "$(grep powersave /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)" ]; then

	echo -n "modprobing ${POWERSAVE_MODULE} ... "
	/sbin/modprobe ${POWERSAVE_MODULE}

	if [ $? = "0" ]; then
		if [ -z "$(grep powersave /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)" ]; then
			echo "module loaded but still no available powersave governor"
			POWERSAVE=0
		else
			echo "done"
			POWERSAVE=1
		fi
	else
		echo "failed"
		POWERSAVE=0
	fi
else
	echo "ok"
	POWERSAVE=1
fi					 

# if there is no cpufreq powersave governor, we can't do our work. exit
if [ ${POWERSAVE} = "0" ]; then
	echo "powersave 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
	# powersave 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
	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 [ "powersave" = "$(cat ${CPUFREQ_DIR}/scaling_governor)" ]; then
	echo "governor already set to powersave"
	exit 1
fi

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

echo ""
echo "frequency statically set to minimum"
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)"

