1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.powerManagement;
8
9in
10
11{
12
13 ###### interface
14
15 options = {
16
17 powerManagement = {
18
19 enable = mkOption {
20 type = types.bool;
21 default = true;
22 description =
23 ''
24 Whether to enable power management. This includes support
25 for suspend-to-RAM and powersave features on laptops.
26 '';
27 };
28
29 resumeCommands = mkOption {
30 type = types.lines;
31 default = "";
32 description = "Commands executed after the system resumes from suspend-to-RAM.";
33 };
34
35 powerUpCommands = mkOption {
36 type = types.lines;
37 default = "";
38 example = literalExample ''
39 "''${pkgs.hdparm}/sbin/hdparm -B 255 /dev/sda"
40 '';
41 description =
42 ''
43 Commands executed when the machine powers up. That is,
44 they're executed both when the system first boots and when
45 it resumes from suspend or hibernation.
46 '';
47 };
48
49 powerDownCommands = mkOption {
50 type = types.lines;
51 default = "";
52 example = literalExample ''
53 "''${pkgs.hdparm}/sbin/hdparm -B 255 /dev/sda"
54 '';
55 description =
56 ''
57 Commands executed when the machine powers down. That is,
58 they're executed both when the system shuts down and when
59 it goes to suspend or hibernation.
60 '';
61 };
62
63 };
64
65 };
66
67
68 ###### implementation
69
70 config = mkIf cfg.enable {
71
72 # FIXME: Implement powersave governor for sandy bridge or later Intel CPUs
73 powerManagement.cpuFreqGovernor = mkDefault "ondemand";
74
75 systemd.targets.post-resume = {
76 description = "Post-Resume Actions";
77 requires = [ "post-resume.service" ];
78 after = [ "post-resume.service" ];
79 wantedBy = [ "sleep.target" ];
80 unitConfig.StopWhenUnneeded = true;
81 };
82
83 # Service executed before suspending/hibernating.
84 systemd.services."pre-sleep" =
85 { description = "Pre-Sleep Actions";
86 wantedBy = [ "sleep.target" ];
87 before = [ "sleep.target" ];
88 script =
89 ''
90 ${cfg.powerDownCommands}
91 '';
92 serviceConfig.Type = "oneshot";
93 };
94
95 systemd.services."post-resume" =
96 { description = "Post-Resume Actions";
97 after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
98 script =
99 ''
100 ${config.systemd.package}/bin/systemctl try-restart post-resume.target
101 ${cfg.resumeCommands}
102 ${cfg.powerUpCommands}
103 '';
104 serviceConfig.Type = "oneshot";
105 };
106
107 };
108
109}