I have been running Omarchy on a 2019 Intel MacBook Pro with Apple's T2 chip. It is close enough to being a great little Linux laptop that the remaining problems become extra annoying.
The last rough edge was suspend/resume. The machine could sleep and wake, but some hardware would come back in a weird half-alive state. Touch Bar needed help. Wi-Fi needed help. Bluetooth looked alive, but devices would not reliably reconnect.
This post is not a universal T2 guide. It is the exact set of local fixes that made this machine usable.
The Machine
The system at the time of writing:
Host: mbp2019
Kernel: 7.0.10-arch1-Watanare-T2-2-t2
Distro: Arch Linux with Omarchy
Model: 2019 Intel MacBook Pro with Apple T2
The important hardware mapping from lspci -nnk:
01:00.0 Broadcom BCM4377b Wireless Network Adapter [14e4:4488]
Kernel driver in use: brcmfmac
01:00.1 Broadcom BRCM4377 Bluetooth Controller [14e4:5fa0]
Kernel driver in use: hci_bcm4377
02:00.1 Apple T2 Bridge Controller [106b:1801]
Kernel driver in use: apple-bce
06:00.0 Intel JHL7540 Thunderbolt 3 USB Controller [8086:15ec]
Kernel driver in use: xhci_hcd
The first two lines are the trap. Wi-Fi and Bluetooth sit next to each other, but they are different PCI functions with different drivers:
0000:01:00.0 -> Wi-Fi -> brcmfmac
0000:01:00.1 -> Bluetooth -> hci_bcm4377
Treating them as one thing is a good way to fix one problem while breaking another.
The Base T2 Pieces
This machine uses the arch-mact2 repository in /etc/pacman.conf:
[arch-mact2]
Server = https://github.com/NoaHimesaka1873/arch-mact2-mirror/releases/download/release
SigLevel = Never
Wi-Fi uses iwd, with this Broadcom quirk in /etc/iwd/main.conf:
[DriverQuirks]
SaeDisable=brcmfmac
The Touch Bar is handled by tiny-dfr. In my case, tiny-dfr.service, bluetooth.service, iwd.service, and the two custom suspend/resume units are all enabled.
The Problem After Resume
The useful failure mode was this:
- The machine resumed.
- The Touch Bar needed the usual T2 module dance and USB re-enumeration.
- Wi-Fi needed the existing
brcmfmacrecovery path. - Bluetooth was powered on and visible in
bluetoothctl show, but paired devices would not reliably reconnect.
The Bluetooth logs had errors like:
Reconnecting services failed: Device or resource busy
Connection timed out
Connection refused
Restarting random networking services is tempting here. Do not do that first. On this machine, Wi-Fi was already working. The fix needed to be Bluetooth-only.
Testing Bluetooth Without Suspending
Before putting anything into a resume hook, I tested the Bluetooth recovery manually:
sudo bash -c 'echo 0000:01:00.1 > /sys/bus/pci/drivers/hci_bcm4377/unbind; sleep 2; echo 0000:01:00.1 > /sys/bus/pci/drivers/hci_bcm4377/bind'
sudo systemctl restart bluetooth.service
That brought Bluetooth back immediately.
That was the important clue. The right fix was not to disturb Wi-Fi. It was to preserve the working Wi-Fi recovery and add the same narrow Bluetooth reset to the resume service.
Suspend Unit
This is /etc/systemd/system/suspend-fix-t2.service on my machine:
[Unit]
Description=Fix T2 suspend
Before=sleep.target
[Service]
Type=oneshot
ExecStart=-/usr/bin/bash -c 'if [ -L /sys/bus/pci/devices/0000:06:00.0/driver ]; then echo 0000:06:00.0 > /sys/bus/pci/drivers/xhci_hcd/unbind; fi'
ExecStart=-/usr/bin/bash -c 'if [ -L /sys/bus/pci/devices/0000:01:00.0/driver ]; then echo 0000:01:00.0 > /sys/bus/pci/drivers/brcmfmac/unbind; fi'
ExecStart=-/usr/bin/bash -c 'if [ -L /sys/bus/pci/devices/0000:01:00.1/driver ]; then echo 0000:01:00.1 > /sys/bus/pci/drivers/hci_bcm4377/unbind; fi'
ExecStart=/usr/bin/systemctl stop tiny-dfr
ExecStart=-/usr/bin/rmmod -f hid_appletb_kbd
ExecStart=-/usr/bin/rmmod -f hid_appletb_bl
ExecStart=-/usr/bin/rmmod -f appletbdrm
ExecStart=-/usr/bin/rmmod -f apple_bce
[Install]
WantedBy=sleep.target
The leading - makes systemd ignore failures for that command. That matters because a device or module may already be absent depending on the current state.
Resume Unit
This is /etc/systemd/system/resume-fix-t2.service:
[Unit]
Description=Reload T2 modules after resume
After=suspend.target
[Service]
Type=oneshot
ExecStart=/usr/bin/sleep 4
ExecStart=/usr/bin/modprobe apple_bce
ExecStart=/usr/bin/sleep 4
ExecStart=/usr/bin/modprobe hid_appletb_bl
ExecStart=/usr/bin/sleep 2
ExecStart=/usr/bin/modprobe hid_appletb_kbd
ExecStart=/usr/bin/sleep 4
ExecStart=-/usr/bin/bash -c "test -e /sys/bus/usb/devices/5-6/bConfigurationValue && echo 0 > /sys/bus/usb/devices/5-6/bConfigurationValue"
ExecStart=/usr/bin/sleep 1
ExecStart=-/usr/bin/bash -c "test -e /sys/bus/usb/devices/5-6/bConfigurationValue && echo 2 > /sys/bus/usb/devices/5-6/bConfigurationValue"
ExecStart=/usr/bin/sleep 3
ExecStart=-/usr/bin/systemctl restart tiny-dfr
ExecStart=-/usr/bin/bash -c 'if [ ! -L /sys/bus/pci/devices/0000:06:00.0/driver ]; then echo 0000:06:00.0 > /sys/bus/pci/drivers/xhci_hcd/bind; fi'
ExecStart=-/usr/bin/bash -c 'if [ ! -L /sys/bus/pci/devices/0000:01:00.0/driver ]; then echo 0000:01:00.0 > /sys/bus/pci/drivers/brcmfmac/bind; fi'
ExecStart=-/usr/bin/bash -c 'if [ ! -L /sys/bus/pci/devices/0000:01:00.1/driver ]; then echo 0000:01:00.1 > /sys/bus/pci/drivers/hci_bcm4377/bind; fi'
ExecStart=-/usr/bin/systemctl restart bluetooth
ExecStart=-/usr/bin/bash -c 'sleep 8; networkctl status wlan0 --no-pager | /usr/bin/grep -q "State: routable" || /usr/bin/systemctl restart iwd'
[Install]
WantedBy=suspend.target
The Touch Bar USB path is machine-specific. Mine is 5-6. Yours may not be.
To find it, look for product ID 8302:
for dev in /sys/bus/usb/devices/*/; do
printf "%s: " "$dev"
cat "$dev/idProduct" 2>/dev/null || true
done
If your Touch Bar path is different, replace 5-6 in the resume service.
Enable The Units
After writing the files:
sudo systemctl daemon-reload
sudo systemctl enable suspend-fix-t2.service resume-fix-t2.service
systemd-analyze verify /etc/systemd/system/suspend-fix-t2.service /etc/systemd/system/resume-fix-t2.service
Then test the whole flow:
systemctl suspend
After waking:
systemctl status bluetooth --no-pager
systemctl status iwd --no-pager
bluetoothctl show
networkctl status wlan0 --no-pager
Useful logs:
journalctl -u suspend-fix-t2.service -u resume-fix-t2.service -b --no-pager
journalctl -u bluetooth.service -b --no-pager
journalctl -u iwd.service -b --no-pager
What Finally Worked
The working recipe was boring, which is usually a good sign:
- Keep the existing
brcmfmacWi-Fi recovery because Wi-Fi needed it and it worked. - Add the Bluetooth PCI function separately with
hci_bcm4377. - Restart
bluetooth.serviceafter binding Bluetooth again. - Reload the T2 / Touch Bar modules in order.
- Re-enumerate the Touch Bar USB device before restarting
tiny-dfr.
The key lesson: do not fix Bluetooth by poking the Wi-Fi driver, and do not fix Wi-Fi by restarting the whole world. On this machine, the reliable path was narrow and boring: reset exactly the device that failed, then restart exactly the service that manages it.
Thanks to the folks in the Omarchy and t2linux discussions who documented the Touch Bar side of this. The Bluetooth bit here is just the extra piece I needed for this specific 13-inch 2019 machine.