at 25.11-pre 5.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.tlp; 9 enableRDW = config.networking.networkmanager.enable; 10 # TODO: Use this for having proper parameters in the future 11 mkTlpConfig = 12 tlpConfig: 13 lib.generators.toKeyValue { 14 mkKeyValue = lib.generators.mkKeyValueDefault { 15 mkValueString = val: if lib.isList val then "\"" + (toString val) + "\"" else toString val; 16 } "="; 17 } tlpConfig; 18in 19{ 20 ###### interface 21 options = { 22 services.tlp = { 23 enable = lib.mkOption { 24 type = lib.types.bool; 25 default = false; 26 description = "Whether to enable the TLP power management daemon."; 27 }; 28 29 settings = lib.mkOption { 30 type = 31 with lib.types; 32 attrsOf (oneOf [ 33 bool 34 int 35 float 36 str 37 (listOf str) 38 ]); 39 default = { }; 40 example = { 41 SATA_LINKPWR_ON_BAT = "med_power_with_dipm"; 42 USB_BLACKLIST_PHONE = 1; 43 }; 44 description = '' 45 Options passed to TLP. See https://linrunner.de/tlp for all supported options.. 46 ''; 47 }; 48 49 extraConfig = lib.mkOption { 50 type = lib.types.lines; 51 default = ""; 52 description = '' 53 Verbatim additional configuration variables for TLP. 54 DEPRECATED: use services.tlp.settings instead. 55 ''; 56 }; 57 58 package = lib.mkOption { 59 type = lib.types.package; 60 default = pkgs.tlp.override { inherit enableRDW; }; 61 defaultText = "pkgs.tlp.override { enableRDW = config.networking.networkmanager.enable; }"; 62 description = "The tlp package to use."; 63 }; 64 }; 65 }; 66 67 ###### implementation 68 config = lib.mkIf cfg.enable { 69 hardware.cpu.x86.msr.enable = true; 70 71 warnings = lib.optional (cfg.extraConfig != "") '' 72 Using config.services.tlp.extraConfig is deprecated and will become unsupported in a future release. Use config.services.tlp.settings instead. 73 ''; 74 75 assertions = [ 76 { 77 assertion = cfg.enable -> config.powerManagement.scsiLinkPolicy == null; 78 message = '' 79 `services.tlp.enable` and `config.powerManagement.scsiLinkPolicy` cannot be set both. 80 Set `services.tlp.settings.SATA_LINKPWR_ON_AC` and `services.tlp.settings.SATA_LINKPWR_ON_BAT` instead. 81 ''; 82 } 83 ]; 84 85 environment.etc = 86 { 87 "tlp.conf".text = (mkTlpConfig cfg.settings) + cfg.extraConfig; 88 } 89 // lib.optionalAttrs enableRDW { 90 "NetworkManager/dispatcher.d/99tlp-rdw-nm".source = 91 "${cfg.package}/lib/NetworkManager/dispatcher.d/99tlp-rdw-nm"; 92 }; 93 94 environment.systemPackages = [ cfg.package ]; 95 96 services.tlp.settings = 97 let 98 cfg = config.powerManagement; 99 maybeDefault = val: lib.mkIf (val != null) (lib.mkDefault val); 100 in 101 { 102 CPU_SCALING_GOVERNOR_ON_AC = maybeDefault cfg.cpuFreqGovernor; 103 CPU_SCALING_GOVERNOR_ON_BAT = maybeDefault cfg.cpuFreqGovernor; 104 CPU_SCALING_MIN_FREQ_ON_AC = maybeDefault cfg.cpufreq.min; 105 CPU_SCALING_MAX_FREQ_ON_AC = maybeDefault cfg.cpufreq.max; 106 CPU_SCALING_MIN_FREQ_ON_BAT = maybeDefault cfg.cpufreq.min; 107 CPU_SCALING_MAX_FREQ_ON_BAT = maybeDefault cfg.cpufreq.max; 108 }; 109 110 services.udev.packages = [ cfg.package ]; 111 112 systemd = { 113 # use native tlp instead because it can also differentiate between AC/BAT 114 services.cpufreq.enable = false; 115 116 packages = [ cfg.package ]; 117 # XXX: These must always be disabled/masked according to [1]. 118 # 119 # [1]: https://github.com/linrunner/TLP/blob/a9ada09e0821f275ce5f93dc80a4d81a7ff62ae4/tlp-stat.in#L319 120 sockets.systemd-rfkill.enable = false; 121 services.systemd-rfkill.enable = false; 122 123 services.tlp = { 124 # XXX: The service should reload whenever the configuration changes, 125 # otherwise newly set power options remain inactive until reboot (or 126 # manual unit restart.) 127 restartTriggers = [ config.environment.etc."tlp.conf".source ]; 128 # XXX: When using systemd.packages (which we do above) the [Install] 129 # section of systemd units does not work (citation needed) so we manually 130 # enforce it here. 131 wantedBy = [ "multi-user.target" ]; 132 }; 133 134 services.tlp-sleep = { 135 # XXX: When using systemd.packages (which we do above) the [Install] 136 # section of systemd units does not work (citation needed) so we manually 137 # enforce it here. 138 before = [ "sleep.target" ]; 139 wantedBy = [ "sleep.target" ]; 140 # XXX: `tlp suspend` requires /var/lib/tlp to exist in order to save 141 # some stuff in there. There is no way, that I know of, to do this in 142 # the package itself, so we do it here instead making sure the unit 143 # won't fail due to the save dir not existing. 144 serviceConfig.StateDirectory = "tlp"; 145 }; 146 }; 147 }; 148}