Published on January 2, 2026 by Dominic Böttger · 3 min read
Running a Surface Pro with the linux-surface kernel, touch works great until you suspend. After resume, the touchscreen stops responding. The ipts kernel module gets into a corrupted state when the Intel MEI firmware suspends while the module is still loaded.
The solution involves unloading the module before suspend and reloading it after resume using systemd sleep hooks.
About the Linux-Surface Project
The linux-surface project is a community-driven effort that provides patched kernels and drivers to enable Linux on Microsoft Surface devices. The standard Linux kernel lacks many Surface-specific drivers, making the linux-surface kernel essential for proper hardware support including touchscreen, pen input, cameras, and power management.
Installing the Linux-Surface Kernel on Ubuntu
Before installing, make sure to update your Surface firmware through Windows first.
# Import the signing keys
wget -qO - https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc \
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/linux-surface.gpg > /dev/null
# Add the repository
echo "deb [arch=amd64] https://pkg.surfacelinux.com/debian release main" \
| sudo tee /etc/apt/sources.list.d/linux-surface.list
# Install the kernel and dependencies
sudo apt update
sudo apt install linux-image-surface linux-headers-surface iptsd libwacom-surface
Secure Boot Configuration
Surface devices have Secure Boot enabled by default. To boot the linux-surface kernel, you need to enroll the linux-surface signing key in your system’s MOK (Machine Owner Key) database:
# Install the secure boot key package
sudo apt install linux-surface-secureboot-mok
After installation, reboot your Surface. During boot, the MOK Manager will appear automatically. Follow these steps:
- Select “Enroll MOK”
- Select “Continue”
- Select “Yes” to enroll the key
- Enter the password you set during installation (default is usually empty, just press Enter)
- Select “Reboot”
After the reboot, verify with uname -r that you’re running the surface kernel (it should show something like 6.x.x-surface).
For complete installation instructions and device-specific quirks, visit the linux-surface wiki.
The Touch Issue After Suspend
With the linux-surface kernel installed, the touchscreen works perfectly - until you suspend. After resume, the touchscreen stops responding. This happens because the ipts kernel module gets into a corrupted state when the Intel MEI firmware suspends while the module is still loaded.
Required Components
- Sleep Hook - Handles module unload/reload around suspend
- Restart Script - Manual touch recovery
- Watchdog Service - Auto-recovery for headless use
Sleep Hook Configuration
Create the systemd sleep hook at /usr/lib/systemd/system-sleep/surface-touch:
#!/bin/bash
# /usr/lib/systemd/system-sleep/surface-touch
LOG_TAG="surface-touch-sleep"
log() { logger -t "$LOG_TAG" "$1"; }
case "$1" in
pre)
log "PRE-SUSPEND: Stopping touch services"
systemctl stop iptsd@*.service 2>/dev/null
pkill -9 iptsd 2>/dev/null
sleep 1
log "PRE-SUSPEND: Unloading ipts module"
modprobe -r ipts 2>/dev/null
;;
post)
log "POST-RESUME: Reloading ipts module"
modprobe ipts 2>/dev/null
sleep 8
if systemctl is-active --quiet iptsd@*.service 2>/dev/null; then
log "POST-RESUME: Touch restored automatically"
fi
;;
esac
Make it executable:
sudo chmod +x /usr/lib/systemd/system-sleep/surface-touch
Restart Script
Create /usr/local/bin/surface-touch-restart for manual recovery:
#!/bin/bash
LOG_TAG="surface-touch"
log() { logger -t "$LOG_TAG" "$1"; }
log "=== Surface Touch Restart ==="
pkill -9 iptsd 2>/dev/null
systemctl reset-failed iptsd@*.service 2>/dev/null
sleep 1
log "Loading ipts module"
modprobe ipts 2>/dev/null
sleep 8
for i in {1..10}; do
if systemctl is-active --quiet iptsd@*.service 2>/dev/null; then
log "Touch restored successfully"
exit 0
fi
sleep 1
done
Installation
sudo chmod +x /usr/local/bin/surface-touch-restart
sudo systemctl daemon-reload
Tested on Surface Pro 6, Ubuntu 24.04, linux-surface kernel 6.18.2-surface-1, iptsd 3.1.0
Written by Dominic Böttger
← Back to blog