From 28ed3fcf743acacf54e3df7c9bcc58da5fe05c14 Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Sun, 19 Oct 2025 16:43:02 +0200 Subject: [PATCH] fix(nb): resolve keyboard/touchpad and btrfs read-only issues after suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit addresses two critical suspend/resume issues on the nb host: 1. Keyboard and touchpad not working after suspend - Added i2c_hid_acpi kernel module - Created systemd service to reload the module after resume - Excluded input devices from TLP USB autosuspend 2. /nix/persist becoming read-only after suspend - Moved swap from /nix/persist to dedicated @swap subvolume - Added systemd service to remount /nix/persist if needed - Separated swap from persistent data to prevent btrfs corruption Changes: - Created hosts/nb/modules/suspend-fixes.nix with resume hooks - Updated swap path from /nix/persist/swapfile to /swap/swapfile - Added /swap filesystem mount for @swap btrfs subvolume - Added USB_EXCLUDE_INPUT=1 to TLP configuration Note: Manual step required before deployment - create @swap subvolume. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- hosts/nb/configuration.nix | 3 ++- hosts/nb/hardware-configuration.nix | 10 +++++++++ hosts/nb/modules/desktop/default.nix | 1 + hosts/nb/modules/suspend-fixes.nix | 32 ++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 hosts/nb/modules/suspend-fixes.nix diff --git a/hosts/nb/configuration.nix b/hosts/nb/configuration.nix index 4f42a9c..070cf9d 100644 --- a/hosts/nb/configuration.nix +++ b/hosts/nb/configuration.nix @@ -30,6 +30,7 @@ in { ./modules/ollama.nix ./modules/qdrant.nix ./modules/battery-brightness.nix + ./modules/suspend-fixes.nix ./cachix.nix ./users @@ -79,7 +80,7 @@ in { services.irqbalance.enable = false; swapDevices = [ { - device = "/nix/persist/swapfile"; + device = "/swap/swapfile"; size = 96 * 1024; # Size is in megabytes (96GB for full hibernation with 92GB RAM) } ]; diff --git a/hosts/nb/hardware-configuration.nix b/hosts/nb/hardware-configuration.nix index a1538fb..a287335 100644 --- a/hosts/nb/hardware-configuration.nix +++ b/hosts/nb/hardware-configuration.nix @@ -92,6 +92,16 @@ ]; }; + fileSystems."/swap" = { + device = "/dev/mapper/root"; + fsType = "btrfs"; + neededForBoot = true; + options = [ + "subvol=@swap" + "noatime" + ]; + }; + swapDevices = [ ]; # Enables DHCP on each ethernet and wireless interface. In case of scripted networking diff --git a/hosts/nb/modules/desktop/default.nix b/hosts/nb/modules/desktop/default.nix index e7e7005..d1e2372 100644 --- a/hosts/nb/modules/desktop/default.nix +++ b/hosts/nb/modules/desktop/default.nix @@ -159,6 +159,7 @@ in { USB_EXCLUDE_PHONE = 0; USB_EXCLUDE_PRINTER = 1; USB_EXCLUDE_WWAN = 0; + USB_EXCLUDE_INPUT = 1; # Exclude keyboard/touchpad to prevent suspend issues # Audio power saving SOUND_POWER_SAVE_ON_AC = 0; diff --git a/hosts/nb/modules/suspend-fixes.nix b/hosts/nb/modules/suspend-fixes.nix new file mode 100644 index 0000000..430890d --- /dev/null +++ b/hosts/nb/modules/suspend-fixes.nix @@ -0,0 +1,32 @@ +{ config, pkgs, lib, ... }: + +{ + # Add i2c_hid_acpi kernel module for proper input device support + boot.kernelModules = [ "i2c_hid_acpi" ]; + + # Systemd service to reload i2c_hid_acpi module after resume + # This fixes keyboard and touchpad not working after suspend + systemd.services.reload-i2c-hid-after-resume = { + description = "Reload i2c_hid_acpi module after resume to fix keyboard/touchpad"; + after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.bash}/bin/bash -c '${pkgs.kmod}/bin/rmmod i2c_hid_acpi; ${pkgs.kmod}/bin/modprobe i2c_hid_acpi'"; + }; + }; + + # Systemd service to remount /nix/persist if it becomes read-only after resume + # This fixes the btrfs read-only issue that can occur with LUKS + btrfs on suspend/resume + systemd.services.remount-persist-after-resume = { + description = "Remount /nix/persist read-write if needed after resume"; + after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.util-linux}/bin/mount -o remount,rw /nix/persist"; + # Don't fail if already mounted rw + SuccessExitStatus = [ 0 32 ]; + }; + }; +}