Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion install/config/hardware/fix-apple-t2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,37 @@ EOF
sudo mkdir -p /etc/limine-entry-tool.d
cat <<EOF | sudo tee /etc/limine-entry-tool.d/t2-mac.conf >/dev/null
# Generated by Omarchy installer for T2 Mac support
KERNEL_CMDLINE[default]+=" intel_iommu=on iommu=pt pcie_ports=compat"
KERNEL_CMDLINE[default]+=" intel_iommu=on iommu=pt pcie_ports=compat mem_sleep_default=s2idle"
EOF

# T2 Macs cannot use S3 (deep) sleep — force s2idle (freeze) mode
sudo mkdir -p /etc/systemd/sleep.conf.d
cat <<EOF | sudo tee /etc/systemd/sleep.conf.d/t2-suspend.conf >/dev/null
[Sleep]
SuspendState=freeze
EOF

# Manage T2 modules and PCI power states around suspend:
# - Disable d3cold on Apple NVMe and T2 Bridge to prevent wake failures
# - Unload brcmfmac (WiFi) to avoid D3 suspend timeout
# - Unload apple-bce (keyboard/trackpad) to ensure clean resume
cat <<'EOF' | sudo tee /etc/systemd/system/omarchy-suspend-t2.service >/dev/null
[Unit]
Description=Manage T2 modules around suspend
Before=sleep.target
StopWhenUnneeded=yes

[Service]
User=root
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'for dev in /sys/bus/pci/devices/*/; do vendor=$(cat "$dev/vendor" 2>/dev/null); device=$(cat "$dev/device" 2>/dev/null); if [[ "$vendor" == "0x106b" ]] && [[ "$device" == "0x2005" || "$device" == "0x1801" || "$device" == "0x1802" ]]; then echo 0 > "$dev/d3cold_allowed" 2>/dev/null; fi; done; rmmod brcmfmac_wcc 2>/dev/null; rmmod brcmfmac 2>/dev/null; rmmod -f apple-bce 2>/dev/null'
ExecStop=/bin/bash -c 'modprobe apple-bce; sleep 2; modprobe brcmfmac'

[Install]
WantedBy=sleep.target
EOF

sudo systemctl enable omarchy-suspend-t2.service
sudo systemctl daemon-reload
fi
54 changes: 54 additions & 0 deletions migrations/1774617744.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
echo "Fix suspend/sleep on T2 MacBooks"

# Only run on T2 Macs
if ! lspci -nn | grep -q "106b:180[12]"; then
exit 0
fi

# Force s2idle (freeze) suspend mode — T2 Macs cannot use S3 (deep) sleep
sudo mkdir -p /etc/systemd/sleep.conf.d
cat <<EOF | sudo tee /etc/systemd/sleep.conf.d/t2-suspend.conf >/dev/null
[Sleep]
SuspendState=freeze
EOF

# Add mem_sleep_default=s2idle to kernel cmdline if not present
T2_CONF="/etc/limine-entry-tool.d/t2-mac.conf"
if [[ -f "$T2_CONF" ]] && ! grep -q "mem_sleep_default=s2idle" "$T2_CONF"; then
sudo sed -i 's/pcie_ports=compat"/pcie_ports=compat mem_sleep_default=s2idle"/' "$T2_CONF"
fi

# Regenerate boot config so kernel cmdline change takes effect
if command -v limine-mkinitcpio >/dev/null 2>&1; then
sudo limine-mkinitcpio
fi

# Create and enable suspend service if not already present
if [[ ! -f /etc/systemd/system/omarchy-suspend-t2.service ]]; then
Comment on lines +16 to +27

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only edits /etc/limine-entry-tool.d/t2-mac.conf and only via a fragile string replacement of pcie_ports=compat". On many installs the effective kernel cmdline comes from /etc/default/limine (which can override drop-ins), so this migration may not actually apply mem_sleep_default=s2idle. Update the effective Limine config (e.g., /etc/default/limine when present) and run limine-update (as other migrations do) so the new cmdline takes effect, and append the param more robustly if the expected substring isn’t present.

Suggested change
T2_CONF="/etc/limine-entry-tool.d/t2-mac.conf"
if [[ -f "$T2_CONF" ]] && ! grep -q "mem_sleep_default=s2idle" "$T2_CONF"; then
sudo sed -i 's/pcie_ports=compat"/pcie_ports=compat mem_sleep_default=s2idle"/' "$T2_CONF"
fi
# Create and enable suspend service if not already present
if [[ ! -f /etc/systemd/system/omarchy-suspend-t2.service ]]; then
add_t2_kernel_param() {
local file="$1"
local param="$2"
[[ -f "$file" ]] || return 0
if grep -q "$param" "$file"; then
return 0
fi
# Prefer to add after pcie_ports=compat if present
if grep -q "pcie_ports=compat" "$file"; then
sudo sed -i 's/pcie_ports=compat/& '"$param"'/g' "$file"
else
# Fall back to appending inside common cmdline variables if present
sudo sed -i 's/^\(LINUX_CMDLINE="[^"]*\)"/\1 '"$param"'"/' "$file" 2>/dev/null || true
sudo sed -i 's/^\(CMDLINE="[^"]*\)"/\1 '"$param"'"/' "$file" 2>/dev/null || true
fi
}
T2_CONF="/etc/limine-entry-tool.d/t2-mac.conf"
DEFAULT_LIMINE="/etc/default/limine"
add_t2_kernel_param "$T2_CONF" "mem_sleep_default=s2idle"
add_t2_kernel_param "$DEFAULT_LIMINE" "mem_sleep_default=s2idle"
# Apply Limine configuration if possible
if command -v limine-update >/dev/null 2>&1; then
sudo limine-update
fi
# Create and enable suspend service if not already present
if [[ ! -f /etc/systemd/system/omarchy-suspend-t2.service ]]; then
if [[ ! -f /etc/systemd/system/omarchy-suspend-t2.service ]]; then

Copilot uses AI. Check for mistakes.
cat <<'EOF' | sudo tee /etc/systemd/system/omarchy-suspend-t2.service >/dev/null
[Unit]
Description=Manage T2 modules around suspend
Before=sleep.target
StopWhenUnneeded=yes

[Service]
User=root
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'for dev in /sys/bus/pci/devices/*/; do vendor=$(cat "$dev/vendor" 2>/dev/null); device=$(cat "$dev/device" 2>/dev/null); if [[ "$vendor" == "0x106b" ]] && [[ "$device" == "0x2005" || "$device" == "0x1801" || "$device" == "0x1802" ]]; then echo 0 > "$dev/d3cold_allowed" 2>/dev/null; fi; done; rmmod brcmfmac_wcc 2>/dev/null; rmmod brcmfmac 2>/dev/null; rmmod -f apple-bce 2>/dev/null'
ExecStop=/bin/bash -c 'modprobe apple-bce; sleep 2; modprobe brcmfmac'

[Install]
WantedBy=sleep.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable omarchy-suspend-t2.service
fi

# Clean up old user-created suspend-t2.service (pre-omarchy naming)
if [[ -f /etc/systemd/system/suspend-t2.service ]]; then
sudo systemctl disable suspend-t2.service 2>/dev/null
sudo rm -f /etc/systemd/system/suspend-t2.service
sudo systemctl daemon-reload
fi