diff -Nru tlp-0.3.9/48tlp-rdw-lock tlp-0.4/48tlp-rdw-lock --- tlp-0.3.9/48tlp-rdw-lock 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/48tlp-rdw-lock 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -#!/bin/sh -# tlp-rdw - lock events during suspend/hibernate cycle -# -# Copyright (c) 2013 Thomas Koch -# This software is licensed under the GPL v2 or later. - -. "${PM_FUNCTIONS}" - -readonly LIBDIRS="/usr/lib/tlp-pm /usr/lib64/tlp-pm" -readonly LIBS="tlp-functions" - -for libdir in $LIBDIRS; do [ -d $libdir ] && break; done -[ -d $libdir ] || exit 0 - -for lib in $LIBS; do - [ -f $libdir/$lib ] || exit 0 - . $libdir/$lib -done - -read_defaults || exit 0 - -[ "$TLP_ENABLE" = "1" ] || exit 0 - -echo_debug "pm" "48tlp-rdw-lock.$1" - -case $1 in - hibernate|suspend) - set_run_flag $LOCK_RDW - ;; - - thaw|resume) - reset_run_flag $LOCK_RDW - ;; - - *) exit $NA - ;; -esac - -exit 0 diff -Nru tlp-0.3.9/49bay tlp-0.4/49bay --- tlp-0.3.9/49bay 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/49bay 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -#!/bin/sh -# tlp - disable Ultrabay on resume if it was disabled on the preceding suspend -# -# Copyright (c) 2013 Thomas Koch -# This software is licensed under the GPL v2 or later. - -. "${PM_FUNCTIONS}" - -readonly LIBDIRS="/usr/lib/tlp-pm /usr/lib64/tlp-pm" -readonly LIBS="tlp-functions" -readonly STATE=tp_bay_off - -get_bay () { - dock=$(grep -l ata_bay /sys/devices/platform/dock.?/type) - dock=${dock%%/type} - if [ ! -d "$dock" ]; then - dock="" - fi -} - -suspend_bay () { - get_bay - if [ -n "$dock" ]; then - if [ -e $dock/docked ]; then - if [ "$(cat $dock/docked)" = "0" ]; then - savestate $STATE 1 - echo_debug "pm" "49bay.suspend: bay=off" - else - echo_debug "pm" "49bay.suspend: bay=on" - fi - fi - fi -} - -resume_bay () { - local cnt - local rc - - state_exists $STATE || return - [ "$(restorestate $STATE)" = "1" ] || return - - get_bay - if [ -n "$dock" ]; then - if [ -e $dock/undock ]; then - cnt=5 - rc=1 - until [ $rc = 0 -o $cnt = 0 ]; do - cnt=$((cnt - 1)) - echo 1 > $dock/undock - rc=$? - [ $rc = 0 ] || sleep 0.5 - done - echo_debug "pm" "49bay.resume_bayoff: rc=$rc" - return 0 - fi - fi -} - -for libdir in $LIBDIRS; do [ -d $libdir ] && break; done -[ -d $libdir ] || exit 0 - -for lib in $LIBS; do - [ -f $libdir/$lib ] || exit 0 - . $libdir/$lib -done - -read_defaults || exit 0 - -[ "$TLP_ENABLE" = "1" ] && [ "$BAY_POWEROFF_ON_BAT" = "1" ] || exit 0 - -echo_debug "pm" "49bay.$1" - -# MAIN -case $1 in - hibernate|suspend) - suspend_bay - ;; - - thaw|resume) - resume_bay - ;; - - *) exit $NA - ;; -esac - -exit 0 - diff -Nru tlp-0.3.9/49tlp tlp-0.4/49tlp --- tlp-0.3.9/49tlp 1970-01-01 00:00:00.000000000 +0000 +++ tlp-0.4/49tlp 2013-09-19 05:54:22.000000000 +0000 @@ -0,0 +1,22 @@ +#!/bin/sh +# tlp - handle suspend/hibernate/resume tasks +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. + +. "${PM_FUNCTIONS}" + +case $1 in + hibernate|suspend) + tlp suspend + ;; + + thaw|resume) + tlp resume + ;; + + *) exit $NA + ;; +esac + +exit 0 diff -Nru tlp-0.3.9/49wwan tlp-0.4/49wwan --- tlp-0.3.9/49wwan 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/49wwan 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -#!/bin/sh -# tlp - restore ThinkPad wwan state after suspend / hibernate -# -# Copyright (c) 2013 Thomas Koch -# This software is licensed under the GPL v2 or later. - -. "${PM_FUNCTIONS}" - -readonly LIBDIRS="/usr/lib/tlp-pm /usr/lib64/tlp-pm" -readonly LIBS="tlp-functions tlp-rf-func" - -suspend_device () { - local state - - state=$(cat $2) - echo 0 > $2 # workaround: switch off before suspend - savestate $1 $state - echo_debug "pm" "49wwan.suspend wwan=$state" -} - -resume_device () { - state_exists $1 || return - restorestate $1 > $2 - echo_debug "pm" "49wwan.resume wwan=$(cat $2)" -} - -for libdir in $LIBDIRS; do [ -d $libdir ] && break; done -[ -d $libdir ] || exit 0 - -for lib in $LIBS; do - [ -f $libdir/$lib ] || exit 0 - . $libdir/$lib -done - -read_defaults || exit 0 - -[ "$TLP_ENABLE" = "1" ] || exit 0 - -echo_debug "pm" "49wwan.$1" - -get_devc wwan -[ -n "$devc" ] || exit 0 - -case $1 in - hibernate|suspend) - suspend_device tp_wwan $devc - ;; - - thaw|resume) - resume_device tp_wwan $devc - ;; - - *) exit $NA - ;; -esac - -exit 0 diff -Nru tlp-0.3.9/COPYING tlp-0.4/COPYING --- tlp-0.3.9/COPYING 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/COPYING 2013-09-19 05:54:22.000000000 +0000 @@ -1,19 +1,19 @@ Author: - Thomas Koch + Thomas Koch Copyright: Copyright (c) 2013 Thomas Koch - + Some code and descriptions were adapted from: - - laptop-mode-tools - Copyright (c) 2004 by Bart Samwel, Kiko Piris, Micha Feigin, + - laptop-mode-tools + Copyright (c) 2004 by Bart Samwel, Kiko Piris, Micha Feigin, Andrew Morton, Herve Eychenne, Dax Kelson, Jan Topinski - http://thinkwiki.org Thinkpad ACPI Battery Control (tpacpi-bat): - Copyright (c) 2011 Elliot Wolk + Copyright (c) 2011 Elliot Wolk License: diff -Nru tlp-0.3.9/Makefile tlp-0.4/Makefile --- tlp-0.3.9/Makefile 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/Makefile 2013-09-19 05:54:22.000000000 +0000 @@ -14,13 +14,13 @@ # you have to change constant definitions in scripts too! CONFFILE = $(DESTDIR)/etc/default/tlp -all: - @/bin/true +all: + @true clean: - @/bin/true - -install-tlp: + @true + +install-tlp: # Package tlp install -D -m 755 tlp $(SBIN)/tlp install -D -m 755 tlp-rf $(BIN)/bluetooth @@ -39,23 +39,20 @@ install -D -m 644 tlp.rules $(ULIB)/rules.d/40-tlp.rules [ -f $(CONFFILE) ] || install -D -m 644 default $(CONFFILE) install -D -m 755 tlp.init $(DESTDIR)/etc/init.d/tlp - install -D -m 755 zztlp $(PLIB)/power.d/zztlp - install -D -m 755 49wwan $(PLIB)/sleep.d/49wwan - install -m 755 49bay $(PLIB)/sleep.d/49bay + install -D -m 755 49tlp $(PLIB)/sleep.d/49tlp install -D -m 644 thinkpad-radiosw $(ACPI)/events/thinkpad-radiosw install -m 755 thinkpad-radiosw.sh $(ACPI)/ install -D -m 644 tlp.bash_completion $(DESTDIR)/etc/bash_completion.d/tlp -install-rdw: +install-rdw: # Package tlp-rdw install -D -m 644 tlp-rdw.rules $(ULIB)/rules.d/40-tlp-rdw.rules install -D -m 755 tlp-rdw-udev $(ULIB)/tlp-rdw-udev install -D -m 755 tlp-rdw-nm $(NMDSP)/99tlp-rdw-nm - install -D -m 755 48tlp-rdw-lock $(PLIB)/sleep.d/48tlp-rdw-lock install: install-tlp install-rdw -uninstall-tlp: +uninstall-tlp: # Package tlp rm $(SBIN)/tlp rm $(BIN)/bluetooth @@ -74,19 +71,16 @@ rm $(ULIB)/rules.d/40-tlp.rules rm $(DESTDIR)/etc/init.d/tlp rm $(DESTDIR)/etc/network/if-up.d/tlp-ifup - rm $(PLIB)/power.d/zztlp - rm $(PLIB)/sleep.d/49wwan - rm $(PLIB)/sleep.d/49bay + rm $(PLIB)/sleep.d/49tlp rm $(ACPI)/events/thinkpad-radiosw rm $(ACPI)/thinkpad-radiosw.sh rm $(DESTDIR)/etc/bash_completion.d/tlp -uninstall-rdw: +uninstall-rdw: # Package tlp-rdw rm $(ULIB)/rules.d/40-tlp-rdw.rules rm $(ULIB)/tlp-rdw-udev rm $(NMDSP)/99tlp-rdw-nm - rm $(PLIB)/sleep.d/48tlp-rdw-lock - + uninstall: uninstall-tlp uninstall-rdw - + diff -Nru tlp-0.3.9/README tlp-0.4/README --- tlp-0.3.9/README 2013-05-02 17:17:07.000000000 +0000 +++ tlp-0.4/README 2013-09-19 05:54:22.000000000 +0000 @@ -1,4 +1,4 @@ -TLP README - 02.05.2013 +TLP README - 19.08.2013 TLP implements advanced power management for Linux. TLP is a pure command line tool with automated background tasks. It does not contain a GUI. @@ -12,6 +12,7 @@ - PCIe active state power management (PCIe ASPM) - Kernel 2.6.35 and above - Runtime power management for PCI(e) bus devices - Kernel 2.6.35 and above - Radeon graphics KMS power management - Kernel 2.6.35 and above, not fglrx +- Radeon graphics dynamic power management - Kernel 3.11 and above, not fglrx - Wifi power saving mode - depending on kernel/driver - Power off optical drive in drive bay (on battery) @@ -29,7 +30,7 @@ - Recalibrate battery - ThinkPads only All TLP settings are stored in /etc/default/tlp. The default configuration -provides optimized power saving out of the box. +provides optimized power saving out of the box. Read the the full documentation at: - http://linrunner.de/tlp diff -Nru tlp-0.3.9/debian/changelog tlp-0.4/debian/changelog --- tlp-0.3.9/debian/changelog 2013-09-19 19:51:18.000000000 +0000 +++ tlp-0.4/debian/changelog 2013-09-19 19:51:19.000000000 +0000 @@ -1,4 +1,61 @@ -tlp (0.3.9-1~precise) precise; urgency=low +tlp (0.4-1~precise) precise; urgency=low + + * Features + - New radeon dynamic power management (dpm); needs Kernel >= 3.11 + (Pali Rohár) + - RUNTIME_PM_BLACKLIST: exclude listed pci(e) device addresses + from Runtime PM (wofritz) + - USB_BLACKLIST_WWAN: exclude wwan devices from usb autosuspend; + works for ids 05c6:* 0bdb:* 1199:* only + - Apply ac settings for faster shutdown + + -- Thomas Koch Thu, 17 Sep 2013 07:51:42 +0200 + +tlp (0.3.11-1) unstable; urgency=low + + *** Testing version (for Arch Linux) *** + + * Bugfixes + - Issue #42: + - Remove dependency to on_ac_power (part of pm-utils in + Arch Linux) + - Fix udev rule to detect power source change ac - bat + + * Packaging + - Pull request #40: systemd: start tlp.service after + local-fs.target instead of graphical.target (cprussin) + + -- Thomas Koch Tue, 10 Sep 2013 21:32:44 +0200 + +tlp (0.3.10.1-1) unstable; urgency=low + + *** Testing version (for Arch Linux) *** + + * Architecture + - Issue #36: detect change of power source via udev instead of being + called by pm-powersave + - Handle suspend/resume w/o pm-utils in systemd environments: + - Encapsulate suspend/resume tasks as a tlp subcommand + - Add tlp-sleep.service to call tlp suspend/resume + - Remove 48tlp-rdw.lock because it doesn't work as expected + + * Features + - Issue #31: detect and use intel_pstate driver to control + turbo mode (ValdikSS) + - Disable wol for all ethernet devices i.e. non-eth0 (blafoo) + - tpacpi-bat: + - merge upstream support for ThinkPad T430u, Edge E335/E530 + + * Bugfixes + - Issue #28: do not touch dirty_(background_)ratio anymore, + i.e. revert setting to kernel defaults + + * Packaging + - debian/control: remove ${shlibs:Depends} + + -- Thomas Koch Sun, 17 Aug 2013 11:51:17 +0200 + +tlp (0.3.9-1) lucid; urgency=low * Features - tpacpi-bat: @@ -37,7 +94,7 @@ - Rename tlp-init.service to tlp.service - postinst/postrm: restart acpid for thinkpad-radiosw event - Move smartmontools to "recommends:" - + * Features - New options CPU_BOOST_ON_* for cpu turbo boost (Linux 3.7 or later) - New option DEVICES_TO_ENABLE_ON_RADIOSW to enable only selected radios @@ -72,7 +129,7 @@ tlp (0.3.7.1-1) lucid; urgency=low * Bug fixes - - #39: tlp-stat: /sys/devices/platform/coretemp.0/temp1_input + - #39: tlp-stat: /sys/devices/platform/coretemp.0/temp1_input does not exist (Laurent Bonnaud) -- Thomas Koch Fri, 17 Aug 2012 17:51:00 +0200 @@ -90,7 +147,7 @@ Ivy Bridge models (X230/T430/...) - DEVICES_TO_ENABLE_ON_SHUTDOWN to prevent other operating systems from missing radios - - DEVICES_TO_ENABLE_ON_STARTUP + - DEVICES_TO_ENABLE_ON_STARTUP - tlp-stat: - show TRIM capabilty for SSDs - add SMART attributes (179, 241) @@ -126,9 +183,9 @@ - Set cpu scaling governor and mix/max frequencies (Alex Lochmann) - tlp-stat: add smart attributes for samsung ssd - tlp-stat: show settings - * Packaging + * Packaging - postinst/postrm: - - disable power.d/harddrive, pci_devices, readahead, + - disable power.d/harddrive, pci_devices, readahead, usb_bluetooth (Package pm-utils, Ubuntu 12.04) - disable conflicting upstart jobs (Package rfkill, Ubuntu 12.04) - split package @@ -152,9 +209,9 @@ * Bug Fixes - #27: tlp-stat complains about missing /proc/acpi/ibm/thermal and start_charge_thresh on X220/T420(s) et al. (Esc) - - Check if start_charge_thresh, stop_charge_thresh, force_discharge + - Check if start_charge_thresh, stop_charge_thresh, force_discharge are writable - - #28: further mitigate race with gdm when disabling radios + - #28: further mitigate race with gdm when disabling radios in init script (blackbox) - #29: tlp-stat: remove smartctl garbage output (SirVival) - #30: supress dmidecode error output (kristatos) @@ -163,7 +220,7 @@ - Start upowerd in init script - #32: show error message suggesting to uninstall latop-mode-tools if present (Kuzoku) - + -- Thomas Koch Mon, 19 Dec 2011 21:40:00 +0100 tlp (0.3.4-1) lucid; urgency=low @@ -192,7 +249,7 @@ tlp (0.3.2-2) lucid; urgency=low - * Bug Fix + * Bug Fix - #23: init.d script not linked/unlinked by install/purge (LePatron) -- Thomas Koch Mon, 11 Jul 2011 22:05:00 +0200 @@ -200,7 +257,7 @@ tlp (0.3.2-1) lucid; urgency=low * Bug Fix - - #22: runtime pm causes shutdown to fail, reboots instead (fabio) + - #22: runtime pm causes shutdown to fail, reboots instead (fabio) disabled by default -- Thomas Koch Mon, 04 Jul 2011 20:25:00 +0200 @@ -215,7 +272,7 @@ - runtime pm (ccyx) - set/disable hard disk spindown timeout (enrico65, hausmarke86) - use power/autosuspend_delay_ms (kernel >= 2.6.38) - - tlp-stat: now runs with root privilege only, + - tlp-stat: now runs with root privilege only, show intel ssd specific smart values, check for pcie aspm disabled by kernel - bluetooth/wifi/wwan: when using rfkill, check for root privilege @@ -224,7 +281,7 @@ * Bug Fixes - #18: tlp start (ac): incorrect ouptut "started in bat mode" fixed (yatpu) - - #19: tlp-stat: incorrect wifi power mgmt detection for + - #19: tlp-stat: incorrect wifi power mgmt detection for wl driver (DrPaulaner) - #20: handle disabled pcie aspm in kernel 2.6.39 gracefully (Schmitti, g3eB4Y) @@ -244,11 +301,11 @@ tlp (0.3.0-1) lucid; urgency=low * Bug Fixes - - Switch wwan off before suspend + - Switch wwan off before suspend (workaround for kernel/network-manager quirk) * Features - Specify DISK_DEVICES with id's from /dev/disk/by-id (egalus) - - tlp diskid: show disk id's + - tlp diskid: show disk id's - DISK_IOSCHED: set i/o scheduler (egalus) - PCIe ASPM - Do not set START_CHARGE_THRESH on tp_smapi-capable ThinkPad Edge @@ -277,7 +334,7 @@ - usb autosuspend/tlp-stat not showing all usb devices - #15: tlp-stat abort w/ ipw2200 (agape) - #16: PHC_CONTROL written to all cpus/cores (pumpe et al.) - + * Features - charge thresholds: new command tlp setcharge (crishu) - DEVICES_TO_DISABLE_ON_STARTUP: handle bluetooth in upstart job @@ -290,9 +347,9 @@ * Bugfixes - tlp-stat: error checking get_ctrl_device, tlp-stat batinfo (mikar) - - #14: delayed login window (greeter) w/ USB_AUTOSUSPEND=1 - (steveurkel, fishmac, saubaer) - + - #14: delayed login window (greeter) w/ USB_AUTOSUSPEND=1 + (steveurkel, fishmac, saubaer) + * Features - tlp fullcharge - set_charge_thresholds on startup only, not on shutdown @@ -306,7 +363,7 @@ * Bugfix/Package change - Conflicts: pm-utils-powersave-policy - - powersave-policy-sata-link-power breaks pm-powersave w/ sata + - powersave-policy-sata-link-power breaks pm-powersave w/ sata controllers in compatible mode an pata controllers (LP# 514881). - TLP implements same functionality as conflicting package anyway ... @@ -316,7 +373,7 @@ * Bugfixes - #11: excessive boottime (+40s) w/ USB_SUSPEND=1 & USB_BLACKLIST="" - - tlp-stat: display hard disk w/o apm as "none/disabled" + - tlp-stat: display hard disk w/o apm as "none/disabled" * Features - bluetooth/wifi/wwan: toggle (#12, thatgui) diff -Nru tlp-0.3.9/debian/control tlp-0.4/debian/control --- tlp-0.3.9/debian/control 2013-09-19 19:51:18.000000000 +0000 +++ tlp-0.4/debian/control 2013-09-19 19:51:19.000000000 +0000 @@ -8,7 +8,7 @@ Package: tlp Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, pm-utils +Depends: ${misc:Depends}, pm-utils Recommends: tlp-rdw, acpid, ethtool, smartmontools, wireless-tools Suggests: acpi-call, tp-smapi-dkms Conflicts: pm-utils-powersave-policy @@ -16,9 +16,9 @@ TLP implements advanced power management for Linux. TLP is a pure command line tool with automated background tasks. It does not contain a GUI. - + Package: tlp-rdw Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, network-manager, tlp +Depends: ${misc:Depends}, network-manager, tlp Description: Radio device wizard Switch radios upon network connect/disconnect and dock/undock. diff -Nru tlp-0.3.9/debian/copyright tlp-0.4/debian/copyright --- tlp-0.3.9/debian/copyright 2013-09-19 19:51:18.000000000 +0000 +++ tlp-0.4/debian/copyright 2013-09-19 19:51:19.000000000 +0000 @@ -8,8 +8,8 @@ License: GPL-2+ Comment: Some code and descriptions were adapted from: - - laptop-mode-tools - Copyright (c) 2004 by Bart Samwel, Kiko Piris, Micha Feigin, + - laptop-mode-tools + Copyright (c) 2004 by Bart Samwel, Kiko Piris, Micha Feigin, Andrew Morton, Herve Eychenne, Dax Kelson, Jan Topinski - http://thinkwiki.org @@ -22,7 +22,7 @@ License: GPL-2+ License: GPL-2+ - On Debian/Ubuntu systems, the full text of the GPL v2 can be found in + On Debian/Ubuntu systems, the full text of the GPL v2 can be found in `/usr/share/common-licenses/GPL-2'. License: GPL-3+ diff -Nru tlp-0.3.9/debian/rules tlp-0.4/debian/rules --- tlp-0.3.9/debian/rules 2013-09-19 19:51:18.000000000 +0000 +++ tlp-0.4/debian/rules 2013-09-19 19:51:19.000000000 +0000 @@ -13,18 +13,18 @@ build: # do nothing - -clean: + +clean: dh_testdir dh_testroot # add here commands to clean up after the build process. # $(MAKE) clean - dh_clean + dh_clean -tlp: +tlp: dh_testdir dh_testroot - dh_prep + dh_prep # install into debian/tlp. $(MAKE) DESTDIR=$(CURDIR)/debian/$@ install-tlp @@ -43,10 +43,10 @@ dh_md5sums -p$@ dh_builddeb -p$@ -tlp-rdw: +tlp-rdw: dh_testdir dh_testroot - dh_prep + dh_prep # install into debian/tlp-rdw. $(MAKE) DESTDIR=$(CURDIR)/debian/$@ install-rdw @@ -65,12 +65,12 @@ # Build architecture-independent files here. binary-indep: tlp tlp-rdw - + # Build architecture-dependent files here. -binary-arch: +binary-arch: # do nothing binary: binary-indep binary-arch # Run targets that don't result in corresponding files -.PHONY: clean tlp tlp-rdw binary-indep binary-arch binary +.PHONY: clean tlp tlp-rdw binary-indep binary-arch binary diff -Nru tlp-0.3.9/debian/tlp.init tlp-0.4/debian/tlp.init --- tlp-0.3.9/debian/tlp.init 2013-09-19 19:51:18.000000000 +0000 +++ tlp-0.4/debian/tlp.init 2013-09-19 19:51:19.000000000 +0000 @@ -1,5 +1,10 @@ #!/bin/sh +# tlp - system startup/shutdown +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. + ### BEGIN INIT INFO # Provides: tlp # Required-Start: $remote_fs $all @@ -17,7 +22,7 @@ force-reload|\ *) TLP=/usr/sbin/tlp - [ -x $TLP ] && $TLP init $1 upwr + [ -x $TLP ] && $TLP init $1 ;; esac diff -Nru tlp-0.3.9/debian/tlp.preinst tlp-0.4/debian/tlp.preinst --- tlp-0.3.9/debian/tlp.preinst 2013-09-19 19:51:18.000000000 +0000 +++ tlp-0.4/debian/tlp.preinst 2013-09-19 19:51:19.000000000 +0000 @@ -2,7 +2,6 @@ #DEBHELPER# # Remove obsolete conffiles -LASTVERSION_C1="0.2.8.900-0ubuntu1" # tlp.conf upstart job LASTVERSION_C2="0.3.5.900-1" # tlp-ifup LASTVERSION_C3="0.3.7.900-1" # tlp.desktop @@ -28,13 +27,9 @@ case "$1" in install|upgrade) if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then - dpkg-maintscript-helper rm_conffile /etc/init/tlp.conf $LASTVERSION_C1 -- "$@" dpkg-maintscript-helper rm_conffile /etc/network/if-up.d/tlp-ifup $LASTVERSION_C2 -- "$@" dpkg-maintscript-helper rm_conffile /etc/xdg/autostart/tlp.desktop $LASTVERSION_C3 -- "$@" else - if dpkg --compare-versions "$2" le "$LASTVERSION_C1"; then - rm_conffile tlp /etc/init.d/tlp; - fi if dpkg --compare-versions "$2" le "$LASTVERSION_C2"; then rm_conffile tlp /etc/network/if-up.d/tlp-ifup; fi diff -Nru tlp-0.3.9/default tlp-0.4/default --- tlp-0.3.9/default 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/default 2013-09-19 05:54:22.000000000 +0000 @@ -1,29 +1,29 @@ # ------------------------------------------------------------------------------ # tlp - Parameters for power save - + # Hint: some features are disabled by default, remove the leading # to enable them - + # Set to 0 to disable/1 to enable TLP TLP_ENABLE=1 - + # Seconds laptop mode has to to wait after the disk goes idle before doing a sync. # Non-zero value enables, zero disables laptop mode. DISK_IDLE_SECS_ON_AC=0 DISK_IDLE_SECS_ON_BAT=2 - + # Dirty page values (timeouts in secs). MAX_LOST_WORK_SECS_ON_AC=15 MAX_LOST_WORK_SECS_ON_BAT=60 # Select a cpu frequency scaling governor: ondemand/powersave/performance/conservative -# Important: +# Important: # - You *must* disable your distribution's governor settings or conflicts will occur # - ondemand is sufficient for *almost all* workloads, you should know what you're doing! #CPU_SCALING_GOVERNOR_ON_AC=ondemand #CPU_SCALING_GOVERNOR_ON_BAT=ondemand # Set the min/max frequency available for the scaling governor. -# Possible values strongly depend on your cpu. For available frequencies see +# Possible values strongly depend on your cpu. For available frequencies see # tlp-stat output, Section "+++ Processor". # Hint: Parameters are disabled by default, remove the leading # to enable them, # otherwise kernel default values are used. @@ -32,7 +32,7 @@ #CPU_SCALING_MIN_FREQ_ON_BAT=0 #CPU_SCALING_MAX_FREQ_ON_BAT=0 -# Set the cpu "turbo boost" feature: 0=disable / 1=allow +# Set the cpu "turbo boost" feature: 0=disable / 1=allow # Requires an Intel Core i processor and kernel 3.7 or later. # Important: # - This may conflict with your distribution's governor settings @@ -47,12 +47,12 @@ # Kernel NMI Watchdog # 0=disable (default, saves power) / 1=enable (for kernel debugging only) NMI_WATCHDOG=0 - + # Change CPU voltages aka "undervolting" - Kernel with PHC patch required # Freq:voltage pairs are written to /sys/devices/system/cpu/cpu0/cpufreq/phc_controls # CAUTION: only use this, if you thoroughly understand what you are doing! #PHC_CONTROLS="F:V F:V F:V F:V" - + # Hard disk devices, separate multiple devices with spaces (default: sda). # Devices can be specified by disk id too (lookup with: tlp diskid). DISK_DEVICES="sda sdb" @@ -71,10 +71,10 @@ #DISK_SPINDOWN_TIMEOUT_ON_AC="0 0" #DISK_SPINDOWN_TIMEOUT_ON_BAT="0 0" -# Select io scheduler for the disk devices: noop/deadline/cfq (Default: cfq) +# Select io scheduler for the disk devices: noop/deadline/cfq (Default: cfq) # Separate values for multiple devices with spaces. #DISK_IOSCHED="cfq cfq" - + # SATA aggressive link power management (ALPM): # min_power/medium_power/max_performance SATA_LINKPWR_ON_AC=max_performance @@ -82,7 +82,7 @@ # PCI Express Active State Power Management (PCIe ASPM): # default/performance/powersave -# Hint: needs kernel boot option pcie_aspm=force on some machines +# Hint: needs kernel boot option pcie_aspm=force on some machines PCIE_ASPM_ON_AC=performance PCIE_ASPM_ON_BAT=powersave @@ -91,22 +91,31 @@ # (Kernel >= 2.6.35 only, not with fglrx driver!) RADEON_POWER_PROFILE_ON_AC=high RADEON_POWER_PROFILE_ON_BAT=low - + +# New radeon dynamic power management method (dpm): battery/performance +# (Kernel >= 3.11 only, requires boot option radeon.dpm=1) +RADEON_DPM_STATE_ON_AC=performance +RADEON_DPM_STATE_ON_BAT=battery + +# New radeon dpm performance level: auto/low/high (auto is recommended) +RADEON_DPM_PERF_LEVEL_ON_AC=auto +RADEON_DPM_PERF_LEVEL_ON_BAT=auto + # WiFi power saving mode: 1=disable/5=enable # (Linux 2.6.32 and later, some adapters only!) WIFI_PWR_ON_AC=1 WIFI_PWR_ON_BAT=5 - + # Disable wake on lan: Y/N WOL_DISABLE=Y - + # Enable audio power saving for Intel HDA, AC97 devices (timeout in secs). # A value of 0 disables / >=1 enables power save. SOUND_POWER_SAVE=1 # Disable controller too (HDA only): Y/N SOUND_POWER_SAVE_CONTROLLER=Y -# Set to 1 to power off optical drive in UltraBay (ThinkPads only) +# Set to 1 to power off optical drive in UltraBay (ThinkPads only) # when running on battery. A value of 0 disables this Feature (Default). # Drive can be powered on again by releasing (and reinserting) the # eject lever or by pressing the disc eject button on newer models. @@ -114,25 +123,35 @@ BAY_POWEROFF_ON_BAT=0 # Optical drive device to power off (default sr0) BAY_DEVICE="sr0" - -# Runtime Power Management for pci(e) bus devices + +# Runtime Power Management for pci(e) bus devices # (Kernel >= 2.6.35 only): on=disable/auto=enable RUNTIME_PM_ON_AC=on RUNTIME_PM_ON_BAT=auto -# Runtime PM for *all* pci(e) bus devices: 0=disable / 1=enable +# Runtime PM for *all* pci(e) bus devices, expect backlisted ones: +# 0=disable / 1=enable # Warning: experimental option, could cause system instabilities RUNTIME_PM_ALL=0 +# Exclude pci(e) device adresses the following list from Runtime PM +# (separate with spaces). Use lspci to get the adresses (1st column). +#RUNTIME_PM_BLACKLIST="bb:dd.f 11:22.3 44:55.6" + # Set to 0 to disable/1 to enable usb autosuspend feature USB_AUTOSUSPEND=1 - + # Devices from the following list are excluded from usb autosuspend -# (separate with spaces). Use lsusb to get the id's. +# (separate with spaces). Use lsusb to get the ids. # Note: input devices (usbhid) are excluded automatically #USB_BLACKLIST="1111:2222 3333:4444" -# Set to 1 to disable autosuspend before shutdown/0 to do nothing +# WWAN devices are excluded from usb autosuspend: +# 0=do not exclude / 1=exclude +# Note: works for ids 05c6:* 0bdb:* 1199:* only +USB_BLACKLIST_WWAN=1 + +# Set to 1 to disable autosuspend before shutdown/0 to do nothing # (workaround for usb devices that cause shutdown problems) #USB_AUTOSUSPEND_DISABLE_ON_SHUTDOWN=1 @@ -141,13 +160,13 @@ # Hint: the parameters DEVICES_TO_DISABLE/ENABLE_ON_STARTUP/SHUTDOWN below # are ignored when this is enabled! RESTORE_DEVICE_STATE_ON_STARTUP=0 - + # Radio devices to disable on startup: bluetooth wifi wwan #DEVICES_TO_DISABLE_ON_STARTUP="bluetooth wifi wwan" # Radio devices to enable on startup: bluetooth wifi wwan #DEVICES_TO_ENABLE_ON_STARTUP="wifi" - + # Radio devices to disable on shutdown: bluetooth wifi wwan # (workaround for devices that are blocking shutdown) #DEVICES_TO_DISABLE_ON_SHUTDOWN="bluetooth wifi wwan" @@ -159,7 +178,7 @@ # Radio devices to enable when wireless radio switch is turned on: # bluetooth wifi wwan (Ubuntu + ThinkPad only) #DEVICES_TO_ENABLE_ON_RADIOSW="wifi wwan" - + # Battery charge thresholds (ThinkPad only, tp-smapi or acpi-call kernel module required) # Charging starts when the remaining capacity falls below the START_CHARGE_TRESH # value and stops when exceeding the STOP_CHARGE_TRESH value. @@ -180,12 +199,12 @@ # Hint: parameters are disabled by default, remove the leading # to enable them -# Radio devices to disable on connect +# Radio devices to disable on connect #DEVICES_TO_DISABLE_ON_LAN_CONNECT="wifi wwan" #DEVICES_TO_DISABLE_ON_WIFI_CONNECT="wwan" #DEVICES_TO_DISABLE_ON_WWAN_CONNECT="wifi" -# Radio devices to enable on disconnect +# Radio devices to enable on disconnect #DEVICES_TO_ENABLE_ON_LAN_DISCONNECT="wifi wwan" #DEVICES_TO_ENABLE_ON_WIFI_DISCONNECT="" #DEVICES_TO_ENABLE_ON_WWAN_DISCONNECT="" diff -Nru tlp-0.3.9/thinkpad-radiosw.sh tlp-0.4/thinkpad-radiosw.sh --- tlp-0.3.9/thinkpad-radiosw.sh 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/thinkpad-radiosw.sh 2013-09-19 05:54:22.000000000 +0000 @@ -10,7 +10,7 @@ for libdir in $LIBDIRS; do [ -d $libdir ] && break; done [ -d $libdir ] || exit 0 -for lib in $LIBS; do +for lib in $LIBS; do [ -f $libdir/$lib ] || exit 0 . $libdir/$lib done diff -Nru tlp-0.3.9/tlp tlp-0.4/tlp --- tlp-0.3.9/tlp 2013-04-12 11:10:47.000000000 +0000 +++ tlp-0.4/tlp 2013-09-19 05:54:22.000000000 +0000 @@ -1,5 +1,5 @@ #!/bin/sh -# tlp - adjust power settings +# tlp - adjust power settings # # Copyright (c) 2013 Thomas Koch # This software is licensed under the GPL v2 or later. @@ -15,7 +15,7 @@ exit 1 fi -for lib in $LIBS; do +for lib in $LIBS; do if [ ! -f $libdir/$lib ]; then echo "Error: missing function library \'$libdir/$lib\'." exit 1 @@ -23,9 +23,38 @@ . $libdir/$lib done +# --- Subroutines +apply_common_settings () { # apply settings common to all modes + # $1: 0=ac mode, 1=battery mode + load_tp_modules + + set_laptopmode $1 + set_dirty_parms $1 + set_scaling_governor $1 + set_scaling_min_max_freq $1 + set_cpu_boost_all $1 + set_sched_powersave $1 + set_nmi_watchdog + set_phc_controls $1 + set_disk_apm_level $1 + set_disk_spindown_timeout $1 + set_disk_io_sched + set_sata_link_power $1 + set_pcie_aspm $1 + set_radeon_profile $1 + set_wifi_power_mode $1 + disable_wake_on_lan $1 + set_sound_power_mode $1 + set_runtime_pm $1 + + return 0 +} + # --- MAIN read_defaults check_tlp_enabled || exit 1 +add_sbin2path + check_laptop_mode_tools || exit 2 # get cmd line args @@ -33,32 +62,53 @@ mode2=$(echo $2 | tr "[:upper:]" "[:lower:]") mode3=$(echo $3 | tr "[:upper:]" "[:lower:]") -echo_debug "run" "+++ mode=$mode $mode2 $mode3" -echo_debug "path" "PATH=$PATH" +# get current power state +get_power_state +pwrmode=$? + +modedebug=$mode +[ -n "$mode2" ] && modedebug="$modedebug $mode2" +[ -n "$mode3" ] && modedebug="$modedebug $mode3" + +echo_debug "run" "+++ mode=$modedebug ($TLPVER) ++++++++++++++++++++++++++++++++++++++++" + +if [ -n "$addpath" ]; then + echo_debug "path" "PATH=$oldpath[$addpath]" +else + echo_debug "path" "PATH=$oldpath" +fi + +if [ $pwrmode -eq 1 ]; then + echo_debug "run" "power_source=bat" +else + echo_debug "run" "power_source=ac" +fi + case "$mode" in init) # system initialization/shutdown: sysv, upstart, systemd, ... + check_root + case $mode2 in start|restart|force-reload) echo -n "Loading tp-smapi kernel module..." load_tp_modules echo "done. " - + init_radio_devices start - + echo -n "Setting battery charge thresholds..." set_charge_thresholds echo "done." - # wake upowerd only if present & arg "upwr" is given - if cmd_exists $UPWR && [ "$mode3" = "upwr" ]; then - echo -n "Starting upowerd..." - $UPWR -e > /dev/null 2>&1 - echo "done." - echo_debug "run" "upower_start" - fi + # apply settings + echo -n "Applying power save settings..." + apply_common_settings $pwrmode + [ "$pwrmode" = "1" ] && poweroff_drivebay 0 + [ "$X_TLP_USB_MODE" = "1" ] && set_usb_suspend 0 auto + echo "done." ;; - + stop) init_radio_devices stop @@ -67,9 +117,14 @@ set_usb_suspend 0 on echo "done." fi - + # remove usb startup flag [ -f $USB_DONE ] && rm $USB_DONE + + # apply ac settings for faster shutdown + echo -n "Applying power save settings..." + apply_common_settings 0 + echo "done." ;; *) @@ -79,99 +134,66 @@ esac ;; - start) # set start power mode depending on state + auto|start) # set start power mode depending on state check_root - get_power_state - pwr=$? - load_tp_modules - set_laptopmode $pwr - set_dirty_parms $pwr - set_scaling_governor $pwr - set_scaling_min_max_freq $pwr - set_cpu_boost_all $pwr - set_sched_powersave $pwr - set_nmi_watchdog - set_phc_controls $pwr - set_disk_apm_level $pwr - set_disk_spindown_timeout $pwr - set_disk_io_sched - set_sata_link_power $pwr - set_pcie_aspm $pwr - set_radeon_profile $pwr - set_wifi_power_mode $pwr - disable_wake_on_lan $pwr - set_sound_power_mode $pwr - set_runtime_pm $pwr - set_usb_suspend 0 auto - set_charge_thresholds - [ "$pwr" = "1" ] && poweroff_drivebay 0 - - echo_started_mode $pwr + apply_common_settings $pwrmode + [ "$pwrmode" = "1" ] && poweroff_drivebay 0 + + if [ "$mode" = "start" ]; then + set_usb_suspend 0 auto + set_charge_thresholds + fi + + echo_started_mode $pwrmode ;; true|bat*) # set battery power mode check_root - load_tp_modules - set_laptopmode 1 - set_dirty_parms 1 - set_scaling_governor 1 - set_scaling_min_max_freq 1 - set_cpu_boost_all 1 - set_sched_powersave 1 - set_nmi_watchdog - set_phc_controls 1 - set_disk_apm_level 1 - set_disk_spindown_timeout 1 - set_disk_io_sched - set_sata_link_power 1 - set_pcie_aspm 1 - set_radeon_profile 1 - set_wifi_power_mode 1 - disable_wake_on_lan 1 - set_sound_power_mode 1 - set_runtime_pm 1 + apply_common_settings 1 + [ "$X_TLP_USB_MODE" = "1" ] && set_usb_suspend 0 auto poweroff_drivebay 0 - + echo_started_mode 1 ;; - + false|ac) # set ac power mode check_root - load_tp_modules - set_laptopmode 0 - set_dirty_parms 0 - set_scaling_governor 0 - set_scaling_min_max_freq 0 - set_cpu_boost_all 0 - set_sched_powersave 0 - set_nmi_watchdog - set_phc_controls 0 - set_disk_apm_level 0 - set_disk_spindown_timeout 0 - set_disk_io_sched - set_sata_link_power 0 - set_pcie_aspm 0 - set_radeon_profile 0 - set_wifi_power_mode 0 - disable_wake_on_lan 0 - set_sound_power_mode 0 - set_runtime_pm 0 - [ "$X_TLP_USB_MODE" = "1" ] && enable_usb_suspend 0 - + apply_common_settings 0 + + [ "$X_TLP_USB_MODE" = "1" ] && set_usb_suspend 0 auto + echo_started_mode 0 ;; + suspend) # handle suspend/hibernate + check_root + save_device_states "wwan" + suspend_drivebay + + apply_common_settings 0 + ;; + + resume) # handle resume + check_root + restore_device_states + resume_drivebay + + get_power_state + pwrmode=$? + apply_common_settings $pwrmode + ;; + usb) # Enable usb autosuspend check_root set_usb_suspend 1 auto ;; - + bayoff) # power off drive bay check_root poweroff_drivebay 1 ;; - + setcharge) # set charge thresholds (temporarily) check_root load_tp_modules @@ -195,14 +217,14 @@ load_tp_modules discharge_battery $2 ;; - + recalibrate) # recalibrate battery, i.e. discharge and charge to 100% check_root load_tp_modules setcharge_battery 96 100 $2 discharge_battery $2 - ;; - + ;; + stat) # show status shift tlp-stat $* @@ -216,10 +238,10 @@ fi done } | sort ;; - - *) + + *) echo "Error: unknown command \"$mode\"." 1>&2 - echo "Usage: tlp start|true|bat|false|ac|wifi|usb|bayoff|discharge|setcharge|fullcharge|recalibrate|stat|diskid" 1>&2 + echo "Usage: tlp start|true|bat|false|ac|usb|bayoff|discharge|setcharge|fullcharge|recalibrate|stat|diskid" 1>&2 ;; esac diff -Nru tlp-0.3.9/tlp-functions tlp-0.4/tlp-functions --- tlp-0.3.9/tlp-functions 2013-05-02 17:17:07.000000000 +0000 +++ tlp-0.4/tlp-functions 2013-09-19 05:54:22.000000000 +0000 @@ -11,12 +11,11 @@ # ---------------------------------------------------------------------------- # Constants -readonly TLPVER="0.3.9" +readonly TLPVER="0.4" readonly CONFFILE=/etc/default/tlp readonly RUNDIR=/var/run/tlp -readonly ACPWR=on_ac_power readonly ETHTOOL=ethtool readonly HDPARM=hdparm readonly IWC=iwconfig @@ -27,7 +26,6 @@ readonly LAPMODE=laptop_mode readonly NMCLI=nmcli readonly NMTOOL=nm-tool -readonly UPWR=upower readonly TPACPIBAT=$libdir/tpacpi-bat # libdir is initialized by main program @@ -38,31 +36,45 @@ readonly I915D=/sys/module/i915/parameters readonly DMID=/sys/class/dmi/id/ readonly CPU_BOOST_ALL_CTRL=/sys/devices/system/cpu/cpufreq/boost +readonly INTEL_PSTATED=/sys/devices/system/cpu/intel_pstate +readonly CPU_TURBO_PSTATE=$INTEL_PSTATED/no_turbo readonly USBD=/sys/bus/usb/devices readonly USB_TIMEOUT=2 readonly USB_TIMEOUT_MS=2000 +readonly USB_WWAN_VENDORS="0bdb 05c6 1199" readonly USB_DONE=usb_done readonly LOCK_RDW=lock.rdw readonly TPMODULES="thinkpad_acpi tp_smapi coretemp acpi_call" +readonly STATEDIR="/var/lib/tlp" +readonly RFSTATEFILE=$STATEDIR/rfkill-saved +readonly BAYSTATEFILE=$STATEDIR/bay-saved # ---------------------------------------------------------------------------- # Functions # --- Tests -patinstr () { # test if pattern matches part of target -- $1: pattern, $2: target - [ -n "$1" -a -n "$2" -a -z "${2##*$1*}" ] - return $? +wordinlist () { # test if word in list + # $1: word, $2: whitespace-separated list of words + local word + + if [ -n "${1-}" ]; then + for word in ${2-}; do + [ "${word}" != "${1}" ] || return 0 # exact match + done + fi + + return 1 # no match } -echo_debug () { # write debug msg if tag matches -- $1: tag; $2: msg; +echo_debug () { # write debug msg if tag matches -- $1: tag; $2: msg; [ "$nodebug" = "1" ] && return 0 - - if patinstr "$1" "$TLP_DEBUG"; then + + if wordinlist "$1" "$TLP_DEBUG"; then $LOGGER -p debug -t "tlp[$$,$PPID]" "$2" fi } @@ -71,10 +83,10 @@ command -v $1 > /dev/null 2>&1 } -check_sysfs () { # check if sysfile exists -- $1: routine; $2: sysfs path - if patinstr "sysfs" "$TLP_DEBUG"; then +check_sysfs () { # check if sysfile exists -- $1: routine; $2: sysfs path + if wordinlist "sysfs" "$TLP_DEBUG"; then if [ ! -e $2 ]; then - $LOGGER -p debug -t "tlp[$$]" "$1:$2 nonexistent" + $LOGGER -p debug -t "tlp[$$,$PPID]" "$1: $2 nonexistent" fi fi } @@ -92,7 +104,7 @@ check_tlp_enabled () { # check if TLP is enabled in config file # rc: 0=disabled/1=enabled - + if [ ! "$TLP_ENABLE" = "1" ]; then echo "Error: TLP power save is disabled. Set TLP_ENABLE=1 in $CONFFILE." 1>&2 return 1 @@ -106,7 +118,7 @@ echo "Error: TLP power save is disabled because laptop-mode-tools is installed." 1>&2 echo " Please uninstall laptop-mode-tools." 1>&2 echo 1>&2 - echo_debug "pm" "check_laptop_mode_tools: yes" + echo_debug "pm" "check_laptop_mode_tools: yes" return 1 else return 0 @@ -119,6 +131,35 @@ [ -d /sys/devices/platform/thinkpad_acpi ] } +# --- PATH +add_sbin2path () { # check if /sbin /usr/sbin in $PATH, otherwise add them + # retval: $PATH, $oldpath, $addpath + local sp + + oldpath="$PATH" + addpath="" + + for sp in /usr/sbin /sbin; do + if [ -d $sp ] && [ ! -h $sp ]; then + # dir exists and is not a symlink + case ":$PATH:" in + *":$sp:"*) # $sp already in $PATH + ;; + + *) # $sp not in $PATH, add it + addpath="$addpath:$sp" + ;; + esac + fi + done + + if [ -n "$addpath" ]; then + export PATH="${PATH}${addpath}" + fi + + return 0 +} + # --- Configuration read_defaults () { # read config file @@ -141,7 +182,7 @@ # load modules, ignore any errors for mod in $TPMODULES; do - $MODPRO $mod > /dev/null 2>&1 + $MODPRO $mod > /dev/null 2>&1 done return 0 } @@ -161,15 +202,31 @@ dmirslt="$ds" fi done - + return 0 } # --- Power Source get_power_state () { # get current power source -- rc: 0=ac, 1=battery - $ACPWR - return $? + # Adapted from pm-utils' on_ac_power + local psrc + local rc=1 # battery is default when no ac is available + + for psrc in /sys/class/power_supply/*; do + if [ -d "$psrc" ] && [ -r "$psrc/type" ] ; then + if [ "$(cat $psrc/type 2> /dev/null)" = "Mains" ]; then + if [ -r "$psrc/online" ]; then + if [ "$(cat $psrc/online 2> /dev/null)" = "1" ]; then + rc=0 + break + fi + fi + fi + fi + done + + return $rc } echo_started_mode () { # print operation mode -- $1: 0=ac mode, 1=battery mode @@ -178,7 +235,7 @@ else echo "TLP started in battery mode." fi - + return 0 } @@ -186,14 +243,14 @@ set_run_flag () { # set flag -- $1: flag name local rc - + [ -d $RUNDIR ] || mkdir $RUNDIR if [ -d $RUNDIR ]; then touch $RUNDIR/$1 rc=$? echo_debug "lock" "set_run_flag.touch: $1; rc=$rc" - + return $rc else # mkdir failed @@ -209,33 +266,33 @@ else echo_debug "lock" "reset_run_flag.not_found: $1" fi - + return 0 } check_run_flag () { # check flag -- $1: flag name local rc - + [ -f $RUNDIR/$1 ] rc=$? echo_debug "lock" "check_run_flag: $1; rc=$rc" - + return $rc } set_timed_lock () { # create timestamp n seconds in the future # $1: lock id, $2: lock duration [s] - + set_run_flag ${1}_timed_lock_$(date +%s -d "+${2} seconds") } check_timed_lock () { # check if active timestamp exists # $1: lock id - + local lockid=$1 local locktime local time=$(date +%s) - + for lockfile in $RUNDIR/${lockid}_timed_lock_*; do if [ -f $lockfile ]; then locktime=${lockfile#${RUNDIR}/${lockid}_timed_lock_} @@ -255,7 +312,7 @@ fi fi done - + echo_debug "lock" "check_timed_lock.not_locked: $time" return 1 } @@ -264,10 +321,10 @@ set_laptopmode () { # set kernel laptop mode -- $1: 0=ac mode, 1=battery mode check_sysfs "set_laptopmode" "/proc/sys/vm/laptop_mode" - + DISK_IDLE_SECS_ON_AC=${DISK_IDLE_SECS_ON_AC:-0} DISK_IDLE_SECS_ON_BAT=${DISK_IDLE_SECS_ON_BAT:-2} - + if [ "$1" = "1" ]; then echo_debug "pm" "set_laptopmode($1): $DISK_IDLE_SECS_ON_BAT" echo $DISK_IDLE_SECS_ON_BAT > /proc/sys/vm/laptop_mode @@ -275,48 +332,48 @@ echo_debug "pm" "set_laptopmode($1): $DISK_IDLE_SECS_ON_AC" echo $DISK_IDLE_SECS_ON_AC > /proc/sys/vm/laptop_mode fi - + return 0 } set_dirty_parms () { # set filesystem buffer params # $1: 0=ac mode, 1=battery mode # concept from laptop-mode-tools - + local age - + check_sysfs "set_dirty_parms" "/proc/sys/vm" - + if [ "$1" = "1" ]; then age=$((${MAX_LOST_WORK_SECS_ON_BAT:-15} * 100)) else - age=$((${MAX_LOST_WORK_SECS_ON_AC:-5} * 100)) + age=$((${MAX_LOST_WORK_SECS_ON_AC:-15} * 100)) fi - + echo_debug "pm" "set_dirty_parms($1): $age" - + echo $age > /proc/sys/vm/dirty_writeback_centisecs echo $age > /proc/sys/vm/dirty_expire_centisecs - + if [ -d /proc/sys/fs/xfs ]; then echo $age > /proc/sys/fs/xfs/age_buffer_centisecs echo $age > /proc/sys/fs/xfs/xfssyncd_centisecs echo 3000 > /proc/sys/fs/xfs/xfsbufd_centisecs fi - if [ "$1" = "1" ]; then - echo 60 > /proc/sys/vm/dirty_ratio - echo 40 > /proc/sys/vm/dirty_background_ratio - else - echo 10 > /proc/sys/vm/dirty_ratio - echo 5 > /proc/sys/vm/dirty_background_ratio - fi - return 0 } # --- CPU +check_intel_pstate () { # detect intel_pstate driver -- retval: $intel_pstate + # Note: intel_pstate requires Linux 3.9 or higher + intel_pstate=0 + + [ -d $INTEL_PSTATED ] && intel_pstate=1 + return 0 +} + set_scaling_governor () { # set scaling governor -- $1: 0=ac mode, 1=battery mode local gov cpu @@ -332,7 +389,7 @@ [ -f $cpu ] && echo $gov > $cpu 2> /dev/null done fi - + return 0 } @@ -353,14 +410,14 @@ [ -f $cpu ] && echo $minfreq > $cpu 2> /dev/null done fi - + if [ -n "$maxfreq" ]; then echo_debug "pm" "set_scaling_min_max_freq($1).max: $maxfreq" for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq; do [ -f $cpu ] && echo $maxfreq > $cpu 2> /dev/null done fi - + return 0 } @@ -372,9 +429,9 @@ # Note: # * needs commit #615b7300717b9ad5c23d1f391843484fe30f6c12 # (linux-2.6 tree), "Add support for disabling dynamic overclocking", - # => requires linux 3.7 or later - - local val + # => requires Linux 3.7 or later + + local val ival if [ "$1" = "1" ]; then val="${CPU_BOOST_ON_BAT:-}" @@ -383,12 +440,24 @@ fi if [ -n "$val" ]; then - if [ -f $CPU_BOOST_ALL_CTRL ]; then + check_intel_pstate + + if [ $intel_pstate -eq 1 ]; then + # use intel_pstate sysfiles + if [ -f $CPU_TURBO_PSTATE ]; then + ival=$(($val ^ 1)) + echo "$ival" > $CPU_TURBO_PSTATE 2> /dev/null + echo_debug "pm" "set_cpu_boost_all($1).intel_pstate: $val" + else + echo_debug "pm" "set_cpu_boost_all($1).intel_pstate.cpu_not_supported" + fi + elif [ -f $CPU_BOOST_ALL_CTRL ]; then + # use acpi_cpufreq sysfiles # simple test for attribute "w" doesn't work, so actually write - if ( echo "$val" > $CPU_BOOST_ALL_CTRL ) 2> /dev/null; then - echo_debug "pm" "set_cpu_boost_all($1): $val" + if ( echo "$val" > $CPU_BOOST_ALL_CTRL ) 2> /dev/null; then + echo_debug "pm" "set_cpu_boost_all($1).acpi_cpufreq: $val" else - echo_debug "pm" "set_cpu_boost_all($1).cpu_not_supported" + echo_debug "pm" "set_cpu_boost_all($1).acpi_cpufreq.cpu_not_supported" fi else echo_debug "pm" "set_cpu_boost_all($1).not_available" @@ -398,8 +467,8 @@ set_sched_powersave () { # set multi-core/-thread powersave policy # $1: 0=ac mode, 1=battery mode - - local pwr pool sdev + + local pwr pool sdev local avail=0 if [ "$1" = "1" ]; then @@ -407,7 +476,7 @@ else pwr=${SCHED_POWERSAVE_ON_AC:-0} fi - + for pool in mc smp smt; do sdev="/sys/devices/system/cpu/sched_${pool}_power_savings" if [ -f $sdev ]; then @@ -416,15 +485,15 @@ avail=1 fi done - + [ "$avail" = "1" ] || echo_debug "pm" "set_sched_powersave($1).not_available" - + return 0 } set_nmi_watchdog () { # enable/disable nmi watchdog local nmiwd=${NMI_WATCHDOG:-0} - + if [ -f /proc/sys/kernel/nmi_watchdog ]; then echo "$nmiwd" > /proc/sys/kernel/nmi_watchdog 2> /dev/null if [ $? = 0 ]; then @@ -435,30 +504,28 @@ else echo_debug "pm" "set_nmi_watchdog.not_available" fi - + return 0 } -set_phc_controls () { # set core voltages - local control +set_phc_controls () { # set core voltages + local control local ctrl_avail="0" - - check_sysfs "set_phc_controls" "/sys/devices/system/cpu/cpu0/cpufreq" - + PHC_CONTROLS=${PHC_CONTROLS:-} - - if [ -n "$PHC_CONTROLS" ]; then - for control in /sys/devices/system/cpu/cpu*/cpufreq/phc_controls; do + + if [ -n "$PHC_CONTROLS" ]; then + for control in /sys/devices/system/cpu/cpu*/cpufreq/phc_controls; do if [ -f $control ]; then echo_debug "pm" "set_phc_controls: $control $PHC_CONTROLS" echo $PHC_CONTROLS > $control ctrl_avail="1" fi done - + [ "$ctrl_avail" = "0" ] && echo_debug "pm" "set_phc_controls.not_available" fi - + return 0 } @@ -467,7 +534,7 @@ check_disk_hdparm_cap () { # check if relevant disk device # $1: dev; rc: 0=yes/1=no - if [ -z "$($HDPARM -I /dev/$1 2>&1 | egrep 'Invalid argument|Invalid exchange|missing sense data')" ]; then + if [ -z "$($HDPARM -I /dev/$1 2>&1 | egrep 'Invalid argument|Invalid exchange|missing sense data')" ]; then return 0 else return 1 @@ -476,53 +543,53 @@ echo_disk_model () { # print disk model -- $1: dev local model - + model=$($HDPARM -I /dev/$1 2>&1 | grep 'Model Number' | \ cut -f2 -d: | sed -r 's/^ *//' ) echo "$model" - + return 0 } echo_disk_firmware () { # print firmware version --- $1: dev local firmware - + firmware=$($HDPARM -I /dev/$1 2>&1 | grep 'Firmware Revision' | \ cut -f2 -d: | sed -r 's/^ *//' ) echo "$firmware" - + return 0 } get_disk_state () { # get disk power state -- $1: dev; retval: $disk_state disk_state=$($HDPARM -C /dev/$1 2>&1 | awk -F ':' '/drive state is/ { gsub(/ /,"",$2); print $2; }') [ -z "$disk_state" ] && disk_state="(not available)" - + return 0 } spindown_disk () { # stop spindle motor -- $1: dev $HDPARM -y /dev/$1 2>&1 > /dev/null - + return 0 } get_disk_apm_level () { # get disk apm level -- $1: dev; rc: apm local apm - + apm=$($HDPARM -I /dev/$1 2>&1 | grep 'Advanced power management level' | \ cut -f2 -d: | egrep "^ *[0-9]+ *$") if [ -n "$apm" ]; then return $apm - else + else return 0 fi - + } get_disk_trim_capability () { # check for trim capability # $1: dev; rc: 0=no, 1=yes, 254=no ssd device - + local trim if [ -n "$($HDPARM -I /dev/$1 2>&1 | grep 'Solid State Device')" ]; then @@ -534,14 +601,14 @@ else trim=255 fi - + return $trim } get_disk_dev () { # translate disk id to device (sdX) # $1: id or dev; retval: $disk_dev, $disk_id - - if [ -L /dev/disk/by-id/$1 ]; then + + if [ -h /dev/disk/by-id/$1 ]; then # $1 is disk id disk_id=$1 disk_dev=$(echo $disk_id | sed -r 's/-part[1-9]+$//') @@ -558,143 +625,143 @@ set_disk_apm_level () { # set disk apm level # $1: 0=ac mode, 1=battery mode - + local dev apm apmlist - + DISK_DEVICES=${DISK_DEVICES:=sda} if [ $1 = "1" ]; then apmlist=$DISK_APM_LEVEL_ON_BAT else apmlist=$DISK_APM_LEVEL_ON_AC fi - + # strip excess blanks from list - apmlist=$(echo -n $apmlist | sed -r 's/ +/ /g; s/^ | $//g') - - [ -z "$apmlist" ] && return 0 - + apmlist=$(echo -n $apmlist | sed -r 's/ +/ /g; s/^ | $//g') + + [ -z "$apmlist" ] && return 0 + for dev in $DISK_DEVICES; do get_disk_dev $dev - + if [ -b /dev/$disk_dev ]; then check_disk_hdparm_cap $disk_dev if [ $? = 0 ]; then # parse list apm=$(echo -n $apmlist | sed -r 's/^(\w+) .*/\1/') apmlist=$(echo -n $apmlist | sed -r 's/^\w+ (.*)/\1/') - + echo_debug "pm" "set_disk_apm_level($1): $disk_dev [$disk_id] $apm" $HDPARM -B $apm /dev/$disk_dev > /dev/null 2>&1 fi fi done - + return 0 -} +} set_disk_spindown_timeout () { # set disk spindown timeout # $1: 0=ac mode, 1=battery mode - + local dev timeout timeoutlist - + DISK_DEVICES=${DISK_DEVICES:=sda} if [ $1 = "1" ]; then timeoutlist=$DISK_SPINDOWN_TIMEOUT_ON_BAT else timeoutlist=$DISK_SPINDOWN_TIMEOUT_ON_AC fi - + # strip excess blanks from list - timeoutlist=$(echo -n $timeoutlist | sed -r 's/ +/ /g; s/^ | $//g') - - [ -z "$timeoutlist" ] && return 0 - + timeoutlist=$(echo -n $timeoutlist | sed -r 's/ +/ /g; s/^ | $//g') + + [ -z "$timeoutlist" ] && return 0 + for dev in $DISK_DEVICES; do get_disk_dev $dev - + if [ -b /dev/$disk_dev ]; then check_disk_hdparm_cap $disk_dev if [ $? = 0 ]; then # parse list timeout=$(echo -n $timeoutlist | sed -r 's/^(\w+) .*/\1/') timeoutlist=$(echo -n $timeoutlist | sed -r 's/^\w+ (.*)/\1/') - + echo_debug "pm" "set_disk_spindown_timeout($1): $disk_dev [$disk_id] $timeout" $HDPARM -S $timeout /dev/$disk_dev > /dev/null 2>&1 fi fi done - + return 0 -} +} -set_disk_io_sched () { # set disk io scheduler +set_disk_io_sched () { # set disk io scheduler local dev sched schedlist schedctrl - + [ -n "$DISK_IOSCHED" ] || return 0 - + DISK_DEVICES=${DISK_DEVICES:=sda} # strip excess blanks from list schedlist=$(echo -n $DISK_IOSCHED | sed -r 's/ +/ /g; s/^ | $//g') - + for dev in $DISK_DEVICES; do get_disk_dev $dev - + if [ -b /dev/$disk_dev ]; then # parse list, add cfq as default when list is too short sched=$(echo -n $schedlist | sed -r 's/^(\w+) .*/\1/') schedlist=$(echo -n "$schedlist cfq"| sed -r 's/^\w+ (.*)/\1/') schedctrl="/sys/block/$disk_dev/queue/scheduler" - + if [ -f $schedctrl ]; then echo_debug "pm" "set_disk_io_sched: $disk_dev [$disk_id] $sched" echo -n $sched > $schedctrl fi fi done - + return 0 } -# --- Device Power Management +# --- Device Power Management set_sata_link_power () { # set sata link power management # $1: 0=ac mode, 1=battery mode - + local i pwr local ctrl_avail="0" - + if [ "$1" = "1" ]; then pwr=${SATA_LINKPWR_ON_BAT:-min_power} else pwr=${SATA_LINKPWR_ON_AC:-max_perfomance} fi echo_debug "pm" "set_sata_link_power($1): $pwr" - + for i in /sys/class/scsi_host/host*/link_power_management_policy ; do if [ -f $i ]; then echo "$pwr" > $i ctrl_avail="1" fi done - + [ "$ctrl_avail" = "0" ] && echo_debug "pm" "set_sata_link_power($1).not_available" - + return 0 -} +} set_pcie_aspm () { # set pcie active state power management # $1: 0=ac mode, 1=battery mode - + local pwr - + if [ "$1" = "1" ]; then pwr=${PCIE_ASPM_ON_BAT:-powersave} else pwr=${PCIE_ASPM_ON_AC:-performance} fi - + if [ -f /sys/module/pcie_aspm/parameters/policy ]; then echo "$pwr" > /sys/module/pcie_aspm/parameters/policy 2> /dev/null if [ $? = 0 ]; then @@ -711,153 +778,177 @@ set_radeon_profile () { # set radeon power profile # $1: 0=ac mode, 1=battery mode - - local pwr card - - if [ "$1" = "1" ]; then - pwr=${RADEON_POWER_PROFILE_ON_BAT:-low} - else - pwr=${RADEON_POWER_PROFILE_ON_AC:-high} - fi - + + local card level pwr rc1 rc2 + local present=0 + for card in /sys/class/drm/card[0-9]/device ; do - if [ -f $card/power_method ] && [ -f $card/power_profile ]; then - echo_debug "pm" "set_radeon_profile($1): $pwr $card" - echo "profile" > $card/power_method - echo "$pwr" > $card/power_profile - return 0 + if [ -f $card/power_dpm_state ] && [ -f $card/power_dpm_force_performance_level ]; then + # Use new radeon dynamic power management method (dpm) + if [ "$1" = "1" ]; then + pwr=$RADEON_DPM_STATE_ON_BAT + level=${RADEON_DPM_PERF_LEVEL_ON_BAT:-auto} + else + pwr=$RADEON_DPM_STATE_ON_AC + level=${RADEON_DPM_PERF_LEVEL_ON_AC:-auto} + fi + + if [ -n "$pwr" ]; then + echo "$pwr" > $card/power_dpm_state 2> /dev/null; rc1=$? + echo "$level" > $card/power_dpm_force_performance_level 2> /dev/null; rc2=$? + echo_debug "pm" "set_radeon_profile($1): $card state=$pwr [rc=$rc1] perf=$level [rc=$rc2]" + fi + + present=1 + + elif [ -f $card/power_method ] && [ -f $card/power_profile ]; then + # Use old radeon power profile method + if [ "$1" = "1" ]; then + pwr=$RADEON_POWER_PROFILE_ON_BAT + else + pwr=$RADEON_POWER_PROFILE_ON_AC + fi + + if [ -n "$pwr" ]; then + echo_debug "pm" "set_radeon_profile($1): $card profile=$pwr " + echo "profile" > $card/power_method 2> /dev/null + echo "$pwr" > $card/power_profile 2> /dev/null + fi + + present=1 fi done - - echo_debug "pm" "set_radeon_profile($1).not_available" - return 0 + + if [ $present -eq 0 ]; then + echo_debug "pm" "set_radeon_profile($1).not_available" + fi + + return 0 } set_sound_power_mode () { # set sound chip power mode SOUND_POWER_SAVE=${SOUND_POWER_SAVE:-1} SOUND_POWER_SAVE_CONTROLLER=${SOUND_POWER_SAVE_CONTROLLER:-Y} - + check_sysfs "set_sound_power_mode" "/sys/module" if [ -d /sys/module/snd_hda_intel ]; then echo_debug "pm" "set_sound_power_mode.hda: $SOUND_POWER_SAVE $SOUND_POWER_SAVE_CONTROLLER" echo "$SOUND_POWER_SAVE" > /sys/module/snd_hda_intel/parameters/power_save - echo "$SOUND_POWER_SAVE_CONTROLLER" > /sys/module/snd_hda_intel/parameters/power_save_controller + echo "$SOUND_POWER_SAVE_CONTROLLER" > /sys/module/snd_hda_intel/parameters/power_save_controller fi - + if [ -d /sys/module/snd_ac97_codec ]; then echo_debug "pm" "set_sound_power_mode.ac97: $SOUND_POWER_SAVE" echo "$SOUND_POWER_SAVE" > /sys/module/snd_ac97_codec/parameters/power_save fi - + + return 0 +} + +get_pci_class_descr () { # get long descr of pci device class + # $1: class; retval: lclass + + case $1 in + 0x020000) lclass="Ethernet controller" ;; + 0x028000) lclass="Wireless" ;; + 0x040300) lclass="Audio device" ;; + 0x060000) lclass="Host Bridge" ;; + 0x080500) lclass="SD Card Reader" ;; + 0x088000|0x088001) lclass="Card Reader" ;; + 0x0c0000|0x0c0010) lclass="Firewire" ;; + *) lclass="" ;; + esac + return 0 } -set_runtime_pm () { # set runtime power management +set_runtime_pm () { # set runtime power management # $1: 0=ac mode, 1=battery mode - # concept from Ubuntu Precise's implementation of pm-utils power.d/pci_devices - - local type device control doall - + + local adress class ccontrol control device doall exc type + if [ "$1" = "1" ]; then - control=${RUNTIME_PM_ON_BAT:-on} + ccontrol=${RUNTIME_PM_ON_BAT:-on} else - control=${RUNTIME_PM_ON_AC:-on} + ccontrol=${RUNTIME_PM_ON_AC:-on} fi doall=${RUNTIME_PM_ALL:-0} - + for type in $PCID; do for device in $type/*; do if [ -f $device/class ] && [ -f $device/power/control ]; then class=$(cat $device/class) - case $class in - 0x020000) # ethernet - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class Ethernet controller]" - ;; - - 0x028000) # wireless - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class Wireless]" - ;; - - 0x040300) # audio device - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class Audio device]" - ;; - - 0x060000) # host bridge - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class Host Bridge]" - ;; - - 0x080500) # SD card reader - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class SD Card Reader]" - ;; - - 0x088000|0x088001) # card reader - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class Card Reader]" - ;; - - 0x0c0000|0x0c0010) # firewire - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class Firewire]" - ;; - - *) # other - if [ "$doall" = "1" ]; then - echo $control > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).$control: $device [$class]" - else - echo on > $device/power/control; - echo_debug "pm" "set_runtime_pm($1).on: $device [$class]" + get_pci_class_descr $class + + control=$ccontrol + exc="" + + if [ "$control" = "auto" ]; then + if [ -z "$lclass" ] && [ $doall -ne 1 ]; then + # device has no long descr and all flag is not set + control="on" + exc="_class" + else + # device has log descr, now check if in blacklist + adress=${device##/*/} + adress=${adress#0000:} + + if wordinlist "$adress" "$RUNTIME_PM_BLACKLIST"; then + # device is in blacklist + control="on" + exc="_bl" fi - ;; - esac + fi + fi + + echo $control > $device/power/control; + + [ -n "$lclass" ] && lclass=" $lclass" + echo_debug "pm" "set_runtime_pm($1).$control$exc: $device [$class$lclass]" fi done done - + return 0 } -# --- Wifi Power Management +# --- Wifi Power Management get_wifi_ifaces () { # get all wifi devices -- retval: $wifaces + local wi wip wifaces="" - - for wi in /sys/class/net/*/phy80211; do - if [ -d $wi ]; then - wi=${wi%/phy80211}; wi=${wi##*/} - - [ -n "$wifaces" ] && wifaces="$wifaces " - wifaces="$wifaces$wi" + + for wip in /sys/class/net/*/phy80211; do + if [ -d $wip ]; then + wi=${wip%/phy80211}; wi=${wi##*/} + wifaces="$wifaces $wi" fi done - + + wifaces="${wifaces# }" return 0 } get_wifi_driver () { # get driver associated with interface -- $1: iface; retval: $wifidrv local drvl - + wifidrv="" if [ -d $NETD/$1 ]; then drvl=$(readlink $NETD/$1/device/driver) [ -n "$drvl" ] && wifidrv=${drvl##*/} fi - + return 0 } set_wifi_power_mode () { # set wifi power save mode -- $1: 0=ac mode, 1=battery mode local pwr iface - local iwrc=1 - + local rc=0 + local cmdx=0 + if [ "$1" = "1" ]; then pwr=${WIFI_PWR_ON_BAT:-5} else @@ -867,42 +958,71 @@ 0|1|N) pwr="off" ;; 2|3|4|5|6|Y) pwr="on" ;; esac - + get_wifi_ifaces - + for iface in $wifaces; do if [ -n "$iface" ]; then - if cmd_exists $IW; then + if [ "$X_DONT_USE_IW" != "1" ] && cmd_exists $IW; then + # try with iw first $IW dev $iface set power_save $pwr > /dev/null 2>&1 - iwrc=$? - if [ $iwrc = 0 ]; then - echo_debug "pm" "set_wifi_power_mode($1, $iface).iw: $pwr" - fi + rc=$? + echo_debug "pm" "set_wifi_power_mode($1, $iface).iw: $pwr; rc=$rc" + cmdx=1 fi - if [ $iwrc != 0 ]; then - $IWC $iface power $pwr > /dev/null 2>&1 - if [ $? = 0 ]; then - echo_debug "pm" "set_wifi_power_mode($1, $iface).iwconfig: $pwr" - else - echo_debug "pm" "set_wifi_power_mode($1, $iface).iwconfig.not_supported" + if cmd_exists $IWC; then + if [ $rc -ne 0 ] || [ $cmdx -eq 0 ]; then + # iw did not succeed or iw not installed -> try with iwconfig + $IWC $iface power $pwr > /dev/null 2>&1 + rc=$? + echo_debug "pm" "set_wifi_power_mode($1, $iface).iwconfig: $pwr; rc=$rc" + cmdx=1 fi fi + if [ $cmdx -eq 0 ]; then + # neither iw nor iwconfig installed -> no way + echo_debug "pm" "set_wifi_power_mode($1, $iface).no_tool" + fi fi done - + return 0 } # --- LAN +get_eth_ifaces () { # get all eth devices -- retval: $ethifaces + local ei eic + ethifaces='' + + for eic in /sys/class/net/*/device/class; do + if [ -f $eic ] \ + && [ "$(cat $eic)" = "0x020000" ] \ + && [ ! -d "${eic%/class}/ieee80211" ]; then + + ei=${eic%/device/class}; ei=${ei##*/} + ethifaces="$ethifaces $ei" + fi + done + + ethifaces="${ethifaces# }" + return 0 +} + disable_wake_on_lan () { # disable WOL + local ei + WOL_DISABLE=${WOL_DISABLE:-N} - + if [ "$WOL_DISABLE" = "Y" ]; then - echo_debug "pm" "disable_wake_on_lan: y" - $ETHTOOL -s eth0 wol d > /dev/null 2>&1 + get_eth_ifaces + + for ei in $ethifaces; do + echo_debug "pm" "disable_wake_on_lan: $ei" + $ETHTOOL -s $ei wol d > /dev/null 2>&1 + done fi - + return 0 } @@ -910,39 +1030,51 @@ set_usb_suspend () { # activate usb autosuspend for all devices except input and blacklisted # $1: 0=silent/1=report result; $2: on/auto - - local devices usbdev subdev control hid usbid busdev + + local devices usbdev subdev control exc usbid busdev vendor local ctrlf="control" local autof="autosuspend_delay_ms" - + check_sysfs "set_usb_suspend" "$USBD" - + if [ "$USB_AUTOSUSPEND" = "1" ]; then devices=$(ls $USBD | grep -v ':') for usbdev in $devices; do if [ -f $USBD/$usbdev/power/autosuspend ] || [ -f $USBD/$usbdev/power/autosuspend_delay_ms ]; then usbid="$(cat $USBD/$usbdev/idVendor):$(cat $USBD/$usbdev/idProduct)" busdev="Bus $(cat $USBD/$usbdev/busnum) Dev $(cat $USBD/$usbdev/devnum)" - - control="$2" - hid="" + + control="${2:-auto}" + exc="" if [ "$control" != "on" ]; then - if patinstr "$usbid" "$USB_BLACKLIST"; then + if wordinlist "$usbid" "$USB_BLACKLIST"; then # device is in blacklist control="on" + exc="_bl" else # check for hid subdevices for subdev in $USBD/$usbdev/*:*; do if [ "$(cat $subdev/bInterfaceClass)" = "03" ]; then control="on" - hid="_hid" + exc="_hid" break fi done + + # check for wwan vendor ids + USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # default: exclude wwan + + if [ $USB_BLACKLIST_WWAN = "1" ] && [ -z "$exc" ]; then + vendor="$(cat $USBD/$usbdev/idVendor)" + if wordinlist "$vendor" "$USB_WWAN_VENDORS"; then + control="on" + exc="_wwan" + fi + fi fi fi - + if [ -f $USBD/$usbdev/power/control ]; then echo "$control" > $USBD/$usbdev/power/control else @@ -950,7 +1082,7 @@ echo "$control" > $USBD/$usbdev/power/level ctrlf="level" fi - + if [ -f $USBD/$usbdev/power/autosuspend_delay_ms ]; then echo $USB_TIMEOUT_MS > $USBD/$usbdev/power/autosuspend_delay_ms 2> /dev/null if [ $? != 0 ]; then @@ -964,17 +1096,17 @@ echo $USB_TIMEOUT > $USBD/$usbdev/power/autosuspend autof="autosuspend" fi - echo_debug "usb" "set_usb_suspend.$control$hid: $busdev ID $usbid $USBD/$usbdev [$ctrlf $autof]" + echo_debug "usb" "set_usb_suspend.$control$exc: $busdev ID $usbid $USBD/$usbdev [$ctrlf $autof]" fi done [ "$1" = "1" ] && echo "usb autosuspend settings applied." else [ "$1" = "1" ] && echo "Error: usb autosuspend is disabled. Set USB_AUTOSUSPEND=1 in $DEFAULT_FILE." fi - + # set "startup completion" flag for tlp-usb-udev set_run_flag $USB_DONE - + return 0 } @@ -1025,7 +1157,7 @@ read_tpacpi_threshold () { # $1: ST/SP (start/stop); $2: 0/1 (battery) # rc: threshold (1..99, 0=default, 255=error) local thresh rc - + thresh=$($TPACPIBAT -g $1 $2 2> /dev/null | cut -f1 -d' ') rc=$? @@ -1038,9 +1170,9 @@ } do_threshold () { # $1: start/stop, $2: BAT0/BAT1, $3: new value - # global param: $tpacpi, $tpsmapi + # global param: $tpacpi, $tpsmapi # rc: 0=ok/1=read error/2=thresh not present/255=no thresh api - + local bati bsys ts local old_thresh=-1 local new_thresh=$3 @@ -1078,7 +1210,7 @@ fi elif [ $tpsmapi -eq 0 ]; then # use tp_smapi bsys=$SMAPIDIR/$2/${1}_charge_thresh - + if [ -f $bsys ]; then old_thresh=$(cat $bsys 2> /dev/null) if [ -z "$old_thresh" ]; then @@ -1089,13 +1221,13 @@ fi else rc=2 # invalid bat argument - fi + fi else # no threshold API available rc=255 fi - - echo_debug "bat" "do_threshold($1, $2): tpacpi-bat=$tpacpi; tp_smapi=$tpsmapi; old=$old_thresh; new=$new_thresh; rc=$rc" + + echo_debug "bat" "do_threshold($1, $2): tpacpi-bat=$tpacpi; tp_smapi=$tpsmapi; old=$old_thresh; new=$new_thresh; rc=$rc" return $rc } @@ -1104,7 +1236,7 @@ # global param: $tpacpi, $tpsmapi # rc: 0 # retval: $start_thresh, $stop_thresh - + local type thresh for type in start stop; do @@ -1112,17 +1244,17 @@ start) thresh=$1 ;; stop) thresh=$2 ;; esac - + thresh=$(echo "$thresh" | egrep '^[0-9]{1,3}$') # check for 1..3 digits [ -z "$thresh" ] && thresh=-1 # replace empty value with -1 # ensure min/max values; replace 0 with defaults 96/100 - case $type in + case $type in start) [ $thresh -eq 0 ] || [ $thresh -gt 96 ] && thresh=96 start_thresh=$thresh ;; - + stop) [ $thresh -eq 0 ] || [ $thresh -gt 100 ] && thresh=100 [ $thresh -ne -1 ] && [ $thresh -lt 5 ] && thresh=5 @@ -1145,7 +1277,7 @@ # $1: BAT0/BAT1; retval: 0=bat exists/1=bat nonexistent/255=no thresh api available # global param: $tpacpi, $tpsmapi # rc: 0=present/1=absent/255=no thresh api - + local rc if [ $tpsmapi -eq 0 ]; then # use tp_smapi @@ -1157,7 +1289,7 @@ else # no threshold API available rc=255 fi - + echo_debug "bat" "bat_exists($1): rc=$rc" return $rc } @@ -1165,12 +1297,12 @@ set_charge_thresholds () { # write all charge thresholds from configuration # global param: $tpacpi, $tpsmapi # rc: 0 - + local rc - + check_tpacpi; check_tpsmapi echo_debug "bat" "set_charge_thresholds: tpacpi-bat=$tpacpi; tp_smapi=$tpsmapi" - + if bat_exists BAT0; then normalize_thresholds "$START_CHARGE_THRESH_BAT0" "$STOP_CHARGE_THRESH_BAT0" @@ -1191,7 +1323,7 @@ if bat_exists BAT1; then normalize_thresholds "$START_CHARGE_THRESH_BAT1" "$STOP_CHARGE_THRESH_BAT1" - + if [ $stop_thresh -ne -1 ]; then do_threshold stop BAT1 $stop_thresh; rc=$? echo_debug "bat" "set_charge_thresholds.stop(BAT1): $stop_thresh; rc=$rc" @@ -1206,7 +1338,7 @@ echo_debug "bat" "set_charge_thresholds.start(BAT1).not_set" fi fi - + return 0 } @@ -1214,7 +1346,7 @@ # $1: BAT0/BAT1, $2: 0=off/1=on # global param: $tpacpi, $tpsmapi # rc: 0=done/1=write error/2=discharge not present/255=no thresh api - + local bati bsys rc=0 if [ $tpacpi -eq 0 ]; then # use tpacpi-bat @@ -1227,10 +1359,10 @@ echo_debug "bat" "do_force_discharge.tpacpi-bat($1, $2): rc=$rc" elif [ $tpsmapi -eq 0 ]; then # use tp_smapi bsys=$SMAPIDIR/$1/force_discharge - + if [ -f $bsys ]; then echo $2 > $bsys 2> /dev/null; rc=$? - else + else rc=2 fi echo_debug "bat" "do_force_discharge.tp_smapi($1, $2): rc=$rc" @@ -1238,14 +1370,14 @@ rc=255 echo_debug "bat" "do_force_discharge.noapi($1, $2)" fi - + return $rc } -get_force_discharge () { # $1: BAT0/BAT1, +get_force_discharge () { # $1: BAT0/BAT1, # global param: $tpacpi, $tpsmapi # rc: 0=done/1=read error/2=discharge not present/255=no thresh api - + local bati bsys rc=0 if [ $tpacpi -eq 0 ]; then # use tpacpi-bat @@ -1261,16 +1393,16 @@ esac elif [ $tpsmapi -eq 0 ]; then # use tp_smapi bsys=$SMAPIDIR/$1/force_discharge - + if [ -f $bsys ]; then rc=$(cat $bsys 2> /dev/null) - else + else rc=2 fi else # no threshold API available rc=255 fi - + echo_debug "bat" "get_force_discharge($1): rc=$rc" return $rc } @@ -1279,7 +1411,7 @@ do_force_discharge $bat 0 echo_debug "bat" "setcharge_battery.cancelled($bat)" echo "Cancelled." - + exit 0 } @@ -1287,7 +1419,7 @@ # $1: start charge threshold, $2: stop charge threshold, $3: battery # global param: $tpacpi, $tpsmapi # rc: 0=ok/1=error - + local rc # $bat is global for cancel_setcharge () trap local act=0 @@ -1297,9 +1429,9 @@ echo_debug "bat" "setcharge_battery.no_ac_power" echo "Error: setting charge thresholds is possible on ac power only." return 1 - fi + fi - # check prerequisites: tpacpi-bat or tp-smapi + # check prerequisites: tpacpi-bat or tp-smapi check_tpacpi; check_tpsmapi echo_debug "bat" "setcharge_battery($1, $2, $3): tpacpi-bat=$tpacpi; tp_smapi=$tpsmapi" @@ -1310,16 +1442,16 @@ fi # check params - if [ $# -gt 0 ]; then + if [ $# -gt 0 ]; then # some parameters given, check them - + # get battery arg bat=${3:-BAT0} # default is BAT0 bat=$(echo $bat | tr "[:lower:]" "[:upper:]") - + # get and check thresholds args normalize_thresholds "$1" "$2" - else + else # no parameters given, assume BAT0 and take thresholds from config file bat=BAT0 normalize_thresholds "$START_CHARGE_THRESH_BAT0" "$STOP_CHARGE_THRESH_BAT0" @@ -1331,13 +1463,13 @@ echo_debug "bat" "setcharge_battery.not_present($bat)" return 1 fi - + # write threshold values echo "Setting temporary charge thresholds for $bat:" - + if [ $stop_thresh -ne -1 ]; then - do_threshold stop $bat $stop_thresh; rc=$? - + do_threshold stop $bat $stop_thresh; rc=$? + echo_debug "bat" "setcharge_battery.stop($bat): $stop_thresh; rc=$rc" if [ $rc -eq 0 ]; then echo " stop = $stop_thresh" @@ -1350,9 +1482,9 @@ echo_debug "bat" "setcharge_battery.stop($bat).not_configured" echo " stop = not configured" fi - + if [ $start_thresh -ne -1 ]; then - do_threshold start $bat $start_thresh; rc=$? + do_threshold start $bat $start_thresh; rc=$? echo_debug "bat" "setcharge_battery.start($bat): $start_thresh; rc=$rc" if [ $rc -eq 0 ]; then @@ -1366,11 +1498,11 @@ echo_debug "bat" "setcharge_battery.start($bat).not_configured" echo " start = not configured" fi - + # trigger charging via discharge if [ $act -eq 1 ]; then trap cancel_setcharge INT # enable ^C hook - + do_force_discharge $bat 1; rc=$? if [ $rc -eq 0 ]; then echo -n "Activating..." @@ -1381,7 +1513,7 @@ echo "done." else trap - INT # remove ^C hook - + echo_debug "bat" "setcharge_battery.force_discharge_not_available($bat): rc=$rc" echo "Cannot activate immediately on this ThinkPad model. Please power off." return 1 @@ -1389,7 +1521,7 @@ trap - INT # remove ^C hook fi - + return 0 } @@ -1398,9 +1530,9 @@ local val="" [ -f $sysf ] && val=$(cat $sysf 2> /dev/null) - val=$(echo "$val" | egrep '^[0-9]+$') # check for non-numeric chars + val=$(echo "$val" | egrep '^[0-9]+$') # check for non-numeric chars [ -z "$val" ] && val=0 # empty string - + return $val } @@ -1417,18 +1549,18 @@ local ccharge=0 # check params - if [ $# -gt 0 ]; then + if [ $# -gt 0 ]; then # some parameters given, check them - + # get battery arg bat=${1:-BAT0} # default is BAT0 bat=$(echo $bat | tr "[:lower:]" "[:upper:]") - else + else # no parameters given, assume BAT0 bat=BAT0 fi - # check prerequisites: tpacpi-bat or tp-smapi + # check prerequisites: tpacpi-bat or tp-smapi check_tpacpi; check_tpsmapi echo_debug "bat" "chargeonce_battery($bat): tpacpi-bat=$tpacpi; tp_smapi=$tpsmapi" if [ $tpacpi -ne 0 ] && [ $tpsmapi -ne 0 ]; then @@ -1438,7 +1570,7 @@ fi # check if selected battery is present - if ! bat_exists $bat ; then + if ! bat_exists $bat ; then echo_debug "bat" "chargeonce_battery($bat).not_present" echo "Error: battery $bat not present." return 1 @@ -1450,7 +1582,7 @@ stop_thresh=$STOP_CHARGE_THRESH_BAT0 start_thresh=$START_CHARGE_THRESH_BAT0 ;; - + BAT1) stop_thresh=$STOP_CHARGE_THRESH_BAT1 start_thresh=$START_CHARGE_THRESH_BAT1 @@ -1471,18 +1603,18 @@ else # use ACPI data bdir="$ACPIBATDIR/$bat" - if [ -f $bdir/energy_full ]; then + if [ -f $bdir/energy_full ]; then get_sysval $bdir/energy_full; efull=$? get_sysval $dir/energy_now; enow=$? fi - + if [ $efull -ne 0 ]; then ccharge=$(( 100 * $enow / $efull )) else ccharge=-1 fi fi - + if [ $ccharge -eq -1 ] ; then echo_debug "bat" "chargeonce_battery($bat).charge_level_unknown: enow=$enow; efull=$efull; ccharge=$ccharge" echo "Error: cannot determine charge level for $bat." @@ -1499,7 +1631,7 @@ else echo_debug "bat" "chargeonce_battery($bat).setcharge: $temp_start_thresh $stop_thresh" fi - + setcharge_battery $temp_start_thresh $stop_thresh $bat return $? } @@ -1509,18 +1641,18 @@ echo_debug "bat" "discharge_battery.cancelled($bat)" echo echo "Discharging of battery $bat cancelled." - + exit 0 } -discharge_battery () { # discharge battery +discharge_battery () { # discharge battery # $1: battery # global param: $tpacpi, $tpsmapi # rc: 0=ok/1=error - - local bdir ef pn rc + + local bdir ef pn rc # $bat is global for cancel_setcharge () trap - + # check prerequisites: must be on ac power if ! get_power_state ; then echo_debug "bat" "discharge_battery.no_ac_power" @@ -1528,7 +1660,7 @@ return 1 fi - # check prerequisites: tpacpi-bat or tp-smapi + # check prerequisites: tpacpi-bat or tp-smapi check_tpacpi; check_tpsmapi echo_debug "bat" "discharge_battery($1, $2, $3): tpacpi-bat=$tpacpi; tp_smapi=$tpsmapi" @@ -1542,7 +1674,7 @@ bat=$1 bat=${bat:=BAT0} # default is BAT0 bat=$(echo $bat | tr "[:lower:]" "[:upper:]") - + # check if selected battery is present if ! bat_exists $bat ; then echo_debug "bat" "discharge_battery.not_present($bat)" @@ -1557,7 +1689,7 @@ echo "Error: discharge function not available for this ThinkPad model." return 1 fi - + trap cancel_discharge INT # enable ^C hook # wait for start @@ -1572,7 +1704,7 @@ # show current battery state if [ $tpsmapi -eq 0 ]; then # use tp_smapi bdir=$SMAPIDIR/$bat - + printf "voltage = %6s [mv]\n" $(cat $bdir/voltage) printf "remaining capacity = %6s [mWh]\n" $(cat $bdir/remaining_capacity) printf "remaining percent = %6s [%%]\n" $(cat $bdir/remaining_percent) @@ -1584,7 +1716,7 @@ if [ -d $bdir ]; then printf "voltage = %6s [mV]\n" $(cat $bdir/voltage_now | sed 's/\(.*\).../\1/') printf "remaining capacity = %6s [mWh]\n" $(cat $bdir/energy_now | sed 's/\(.*\).../\1/') - + ef=$(cat $bdir/energy_full) if [ "$ef" != "0" ]; then printf "remaining percent = %6s [%%]\n" \ @@ -1592,7 +1724,7 @@ else printf "remaining percent = not available [%]\n" fi - + pn=$(cat $bdir/power_now) if [ "$pn" != "0" ]; then printf "remaining time = %6s [min]\n" \ @@ -1601,8 +1733,8 @@ else printf "remaining time = not discharging [min]\n" fi - - fi + + fi fi echo "Press Ctrl+C to cancel." sleep 2 @@ -1618,18 +1750,75 @@ # --- Drive Bay +get_drivebay_device () { # Find generic dock interface for drive bay + # rc: 0; retval: $dock + dock=$(grep -l ata_bay /sys/devices/platform/dock.?/type) + dock=${dock%%/type} + if [ ! -d "$dock" ]; then + dock="" + fi + + return 0 +} + +suspend_drivebay () { # Save power state of drive bay before suspend + + get_drivebay_device + if [ -n "$dock" ]; then + if [ -e $dock/docked ]; then + mkdir -p $STATEDIR + + if [ "$(cat $dock/docked)" = "0" ]; then + echo "off" > $BAYSTATEFILE + echo_debug "pm" "suspend_drivebay: bay=off" + else + echo "on" > $BAYSTATEFILE + echo_debug "pm" "suspend_drivebay: bay=on" + fi + fi + fi + + return 0 +} + +resume_drivebay () { # Restore power state of drive bay after restore + local cnt rc + + [ -f $BAYSTATEFILE ] || return 0 + + if [ "$(cat $BAYSTATEFILE)" = "off" ]; then + get_drivebay_device + if [ -n "$dock" ]; then + if [ -e $dock/undock ]; then + cnt=5 + rc=1 + until [ $rc = 0 -o $cnt = 0 ]; do + cnt=$((cnt - 1)) + echo 1 > $dock/undock + rc=$? + [ $rc = 0 ] || sleep 0.5 + done + echo_debug "pm" "resume_drivebay.off: rc=$rc" + return 0 + fi + fi + fi + + rm -f $BAYSTATEFILE 2> /dev/null + + return 0 +} + poweroff_drivebay () { # power off optical drive in drive bay # $1: 0=conditional+quiet mode, 1=force+verbose mode # Some code adapted from http://www.thinkwiki.org/wiki/How_to_hotswap_UltraBay_devices - - local dock optdrv syspath - - # Run only if either explicitly enabled or forced + + local optdrv syspath + + # Run only if either explicitly enabled or forced [ "$BAY_POWEROFF_ON_BAT" = "1" ] || [ "$1" = "1" ] || return 0 - # Find generic dock interface for bay - dock=$(grep -l ata_bay /sys/devices/platform/dock.?/type) - dock=${dock%%/type} + get_drivebay_device if [ -z "$dock" ] || [ ! -d "$dock" ]; then echo_debug "pm" "poweroff_drivebay.no_bay_device" [ "$1" = "1" ] && echo "Error: cannot locate bay device." @@ -1641,7 +1830,7 @@ if [ $(cat $dock/docked) = "0" ]; then echo_debug "pm" "poweroff_drivebay.drive_already_off" [ "$1" = "1" ] && echo "No drive in bay (or power already off)." - else + else # Check for optical drive optdrv=/dev/${BAY_DEVICE:=sr0} if [ ! -b "$optdrv" ]; then @@ -1650,14 +1839,14 @@ return 0 else echo_debug "pm" "poweroff_drivebay: optdrv=$optdrv" - - # Unmount media + + # Unmount media umount -l $optdrv > /dev/null 2>&1 - + # Power off drive $HDPARM -Y $optdrv > /dev/null 2>&1 sleep 1 - + # Unregister scsi device syspath="/sys$($UDEVADM info --query=path --name=$optdrv | perl -pe 's!/block/...$!!')" echo_debug "pm" "poweroff_drivebay: syspath=$syspath" @@ -1669,6 +1858,6 @@ echo_debug "pm" "poweroff_drivebay.bay_powered_off" fi fi - + return 0 } diff -Nru tlp-0.3.9/tlp-nop tlp-0.4/tlp-nop --- tlp-0.3.9/tlp-nop 2012-08-13 19:11:40.000000000 +0000 +++ tlp-0.4/tlp-nop 2013-09-19 05:54:22.000000000 +0000 @@ -1,6 +1,6 @@ #!/bin/sh # tlp - if tlp is enabled, override corresponding script -# in /usr/lib*/pm-utils/power.d/ +# in /usr/lib*/pm-utils/power.d/ CONFFILE=/etc/default/tlp LIBDIRS='/usr/lib /usr/lib64' diff -Nru tlp-0.3.9/tlp-pcilist tlp-0.4/tlp-pcilist --- tlp-0.3.9/tlp-pcilist 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-pcilist 2013-09-19 05:54:22.000000000 +0000 @@ -9,7 +9,7 @@ use strict; use warnings; -# Get sysfs value, return empty string if nonexistent or not readable +# Get sysfs value, return empty string if nonexistent or not readable sub catsysf { my $sysval = ""; if (open SYSF, "$_[0]") { diff -Nru tlp-0.3.9/tlp-rdw-nm tlp-0.4/tlp-rdw-nm --- tlp-0.3.9/tlp-rdw-nm 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-rdw-nm 2013-09-19 05:54:22.000000000 +0000 @@ -13,7 +13,7 @@ for libdir in $LIBDIRS; do [ -d $libdir ] && break; done [ -d $libdir ] || exit 0 -for lib in $LIBS; do +for lib in $LIBS; do [ -f $libdir/$lib ] || exit 0 . $libdir/$lib done @@ -46,7 +46,7 @@ # get connection state for devices != hso|usb|wwan nmstate=$($NMCLI dev | grep 'gsm' | egrep -v 'hso|usb|wwan' | awk '{ print $3; }') - + # when action matches state, then it is probably type 3g/gsm case $action in up) [ "$nmstate" = "connected" ] && itype="gsm" ;; @@ -54,7 +54,7 @@ esac ;; - *) # iface = dev -> all other devices, including 3g with specific driver + *) # iface = dev -> all other devices, including 3g with specific driver itype="$($NMCLI dev | awk '$1 ~ /'$iface'/ { print $2; }')" ;; esac @@ -69,7 +69,7 @@ nmstate=$($NMTOOL | egrep -v 'Device:.*(hso|usb|wwan)' | grep -A3 'Device:' \ | grep -A2 'Mobile Broadband (GSM)' | grep 'State:' \ | awk '{ print $2; }') - + # when action matches state, then it is probably type 3g/gsm case $action in up) [ "$nmstate" = "connected" ] && itype="gsm" ;; @@ -77,18 +77,18 @@ esac ;; - *) # iface = dev -> all other devices, including 3g with specific driver + *) # iface = dev -> all other devices, including 3g with specific driver nmtype=$($NMTOOL | grep -A1 $iface | grep 'Type:' | cut -c22-) case $nmtype in "Wired") itype="802-3-ethernet" ;; "802.11 WiFi") itype="802-11-wireless" ;; "Mobile Broadband (GSM)") itype="gsm" ;; - esac + esac ;; esac - + echo_debug "nm" "rdw_nm($iface).$action: type=$itype [nm-tool]" -fi +fi case $action in up) # interface up, disable configured interfaces @@ -99,15 +99,15 @@ 802-3-ethernet) for dev in $DEVICES_TO_DISABLE_ON_LAN_CONNECT; do [ -n "$dev" ] && device_off $dev - done + done ;; - + 802-11-wireless) - for dev in $DEVICES_TO_DISABLE_ON_WIFI_CONNECT; do + for dev in $DEVICES_TO_DISABLE_ON_WIFI_CONNECT; do [ -n "$dev" ] && [ "$dev" != wifi ] && device_off $dev done ;; - + gsm) for dev in $DEVICES_TO_DISABLE_ON_WWAN_CONNECT; do [ -n "$dev" ] && [ "$dev" != wwan ] && device_off $dev @@ -119,25 +119,25 @@ down) # interface down, enable configured interfaces case $itype in 802-3-ethernet) - for dev in $DEVICES_TO_ENABLE_ON_LAN_DISCONNECT; do + for dev in $DEVICES_TO_ENABLE_ON_LAN_DISCONNECT; do [ -n "$dev" ] && device_on $dev done ;; - + 802-11-wireless) - for dev in $DEVICES_TO_ENABLE_ON_WIFI_DISCONNECT; do + for dev in $DEVICES_TO_ENABLE_ON_WIFI_DISCONNECT; do [ -n "$dev" ] && [ "$dev" != wifi ] && device_on $dev done ;; - + gsm) - for dev in $DEVICES_TO_ENABLE_ON_WWAN_DISCONNECT; do + for dev in $DEVICES_TO_ENABLE_ON_WWAN_DISCONNECT; do [ -n "$dev" ] && [ "$dev" != wwan ] && device_on $dev done ;; esac ;; # down - -esac - + +esac + exit 0 diff -Nru tlp-0.3.9/tlp-rdw-udev tlp-0.4/tlp-rdw-udev --- tlp-0.3.9/tlp-rdw-udev 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-rdw-udev 2013-09-19 05:54:22.000000000 +0000 @@ -12,7 +12,7 @@ for libdir in $LIBDIRS; do [ -d $libdir ] && break; done [ -d $libdir ] || exit 0 -for lib in $LIBS; do +for lib in $LIBS; do [ -f $libdir/$lib ] || exit 0 . $libdir/$lib done @@ -20,6 +20,7 @@ # --- MAIN read_defaults check_tlp_enabled || exit 0 +add_sbin2path # Get state ddir=/sys/devices/platform/$1 @@ -31,27 +32,27 @@ case $EVENT in dock) # laptop was docked - + # enable configured radios - for dev in $DEVICES_TO_ENABLE_ON_DOCK; do + for dev in $DEVICES_TO_ENABLE_ON_DOCK; do [ -n "$dev" ] && device_on $dev done - + # disable configured radios - for dev in $DEVICES_TO_DISABLE_ON_DOCK; do + for dev in $DEVICES_TO_DISABLE_ON_DOCK; do [ -n "$dev" ] && device_off $dev done ;; - + undock) # laptop was undocked # enable configured radios - for dev in $DEVICES_TO_ENABLE_ON_UNDOCK; do + for dev in $DEVICES_TO_ENABLE_ON_UNDOCK; do [ -n "$dev" ] && device_on $dev done - + # disable configured radios - for dev in $DEVICES_TO_DISABLE_ON_UNDOCK; do + for dev in $DEVICES_TO_DISABLE_ON_UNDOCK; do [ -n "$dev" ] && device_off $dev done ;; diff -Nru tlp-0.3.9/tlp-rdw.rules tlp-0.4/tlp-rdw.rules --- tlp-0.3.9/tlp-rdw.rules 2012-03-22 21:50:23.000000000 +0000 +++ tlp-0.4/tlp-rdw.rules 2013-09-19 05:54:22.000000000 +0000 @@ -1,4 +1,7 @@ # tlp-rdw - udev rules +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. # handle dock/undock events ACTION=="change", SUBSYSTEM=="platform", KERNEL=="dock.*", ATTR{type}=="dock_station", RUN+="/lib/udev/tlp-rdw-udev %k" diff -Nru tlp-0.3.9/tlp-rf tlp-0.4/tlp-rf --- tlp-0.3.9/tlp-rf 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-rf 2013-09-19 05:54:22.000000000 +0000 @@ -12,7 +12,7 @@ for libdir in $LIBDIRS; do [ -d $libdir ] && break; done [ -d $libdir ] || exit 0 -for lib in $LIBS; do +for lib in $LIBS; do [ -f $libdir/$lib ] || exit 0 . $libdir/$lib done @@ -33,12 +33,12 @@ device_off $self echo_device_state $self $devs ;; - + toggle) device_toggle $self echo_device_state $self $devs ;; - + *) device_state $self echo_device_state $self $devs diff -Nru tlp-0.3.9/tlp-rf-func tlp-0.4/tlp-rf-func --- tlp-0.3.9/tlp-rf-func 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-rf-func 2013-09-19 05:54:22.000000000 +0000 @@ -11,15 +11,14 @@ readonly RFKD="/dev/rfkill" readonly ALLDEV="bluetooth wifi wwan" -readonly STATEDIR="/var/lib/tlp" -readonly STATEFILE=$STATEDIR/rfkill-saved + # ---------------------------------------------------------------------------- # Functions get_devc () { # get control device for radio type -- $1: rftype; retval $devc - local i - + local i + check_sysfs "get_devc" "/sys/class/rfkill" devc="" @@ -27,11 +26,11 @@ rfkdev="1" devon="1" devoff="0" - + case $1 in wwan|bluetooth) for i in /sys/class/rfkill/rfkill* ; do - if [ -f $i/type ] && [ "$(cat $i/type)" = "$1" ]; then + if [ -f $i/type ] && [ "$(cat $i/type)" = "$1" ]; then devc="$i/state" echo_debug "rf" "get_devc($1) = $devc" return 0 @@ -50,43 +49,43 @@ return 0 fi done - + for i in /sys/class/rfkill/rfkill* ; do - if [ -f $i/type ] && [ "$(cat $i/type)" = "wlan" ]; then + if [ -f $i/type ] && [ "$(cat $i/type)" = "wlan" ]; then devc="$i/state" echo_debug "rf" "get_devc($1) = $devc" return 0 fi done ;; - + *) echo "Error: unknown device type \"$1\"" 1>&2 echo_debug "rf" "get_devc($1).unknown_type" return 0 ;; esac - + echo_debug "rf" "get_devc($1).not_present" - + return 0 } err_no_root_priv () { # check root privilege echo "Error: missing root privilege." 1>&2 echo_debug "rf" "$1.missing_root_privilege" - + return 0 } get_devs () { # get radio device state -- $1: rftype; retval $devs: 0=off/1=on if [ -n "$devc" ]; then - devs=$(cat $devc) + devs=$(cat $devc) [ "$rfkdev" = "0" ] && devs=$(($devs ^ $devoff)) fi echo_debug "rf" "get_devs($1) = $devs" - + return 0 } @@ -94,11 +93,11 @@ test_root || [ -w $RFKD ] } -device_state () { # get radio type state -- $1: rftype; retval $devc, $devs: 0=off/1=on +device_state () { # get radio type state -- $1: rftype; retval $devc, $devs: 0=off/1=on echo_debug "rf" "device_state($1)" - + get_devc $1 - get_devs $1 + get_devs $1 } device_on () { # enable radio type -- $1: rftype @@ -184,7 +183,7 @@ echo_debug "rf" "device_toggle($1).rfkill" case $devs in 0) $RFKILL unblock $1 ;; - 1) $RFKILL block $1 ;; + 1) $RFKILL block $1 ;; *) ;; esac else @@ -251,34 +250,34 @@ bluetooth) devstr="bluetooth" ;; - + wifi) devstr="wifi " ;; - + wwan) devstr="wwan " ;; - + *) devstr=$1 ;; esac case $2 in - 0) + 0) echo "$devstr = off (software)" ;; - 1) + 1) echo "$devstr = on" ;; - - 2) + + 2) echo "$devstr = off (hardware)" ;; - - 254) + + 254) echo "$devstr = none (no device)" ;; @@ -289,37 +288,38 @@ return 0 } -save_device_states () { # save all radio type states +save_device_states () { # save radio states -- $1: list of rftypes local dev + local devlist=${1:-$ALLDEV} # when arg empty -> use all - echo_debug "rf" "save_device_states" + echo_debug "rf" "save_device_states($devlist)" # create empty state file mkdir -p $STATEDIR - > $STATEFILE + : > $RFSTATEFILE # iterate over all possible devices -> save state in file - for dev in $ALLDEV; do + for dev in $devlist; do device_state $dev - echo "$dev $devs" >> $STATEFILE + echo "$dev $devs" >> $RFSTATEFILE done - + return 0 } -restore_device_states () { # restore all radio type states +restore_device_states () { # restore radio type states local sline echo_debug "rf" "restore_device_states" - - if [ -f $STATEFILE ]; then + + if [ -f $RFSTATEFILE ]; then set_run_flag $LOCK_RDW - + # read state file while read sline; do set -- $sline # read dev, state into $1, $2 - device_set_state $1 $2 - done < $STATEFILE + device_set_state $1 $2 + done < $RFSTATEFILE reset_run_flag $LOCK_RDW @@ -332,7 +332,7 @@ init_radio_devices () { # initialize all radio type states # $1: start/stop/radiosw # called from init scripts - + local dev devs2disable devs2enable restore # save/restore mode is disabled by default @@ -355,11 +355,11 @@ echo "No saved radio device states found." fi ;; - + stop) save_device_states echo "Radio device states saved." - ;; + ;; esac else # "disable/enable on startup/shutdown" or "radiosw" mode @@ -368,7 +368,7 @@ devs2disable="$DEVICES_TO_DISABLE_ON_STARTUP" devs2enable="$DEVICES_TO_ENABLE_ON_STARTUP" ;; - + stop) devs2disable="$DEVICES_TO_DISABLE_ON_SHUTDOWN" devs2enable="$DEVICES_TO_ENABLE_ON_SHUTDOWN" @@ -395,7 +395,7 @@ if [ "$1" = "radiosw" ]; then # radiosw mode: disable radios not listed for dev in bluetooth wifi wwan; do - if ! patinstr "$dev" "$devs2enable"; then + if ! wordinlist "$dev" "$devs2enable"; then device_off $dev fi done @@ -410,10 +410,10 @@ fi fi - # clean up: discard state file - rm -f $STATEFILE 2> /dev/null + # clean up: discard state file + rm -f $RFSTATEFILE 2> /dev/null fi - + return 0 } diff -Nru tlp-0.3.9/tlp-run-on tlp-0.4/tlp-run-on --- tlp-0.3.9/tlp-run-on 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-run-on 2013-09-19 05:54:22.000000000 +0000 @@ -16,13 +16,13 @@ case $self in run-on-ac) - if on_ac_power; then + if on_ac_power; then $cmd $@ fi ;; - + run-on-bat) - if ! on_ac_power; then + if ! on_ac_power; then $cmd $@ fi ;; diff -Nru tlp-0.3.9/tlp-sleep.service tlp-0.4/tlp-sleep.service --- tlp-0.3.9/tlp-sleep.service 1970-01-01 00:00:00.000000000 +0000 +++ tlp-0.4/tlp-sleep.service 2013-09-19 05:54:22.000000000 +0000 @@ -0,0 +1,18 @@ +# tlp - systemd suspend/resume service +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. + +[Unit] +Description=TLP suspend/resume +Before=sleep.target +StopWhenUnneeded=yes + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/tlp suspend +ExecStop=/usr/sbin/tlp resume + +[Install] +WantedBy=sleep.target diff -Nru tlp-0.3.9/tlp-stat tlp-0.4/tlp-stat --- tlp-0.3.9/tlp-stat 2013-05-02 17:17:07.000000000 +0000 +++ tlp-0.4/tlp-stat 2013-09-19 05:54:22.000000000 +0000 @@ -71,7 +71,7 @@ format=$( echo $format | sed -r "s/##(.*)##/\1/" ) printf "$format\n" "$sysf" "$val" fi - + return 0 } @@ -144,7 +144,7 @@ show_bat=1 needs_root_priv=1 ;; - + "-c"|"--config") show_all=0 show_conf=1 @@ -162,7 +162,7 @@ show_temp=1 : ${needs_root_priv:=0} ;; - + "-T"|"--trace") show_all=0 show_trace=1 @@ -176,7 +176,7 @@ esac done } - + # --- Locate and source libraries for libdir in $LIBDIRS; do [ -d $libdir ] && break; done @@ -185,7 +185,7 @@ exit 1 fi -for lib in $LIBS; do +for lib in $LIBS; do if [ ! -f $libdir/$lib ]; then echo "Error: missing function library \'$libdir/$lib\'." exit 1 @@ -195,6 +195,8 @@ # --- MAIN +add_sbin2path + read_args $* : ${needs_root_priv:=1} @@ -232,7 +234,7 @@ echo "System = $dmirslt" read_dmi bios_version echo "BIOS = $dmirslt" - + # --- show release & kernel info cmd_exists $LSBREL && echo "Release = $($LSBREL -d -s)" echo "Kernel = $(uname -r -m)" @@ -256,31 +258,45 @@ echo "power source = battery" fi echo - + # --- show cpu info echo "+++ Processor" sed -rn 's/model name[ \t]+: (.+)/CPU Model = \1/p' /proc/cpuinfo | head -1 echo for cpuf in /sys/devices/system/cpu/cpu*/cpufreq; do - if [ -f $cpuf/scaling_governor ]; then + if [ -f $cpuf/scaling_driver ]; then + printparm "%-54s = ##%s##" $cpuf/scaling_driver printparm "%-54s = ##%s##" $cpuf/scaling_governor - printf "%-54s = %8d [kHz]\n" $cpuf/scaling_min_freq $(cat $cpuf/scaling_min_freq) - printf "%-54s = %8d [kHz]\n" $cpuf/scaling_max_freq $(cat $cpuf/scaling_max_freq) - printf "%s = " $cpuf/scaling_available_frequencies - for freq in $(cat $cpuf/scaling_available_frequencies); do - printf "%s " $freq - done - printf "[kHz]\n\n" + + if [ -f $cpuf/scaling_min_freq ]; then + printf "%-54s = %8d [kHz]\n" $cpuf/scaling_min_freq $(cat $cpuf/scaling_min_freq) + fi + + if [ -f $cpuf/scaling_max_freq ]; then + printf "%-54s = %8d [kHz]\n" $cpuf/scaling_max_freq $(cat $cpuf/scaling_max_freq) + fi + + if [ -f $cpuf/scaling_available_frequencies ]; then + printf "%s = " $cpuf/scaling_available_frequencies + for freq in $(cat $cpuf/scaling_available_frequencies); do + printf "%s " $freq + done + printf "[kHz]\n" + fi + printf "\n" fi done - - if [ -f $CPU_BOOST_ALL_CTRL ]; then + check_intel_pstate + + if [ $intel_pstate -eq 1 ]; then + printparm "%-54s = ##%d##" $CPU_TURBO_PSTATE + elif [ -f $CPU_BOOST_ALL_CTRL ]; then get_sysval $CPU_BOOST_ALL_CTRL; boost=$? # simple test for attribute "w" doesn't work, so actually write - if ( echo "$boost" > $CPU_BOOST_ALL_CTRL ) 2> /dev/null; then + if ( echo "$boost" > $CPU_BOOST_ALL_CTRL ) 2> /dev/null; then printparm "%-54s = ##%d##" $CPU_BOOST_ALL_CTRL else printparm "%-54s = ##%d## (cpu not supported)" $CPU_BOOST_ALL_CTRL @@ -288,13 +304,13 @@ else printparm "%-54s = (not available)" $CPU_BOOST_ALL_CTRL fi - - + + for pool in mc smp smt; do sdev="/sys/devices/system/cpu/sched_${pool}_power_savings" [ -f $sdev ] && printparm "%-54s = ##%d##" $sdev done - + # --- show nmi watchdog printparm "%-54s = ##%d##" $NMIWD echo @@ -312,12 +328,12 @@ done if [ $phc_avail = 0 ]; then echo "PHC kernel not available." - echo + echo fi - + fi # show_all -if [ "$show_temp" = "1" ] || [ "$show_all" = "1" ]; then +if [ "$show_temp" = "1" ] || [ "$show_all" = "1" ]; then # --- show temperatures echo "+++ Temperatures" if [ -f $IBMTHERMAL ]; then @@ -342,7 +358,7 @@ if [ $cmax -gt 0 ]; then printf "CPU temp = %5d [°C]\n" $(( $cmax / 1000 )) fi - + fi # --- show fan speed @@ -363,10 +379,10 @@ fi fi echo - + fi # show_temp -if [ "$show_all" = "1" ]; then +if [ "$show_all" = "1" ]; then # --- show laptop-mode, dirty buffers params echo "+++ File System" printparm "%-38s = ##%5d##" /proc/sys/vm/laptop_mode @@ -375,32 +391,32 @@ printparm "%-38s = ##%5d##" /proc/sys/vm/dirty_ratio printparm "%-38s = ##%5d##" /proc/sys/vm/dirty_background_ratio printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/age_buffer_centisecs - printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/xfssyncd_centisecs + printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/xfssyncd_centisecs printparm "%-38s = ##%5d##" /proc/sys/fs/xfs/xfsbufd_centisecs - echo - + echo + # --- show disk info form hdparm echo "+++ Storage Devices" DISK_DEVICES=${DISK_DEVICES:=sda} for dev in $DISK_DEVICES; do # iterate all devices get_disk_dev $dev - + if [ -b /dev/$disk_dev ]; then get_disk_state $disk_dev check_disk_hdparm_cap $disk_dev if [ $? = 0 ]; then echo "/dev/$disk_dev:" - + if [ -n "$disk_id" ]; then echo " Disk ID = $disk_id" fi - + echo -n " Model = " echo_disk_model $disk_dev - + echo -n " Firmware = " echo_disk_firmware $disk_dev - + get_disk_apm_level $disk_dev apm=$? echo -n " APM Level = " @@ -417,12 +433,12 @@ 0) echo " TRIM = not supported" ;; 1) echo " TRIM = supported" ;; esac - + echo " scheduler = $(cat /sys/block/$disk_dev/queue/scheduler | sed -r 's/.*\[(.*)\].*/\1/')" - + if cmd_exists $SMARTCTL ; then # --- show SMART data - echo + echo echo " SMART info:" $SMARTCTL -A /dev/$disk_dev | grep -v '<==' | \ awk -F ' ' '$2 ~ /Start_Stop_Count|Load_Cycle_Count|Reallocated_Sector_Ct|Used_Rsvd_Blk_Cnt_Chip|Used_Rsvd_Blk_Cnt_Tot/ \ @@ -442,16 +458,16 @@ fi echo - # restore standby state + # restore standby state [ "$disk_state" = "standby" ] && spindown_disk $disk_dev fi fi done echo - + # --- show sata alpm mode echo "+++ SATA Aggressive Link Power Management" - cnt=0 + cnt=0 for i in /sys/class/scsi_host/host* ; do if [ -f $i/link_power_management_policy ]; then printparm "%-56s = ##%s##" $i/link_power_management_policy @@ -460,9 +476,9 @@ done if [ $cnt = 0 ]; then echo "No AHCI-enabled host controller detected." - fi - echo - + fi + echo + # --- show pcie aspm state echo "+++ PCIe Active State Power Management" if [ -f $ASPM ]; then @@ -472,14 +488,14 @@ echo "$ASPM = $pol" else echo "$ASPM = $pol (using bios preferences)" - fi + fi else echo "$ASPM = (not available)" fi echo - + # --- show i915 power mgmt - if [ -d $I915D ]; then + if [ -d $I915D ]; then echo "+++ Intel Graphics" printparm_i915 $I915D/powersave printparm_i915 $I915D/i915_enable_rc6 @@ -488,10 +504,19 @@ printparm_i915 $I915D/semaphores echo fi - - # --- show radeon power profile + + # --- show radeon power profile or dpm state for card in /sys/class/drm/card[0-9]/device ; do - if [ -f $card/power_method ] && [ -f $card/power_profile ]; then + if [ -f $card/power_dpm_state ] && [ -f $card/power_dpm_force_performance_level ]; then + # Use new radeon dpm state + echo "+++ Radeon Graphics" + printparm "%-25s = ##%s##" $card/power_dpm_state + printparm "%-25s = ##%s##" $card/power_dpm_force_performance_level + echo + break + + elif [ -f $card/power_method ] && [ -f $card/power_profile ]; then + # Use old radeon power profile echo "+++ Radeon Graphics" printparm "%-25s = ##%s##" $card/power_method printparm "%-25s = ##%s##" $card/power_profile @@ -501,7 +526,7 @@ done fi # show_all -if [ "$show_rfkill" = "1" ] || [ "$show_all" = "1" ]; then +if [ "$show_rfkill" = "1" ] || [ "$show_all" = "1" ]; then echo "+++ Wireless" # --- show rfkill state for i in bluetooth wifi wwan; do @@ -510,55 +535,41 @@ echo_device_state $i $devs done echo -fi # show_rfkill -if [ "$show_all" = "1" ]; then # --- show wifi power mode get_wifi_ifaces for iface in $wifaces; do if [ -n "$iface" ]; then - iwrc=1 - if cmd_exists $IW; then - wifipm=$($IW dev $iface get power_save 2> /dev/null) - iwrc=$? - if [ $iwrc = 0 ]; then - wifipm=$(echo $wifipm | sed -r 's/.*(on|off).*/\1/') - fi + wifipm="" + + if [ "$X_DONT_USE_IW" != "1" ] && cmd_exists $IW; then + # try with iw first + wifipm=$($IW dev $iface get power_save 2> /dev/null | \ + grep "Power save" | \ + sed -r 's/.*Power save: (on|off).*/\1/') fi - if [ $iwrc != 0 ]; then - wifipm=$($IWC $iface 2> /dev/null | grep "Power Management" | \ - sed -r 's/.*Power Management:(on|off).*/\1/') + + if cmd_exists $IWC; then + if [ -z "$wifipm" ]; then + # iw did not succeed or iw not installed -> try with iwconfig + wifipm=$($IWC $iface 2> /dev/null | \ + grep "Power Management" | \ + sed -r 's/.*Power Management:(on|off).*/\1/') + fi fi get_wifi_driver $iface echo -n "$iface($wifidrv): power management = " case $wifipm in - on) - echo "on" - ;; - - off) - if cmd_exists $IW && [ $iwrc = 0 ]; then - $IW dev $iface set power_save off > /dev/null 2>&1 - else - $IWC $iface power off > /dev/null 2>&1 - fi - - if [ $? = 0 ] ; then - echo "off" - else - echo "off (not supported)" - fi - ;; - - *) - echo "unknown" - ;; + on|off) echo "$wifipm" ;; + *) echo "unknown" ;; esac fi done [ -n "$wifaces" ] && echo +fi # show_rfkill +if [ "$show_all" = "1" ]; then # --- show sound power mode echo "+++ Audio" if [ -d /sys/module/snd_hda_intel ]; then @@ -569,7 +580,7 @@ printparm "%s = ##%s##" /sys/module/snd_ac97_codec/parameters/power_save fi echo - + fi # show_all if [ "$show_bat" = "1" ] || [ "$show_all" = "1" ]; then @@ -596,21 +607,21 @@ esac echo fi - + if [ $tpsmapi -eq 0 ]; then # it's a ThinkPad with tp-smapi - + for batd in $SMAPIDIR/BAT[01]; do if [ -d $batd ]; then batt=${batd##/*/} - + if bat_exists $batt ; then case $batt in BAT0) bati=1; echo "+++ ThinkPad Battery Status (Main)" ;; BAT1) bati=2; echo "+++ ThinkPad Battery Status (Ultrabay/Slice)" ;; *) bati=1 echo "+++ ThinkPad Battery Status" ;; esac - + printparm "%-59s = ##%s##" $batd/manufacturer printparm "%-59s = ##%s##" $batd/model printparm "%-59s = ##%s##" $batd/manufacture_date @@ -625,14 +636,14 @@ printparm "%-59s = ##%6d## [mW]" $batd/power_now printparm "%-59s = ##%6d## [mW]" $batd/power_avg echo - + if [ $tpacpi -eq 0 ]; then # --- show ThinkPad charge thresholds via tpacpi-bat print_tpacpi_thresholds $batt $bati else # show thresholds via tp-smapi printparm "%-59s = ##%6d## [%%]" $batd/start_charge_thresh - printparm "%-59s = ##%6d## [%%]" $batd/stop_charge_thresh + printparm "%-59s = ##%6d## [%%]" $batd/stop_charge_thresh printparm "%-59s = ##%6d##" $batd/force_discharge fi echo @@ -641,14 +652,14 @@ done elif [ -d $ACPIBATDIR ]; then # --- show ACPI data - + for batd in $ACPIBATDIR/*; do if [ -d $batd ] \ && [ "$(cat $batd/type)" = "Battery" ] \ && [ "$(cat $batd/present)" = "1" ]; then batt=${batd##/*/} - + if [ $tpacpi -eq 0 ]; then # it's a ThinkPad with tpacpi-bat only case $batt in @@ -657,10 +668,10 @@ *) bati=1; echo "+++ ThinkPad Battery Status" ;; esac else - # it's some other laptop model or brand + # it's some other laptop model or brand echo "+++ Battery Status" fi - + printparm "%-59s = ##%s##" $batd/manufacturer printparm "%-59s = ##%s##" $batd/model_name @@ -671,7 +682,7 @@ printf "%-59s = (not supported)\n" $batd/cycle_count fi - if [ -f $batd/energy_full ]; then + if [ -f $batd/energy_full ]; then printparm "%-59s = ##%6d## [mWh]" $batd/energy_full_design "" 000 printparm "%-59s = ##%6d## [mWh]" $batd/energy_full "" 000 printparm "%-59s = ##%6d## [mWh]" $batd/energy_now "" 000 @@ -692,23 +703,23 @@ fi # if $tpcacpi fi # if $batd done # $batd - + fi # if /sys/class/power_supply - + fi # show_bat if [ "$show_all" = "1" ]; then # -- show runtime pm echo "+++ Runtime Power Management" doall=${RUNTIME_PM_ALL:-0} - + if cmd_exists $TLPPCI; then - $TLPPCI + $TLPPCI else echo "Error: missing subcommand $TLPPCI." fi - echo - + echo + # -- show usb autosuspend echo "+++ USB" if [ "$USB_AUTOSUSPEND" = "1" ]; then @@ -718,9 +729,9 @@ fi echo "tlp usb blacklist = ${USB_BLACKLIST:=(not configured)}" echo - + if cmd_exists $TLPUSB; then - $TLPUSB + $TLPUSB else echo "Error: missing subcommand $TLPUSB." fi @@ -769,7 +780,7 @@ grep "tlp\[" $DEBUGLOG else echo "Error: $DEBUGLOG does not exist." - echo + echo echo "Solution: create an rsyslog conffile /etc/rsyslog.d/90-debug.conf with the following contents" echo " *.=debug;\\" echo " mail,authpriv,cron.none;\\" diff -Nru tlp-0.3.9/tlp-usb-udev tlp-0.4/tlp-usb-udev --- tlp-0.3.9/tlp-usb-udev 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-usb-udev 2013-09-19 05:54:22.000000000 +0000 @@ -10,6 +10,7 @@ readonly USBD=/sys/bus/usb/devices readonly USB_TIMEOUT=2 readonly USB_TIMEOUT_MS=2000 +readonly USB_WWAN_VENDORS="0bdb 05c6 1199" readonly RUNDIR=/var/run/tlp readonly USB_DONE=usb_done @@ -17,23 +18,27 @@ readonly CONFFILE=/etc/default/tlp # --- Subroutines -patinstr () { # $1: pattern, $2: target -- test if pattern matches part of target - [ -n "$1" -a -n "$2" -a -z "${2##*$1*}" ] - return $? +wordinlist () { # test if word in list + # $1: word, $2: whitespace-separated list of words + local word + + if [ -n "${1-}" ]; then + for word in ${2-}; do + [ "${word}" != "${1}" ] || return 0 # exact match + done + fi + + return 1 # no match } -echo_debug () { # $1: tag; $2: msg; echo debug msg if tag matches - if patinstr "$1" "$TLP_DEBUG"; then +echo_debug () { # $1: tag; $2: msg; echo debug msg if tag matches + if wordinlist "$1" "$TLP_DEBUG"; then $LOGGER -p debug -t "tlp[$$,$PPID]" "$2" fi } # --- MAIN -# Get args -usbdevp=/sys$1 -hid='' - # Read config [ -f $CONFFILE ] || exit 0 . $CONFFILE @@ -52,61 +57,77 @@ # Mode 2 (default): # - Everything - including system startup, but not shutdown - is handled by this udev script - # Do exit if mode 1 and no startup completion flag [ "$X_TLP_USB_MODE" = "1" ] && [ ! -f $RUNDIR/$USB_DONE ] && exit 0 -# Check for hid subdevices -for subdevp in $usbdevp/*:*; do - if [ -d $subdevp ] && [ "$(cat $subdevp/bInterfaceClass)" = "03" ]; then - hid="_hid" - break - fi -done +# Get args +usbdev=/sys$1 +exc="" # Handle device -if [ -f $usbdevp/power/autosuspend ] || [ -f $usbdevp/power/autosuspend_delay_ms ]; then +if [ -f $usbdev/power/autosuspend ] || [ -f $usbdev/power/autosuspend_delay_ms ]; then + # device is autosuspendable + # wait for sysfs to settle sleep 0.5 - # device is autosuspendable + # Check for hid subdevices and exclude them + for subdev in $usbdev/*:*; do + if [ -d $subdev ] && [ "$(cat $subdev/bInterfaceClass)" = "03" ]; then + exc="_hid" + break + fi + done + + # Check for wwan vendor ids + USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # default is exclude + + if [ $USB_BLACKLIST_WWAN = "1" ] && [ -z "$exc" ]; then + vendor="$(cat $usbdev/idVendor)" + if wordinlist "$vendor" "$USB_WWAN_VENDORS"; then + exc="_wwan" + fi + fi + + # Apply autosuspend ctrlf="control" autof="autosuspend_delay_ms" - usbid="$(cat $usbdevp/idVendor):$(cat $usbdevp/idProduct)" - busdev="Bus $(cat $usbdevp/busnum) Dev $(cat $usbdevp/devnum)" - + usbid="$(cat $usbdev/idVendor):$(cat $usbdev/idProduct)" + busdev="Bus $(cat $usbdev/busnum) Dev $(cat $usbdev/devnum)" + control="auto" - if [ "$hid" = "_hid" ]; then - # hid devices + if [ -n "$exc" ]; then + # hid or wwan device control="on" - elif patinstr "$usbid" "$USB_BLACKLIST"; then + elif wordinlist "$usbid" "$USB_BLACKLIST"; then # blacklisted device control="on" + exc="_bl" fi - - if [ -f $usbdevp/power/control ]; then - echo "$control" > $usbdevp/power/control + + if [ -f $usbdev/power/control ]; then + echo "$control" > $usbdev/power/control else # level is deprecated - echo "$control" > $usbdevp/power/level + echo "$control" > $usbdev/power/level ctrlf="level" fi - - if [ -f $usbdevp/power/autosuspend_delay_ms ]; then - echo $USB_TIMEOUT_MS > $usbdevp/power/autosuspend_delay_ms 2> /dev/null + + if [ -f $usbdev/power/autosuspend_delay_ms ]; then + echo $USB_TIMEOUT_MS > $usbdev/power/autosuspend_delay_ms 2> /dev/null if [ $? != 0 ]; then # openSUSE 11.4/2.6.37: writing to autosuspend_delay_ms fails -> fallback to autosuspend - echo_debug "usb" "udev_usb.autosuspend_delay_ms_not_writable: $busdev ID $usbid $usbdevp" - echo $USB_TIMEOUT > $usbdevp/power/autosuspend + echo_debug "usb" "udev_usb.autosuspend_delay_ms_not_writable: $busdev ID $usbid $usbdev" + echo $USB_TIMEOUT > $usbdev/power/autosuspend autof="autosuspend" fi else # autosuspend is deprecated - echo $USB_TIMEOUT > $usbdevp/power/autosuspend + echo $USB_TIMEOUT > $usbdev/power/autosuspend autof="autosuspend" fi - - echo_debug "usb" "udev_usb.$control$hid: $busdev ID $usbid $usbdevp [$ctrlf $autof]" + + echo_debug "usb" "udev_usb.$control$exc: $busdev ID $usbid $usbdev [$ctrlf $autof]" fi exit 0 diff -Nru tlp-0.3.9/tlp-usblist tlp-0.4/tlp-usblist --- tlp-0.3.9/tlp-usblist 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp-usblist 2013-09-19 05:54:22.000000000 +0000 @@ -12,7 +12,7 @@ my %usbdevices; my $udev; -# Get sysfs value, return empty string if nonexistent or not readable +# Get sysfs value, return empty string if nonexistent or not readable sub catsysf { my $sysval = ""; if (open SYSF, "$_[0]") { @@ -26,42 +26,42 @@ sub usbdriverlist { my $driverlist = ""; my $subdev; - + # Iterate subdevices foreach $subdev (glob "$_[0]/*:*") { - if (-l "$subdev/driver") { + if (-l "$subdev/driver") { ( my $driver = readlink ("$subdev/driver") ) =~ s{.*/}{}; - + if (index ($driverlist, $driver) == -1) { - if ($driverlist) { $driverlist = $driverlist . ", " . $driver; } + if ($driverlist) { $driverlist = $driverlist . ", " . $driver; } else { $driverlist = $driver; } } # if index } # if $subdev/driver } # foreach $subdev - + if (! $driverlist) { $driverlist = "no driver"; } - return $driverlist + return $driverlist } # Read usb device tree attributes as arrays into %usbdevices hash, indexed by Bus_Device foreach $udev (grep { ! /:/ } glob "/sys/bus/usb/devices/*") { my $asf = "autosuspend_delay_ms"; my $asv = catsysf ("$udev/power/$asf"); - - if (length ($asv) == 0) { + + if (length ($asv) == 0) { # autosuspend_delay_ms nonexistent or not readable, try autosuspend (deprecated) - $asf = "autosuspend"; + $asf = "autosuspend"; $asv = catsysf ("$udev/power/$asf"); } - - if (length ($asv) > 0) { + + if (length ($asv) > 0) { my $cnf = "control"; my $cnv = catsysf ("$udev/power/$cnf"); if (! $cnv) { $cnf = "level"; # level is deprecated $cnv = catsysf ("$udev/power/$cnf"); } - my $usbk = sprintf ("%03d_%03d", + my $usbk = sprintf ("%03d_%03d", catsysf ("$udev/busnum"), catsysf ("$udev/devnum") ); my $usbv; @@ -79,7 +79,7 @@ my ($bus, $dev, $usbid, $desc) = /Bus (\S+) Device (\S+): ID (\S+)[ ]+(.*)/; my $usbk = $bus . "_" . $dev; $desc ||= ""; - print "Bus $bus Device $dev ID $usbid $usbdevices{$usbk}[1] -- $desc (" + print "Bus $bus Device $dev ID $usbid $usbdevices{$usbk}[1] -- $desc (" . usbdriverlist ($usbdevices{$usbk}[0]) . ")\n"; } diff -Nru tlp-0.3.9/tlp.init tlp-0.4/tlp.init --- tlp-0.3.9/tlp.init 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp.init 2013-09-19 05:54:22.000000000 +0000 @@ -1,5 +1,10 @@ #!/bin/sh +# tlp - system startup/shutdown +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. + ### BEGIN INIT INFO # Provides: tlp # Required-Start: $remote_fs $all @@ -17,7 +22,7 @@ force-reload|\ *) TLP=/usr/sbin/tlp - [ -x $TLP ] && $TLP init $1 upwr + [ -x $TLP ] && $TLP init $1 ;; esac diff -Nru tlp-0.3.9/tlp.rules tlp-0.4/tlp.rules --- tlp-0.3.9/tlp.rules 2012-03-22 21:50:23.000000000 +0000 +++ tlp-0.4/tlp.rules 2013-09-19 05:54:22.000000000 +0000 @@ -1,4 +1,10 @@ # tlp - udev rules +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. + +# handle change of power source ac/bat +ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", RUN+="/usr/sbin/tlp auto" # handle added usb devices (exclude subdevices) ACTION=="add", SUBSYSTEM=="usb", DRIVER=="usb", ENV{DEVTYPE}=="usb_device", RUN+="/lib/udev/tlp-usb-udev %p" diff -Nru tlp-0.3.9/tlp.service tlp-0.4/tlp.service --- tlp-0.3.9/tlp.service 2013-03-30 12:14:09.000000000 +0000 +++ tlp-0.4/tlp.service 2013-09-19 05:54:22.000000000 +0000 @@ -1,15 +1,11 @@ -# This file is part of systemd. +# tlp - systemd startup/shutdown service # -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. [Unit] -Description=Initialisation for TLP -DefaultDependencies=no -Requires=upower.service -After=upower.service +Description=TLP system startup/shutdown +After=multi-user.target Before=shutdown.target [Service] @@ -19,4 +15,4 @@ ExecStop=/usr/sbin/tlp init stop [Install] -WantedBy=graphical.target +WantedBy=multi-user.target diff -Nru tlp-0.3.9/tlp.upstart tlp-0.4/tlp.upstart --- tlp-0.3.9/tlp.upstart 2012-08-13 19:11:40.000000000 +0000 +++ tlp-0.4/tlp.upstart 2013-09-19 05:54:22.000000000 +0000 @@ -1,4 +1,7 @@ -# TLP settings on system startup/shutdown +# tlp - system startup/shutdown +# +# Copyright (c) 2013 Thomas Koch +# This software is licensed under the GPL v2 or later. description "tlp" @@ -9,14 +12,14 @@ pre-start script [ -x $TLP ] || exit 4 - $TLP init start upwr + $TLP init start end script post-stop script [ -x $TLP ] || exit 4 - $TLP init stop - + $TLP init stop + end script diff -Nru tlp-0.3.9/tpacpi-bat tlp-0.4/tpacpi-bat --- tlp-0.3.9/tpacpi-bat 2013-05-02 17:17:07.000000000 +0000 +++ tlp-0.4/tpacpi-bat 2013-09-19 05:54:22.000000000 +0000 @@ -42,11 +42,17 @@ my $aslBases = { 'default' => '\_SB.PCI0.LPC.EC.HKEY', 'ThinkPad E420s' => '\_SB.PCI0.LPCB.EC0.HKEY', + 'ThinkPad Edge E335' => '\_SB.PCI0.LPC0.EC0.HKEY', + 'ThinkPad Edge E430' => '\_SB.PCI0.LPCB.EC0.HKEY', + 'ThinkPad Edge E530' => '\_SB.PCI0.LPCB.EC0.HKEY', 'ThinkPad L430' => '\_SB.PCI0.LPCB.H_EC.HKEY', 'ThinkPad L530' => '\_SB.PCI0.LPCB.H_EC.HKEY', 'ThinkPad S420' => '\_SB.PCI0.LPCB.EC0.HKEY', 'ThinkPad S430' => '\_SB.PCI0.LPCB.EC0.HKEY', 'ThinkPad Edge S430' => '\_SB.PCI0.LPCB.EC0.HKEY', + 'ThinkPad S431' => '\_SB.PCI0.LPCB.EC0.HKEY', + 'ThinkPad S3-S431' => '\_SB.PCI0.LPCB.EC0.HKEY', + 'ThinkPad T430u' => '\_SB.PCI0.LPCB.EC.HKEY', 'ThinkPad X121e' => '\_SB.PCI0.LPCB.EC.HKEY', }; diff -Nru tlp-0.3.9/zztlp tlp-0.4/zztlp --- tlp-0.3.9/zztlp 2013-05-02 16:54:33.000000000 +0000 +++ tlp-0.4/zztlp 2013-09-19 05:54:22.000000000 +0000 @@ -14,12 +14,12 @@ [ -x $TLP ] || exit 0 $TLP $1 ;; - + help) print_help ;; - + *) - exit $NA + exit $NA ;; esac