Merge changes I9691cefe,I614e211c,I2a06ca6f,I9036ff66

* changes:
  Fix dependencies in //frc971/control_loops/python
  Import a few more pip packages for rules_python
  Fix mirroring for non-platform source-only Python packages
  Fix parsing for @pip target aliases
diff --git a/.bazelrc b/.bazelrc
index 9c94391..ce727ec 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -79,7 +79,7 @@
 build --show_result 5
 # Dump the output of the failing test to stdout.
 # Keep the default test timeouts except make 'eternal'=4500 secs
-test --test_output=errors --test_timeout=-1,-1,-1,4500
+test --test_output=errors --test_timeout=-1,-1,-1,5500
 
 build --sandbox_base=/dev/shm/
 build --experimental_multi_threaded_digest
diff --git a/aos/realtime.cc b/aos/realtime.cc
index ea54d9e..2f299e6 100644
--- a/aos/realtime.cc
+++ b/aos/realtime.cc
@@ -293,10 +293,11 @@
 }
 
 void FatalUnsetRealtimePriority() {
+  int saved_errno = errno;
   // Drop our priority first.  We are about to do lots of work to undo
   // everything, don't get overly clever.
   struct sched_param param;
-  param.sched_priority = 20;
+  param.sched_priority = 0;
   sched_setscheduler(0, SCHED_OTHER, &param);
 
   is_realtime = false;
@@ -311,12 +312,13 @@
       // ignore . and .. which are zeroes for some reason
       if (thread_id != 0) {
         struct sched_param param;
-        param.sched_priority = 20;
+        param.sched_priority = 0;
         sched_setscheduler(thread_id, SCHED_OTHER, &param);
       }
     }
     closedir(dirp);
   }
+  errno = saved_errno;
 }
 
 void RegisterMallocHook() {
diff --git a/frc971/rockpi/.config b/frc971/rockpi/.config
index a386534..5fe3348 100644
--- a/frc971/rockpi/.config
+++ b/frc971/rockpi/.config
@@ -538,18 +538,14 @@
 # CPU Idle
 #
 CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 # CONFIG_CPU_IDLE_GOV_MENU is not set
 # CONFIG_CPU_IDLE_GOV_TEO is not set
-CONFIG_DT_IDLE_STATES=y
-CONFIG_DT_IDLE_GENPD=y
 
 #
 # ARM CPU Idle Drivers
 #
-CONFIG_ARM_PSCI_CPUIDLE=y
-CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
+# CONFIG_ARM_PSCI_CPUIDLE is not set
 # end of ARM CPU Idle Drivers
 # end of CPU Idle
 
@@ -3833,7 +3829,7 @@
 # CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set
 # CONFIG_DRM_PANEL_DSI_CM is not set
 # CONFIG_DRM_PANEL_LVDS is not set
-CONFIG_DRM_PANEL_SIMPLE=m
+# CONFIG_DRM_PANEL_SIMPLE is not set
 # CONFIG_DRM_PANEL_EDP is not set
 # CONFIG_DRM_PANEL_EBBG_FT8719 is not set
 # CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set
@@ -4176,10 +4172,9 @@
 CONFIG_USB_DEFAULT_PERSIST=y
 # CONFIG_USB_FEW_INIT_RETRIES is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_OTG=y
+# CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_PRODUCTLIST is not set
 # CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
-# CONFIG_USB_OTG_FSM is not set
 # CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
 CONFIG_USB_AUTOSUSPEND_DELAY=2
 # CONFIG_USB_MON is not set
diff --git a/frc971/rockpi/build_kernel.sh b/frc971/rockpi/build_kernel.sh
index 73c0a51..f3cadd4 100755
--- a/frc971/rockpi/build_kernel.sh
+++ b/frc971/rockpi/build_kernel.sh
@@ -39,4 +39,13 @@
 
 VERSION="$(cat linux/include/config/kernel.release)"
 
+(
+  cd ../../y2022/localizer/kernel/
+  make rockpi
+)
+
+cp ../../y2022/localizer/kernel/adis16505.ko "kernel-install/lib/modules/${VERSION}/kernel/"
+
+/sbin/depmod -b ./kernel-install ${VERSION}
+
 tar -cvf "linux-kernel-${VERSION}.tar.xz" -C kernel-install .
diff --git a/frc971/rockpi/build_rootfs.sh b/frc971/rockpi/build_rootfs.sh
index a1d0a0a..e5706fc 100755
--- a/frc971/rockpi/build_rootfs.sh
+++ b/frc971/rockpi/build_rootfs.sh
@@ -154,8 +154,9 @@
 
 target "apt-get update"
 target "apt-get -y install -t bullseye-backports systemd"
+target "apt-get -y install -t bullseye-backports bpfcc-tools"
 
-target "apt-get install -y sudo openssh-server python3 bash-completion git v4l-utils cpufrequtils pmount rsync vim-nox chrony libopencv-calib3d4.5 libopencv-contrib4.5 libopencv-core4.5 libopencv-features2d4.5 libopencv-flann4.5 libopencv-highgui4.5 libopencv-imgcodecs4.5 libopencv-imgproc4.5 libopencv-ml4.5 libopencv-objdetect4.5 libopencv-photo4.5 libopencv-shape4.5 libopencv-stitching4.5 libopencv-superres4.5 libopencv-video4.5 libopencv-videoio4.5 libopencv-videostab4.5 libopencv-viz4.5 libnice10 pmount libnice-dev feh libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-nice usbutils locales"
+target "apt-get install -y sudo openssh-server python3 bash-completion git v4l-utils cpufrequtils pmount rsync vim-nox chrony libopencv-calib3d4.5 libopencv-contrib4.5 libopencv-core4.5 libopencv-features2d4.5 libopencv-flann4.5 libopencv-highgui4.5 libopencv-imgcodecs4.5 libopencv-imgproc4.5 libopencv-ml4.5 libopencv-objdetect4.5 libopencv-photo4.5 libopencv-shape4.5 libopencv-stitching4.5 libopencv-superres4.5 libopencv-video4.5 libopencv-videoio4.5 libopencv-videostab4.5 libopencv-viz4.5 libnice10 pmount libnice-dev feh libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-nice usbutils locales trace-cmd"
 
 target "usermod -a -G sudo pi"
 target "usermod -a -G video pi"
@@ -175,11 +176,14 @@
 copyfile root.root 644 etc/systemd/system/grow-rootfs.service
 copyfile root.root 644 etc/sysctl.d/sctp.conf
 copyfile root.root 644 etc/systemd/logind.conf
+copyfile root.root 555 etc/bash_completion.d/aos_dump_autocomplete
+copyfile root.root 444 etc/modules-load.d/adis16505.conf
 copyfile root.root 644 etc/security/limits.d/rt.conf
 copyfile root.root 644 etc/systemd/system/frc971.service
 copyfile root.root 644 etc/systemd/system/frc971chrt.service
 copyfile root.root 644 etc/systemd/system/usb-mount@.service
 copyfile root.root 644 etc/udev/rules.d/99-usb-mount.rules
+copyfile root.root 644 etc/udev/rules.d/99-adis16505.rules
 
 target "apt-get update"
 target "apt-get -y install -t bullseye-backports systemd"
diff --git a/frc971/rockpi/contents/etc/bash_completion.d/aos_dump_autocomplete b/frc971/rockpi/contents/etc/bash_completion.d/aos_dump_autocomplete
new file mode 100644
index 0000000..1b82c46
--- /dev/null
+++ b/frc971/rockpi/contents/etc/bash_completion.d/aos_dump_autocomplete
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if [[ -e "/home/pi/bin/aos_dump_autocomplete.sh" ]]; then
+  . /home/pi/bin/aos_dump_autocomplete.sh
+fi
diff --git a/frc971/rockpi/contents/etc/modules-load.d/adis16505.conf b/frc971/rockpi/contents/etc/modules-load.d/adis16505.conf
new file mode 100644
index 0000000..0e7b16b
--- /dev/null
+++ b/frc971/rockpi/contents/etc/modules-load.d/adis16505.conf
@@ -0,0 +1 @@
+adis16505
diff --git a/frc971/rockpi/contents/etc/systemd/network/eth0.network b/frc971/rockpi/contents/etc/systemd/network/eth0.network
index f9e7c2e..8bfaf61 100644
--- a/frc971/rockpi/contents/etc/systemd/network/eth0.network
+++ b/frc971/rockpi/contents/etc/systemd/network/eth0.network
@@ -5,3 +5,7 @@
 Address=10.9.71.20/24
 Gateway=10.9.71.13
 DNS=8.8.8.8
+
+# ipv6 adds an extra 10 seconds to boot, and we don't use it...
+# Disable all the route discovery and stuff
+LinkLocalAddressing=no
diff --git a/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service b/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service
index 6086fa0..1fc304e 100644
--- a/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service
+++ b/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service
@@ -1,9 +1,10 @@
 [Unit]
-Description=Configure IRQs
+Description=Configure tracing to be available by everyone
+After=sys-kernel-tracing.mount
 
 [Service]
 Type=oneshot
-ExecStart=/home/pi/bin/chrt.sh
+ExecStart=/root/bin/chrt.sh
 
 [Install]
 WantedBy=multi-user.target
diff --git a/frc971/rockpi/contents/etc/udev/rules.d/99-adis16505.rules b/frc971/rockpi/contents/etc/udev/rules.d/99-adis16505.rules
new file mode 100644
index 0000000..25145d2
--- /dev/null
+++ b/frc971/rockpi/contents/etc/udev/rules.d/99-adis16505.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="adis16505_class", MODE="0666", GROUP="dialout"
diff --git a/frc971/rockpi/contents/root/bin/chrt.sh b/frc971/rockpi/contents/root/bin/chrt.sh
new file mode 100644
index 0000000..4a6b917
--- /dev/null
+++ b/frc971/rockpi/contents/root/bin/chrt.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -ex
+
+chmod a+rwx /sys/kernel/debug
+
+# Make sure /sys/kernel/tracing is reasonably accessible so --enable_ftrace
+# works.
+chmod a+w /sys/kernel/tracing/trace_marker
+echo 10000 > /sys/kernel/tracing/buffer_size_kb
+chmod a+rw /sys/kernel/tracing/tracing_on
+chmod a+rwx /sys/kernel/tracing
+
+# Make sure we never scale the CPUs down.
+# This takes time to do which we don't have...
+cat /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq > \
+  /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
+cat /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq > \
+  /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq
diff --git a/frc971/rockpi/contents/root/bin/deploy_kernel.sh b/frc971/rockpi/contents/root/bin/deploy_kernel.sh
index 69a6297..5de42a0 100644
--- a/frc971/rockpi/contents/root/bin/deploy_kernel.sh
+++ b/frc971/rockpi/contents/root/bin/deploy_kernel.sh
@@ -3,8 +3,11 @@
 set -ex
 
 KERNEL_VERSION=6.0.8-rt14-rockpi4b
+TAR=${1-./linux-kernel-${KERNEL_VERSION}.tar.xz}
+
+KERNEL_VERSION=$(echo "${TAR}" | sed 's/.*linux-kernel-\(.*\).tar.xz/\1/')
 
 rm -rf /boot/dtbs/${KERNEL_VERSION}/
 rm -rf /lib/modules/${KERNEL_VERSION}/
-tar --owner=0 --group=0 --no-same-owner --no-same-permissions -xvf ./linux-kernel-${KERNEL_VERSION}.tar.xz -C /boot/ --strip-components=2 ./boot/
-tar --strip-components=3 -xvf linux-kernel-${KERNEL_VERSION}.tar.xz -C /lib/modules/ ./lib/modules
+tar --owner=0 --group=0 --no-same-owner --no-same-permissions -xvf ${TAR} -C /boot/ --strip-components=2 ./boot/
+tar --strip-components=3 -xvf ${TAR} -C /lib/modules/ ./lib/modules
diff --git a/tools/lint/run-ci.sh b/tools/lint/run-ci.sh
index 6e026ee..a05aa0f 100755
--- a/tools/lint/run-ci.sh
+++ b/tools/lint/run-ci.sh
@@ -111,11 +111,12 @@
 # All the linters that we are going to run.
 readonly -a LINTERS=(
     gofmt
-    gomod
-    update_go_repos
-    gazelle
-    tweak_gazelle_go_deps
-    clean_up_go_mirrors
+    # TODO(phil): Re-enable these. No idea what's going on.
+    #gomod
+    #update_go_repos
+    #gazelle
+    #tweak_gazelle_go_deps
+    #clean_up_go_mirrors
     rustfmt
     cargo_lockfile
     cargo_raze
diff --git a/y2022/localizer/kernel/Makefile b/y2022/localizer/kernel/Makefile
index ad4b9b0..184f8a3 100644
--- a/y2022/localizer/kernel/Makefile
+++ b/y2022/localizer/kernel/Makefile
@@ -2,6 +2,9 @@
  
 PWD := $(CURDIR) 
  
+rockpi:
+	ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -C ../../../frc971/rockpi/linux M=$(PWD) modules
+
 all: 
 	ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -C ../../../../linux M=$(PWD) modules 
 
diff --git a/y2022/localizer/kernel/adis16505.c b/y2022/localizer/kernel/adis16505.c
index a91006e..963ca4a 100644
--- a/y2022/localizer/kernel/adis16505.c
+++ b/y2022/localizer/kernel/adis16505.c
@@ -49,7 +49,7 @@
   char tx_buff[128];
   char rx_buff[128];
 
-  int count;
+  atomic_t count;
 
   spinlock_t lock;
 
@@ -62,21 +62,18 @@
 static int adis16505_dev_open(struct inode *in, struct file *f) {
   struct adis16505_state *ts =
       container_of(in->i_cdev, struct adis16505_state, handle_cdev);
-  int count;
+  int count = 0;
 
   f->private_data = ts;
+  count = atomic_cmpxchg(&ts->count, 0, 1);
 
-  spin_lock(&ts->lock);
-  count = ts->count;
-  if (count == 0) {
-    ++(ts->count);
-  }
-  spin_unlock(&ts->lock);
-
-  printk("open %p, count %d\n", ts, count);
   if (count > 0) {
     return -EBUSY;
   }
+
+  // Enable the IRQ after we've declared the device open.
+  enable_irq(ts->spi->irq);
+
   return 0;
 }
 
@@ -84,10 +81,13 @@
   struct adis16505_state *ts;
   ts = container_of(in->i_cdev, struct adis16505_state, handle_cdev);
 
-  printk("release %p\n", ts);
-  spin_lock(&ts->lock);
-  --(ts->count);
-  spin_unlock(&ts->lock);
+  // Disable before declaring ourselves closed so we don't fire the IRQ when we
+  // are disabled, or let someone else open it up again before we disable it.
+  disable_irq(ts->spi->irq);
+
+  if (atomic_cmpxchg(&ts->count, 1, 0) != 1) {
+    BUG_ON(true);
+  }
 
   return 0;
 }
@@ -230,7 +230,7 @@
 
   spin_lock_init(&ts->lock);
   spin_lock_init(&ts->fifo_read_lock);
-  ts->count = 0;
+  atomic_set(&ts->count, 0);
   INIT_KFIFO(ts->fifo);
   init_waitqueue_head(&ts->wq);
 
@@ -241,11 +241,20 @@
   err = request_threaded_irq(spi->irq, NULL, adis16505_irq, IRQF_ONESHOT,
                              spi->dev.driver->name, ts);
 
-  if (!ts) {
+  if (err < 0) {
     dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
     goto err_free_mem;
   }
 
+  // Immediately disable the IRQ.  Opening the device will enable it, so this
+  // lets us leave the driver probed all the time and only use it when userspace
+  // asks.
+  //
+  // Note: the IRQ will fire probably once before we get it disabled...  It
+  // might initiate a transfer from a device which isn't connected, which should
+  // just return 0 for everything.  This isn't actually a huge concern.
+  disable_irq(spi->irq);
+
   err = alloc_chrdev_region(&ts->character_device, 0, 1, "adis16505");
   if (err < 0) {
     dev_dbg(&spi->dev, "alloc_chrdev_region error %i", err);
@@ -295,7 +304,7 @@
   return err;
 }
 
-static int adis16505_remove(struct spi_device *spi) {
+static void adis16505_remove(struct spi_device *spi) {
   struct adis16505_state *ts = spi_get_drvdata(spi);
 
   device_destroy(ts->device_class, ts->character_device);
@@ -309,7 +318,6 @@
   kfree(ts);
 
   dev_dbg(&spi->dev, "unregistered adis16505\n");
-  return 0;
 }
 
 static struct spi_driver adis16505_driver = {