ThinkPad X60 power saving

Table of Contents

This is what I use to mess about my laptop’s power settings.

The c’t article is here but only available to subscribers. No real need to read it if you want to use the script. I just wanted references to what I build the scrip on.

#!/bin/bash
#
# small shell script to set powersaving option
# c't 20/2011 page 150
# and
# https://lwn.net/Articles/496828/
#
# pcfe, 2011-09-12
# aded status and stop sections on 2012-07-28

usage()
{
  echo "Usage: $0 { start | stop | status }"
  exit 1
}

start()
{
  # audio codec sleeps after 1 second
  echo 1 > /sys/module/snd_hda_intel/parameters/power_save

  # APLM (Aggressive Link Power Management) on all SATA ports
  # getting timeouts on amanda estimates and it is a bit sluggish
  # going from min popwer to med power
  # pcfe, 2011-09-21
  #for i in /sys/class/scsi_host/host[012345]/link_power_management_policy ; do echo min_power > ${i};done
  for i in /sys/class/scsi_host/host[012345]/link_power_management_policy ; do echo medium_power > ${i};done

  # PCI and i2c device automatic power mode
  find /sys/bus/{pci,i2c}/devices/*/power/control | while read LINE; do echo 'auto' > ${LINE}; done

  # auto-suspend for all USB devices
  # this is on auto for most but not the bluetooth controller and it's hub (5-1 and 5-2)
  for i in /sys/bus/usb/devices/*/power/control ; do echo auto > ${i};done

  # NMI watchdog off
  echo 0 > /proc/sys/kernel/nmi_watchdog

  # WOL (Wake on Lan) off
  #ethtool -s em1 wol d
  ethtool -s p2p1 wol d

  # change VM writeback timeout from 500 to 1500
  echo 1500 > /proc/sys/vm/dirty_writeback_centisecs

  # Enable Laptop Mode - this one is a bonus
  echo "5" > /proc/sys/vm/laptop_mode
}

stop()
{
  # audio codec sleep off
  echo 0 > /sys/module/snd_hda_intel/parameters/power_save

  # APLM (Aggressive Link Power Management) on all SATA ports to maximum performance
  for i in /sys/class/scsi_host/host[012345]/link_power_management_policy ; do echo max_performance > ${i};done

  # PCI device power status to on
  find /sys/bus/pci/devices/*/power/control | while read LINE; do echo 'on' > ${LINE}; done
  # i2c device power status to auto
  find /sys/bus/i2c/devices/*/power/control | while read LINE; do echo 'on' > ${LINE}; done

  # auto-suspend for all USB devices
  # this is on auto after boot for most but not the bluetooth controller and it's hub (5-1 and 5-2)
  # so set just these two to on again
  for i in /sys/bus/usb/devices/5-?/power/control ; do echo on > ${i};done

  # NMI watchdog off
  echo 1 > /proc/sys/kernel/nmi_watchdog

  # WOL (Wake on Lan) Wake on MagicPacket™
  ethtool -s p2p1 wol g

  # change VM writeback timeout from 500 to 1500
  echo 500 > /proc/sys/vm/dirty_writeback_centisecs

  # Enable Laptop Mode - this one is a bonus
  echo "0" > /proc/sys/vm/laptop_mode
}

status()
{
  # audio codec
  echo -n "/sys/module/snd_hda_intel/parameters/power_save "
  cat /sys/module/snd_hda_intel/parameters/power_save

  # APLM (Aggressive Link Power Management) on all SATA ports
  for i in /sys/class/scsi_host/host[012345]/link_power_management_policy ; do echo -n "${i} " ; cat ${i};done

  # Device power savings
  # way too much output to be quickly human-readable
  #find /sys/bus/{pci,i2c}/devices/*/power/control | while read LINE; do echo -n "${LINE} " ; cat ${LINE}; done

  # auto-suspend for all USB devices
  # way too much output to be quickly human-readable
  #for i in /sys/bus/usb/devices/*/power/control ; do echo -n "${i} " ; cat ${i};done

  # NMI watchdog
  echo -n "/proc/sys/kernel/nmi_watchdog "
  cat /proc/sys/kernel/nmi_watchdog

  # WOL (Wake on Lan) and opther options
  echo -n "Wired betwork WOL status: "
  ethtool p2p1 | grep ^[[:space:]]Wake-on

  # change VM writeback timeout from 500 to 1500
  echo -n "/proc/sys/vm/dirty_writeback_centisecs "
  cat /proc/sys/vm/dirty_writeback_centisecs

  # Enable Laptop Mode - this one is a bonus
  echo -n "/proc/sys/vm/laptop_mode "
  cat /proc/sys/vm/laptop_mode
}

# command not found
RETVAL=127

case "$1" in
  start)
    start
    RETVAL=0
  ;;
  stop)
    stop
    RETVAL=0
  ;;
  status)
    status
    RETVAL=0
  ;;
  *)
    usage
    RETVAL=1
esac

exit $RETVAL