Merge branch 'master' into staging
[jackhill/guix/guix.git] / gnu / services / pm.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
3 ;;;
4 ;;; This file is part of GNU Guix.
5 ;;;
6 ;;; GNU Guix is free software: you can redistribute it and/or modify
7 ;;; it under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation, either version 3 of the License, or
9 ;;; (at your option) any later version.
10 ;;;
11 ;;; GNU Guix is distributed in the hope that it will be useful,
12 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
15 ;;;
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19 (define-module (gnu services pm)
20 #:use-module (guix gexp)
21 #:use-module (guix packages)
22 #:use-module (guix records)
23 #:use-module (gnu packages linux)
24 #:use-module (gnu services)
25 #:use-module (gnu services base)
26 #:use-module (gnu services configuration)
27 #:use-module (gnu services shepherd)
28 #:use-module (gnu system shadow)
29 #:export (tlp-service-type
30 tlp-configuration))
31
32 (define (uglify-field-name field-name)
33 (let ((str (symbol->string field-name)))
34 (string-join (string-split
35 (string-upcase
36 (if (string-suffix? "?" str)
37 (substring str 0 (1- (string-length str)))
38 str))
39 #\-)
40 "_")))
41
42 (define (serialize-field field-name val)
43 (format #t "~a=~a\n" (uglify-field-name field-name) val))
44
45 (define (serialize-boolean field-name val)
46 (serialize-field field-name (if val "1" "0")))
47 (define-maybe boolean)
48
49 (define (serialize-string field-name val)
50 (serialize-field field-name val))
51 (define-maybe string)
52
53 (define (space-separated-string-list? val)
54 (and (list? val)
55 (and-map (lambda (x)
56 (and (string? x) (not (string-index x #\space))))
57 val)))
58 (define (serialize-space-separated-string-list field-name val)
59 (serialize-field field-name
60 (format #f "~s"
61 (string-join val " "))))
62 (define-maybe space-separated-string-list)
63
64 (define (non-negative-integer? val)
65 (and (exact-integer? val) (not (negative? val))))
66 (define (serialize-non-negative-integer field-name val)
67 (serialize-field field-name val))
68 (define-maybe non-negative-integer)
69
70 (define (on-off-boolean? val)
71 (boolean? val))
72 (define (serialize-on-off-boolean field-name val)
73 (serialize-field field-name (if val "on" "off")))
74 (define-maybe on-off-boolean)
75
76 (define (y-n-boolean? val)
77 (boolean? val))
78 (define (serialize-y-n-boolean field-name val)
79 (serialize-field field-name (if val "Y" "N")))
80
81 (define-configuration tlp-configuration
82 (tlp
83 (package tlp)
84 "The TLP package.")
85
86 (tlp-enable?
87 (boolean #t)
88 "Set to true if you wish to enable TLP.")
89
90 (tlp-default-mode
91 (string "AC")
92 "Default mode when no power supply can be detected. Alternatives are
93 AC and BAT.")
94
95 (disk-idle-secs-on-ac
96 (non-negative-integer 0)
97 "Number of seconds Linux kernel has to wait after the disk goes idle,
98 before syncing on AC.")
99
100 (disk-idle-secs-on-bat
101 (non-negative-integer 2)
102 "Same as @code{disk-idle-ac} but on BAT mode.")
103
104 (max-lost-work-secs-on-ac
105 (non-negative-integer 15)
106 "Dirty pages flushing periodicity, expressed in seconds.")
107
108 (max-lost-work-secs-on-bat
109 (non-negative-integer 60)
110 "Same as @code{max-lost-work-secs-on-ac} but on BAT mode.")
111
112 (cpu-scaling-governor-on-ac
113 (maybe-space-separated-string-list 'disabled)
114 "CPU frequency scaling governor on AC mode. With intel_pstate
115 driver, alternatives are powersave and performance. With acpi-cpufreq driver,
116 alternatives are ondemand, powersave, performance and conservative.")
117
118 (cpu-scaling-governor-on-bat
119 (maybe-space-separated-string-list 'disabled)
120 "Same as @code{cpu-scaling-governor-on-ac} but on BAT mode.")
121
122 (cpu-scaling-min-freq-on-ac
123 (maybe-non-negative-integer 'disabled)
124 "Set the min available frequency for the scaling governor on AC.")
125
126 (cpu-scaling-max-freq-on-ac
127 (maybe-non-negative-integer 'disabled)
128 "Set the max available frequency for the scaling governor on AC.")
129
130 (cpu-scaling-min-freq-on-bat
131 (maybe-non-negative-integer 'disabled)
132 "Set the min available frequency for the scaling governor on BAT.")
133
134 (cpu-scaling-max-freq-on-bat
135 (maybe-non-negative-integer 'disabled)
136 "Set the max available frequency for the scaling governor on BAT.")
137
138 (cpu-min-perf-on-ac
139 (maybe-non-negative-integer 'disabled)
140 "Limit the min P-state to control the power dissipation of the CPU,
141 in AC mode. Values are stated as a percentage of the available performance.")
142
143 (cpu-max-perf-on-ac
144 (maybe-non-negative-integer 'disabled)
145 "Limit the max P-state to control the power dissipation of the CPU,
146 in AC mode. Values are stated as a percentage of the available performance.")
147
148 (cpu-min-perf-on-bat
149 (maybe-non-negative-integer 'disabled)
150 "Same as @code{cpu-min-perf-on-ac} on BAT mode.")
151
152 (cpu-max-perf-on-bat
153 (maybe-non-negative-integer 'disabled)
154 "Same as @code{cpu-max-perf-on-ac} on BAT mode.")
155
156 (cpu-boost-on-ac?
157 (maybe-boolean 'disabled)
158 "Enable CPU turbo boost feature on AC mode.")
159
160 (cpu-boost-on-bat?
161 (maybe-boolean 'disabled)
162 "Same as @code{cpu-boost-on-ac?} on BAT mode.")
163
164 (sched-powersave-on-ac?
165 (boolean #f)
166 "Allow Linux kernel to minimize the number of CPU cores/hyper-threads
167 used under light load conditions.")
168
169 (sched-powersave-on-bat?
170 (boolean #t)
171 "Same as @code{sched-powersave-on-ac?} but on BAT mode.")
172
173 (nmi-watchdog?
174 (boolean #f)
175 "Enable Linux kernel NMI watchdog.")
176
177 (phc-controls
178 (maybe-string 'disabled)
179 "For Linux kernels with PHC patch applied, change CPU voltages.
180 An example value would be @samp{\"F:V F:V F:V F:V\"}.")
181
182 (energy-perf-policy-on-ac
183 (string "performance")
184 "Set CPU performance versus energy saving policy on AC. Alternatives are
185 performance, normal, powersave.")
186
187 (energy-perf-policy-on-bat
188 (string "powersave")
189 "Same as @code{energy-perf-policy-ac} but on BAT mode.")
190
191 (disks-devices
192 (space-separated-string-list '("sda"))
193 "Hard disk devices.")
194
195 (disk-apm-level-on-ac
196 (space-separated-string-list '("254" "254"))
197 "Hard disk advanced power management level.")
198
199 (disk-apm-level-on-bat
200 (space-separated-string-list '("128" "128"))
201 "Same as @code{disk-apm-bat} but on BAT mode.")
202
203 (disk-spindown-timeout-on-ac
204 (maybe-space-separated-string-list 'disabled)
205 "Hard disk spin down timeout. One value has to be specified for
206 each declared hard disk.")
207
208 (disk-spindown-timeout-on-bat
209 (maybe-space-separated-string-list 'disabled)
210 "Same as @code{disk-spindown-timeout-on-ac} but on BAT mode.")
211
212 (disk-iosched
213 (maybe-space-separated-string-list 'disabled)
214 "Select IO scheduler for disk devices. One value has to be specified
215 for each declared hard disk. Example alternatives are cfq, deadline and noop.")
216
217 (sata-linkpwr-on-ac
218 (string "max_performance")
219 "SATA aggressive link power management (ALPM) level. Alternatives are
220 min_power, medium_power, max_performance.")
221
222 (sata-linkpwr-on-bat
223 (string "min_power")
224 "Same as @code{sata-linkpwr-ac} but on BAT mode.")
225
226 (sata-linkpwr-blacklist
227 (maybe-string 'disabled)
228 "Exclude specified SATA host devices for link power management.")
229
230 (ahci-runtime-pm-on-ac?
231 (maybe-on-off-boolean 'disabled)
232 "Enable Runtime Power Management for AHCI controller and disks
233 on AC mode.")
234
235 (ahci-runtime-pm-on-bat?
236 (maybe-on-off-boolean 'disabled)
237 "Same as @code{ahci-runtime-pm-on-ac} on BAT mode.")
238
239 (ahci-runtime-pm-timeout
240 (non-negative-integer 15)
241 "Seconds of inactivity before disk is suspended.")
242
243 (pcie-aspm-on-ac
244 (string "performance")
245 "PCI Express Active State Power Management level. Alternatives are
246 default, performance, powersave.")
247
248 (pcie-aspm-on-bat
249 (string "powersave")
250 "Same as @code{pcie-aspm-ac} but on BAT mode.")
251
252 (radeon-power-profile-on-ac
253 (string "high")
254 "Radeon graphics clock speed level. Alternatives are
255 low, mid, high, auto, default.")
256
257 (radeon-power-profile-on-bat
258 (string "low")
259 "Same as @code{radeon-power-ac} but on BAT mode.")
260
261 (radeon-dpm-state-on-ac
262 (string "performance")
263 "Radeon dynamic power management method (DPM). Alternatives are
264 battery, performance.")
265
266 (radeon-dpm-state-on-bat
267 (string "battery")
268 "Same as @code{radeon-dpm-state-ac} but on BAT mode.")
269
270 (radeon-dpm-perf-level-on-ac
271 (string "auto")
272 "Radeon DPM performance level. Alternatives are
273 auto, low, high.")
274
275 (radeon-dpm-perf-level-on-bat
276 (string "auto")
277 "Same as @code{radeon-dpm-perf-ac} but on BAT mode.")
278
279 (wifi-pwr-on-ac?
280 (on-off-boolean #f)
281 "Wifi power saving mode.")
282
283 (wifi-pwr-on-bat?
284 (on-off-boolean #t)
285 "Same as @code{wifi-power-ac?} but on BAT mode.")
286
287 (wol-disable?
288 (y-n-boolean #t)
289 "Disable wake on LAN.")
290
291 (sound-power-save-on-ac
292 (non-negative-integer 0)
293 "Timeout duration in seconds before activating audio power saving
294 on Intel HDA and AC97 devices. A value of 0 disables power saving.")
295
296 (sound-power-save-on-bat
297 (non-negative-integer 1)
298 "Same as @code{sound-powersave-ac} but on BAT mode.")
299
300 (sound-power-save-controller?
301 (y-n-boolean #t)
302 "Disable controller in powersaving mode on Intel HDA devices.")
303
304 (bay-poweroff-on-bat?
305 (boolean #f)
306 "Enable optical drive in UltraBay/MediaBay on BAT mode.
307 Drive can be powered on again by releasing (and reinserting) the eject lever
308 or by pressing the disc eject button on newer models.")
309
310 (bay-device
311 (string "sr0")
312 "Name of the optical drive device to power off.")
313
314 (runtime-pm-on-ac
315 (string "on")
316 "Runtime Power Management for PCI(e) bus devices. Alternatives are
317 on and auto.")
318
319 (runtime-pm-on-bat
320 (string "auto")
321 "Same as @code{runtime-pm-ac} but on BAT mode.")
322
323 (runtime-pm-all?
324 (boolean #t)
325 "Runtime Power Management for all PCI(e) bus devices, except
326 blacklisted ones.")
327
328 (runtime-pm-blacklist
329 (maybe-space-separated-string-list 'disabled)
330 "Exclude specified PCI(e) device addresses from Runtime Power Management.")
331
332 (runtime-pm-driver-blacklist
333 (space-separated-string-list '("radeon" "nouveau"))
334 "Exclude PCI(e) devices assigned to the specified drivers from
335 Runtime Power Management.")
336
337 (usb-autosuspend?
338 (boolean #t)
339 "Enable USB autosuspend feature.")
340
341 (usb-blacklist
342 (maybe-string 'disabled)
343 "Exclude specified devices from USB autosuspend.")
344
345 (usb-blacklist-wwan?
346 (boolean #t)
347 "Exclude WWAN devices from USB autosuspend.")
348
349 (usb-whitelist
350 (maybe-string 'disabled)
351 "Include specified devices into USB autosuspend, even if they are
352 already excluded by the driver or via @code{usb-blacklist-wwan?}.")
353
354 (usb-autosuspend-disable-on-shutdown?
355 (maybe-boolean 'disabled)
356 "Enable USB autosuspend before shutdown.")
357
358 (restore-device-state-on-startup?
359 (boolean #f)
360 "Restore radio device state (bluetooth, wifi, wwan) from previous
361 shutdown on system startup."))
362
363
364 (define (tlp-shepherd-service config)
365 (let* ((tlp-bin (file-append
366 (tlp-configuration-tlp config) "/bin/tlp"))
367 (tlp-action (lambda args
368 #~(lambda _
369 (zero? (system* #$tlp-bin #$@args))))))
370 (list (shepherd-service
371 (documentation "Run TLP script.")
372 (provision '(tlp))
373 (requirement '(user-processes))
374 (start (tlp-action "init" "start"))
375 (stop (tlp-action "init" "stop"))))))
376
377 (define (tlp-activation config)
378 (let* ((config-str (with-output-to-string
379 (lambda ()
380 (serialize-configuration
381 config
382 tlp-configuration-fields))))
383 (config-file (plain-file "tlp" config-str)))
384 (with-imported-modules '((guix build utils))
385 #~(begin
386 (use-modules (guix build utils))
387 (copy-file #$config-file "/etc/tlp")))))
388
389 (define tlp-service-type
390 (service-type
391 (name 'tlp)
392 (extensions
393 (list
394 (service-extension shepherd-root-service-type
395 tlp-shepherd-service)
396 (service-extension udev-service-type
397 (compose list tlp-configuration-tlp))
398 (service-extension activation-service-type
399 tlp-activation)))
400 (default-value (tlp-configuration))))
401
402 (define (generate-tlp-documentation)
403 (generate-documentation
404 `((tlp-configuration ,tlp-configuration-fields))
405 'tlp-configuration))