After running Frigate NVR with CPU inference for way too long, I decided it was finally time to start using an accelerator, and ordered a Google Coral USB Accelerator. When plugging in the device, it appeared in lsusb like this:

Bus 002 Device 003: ID 1a6e:089a Global Unichip Corp.

The Frigate docs mention that it needs to initialize the Coral USB first, before it can use it. Frigate will try to initialize the device, but doing so will change the USB ID. This is problematic if you are running Frigate in a VM, and need to passthrough the device using the USB ID. After initialization, the device appears like this in lsusb:

Bus 002 Device 004: ID 18d1:9302 Google Inc.

For initial testing, I did things manually: I enabled USB passthrough for 1a6e:089a in the VM, started the VM, configured Frigate to use edgetpu type detector, and started Frigate. At that point, the USB ID for the device changed, as expected. I then shut down the VM, disabled passthrough for 1a6e:089a and enabled passhthrough for 18d1:9302 and started the VM again. The Frigate logs now confirm the TPU is found:

[2025-01-22 13:51:54] frigate.detectors.plugins.edgetpu_tfl INFO    : Attempting to load TPU as auto
[2025-01-22 13:51:58] frigate.detectors.plugins.edgetpu_tfl INFO    : TPU found

I once again shut down the VM to see what would happen to the USB ID, and found that the USB ID did not change back to 18d1:9302, so I started the VM again and left things as they were. Until I had a power outage long enough to shut down the physical server before the UPS batteries depleted. When power was restored, I found myself unable to start the VM:

# virsh start k3s-01
error: Failed to start domain 'k3s-01'
error: internal error: Did not find USB device 18d1:9302

So it appears the initialization of the Coral USB loads the EdgeTPU driver in volatile memory, similar to e.g. the firmware of many modern Wi-Fi devices. For Wi-Fi devices, the kernel handles loading the firmware when the module is loaded, but as there is no module for the Coral USB, we can not rely on this, and need to come up with something to load the firmware. I then found a comment on a Github issue that loads the firmware using a Proxmox hook script. I don't use Proxmox, but the comment does contain a command that can be used to load the firmware. Great, now we can throw that in a udev rule to load the firmware upon plugging in the device.

Download the apex_latest_single_ep.bin firmware, place it in /usr/local/lib/firmware, and create the following udev rule, in e.g. /etc/udev/rules.d/95-coral.rules:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1a6e", ATTR{idProduct}=="089a", RUN+="/usr/bin/dfu-util -D /usr/local/lib/firmware/apex_latest_single_ep.bin -d '1a6e:089a' -R"

As this uses dfu-util, you need to make sure it is actually installed, preferably using your distro's native package management. In my case, on Gentoo:

emerge dfu-util

One final thing to do: make sure the udev rule is loaded:

udevadm control --reload

Now plug in the Coral USB and verify things worked. Your dmesg output should contain something like this:

[324461.087485] usb 3-6: new SuperSpeed USB device number 3 using xhci_hcd
[324461.955624] usb 3-6: reset SuperSpeed USB device number 3 using xhci_hcd                                                                              [324461.975783] usb 3-6: LPM exit latency is zeroed, disabling LPM.
[324461.981855] usb 3-6: device firmware changed                                                                                                          [324461.991545] usb 3-6: USB disconnect, device number 3
[324462.179501] usb 3-6: new SuperSpeed USB device number 4 using xhci_hcd                                                                                [324462.199740] usb 3-6: LPM exit latency is zeroed, disabling LPM.

When running lsusb, the device should immediately appear with the correct USB ID:

Bus 002 Device 004: ID 18d1:9302 Google Inc.

And now I no longer have to worry about the VM being unable to start after a long power outage, which unfortunately is not uncommon in Bulgaria, especially in some villages.