Subject: bug#26137: [PATCH v3 4/6] gnu: Add tlp service.

From: Mathieu Othacehe <[email-masked]>
Date: Fri, 24 Mar 2017 11:00:15 +0100

* gnu/services/pm.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add gnu/services/tlp.scm.
* doc/guix.texi (Power management Services): New section.
---
 doc/guix.texi       | 505 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gnu/local.mk        |   2 +
 gnu/services/pm.scm | 404 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 911 insertions(+)
 create mode 100644 gnu/services/pm.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index fb0862096..79d9c9fcb 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -216,6 +216,7 @@ Services
 * VPN Services::                VPN daemons.
 * Network File System::         NFS related services.
 * Continuous Integration::      The Cuirass service.
+* Power management Services::   The TLP tool.
 * Miscellaneous Services::      Other services.
 
 Defining Services
@@ -8451,6 +8452,7 @@ declaration.
 * VPN Services::                VPN daemons.
 * Network File System::         NFS related services.
 * Continuous Integration::      The Cuirass service.
+* Power management Services::   The TLP tool.
 * Miscellaneous Services::      Other services.
 @end menu
 
@@ -13708,6 +13710,509 @@ The Cuirass package to use.
 @end table
 @end deftp
 
+@node Power management Services
+@subsubsection Power management Services
+
+@cindex power management with TLP
+The @code{(gnu services pm)} module provides a Guix service definition
+for the Linux power management tool TLP.
+
+TLP enables various powersaving modes in userspace and kernel.
+Contrary to @code{upower-service}, it is not a passive,
+monitoring tool, as it will apply custom settings each time a new power
+source is detected.  More information can be found at
+@uref{http://linrunner.de/en/tlp/tlp.html, TLP home page.}.
+
+@deffn {Scheme Variable} tlp-service-type
+The service type for the TLP tool.  Its value should be a valid
+TLP configuration (see below).  For example:
+@example
+(service tlp-service-type (tlp-configuration))
+@end example
+@end deffn
+
+By default TLP does not need much configuration but most TLP parameters
+can be tweaked using @code{tlp-configuration}.
+
+Each parameter definition is preceded by its type; for example,
+@samp{boolean foo} indicates that the @code{foo} parameter
+should be specified as a boolean.  Types starting with
+@code{maybe-} denote parameters that won't show up in TLP config file
+when their value is @code{'disabled}.
+
+@c The following documentation was initially generated by
+@c (generate-tlp-documentation) in (gnu services pm).  Manually maintained
+@c documentation is better, so we shouldn't hesitate to edit below as
+@c needed.  However if the change you want to make to this documentation
+@c can be done in an automated way, it's probably easier to change
+@c (generate-documentation) than to make it below and have to deal with
+@c the churn as TLP updates.
+
+Available @code{tlp-configuration} fields are:
+
+@deftypevr {@code{tlp-configuration} parameter} package tlp
+The TLP package.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean tlp-enable?
+Set to true if you wish to enable TLP.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string tlp-default-mode
+Default mode when no power supply can be detected.  Alternatives are AC
+and BAT.
+
+Defaults to @samp{"AC"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer disk-idle-secs-on-ac
+Number of seconds Linux kernel has to wait after the disk goes idle,
+before syncing on AC.
+
+Defaults to @samp{0}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer disk-idle-secs-on-bat
+Same as @code{disk-idle-ac} but on BAT mode.
+
+Defaults to @samp{2}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer max-lost-work-secs-on-ac
+Dirty pages flushing periodicity, expressed in seconds.
+
+Defaults to @samp{15}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer max-lost-work-secs-on-bat
+Same as @code{max-lost-work-secs-on-ac} but on BAT mode.
+
+Defaults to @samp{60}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-space-separated-string-list cpu-scaling-governor-on-ac
+CPU frequency scaling governor on AC mode.  With intel_pstate driver,
+alternatives are powersave and performance.  With acpi-cpufreq driver,
+alternatives are ondemand, powersave, performance and conservative.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-space-separated-string-list cpu-scaling-governor-on-bat
+Same as @code{cpu-scaling-governor-on-ac} but on BAT mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-scaling-min-freq-on-ac
+Set the min available frequency for the scaling governor on AC.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-scaling-max-freq-on-ac
+Set the max available frequency for the scaling governor on AC.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-scaling-min-freq-on-bat
+Set the min available frequency for the scaling governor on BAT.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-scaling-max-freq-on-bat
+Set the max available frequency for the scaling governor on BAT.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-min-perf-on-ac
+Limit the min P-state to control the power dissipation of the CPU, in AC
+mode.  Values are stated as a percentage of the available performance.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-max-perf-on-ac
+Limit the max P-state to control the power dissipation of the CPU, in AC
+mode.  Values are stated as a percentage of the available performance.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-min-perf-on-bat
+Same as @code{cpu-min-perf-on-ac} on BAT mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-non-negative-integer cpu-max-perf-on-bat
+Same as @code{cpu-max-perf-on-ac} on BAT mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-boolean cpu-boost-on-ac?
+Enable CPU turbo boost feature on AC mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-boolean cpu-boost-on-bat?
+Same as @code{cpu-boost-on-ac?} on BAT mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean sched-powersave-on-ac?
+Allow Linux kernel to minimize the number of CPU cores/hyper-threads
+used under light load conditions.
+
+Defaults to @samp{#f}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean sched-powersave-on-bat?
+Same as @code{sched-powersave-on-ac?} but on BAT mode.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean nmi-watchdog?
+Enable Linux kernel NMI watchdog.
+
+Defaults to @samp{#f}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-string phc-controls
+For Linux kernels with PHC patch applied, change CPU voltages.  An
+example value would be @samp{"F:V F:V F:V F:V"}.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string energy-perf-policy-on-ac
+Set CPU performance versus energy saving policy on AC.  Alternatives are
+performance, normal, powersave.
+
+Defaults to @samp{"performance"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string energy-perf-policy-on-bat
+Same as @code{energy-perf-policy-ac} but on BAT mode.
+
+Defaults to @samp{"powersave"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} space-separated-string-list disks-devices
+Hard disk devices.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} space-separated-string-list disk-apm-level-on-ac
+Hard disk advanced power management level.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} space-separated-string-list disk-apm-level-on-bat
+Same as @code{disk-apm-bat} but on BAT mode.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-space-separated-string-list disk-spindown-timeout-on-ac
+Hard disk spin down timeout.  One value has to be specified for each
+declared hard disk.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-space-separated-string-list disk-spindown-timeout-on-bat
+Same as @code{disk-spindown-timeout-on-ac} but on BAT mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-space-separated-string-list disk-iosched
+Select IO scheduler for disk devices.  One value has to be specified for
+each declared hard disk.  Example alternatives are cfq, deadline and
+noop.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string sata-linkpwr-on-ac
+SATA aggressive link power management (ALPM) level.  Alternatives are
+min_power, medium_power, max_performance.
+
+Defaults to @samp{"max_performance"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string sata-linkpwr-on-bat
+Same as @code{sata-linkpwr-ac} but on BAT mode.
+
+Defaults to @samp{"min_power"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-string sata-linkpwr-blacklist
+Exclude specified SATA host devices for link power management.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-on-off-boolean ahci-runtime-pm-on-ac?
+Enable Runtime Power Management for AHCI controller and disks on AC
+mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-on-off-boolean ahci-runtime-pm-on-bat?
+Same as @code{ahci-runtime-pm-on-ac} on BAT mode.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer ahci-runtime-pm-timeout
+Seconds of inactivity before disk is suspended.
+
+Defaults to @samp{15}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string pcie-aspm-on-ac
+PCI Express Active State Power Management level.  Alternatives are
+default, performance, powersave.
+
+Defaults to @samp{"performance"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string pcie-aspm-on-bat
+Same as @code{pcie-aspm-ac} but on BAT mode.
+
+Defaults to @samp{"powersave"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string radeon-power-profile-on-ac
+Radeon graphics clock speed level.  Alternatives are low, mid, high,
+auto, default.
+
+Defaults to @samp{"high"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string radeon-power-profile-on-bat
+Same as @code{radeon-power-ac} but on BAT mode.
+
+Defaults to @samp{"low"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string radeon-dpm-state-on-ac
+Radeon dynamic power management method (DPM).  Alternatives are battery,
+performance.
+
+Defaults to @samp{"performance"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string radeon-dpm-state-on-bat
+Same as @code{radeon-dpm-state-ac} but on BAT mode.
+
+Defaults to @samp{"battery"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string radeon-dpm-perf-level-on-ac
+Radeon DPM performance level.  Alternatives are auto, low, high.
+
+Defaults to @samp{"auto"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string radeon-dpm-perf-level-on-bat
+Same as @code{radeon-dpm-perf-ac} but on BAT mode.
+
+Defaults to @samp{"auto"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} on-off-boolean wifi-pwr-on-ac?
+Wifi power saving mode.
+
+Defaults to @samp{#f}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} on-off-boolean wifi-pwr-on-bat?
+Same as @code{wifi-power-ac?} but on BAT mode.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} y-n-boolean wol-disable?
+Disable wake on LAN.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer sound-power-save-on-ac
+Timeout duration in seconds before activating audio power saving on
+Intel HDA and AC97 devices.  A value of 0 disables power saving.
+
+Defaults to @samp{0}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} non-negative-integer sound-power-save-on-bat
+Same as @code{sound-powersave-ac} but on BAT mode.
+
+Defaults to @samp{1}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} y-n-boolean sound-power-save-controller?
+Disable controller in powersaving mode on Intel HDA devices.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean bay-poweroff-on-bat?
+Enable optical drive in UltraBay/MediaBay on BAT mode.  Drive can be
+powered on again by releasing (and reinserting) the eject lever or by
+pressing the disc eject button on newer models.
+
+Defaults to @samp{#f}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string bay-device
+Name of the optical drive device to power off.
+
+Defaults to @samp{"sr0"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string runtime-pm-on-ac
+Runtime Power Management for PCI(e) bus devices.  Alternatives are on
+and auto.
+
+Defaults to @samp{"on"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} string runtime-pm-on-bat
+Same as @code{runtime-pm-ac} but on BAT mode.
+
+Defaults to @samp{"auto"}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean runtime-pm-all?
+Runtime Power Management for all PCI(e) bus devices, except blacklisted
+ones.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-space-separated-string-list runtime-pm-blacklist
+Exclude specified PCI(e) devices adresses from Runtime Power Management.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} space-separated-string-list runtime-pm-driver-blacklist
+Exclude PCI(e) devices assigned to the specified drivers from Runtime
+Power Management.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean usb-autosuspend?
+Enable USB autosuspend feature.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-string usb-blacklist
+Exclude specified devices from USB autosuspend.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean usb-blacklist-wwan?
+Exclude WWAN devices from USB autosuspend.
+
+Defaults to @samp{#t}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-string usb-whitelist
+Include specified devices into USB autosuspend, even if they are already
+excluded by the driver or via @code{usb-blacklist-wwan?}.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} maybe-boolean usb-autosuspend-disable-on-shutdown?
+Enable USB autosuspend before shutdown.
+
+Defaults to @samp{disabled}.
+
+@end deftypevr
+
+@deftypevr {@code{tlp-configuration} parameter} boolean restore-device-state-on-startup?
+Restore radio device state (bluetooth, wifi, wwan) from previous
+shutdown on system startup.
+
+Defaults to @samp{#f}.
+
+@end deftypevr
+
 @node Miscellaneous Services
 @subsubsection Miscellaneous Services
 
diff --git a/gnu/local.mk b/gnu/local.mk
index 0eb18f26c..f589cd946 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -10,6 +10,7 @@
 # Copyright © 2016, 2017 Ricardo Wurmus <[email-masked]>
 # Copyright © 2016 Ben Woodcroft <[email-masked]>
 # Copyright © 2017 Clément Lassieur <[email-masked]>
+# Copyright © 2017 Mathieu Othacehe <[email-masked]>
 #
 # This file is part of GNU Guix.
 #
@@ -422,6 +423,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/services/nfs.scm			\
   %D%/services/shepherd.scm			\
   %D%/services/herd.scm				\
+  %D%/services/pm.scm				\
   %D%/services/sddm.scm				\
   %D%/services/spice.scm				\
   %D%/services/ssh.scm				\
diff --git a/gnu/services/pm.scm b/gnu/services/pm.scm
new file mode 100644
index 000000000..ec35e5701
--- /dev/null
+++ b/gnu/services/pm.scm
@@ -0,0 +1,404 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Mathieu Othacehe <[email-masked]>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix 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 3 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu services pm)
+  #:use-module (guix gexp)
+  #:use-module (guix packages)
+  #:use-module (guix records)
+  #:use-module (gnu packages linux)
+  #:use-module (gnu services)
+  #:use-module (gnu services base)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu services shepherd)
+  #:use-module (gnu system shadow)
+  #:export (tlp-service-type
+            tlp-configuration))
+
+(define (uglify-field-name field-name)
+  (let ((str (symbol->string field-name)))
+    (string-join (string-split
+                  (string-upcase
+                   (if (string-suffix? "?" str)
+                       (substring str 0 (1- (string-length str)))
+                       str))
+                  #\-)
+                 "_")))
+
+(define (serialize-field field-name val)
+  (format #t "~a=~a\n" (uglify-field-name field-name) val))
+
+(define (serialize-boolean field-name val)
+  (serialize-field field-name (if val "1" "0")))
+(define-maybe boolean)
+
+(define (serialize-string field-name val)
+  (serialize-field field-name val))
+(define-maybe string)
+
+(define (space-separated-string-list? val)
+  (and (list? val)
+       (and-map (lambda (x)
+                  (and (string? x) (not (string-index x #\space))))
+                val)))
+(define (serialize-space-separated-string-list field-name val)
+  (serialize-field field-name
+                   (format #f "~s"
+                           (string-join val " "))))
+(define-maybe space-separated-string-list)
+
+(define (non-negative-integer? val)
+  (and (exact-integer? val) (not (negative? val))))
+(define (serialize-non-negative-integer field-name val)
+  (serialize-field field-name val))
+(define-maybe non-negative-integer)
+
+(define (on-off-boolean? val)
+  (boolean? val))
+(define (serialize-on-off-boolean field-name val)
+  (serialize-field field-name (if val "on" "off")))
+(define-maybe on-off-boolean)
+
+(define (y-n-boolean? val)
+  (boolean? val))
+(define (serialize-y-n-boolean field-name val)
+  (serialize-field field-name (if val "Y" "N")))
+
+(define-configuration tlp-configuration
+  (tlp
+   (package tlp)
+   "The TLP package.")
+
+  (tlp-enable?
+   (boolean #t)
+   "Set to true if you wish to enable TLP.")
+
+  (tlp-default-mode
+   (string "AC")
+   "Default mode when no power supply can be detected.  Alternatives are
+AC and BAT.")
+
+  (disk-idle-secs-on-ac
+   (non-negative-integer 0)
+   "Number of seconds Linux kernel has to wait after the disk goes idle,
+before syncing on AC.")
+
+  (disk-idle-secs-on-bat
+   (non-negative-integer 2)
+   "Same as @code{disk-idle-ac} but on BAT mode.")
+
+  (max-lost-work-secs-on-ac
+   (non-negative-integer 15)
+   "Dirty pages flushing periodicity, expressed in seconds.")
+
+  (max-lost-work-secs-on-bat
+   (non-negative-integer 60)
+   "Same as @code{max-lost-work-secs-on-ac} but on BAT mode.")
+
+  (cpu-scaling-governor-on-ac
+   (maybe-space-separated-string-list 'disabled)
+   "CPU frequency scaling governor on AC mode.  With intel_pstate
+driver, alternatives are powersave and performance.  With acpi-cpufreq driver,
+alternatives are ondemand, powersave, performance and conservative.")
+
+  (cpu-scaling-governor-on-bat
+   (maybe-space-separated-string-list 'disabled)
+   "Same as @code{cpu-scaling-governor-on-ac} but on BAT mode.")
+
+  (cpu-scaling-min-freq-on-ac
+   (maybe-non-negative-integer 'disabled)
+   "Set the min available frequency for the scaling governor on AC.")
+
+  (cpu-scaling-max-freq-on-ac
+   (maybe-non-negative-integer 'disabled)
+   "Set the max available frequency for the scaling governor on AC.")
+
+  (cpu-scaling-min-freq-on-bat
+   (maybe-non-negative-integer 'disabled)
+   "Set the min available frequency for the scaling governor on BAT.")
+
+  (cpu-scaling-max-freq-on-bat
+   (maybe-non-negative-integer 'disabled)
+   "Set the max available frequency for the scaling governor on BAT.")
+
+  (cpu-min-perf-on-ac
+   (maybe-non-negative-integer 'disabled)
+   "Limit the min P-state to control the power dissipation of the CPU,
+in AC mode.  Values are stated as a percentage of the available performance.")
+
+  (cpu-max-perf-on-ac
+   (maybe-non-negative-integer 'disabled)
+   "Limit the max P-state to control the power dissipation of the CPU,
+in AC mode.  Values are stated as a percentage of the available performance.")
+
+  (cpu-min-perf-on-bat
+   (maybe-non-negative-integer 'disabled)
+   "Same as @code{cpu-min-perf-on-ac} on BAT mode.")
+
+  (cpu-max-perf-on-bat
+   (maybe-non-negative-integer 'disabled)
+   "Same as @code{cpu-max-perf-on-ac} on BAT mode.")
+
+  (cpu-boost-on-ac?
+   (maybe-boolean 'disabled)
+   "Enable CPU turbo boost feature on AC mode.")
+
+  (cpu-boost-on-bat?
+   (maybe-boolean 'disabled)
+   "Same as @code{cpu-boost-on-ac?} on BAT mode.")
+
+  (sched-powersave-on-ac?
+   (boolean #f)
+   "Allow Linux kernel to minimize the number of CPU cores/hyper-threads
+used under light load conditions.")
+
+  (sched-powersave-on-bat?
+   (boolean #t)
+   "Same as @code{sched-powersave-on-ac?} but on BAT mode.")
+
+  (nmi-watchdog?
+   (boolean #f)
+   "Enable Linux kernel NMI watchdog.")
+
+  (phc-controls
+   (maybe-string 'disabled)
+   "For Linux kernels with PHC patch applied, change CPU voltages.
+An example value would be @samp{\"F:V F:V F:V F:V\"}.")
+
+  (energy-perf-policy-on-ac
+   (string "performance")
+   "Set CPU performance versus energy saving policy on AC.  Alternatives are
+performance, normal, powersave.")
+
+  (energy-perf-policy-on-bat
+   (string "powersave")
+   "Same as @code{energy-perf-policy-ac} but on BAT mode.")
+
+  (disks-devices
+   (space-separated-string-list '("sda"))
+   "Hard disk devices.")
+
+  (disk-apm-level-on-ac
+   (space-separated-string-list '("254" "254"))
+   "Hard disk advanced power management level.")
+
+  (disk-apm-level-on-bat
+   (space-separated-string-list '("128" "128"))
+   "Same as @code{disk-apm-bat} but on BAT mode.")
+
+  (disk-spindown-timeout-on-ac
+   (maybe-space-separated-string-list 'disabled)
+   "Hard disk spin down timeout.  One value has to be specified for
+each declared hard disk.")
+
+  (disk-spindown-timeout-on-bat
+   (maybe-space-separated-string-list 'disabled)
+   "Same as @code{disk-spindown-timeout-on-ac} but on BAT mode.")
+
+  (disk-iosched
+   (maybe-space-separated-string-list 'disabled)
+   "Select IO scheduler for disk devices.  One value has to be specified
+for each declared hard disk.  Example alternatives are cfq, deadline and noop.")
+
+  (sata-linkpwr-on-ac
+   (string "max_performance")
+   "SATA aggressive link power management (ALPM) level.  Alternatives are
+min_power, medium_power, max_performance.")
+
+  (sata-linkpwr-on-bat
+   (string "min_power")
+   "Same as @code{sata-linkpwr-ac} but on BAT mode.")
+
+  (sata-linkpwr-blacklist
+   (maybe-string 'disabled)
+   "Exclude specified SATA host devices for link power management.")
+
+  (ahci-runtime-pm-on-ac?
+   (maybe-on-off-boolean 'disabled)
+   "Enable Runtime Power Management for AHCI controller and disks
+on AC mode.")
+
+  (ahci-runtime-pm-on-bat?
+   (maybe-on-off-boolean 'disabled)
+   "Same as @code{ahci-runtime-pm-on-ac} on BAT mode.")
+
+  (ahci-runtime-pm-timeout
+   (non-negative-integer 15)
+   "Seconds of inactivity before disk is suspended.")
+
+  (pcie-aspm-on-ac
+   (string "performance")
+   "PCI Express Active State Power Management level.  Alternatives are
+default, performance, powersave.")
+
+  (pcie-aspm-on-bat
+   (string "powersave")
+   "Same as @code{pcie-aspm-ac} but on BAT mode.")
+
+  (radeon-power-profile-on-ac
+   (string "high")
+   "Radeon graphics clock speed level.  Alternatives are
+low, mid, high, auto, default.")
+
+  (radeon-power-profile-on-bat
+   (string "low")
+   "Same as @code{radeon-power-ac} but on BAT mode.")
+
+  (radeon-dpm-state-on-ac
+   (string "performance")
+   "Radeon dynamic power management method (DPM).  Alternatives are
+battery, performance.")
+
+  (radeon-dpm-state-on-bat
+   (string "battery")
+   "Same as @code{radeon-dpm-state-ac} but on BAT mode.")
+
+  (radeon-dpm-perf-level-on-ac
+   (string "auto")
+   "Radeon DPM performance level.  Alternatives are
+auto, low, high.")
+
+  (radeon-dpm-perf-level-on-bat
+   (string "auto")
+   "Same as @code{radeon-dpm-perf-ac} but on BAT mode.")
+
+  (wifi-pwr-on-ac?
+   (on-off-boolean #f)
+   "Wifi power saving mode.")
+
+  (wifi-pwr-on-bat?
+   (on-off-boolean #t)
+   "Same as @code{wifi-power-ac?} but on BAT mode.")
+
+  (wol-disable?
+   (y-n-boolean #t)
+   "Disable wake on LAN.")
+
+  (sound-power-save-on-ac
+   (non-negative-integer 0)
+   "Timeout duration in seconds before activating audio power saving
+ on Intel HDA and AC97 devices.  A value of 0 disables power saving.")
+
+  (sound-power-save-on-bat
+   (non-negative-integer 1)
+   "Same as @code{sound-powersave-ac} but on BAT mode.")
+
+  (sound-power-save-controller?
+   (y-n-boolean #t)
+   "Disable controller in powersaving mode on Intel HDA devices.")
+
+  (bay-poweroff-on-bat?
+   (boolean #f)
+   "Enable optical drive in UltraBay/MediaBay on BAT mode.
+Drive can be powered on again by releasing (and reinserting) the eject lever
+or by pressing the disc eject button on newer models.")
+
+  (bay-device
+   (string "sr0")
+   "Name of the optical drive device to power off.")
+
+  (runtime-pm-on-ac
+   (string "on")
+   "Runtime Power Management for PCI(e) bus devices.  Alternatives are
+on and auto.")
+
+  (runtime-pm-on-bat
+   (string "auto")
+   "Same as @code{runtime-pm-ac} but on BAT mode.")
+
+  (runtime-pm-all?
+   (boolean #t)
+   "Runtime Power Management for all PCI(e) bus devices, except
+blacklisted ones.")
+
+  (runtime-pm-blacklist
+   (maybe-space-separated-string-list 'disabled)
+   "Exclude specified PCI(e) devices adresses from Runtime Power Management.")
+
+  (runtime-pm-driver-blacklist
+   (space-separated-string-list '("radeon" "nouveau"))
+   "Exclude PCI(e) devices assigned to the specified drivers from
+Runtime Power Management.")
+
+  (usb-autosuspend?
+   (boolean #t)
+   "Enable USB autosuspend feature.")
+
+  (usb-blacklist
+   (maybe-string 'disabled)
+   "Exclude specified devices from USB autosuspend.")
+
+  (usb-blacklist-wwan?
+   (boolean #t)
+   "Exclude WWAN devices from USB autosuspend.")
+
+  (usb-whitelist
+   (maybe-string 'disabled)
+   "Include specified devices into USB autosuspend, even if they are
+already excluded by the driver or via @code{usb-blacklist-wwan?}.")
+
+  (usb-autosuspend-disable-on-shutdown?
+   (maybe-boolean 'disabled)
+   "Enable USB autosuspend before shutdown.")
+
+  (restore-device-state-on-startup?
+   (boolean #f)
+   "Restore radio device state (bluetooth, wifi, wwan) from previous
+shutdown on system startup."))
+
+
+(define (tlp-shepherd-service config)
+  (let* ((tlp-bin (file-append
+                   (tlp-configuration-tlp config) "/bin/tlp"))
+         (tlp-action (lambda args
+                       #~(lambda _
+                           (zero? (system* #$tlp-bin #$@args))))))
+    (list (shepherd-service
+           (documentation "Run TLP script.")
+           (provision '(tlp))
+           (requirement '(user-processes))
+           (start (tlp-action "init" "start"))
+           (stop  (tlp-action "init" "stop"))))))
+
+(define (tlp-activation config)
+  (let* ((config-str (with-output-to-string
+                       (lambda ()
+                         (serialize-configuration
+                          config
+                          tlp-configuration-fields))))
+         (config-file (plain-file "tlp" config-str)))
+    (with-imported-modules '((guix build utils))
+      #~(begin
+          (use-modules (guix build utils))
+          (copy-file #$config-file "/etc/tlp")))))
+
+(define tlp-service-type
+  (service-type
+   (name 'tlp)
+   (extensions
+    (list
+     (service-extension shepherd-root-service-type
+                        tlp-shepherd-service)
+     (service-extension udev-service-type
+                        (compose list tlp-configuration-tlp))
+     (service-extension activation-service-type
+                        tlp-activation)))))
+
+(define (generate-tlp-documentation)
+  (generate-documentation
+   `((tlp-configuration ,tlp-configuration-fields))
+   'tlp-configuration))
-- 
2.12.0