1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8with lib;
9
10let
11 cfg = config.powerManagement.powertop;
12in
13{
14 ###### interface
15
16 options.powerManagement.powertop = {
17 enable = mkEnableOption "powertop auto tuning on startup";
18
19 preStart = mkOption {
20 type = types.lines;
21 default = "";
22 description = ''
23 Shell commands executed before `powertop` is started.
24 '';
25 };
26
27 postStart = mkOption {
28 type = types.lines;
29 default = "";
30 example = ''
31 ''${lib.getExe' config.systemd.package "udevadm"} trigger -c bind -s usb -a idVendor=046d -a idProduct=c08c
32 '';
33 description = ''
34 Shell commands executed after `powertop` is started.
35
36 This can be used to workaround problematic configurations. For example,
37 you can retrigger an `udev` rule to disable power saving on unsupported
38 USB devices:
39 ```
40 services.udev.extraRules = ''''
41 # disable USB auto suspend for Logitech, Inc. G PRO Gaming Mouse
42 ACTION=="bind", SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08c", TEST=="power/control", ATTR{power/control}="on"
43 '''';
44 ```
45 '';
46 };
47 };
48
49 ###### implementation
50
51 config = mkIf (cfg.enable) {
52 systemd.services = {
53 powertop = {
54 documentation = [ "man:powertop(8)" ];
55 wantedBy = [ "multi-user.target" ];
56 after = [ "multi-user.target" ];
57 description = "Powertop tunings";
58 path = [ pkgs.kmod ];
59 preStart = cfg.preStart;
60 postStart = cfg.postStart;
61 serviceConfig = {
62 Type = "oneshot";
63 RemainAfterExit = "yes";
64 ExecStart = "${pkgs.powertop}/bin/powertop --auto-tune";
65 };
66 };
67 };
68 };
69}