diff --git a/bin/omarchy-hibernation-setup b/bin/omarchy-hibernation-setup index 108e8ffa..a43d34ec 100755 --- a/bin/omarchy-hibernation-setup +++ b/bin/omarchy-hibernation-setup @@ -62,6 +62,18 @@ echo "HOOKS+=(resume)" | sudo tee "$MKINITCPIO_CONF" >/dev/null # Ensure keyboard backlight doesn't prevent sleep sudo cp -p "$OMARCHY_PATH/default/systemd/system-sleep/keyboard-backlight" /usr/lib/systemd/system-sleep/ +# Add resume= kernel parameters so the initramfs resume hook knows where to find the +# hibernation image. Without these, resume happens late (after GPU drivers load) and fails. +RESUME_DROP_IN="/etc/limine-entry-tool.d/resume.conf" +if [[ ! -f "$RESUME_DROP_IN" ]]; then + echo "Adding resume kernel parameters" + sudo swapon -p 0 "$SWAP_FILE" 2>/dev/null + RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//') + RESUME_OFFSET=$(btrfs inspect-internal map-swapfile -r "$SWAP_FILE") + sudo mkdir -p /etc/limine-entry-tool.d + echo "KERNEL_CMDLINE[default]+=\"resume=$RESUME_DEVICE resume_offset=$RESUME_OFFSET\"" | sudo tee "$RESUME_DROP_IN" >/dev/null +fi + # Use ACPI alarm for RTC wakeup on s2idle systems (needed for suspend-then-hibernate) if grep -q "\[s2idle\]" /sys/power/mem_sleep 2>/dev/null; then LIMINE_DROP_IN="/etc/limine-entry-tool.d/rtc-alarm.conf" diff --git a/default/systemd/system-sleep/force-igpu b/default/systemd/system-sleep/force-igpu index ab0d6d6c..6f129438 100755 --- a/default/systemd/system-sleep/force-igpu +++ b/default/systemd/system-sleep/force-igpu @@ -5,14 +5,25 @@ # will wake after suspend in Hybrid mode, even if the system was in Integrated mode before # suspending. -if [[ $1 == "post" ]]; then - # small delay so the device is fully re-enumerated - sleep 4 +case "$1" in + pre) + # Before hibernating, switch to Vfio so the nvidia driver is detached from the dGPU. + # Without this, hibernate resume fails because the nvidia driver can't freeze a + # powered-off dGPU (returns -EIO), which aborts the entire resume. + if [[ $2 == "hibernate" ]]; then + /usr/bin/supergfxctl -m Vfio + sleep 1 + fi + ;; + post) + # small delay so the device is fully re-enumerated + sleep 4 - # force-bind dGPU to vfio (fully detached from nvidia) - /usr/bin/supergfxctl -m Vfio - sleep 1 + # force-bind dGPU to vfio (fully detached from nvidia) + /usr/bin/supergfxctl -m Vfio + sleep 1 - # then go back to Integrated, which powers it off again - /usr/bin/supergfxctl -m Integrated -fi + # then go back to Integrated, which powers it off again + /usr/bin/supergfxctl -m Integrated + ;; +esac