Summary
On Intel T2 MacBook Pro (T2, Touch Bar model) running the t2-resolute kernel on
Ubuntu 26.04, the appletbdrm driver reliably fails to probe the Touch Bar
display at boot with -ETIMEDOUT (-110), so /dev/dri/card* for the Touch Bar
is never created. This leaves tiny-dfr.service permanently dead (its
dev-tiny_dfr_display.device BindsTo target never appears), so the Touch Bar
never lights up after boot, even though tiny-dfr is correctly installed and
all relevant kernel modules (apple_bce, hid_appletb_kbd, hid_appletb_bl,
appletbdrm) load successfully.
A full unload/reload of the apple_bce → hid_appletb_bl → hid_appletb_kbd
module stack with delays, followed by cycling the Touch Bar USB device's
bConfigurationValue (0 then 2) and restarting tiny-dfr, reliably recovers
the Touch Bar — but this has to be done manually (or via a custom boot-time
script) on every boot, since the initial probe at boot always loses the race.
Environment
- Hardware: MacBook Pro with Intel T2 chip, Touch Bar model (USB
05ac:8302
"Touch Bar Display", 05ac:8102 "Touch Bar Backlight")
- OS: Ubuntu 26.04 LTS (Resolute Raccoon)
- Kernel:
7.1.2-1-t2-resolute (t2-resolute flavor, #1 SMP PREEMPT_DYNAMIC)
tiny-dfr package: 0.3.7-4-resolute
- Relevant loaded modules:
apple_bce, appletbdrm, hid_appletb_kbd,
hid_appletb_bl, hid_multitouch
Steps to reproduce
- Boot the machine normally (cold boot).
- Check
systemctl status tiny-dfr → inactive (dead), with:
Dependency failed for tiny-dfr.service - Tiny Apple T2 and Silicon Macs Touch Bar daemon.
Job tiny-dfr.service/start failed with result 'dependency'.
- Check
systemctl status dev-tiny_dfr_display.device → never becomes active.
- Check kernel log:
appletbdrm 7-6:2.1: [drm] *ERROR* Failed to send message (-110)
appletbdrm 7-6:2.1: [drm] *ERROR* Failed to get display information
appletbdrm 7-6:2.1: probe with driver appletbdrm failed with error -110
usbcore: registered new interface driver appletbdrm
This happens consistently ~15-17 seconds after the Touch Bar USB device
first enumerates, on every cold boot.
Expected behavior
appletbdrm successfully probes the Touch Bar Display USB interface
(7-6:2.1 in this instance) at boot, creating a DRM card device, which makes
/dev/tiny_dfr_display appear and lets tiny-dfr.service start normally —
same as what happens after the manual recovery below.
Actual behavior
appletbdrm_probe() times out (-110/ETIMEDOUT) talking to the device over
the apple_bce/bce-vhci virtual USB layer, and never binds. Once this
happens, even rebinding the driver (rmmod/modprobe appletbdrm,
unbind/bind, or toggling authorized) does not recover it — the
bce-vhci channel itself appears to get wedged and stops responding even to
raw bConfigurationValue sysfs writes (which themselves then start returning
Connection timed out (os error 110)).
The only thing that reliably recovers it (without a full reboot) is unloading
the entire apple_bce module (which also tears down T2 audio, so any
process holding /dev/snd/* open — e.g. PipeWire/WirePlumber — must be
stopped first) and reloading the stack with explicit delays:
systemctl stop tiny-dfr
rmmod hid_appletb_kbd
rmmod hid_appletb_bl
rmmod appletbdrm
rmmod apple_bce
modprobe apple_bce
sleep 4
modprobe hid_appletb_bl
sleep 4
modprobe hid_appletb_kbd
sleep 2
echo 0 > /sys/bus/usb/devices/7-6/bConfigurationValue
sleep 1
echo 2 > /sys/bus/usb/devices/7-6/bConfigurationValue
sleep 3
systemctl restart tiny-dfr
After this sequence, dmesg shows:
[drm] Initialized appletbdrm 1.0.0 for 7-6:2.1 on minor 0
usbcore: registered new interface driver appletbdrm
and the Touch Bar comes up correctly.
Notes / related reports
- This looks like the same class of regression discussed in
t2linux/wiki#635 ("TouchBar
appletbdrm the module reload functionality is broken, not the initial
loading!"), reported as appearing around kernel 6.12.31+ and confirmed
present on 7.0.5. Here it also affects initial boot-time loading, not
just reload after suspend — possibly because by kernel 7.1.2 the race
window has gotten consistently lost rather than only "sometimes."
- A community workaround for the equivalent post-suspend/resume version of
this race is documented in
basecamp/omarchy#5862,
using the same reload-with-delays + bConfigurationValue cycle pattern
used above, via suspend-fix-t2.service/resume-fix-t2.service.
- This is unrelated to
basecamp/omarchy#3791,
which is an Arch/Omarchy packaging issue (services not enabled, missing
video group membership, Apple-Silicon-only systemd unit dependencies) —
not a kernel-level probe failure.
Suggested fix direction
The race is most likely in appletbdrm_probe() (or in apple_bce's
bce-vhci virtual host controller setup) — the driver attempts to send its
"get display information" vendor message before the vhci channel for that
USB interface has finished settling after the device's bConfigurationValue
is switched by udev. A built-in retry (with backoff) around the initial
display-info request in appletbdrm_probe() would likely fix this without
requiring a full apple_bce reload.
Current workaround in use
A systemd oneshot unit (touchbar-boot-fix.service) running early at boot,
before display-manager.service and tiny-dfr.service, that performs the
reload-with-delays sequence above automatically. Adds roughly 14s to boot
(the deliberate sleeps, needed to give the bce-vhci channel time to
settle), but reliably brings the Touch Bar up on every cold boot.
Note: the script and unit must use systemctl --no-block for any
tiny-dfr.service start/stop calls. A blocking systemctl restart tiny-dfr from inside this script deadlocks against the unit's own
Before=tiny-dfr.service ordering (tiny-dfr can't start until the script
exits, but a blocking call would have the script wait on tiny-dfr to
start) — it doesn't fail loudly, it just hangs for the full
TimeoutStartSec and gets SIGTERM'd, costing an extra ~60s of boot time
before tiny-dfr is finally (correctly) started by udev anyway. Mentioning
this explicitly in case anyone building on this workaround hits the same
trap.
Install as /usr/local/sbin/touchbar-boot-fix.sh (root, chmod 755):
#!/bin/bash
# Works around a boot-time race where appletbdrm probes the T2 Touch Bar
# (USB 05ac:8302) before the apple-bce vhci channel is ready, failing with
# -ETIMEDOUT and leaving /dev/tiny_dfr_display (and tiny-dfr.service) dead.
# Reloading the whole apple_bce stack with delays clears the wedged channel.
set -u
log() { echo "touchbar-boot-fix: $*"; }
TBDEV=""
for d in /sys/bus/usb/devices/[0-9]*-[0-9]*; do
[ -f "$d/idProduct" ] || continue
if [ "$(cat "$d/idProduct" 2>/dev/null)" = "8302" ]; then
TBDEV="$(basename "$d")"
break
fi
done
if [ -z "$TBDEV" ]; then
log "no 05ac:8302 Touch Bar Display USB device found, nothing to do"
exit 0
fi
for drv in /sys/bus/usb/devices/"$TBDEV":*/driver; do
if [ "$(basename "$(readlink -f "$drv")" 2>/dev/null)" = "appletbdrm" ]; then
log "appletbdrm already bound to $TBDEV, nothing to do"
exit 0
fi
done
log "reloading apple_bce/touchbar stack (device $TBDEV)"
# --no-block: this unit is ordered Before=tiny-dfr.service, so a blocking
# `systemctl restart` on tiny-dfr here would deadlock against that ordering
# (tiny-dfr can't start until we exit, but we'd be waiting on it to start).
systemctl --no-block stop tiny-dfr.service 2>/dev/null
log "rmmod hid_appletb_kbd hid_appletb_bl appletbdrm apple_bce"
rmmod hid_appletb_kbd 2>/dev/null
rmmod hid_appletb_bl 2>/dev/null
rmmod appletbdrm 2>/dev/null
sleep 1
timeout 15 rmmod apple_bce 2>/dev/null
log "modprobe apple_bce"
timeout 15 modprobe apple_bce
sleep 4
log "modprobe hid_appletb_bl"
modprobe hid_appletb_bl
sleep 4
log "modprobe hid_appletb_kbd"
modprobe hid_appletb_kbd
sleep 2
log "cycling bConfigurationValue on $TBDEV"
echo 0 > /sys/bus/usb/devices/"$TBDEV"/bConfigurationValue 2>/dev/null
sleep 1
echo 2 > /sys/bus/usb/devices/"$TBDEV"/bConfigurationValue 2>/dev/null
sleep 3
udevadm settle --timeout=10 2>/dev/null
# Non-blocking safety net: the udev rule's SYSTEMD_WANTS on the touchpad
# input device normally re-triggers tiny-dfr.service on its own once the
# device re-enumerates above; this is just a backstop.
systemctl --no-block restart tiny-dfr.service 2>/dev/null
log "done"
exit 0
Install as /etc/systemd/system/touchbar-boot-fix.service:
[Unit]
Description=Work around appletbdrm Touch Bar probe race at boot
DefaultDependencies=no
After=systemd-udev-settle.service local-fs.target
Before=display-manager.service tiny-dfr.service
Wants=systemd-udev-settle.service
[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=60
ExecStart=/usr/local/sbin/touchbar-boot-fix.sh
[Install]
WantedBy=sysinit.target
Enable with:
sudo chmod 755 /usr/local/sbin/touchbar-boot-fix.sh
sudo systemctl daemon-reload
sudo systemctl enable touchbar-boot-fix.service
The idProduct=8302 lookup makes the script independent of the USB bus
path (7-6 here, but this varies by machine/boot enumeration order), so it
should work unmodified on other T2 Touch Bar Macs.
Summary
On Intel T2 MacBook Pro (T2, Touch Bar model) running the
t2-resolutekernel onUbuntu 26.04, the
appletbdrmdriver reliably fails to probe the Touch Bardisplay at boot with
-ETIMEDOUT (-110), so/dev/dri/card*for the Touch Baris never created. This leaves
tiny-dfr.servicepermanently dead (itsdev-tiny_dfr_display.deviceBindsTotarget never appears), so the Touch Barnever lights up after boot, even though
tiny-dfris correctly installed andall relevant kernel modules (
apple_bce,hid_appletb_kbd,hid_appletb_bl,appletbdrm) load successfully.A full unload/reload of the
apple_bce→hid_appletb_bl→hid_appletb_kbdmodule stack with delays, followed by cycling the Touch Bar USB device's
bConfigurationValue(0 then 2) and restartingtiny-dfr, reliably recoversthe Touch Bar — but this has to be done manually (or via a custom boot-time
script) on every boot, since the initial probe at boot always loses the race.
Environment
05ac:8302"Touch Bar Display",
05ac:8102"Touch Bar Backlight")7.1.2-1-t2-resolute(t2-resolute flavor,#1 SMP PREEMPT_DYNAMIC)tiny-dfrpackage:0.3.7-4-resoluteapple_bce,appletbdrm,hid_appletb_kbd,hid_appletb_bl,hid_multitouchSteps to reproduce
systemctl status tiny-dfr→inactive (dead), with:systemctl status dev-tiny_dfr_display.device→ never becomes active.first enumerates, on every cold boot.
Expected behavior
appletbdrmsuccessfully probes the Touch Bar Display USB interface(
7-6:2.1in this instance) at boot, creating a DRM card device, which makes/dev/tiny_dfr_displayappear and letstiny-dfr.servicestart normally —same as what happens after the manual recovery below.
Actual behavior
appletbdrm_probe()times out (-110/ETIMEDOUT) talking to the device overthe
apple_bce/bce-vhcivirtual USB layer, and never binds. Once thishappens, even rebinding the driver (
rmmod/modprobe appletbdrm,unbind/bind, or toggling
authorized) does not recover it — thebce-vhcichannel itself appears to get wedged and stops responding even toraw
bConfigurationValuesysfs writes (which themselves then start returningConnection timed out (os error 110)).The only thing that reliably recovers it (without a full reboot) is unloading
the entire
apple_bcemodule (which also tears down T2 audio, so anyprocess holding
/dev/snd/*open — e.g. PipeWire/WirePlumber — must bestopped first) and reloading the stack with explicit delays:
After this sequence, dmesg shows:
and the Touch Bar comes up correctly.
Notes / related reports
t2linux/wiki#635 ("TouchBar
appletbdrm the module reload functionality is broken, not the initial
loading!"), reported as appearing around kernel 6.12.31+ and confirmed
present on 7.0.5. Here it also affects initial boot-time loading, not
just reload after suspend — possibly because by kernel 7.1.2 the race
window has gotten consistently lost rather than only "sometimes."
this race is documented in
basecamp/omarchy#5862,
using the same reload-with-delays +
bConfigurationValuecycle patternused above, via
suspend-fix-t2.service/resume-fix-t2.service.basecamp/omarchy#3791,
which is an Arch/Omarchy packaging issue (services not enabled, missing
videogroup membership, Apple-Silicon-only systemd unit dependencies) —not a kernel-level probe failure.
Suggested fix direction
The race is most likely in
appletbdrm_probe()(or inapple_bce'sbce-vhcivirtual host controller setup) — the driver attempts to send its"get display information" vendor message before the vhci channel for that
USB interface has finished settling after the device's
bConfigurationValueis switched by udev. A built-in retry (with backoff) around the initial
display-info request in
appletbdrm_probe()would likely fix this withoutrequiring a full
apple_bcereload.Current workaround in use
A
systemdoneshot unit (touchbar-boot-fix.service) running early at boot,before
display-manager.serviceandtiny-dfr.service, that performs thereload-with-delays sequence above automatically. Adds roughly 14s to boot
(the deliberate
sleeps, needed to give thebce-vhcichannel time tosettle), but reliably brings the Touch Bar up on every cold boot.
Note: the script and unit must use
systemctl --no-blockfor anytiny-dfr.servicestart/stop calls. A blockingsystemctl restart tiny-dfrfrom inside this script deadlocks against the unit's ownBefore=tiny-dfr.serviceordering (tiny-dfr can't start until the scriptexits, but a blocking call would have the script wait on tiny-dfr to
start) — it doesn't fail loudly, it just hangs for the full
TimeoutStartSecand gets SIGTERM'd, costing an extra ~60s of boot timebefore tiny-dfr is finally (correctly) started by udev anyway. Mentioning
this explicitly in case anyone building on this workaround hits the same
trap.
Install as
/usr/local/sbin/touchbar-boot-fix.sh(root,chmod 755):Install as
/etc/systemd/system/touchbar-boot-fix.service:Enable with:
sudo chmod 755 /usr/local/sbin/touchbar-boot-fix.sh sudo systemctl daemon-reload sudo systemctl enable touchbar-boot-fix.serviceThe
idProduct=8302lookup makes the script independent of the USB buspath (
7-6here, but this varies by machine/boot enumeration order), so itshould work unmodified on other T2 Touch Bar Macs.