fan-ctl (2344B)
1 #!/usr/bin/env bash 2 # fan-ctl — root-side actions for the daemon-sec.fans bar widget (run via 3 # pkexec; the shell's polkit plugin presents the auth dialog). Thin dispatcher 4 # over ~/.local/bin/fanfix, except `cap`, which re-applies the clock cap 5 # without fanfix's built-in 20 s stress test so a panel click stays instant. 6 set -uo pipefail 7 8 FANFIX=/home/daemon-sec/.local/bin/fanfix 9 CONF=/etc/tmpfiles.d/99-cpu-freq-cap.conf 10 CPU0=/sys/devices/system/cpu/cpu0/cpufreq 11 12 [ "$(id -u)" = 0 ] || { echo "fan-ctl must run as root (pkexec)" >&2; exit 1; } 13 14 case "${1:-}" in 15 auto|max) 16 exec "$FANFIX" fan "$1" ;; 17 set) 18 pct="${2:?usage: fan-ctl set <30-100>}" 19 exec "$FANFIX" fan "$pct" ;; 20 curve) 21 case "${2:-}" in 22 on|off) exec "$FANFIX" fan curve "$2" ;; 23 *) echo "usage: fan-ctl curve on|off" >&2; exit 2 ;; 24 esac ;; 25 drivers) 26 exec "$FANFIX" fans --persist ;; 27 cap) 28 mhz="${2:-3200}" 29 [[ "$mhz" =~ ^[0-9]+$ ]] || { echo "cap must be a number (MHz)" >&2; exit 2; } 30 khz=$(( mhz < 100000 ? mhz * 1000 : mhz )) 31 hwmax=$(cat "$CPU0/cpuinfo_max_freq") 32 { [ "$khz" -ge 1500000 ] && [ "$khz" -le "$hwmax" ]; } \ 33 || { echo "cap out of range (1500-$(( hwmax / 1000 )) MHz)" >&2; exit 2; } 34 cat > "$CONF" <<EOF 35 # fanfix: broken GPU fan -> EC pins CPU at 399 MHz at ~79 C. Cap every core so it never gets there. 36 # Remove with: fanfix uninstall (after the fan is replaced) 37 w /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq - - - - ${khz} 38 EOF 39 systemd-tmpfiles --create "$CONF" 40 powerprofilesctl set performance 2>/dev/null || true 41 systemd-tmpfiles --create "$CONF" # profile switches toggle boost; re-assert 42 echo "cap = $(( $(cat "$CPU0/scaling_max_freq") / 1000 )) MHz, persisted in $CONF" ;; 43 uncap) 44 # Full boost. The EC's fan-abnormal policy still stalls the CPU at ~79 C, 45 # so sustained all-core loads may hit the 400 MHz clamp — deliberate choice. 46 rm -f "$CONF" 47 echo 1 > /sys/devices/system/cpu/cpufreq/boost 48 for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq; do 49 cat "${f%scaling_max_freq}cpuinfo_max_freq" > "$f" 50 done 51 echo "uncapped: max = $(( $(cat "$CPU0/scaling_max_freq") / 1000 )) MHz, turbo boost on" ;; 52 *) 53 echo "usage: fan-ctl auto|max|set <pct>|curve on|off|drivers|cap [MHz]|uncap" >&2 54 exit 2 ;; 55 esac