Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-868GitHub issuePublicDecided· Out of scope

IPU7 camera: ov08x40 sensor bind is lost on suspend/resume and camera-init can't restore it (XPS 16 DA16260)

Reported by suhaskashyaps · filed Sep 7, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
AreaOutside the audited area· Decided by agents · verified
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Decided by agents and verified by a second, independent agent — see the decision.

Original report

IPU7 camera: ov08x40 sensor bind is lost on suspend/resume and camera-init can't restore it (XPS 16 DA16260)revision 1 · captured 2026-09-28 21:23 UTC via poll

Summary

On this Panther Lake laptop the built-in camera works at boot and stops after
the first suspend/resume. The ov08x40 sensor binds once, at boot; a
suspend/resume drops that bind, and nothing restores it. From then on every
browser sees the "Hardware ISP Camera" (/dev/video50) but gets no frames, and
Google Meet shows "Camera might be blocked." Only a reboot brings the
camera back — until the next suspend.

An earlier version of this issue blamed a GStreamer/GLib ABI break in
icamerasrc and a stale CameraShm segment. Both are real symptoms but
neither is the cause: they are what a missing sensor looks like from
userspace. Corrected diagnosis below.

Environment

  • Laptop: Dell XPS 16 DA16260
  • CPU: Intel Core Ultra X7 358H (Panther Lake)
  • IPU: 00:05.0 [8086:b05d] — driver intel-ipu7 (out-of-tree DKMS, (OE))
  • Sensor: OmniVision OV08X40, ACPI HID OVTI08F4; companion INT3472:00/01

at _STA=15; Intel CVS (INTC10E1 / INTC10CC) present
- OS: Omarchy, VERSION_ID="4.0.2"
- Kernel: 7.1.8-arch1-2-ptl
- Packages: intel-ipu7-camera 1.0.5-1 (prebuilt 2026-07-14, "Unknown
Packager", URL github.com/TsaiGaggery/hurrican_omarchy_enabling),
v4l2-relayd 0.2.0-2.2, v4l2loopback-dkms 0.15.4-2, gstreamer 1.28.6-2,
glib2 2.88.3-1
- Browser: Chromium (Omarchy default), Meet as --app=https://meet.google.com

Reproduction

  1. Boot. The camera works in Chromium and qcam.
  2. systemctl suspend, then resume.
  3. The camera is gone. Meet shows "Camera might be blocked." It stays gone

across further suspend/resume cycles.
4. Reboot restores it.

Evidence

The sensor binds once, at boot, and never again. Full journald history (one
week, ~15 suspend/resume cycles) contains exactly one bind:

Aug 31 15:15:52  intel-ipu7 0000:00:05.0: Found supported sensor OVTI08F4:00
Aug 31 15:15:52  intel-ipu7 0000:00:05.0: Connected 1 cameras
Aug 31 15:15:52  intel-ipu7 0000:00:05.0: CSE authenticate_run done
Aug 31 15:15:53  Intel CVS driver i2c-INTC10E1:00: cvs_common_probe:Transfer of ownership success
Aug 31 15:15:58  ov08x40 i2c-OVTI08F4:00: supply dovdd not found, using dummy regulator
Aug 31 15:15:58  intel_ipu7_isys.isys ...: bind ov08x40 17-0036 nlanes is 2 port is 0
Aug 31 15:15:58  intel_ipu7_isys.isys ...: All sensor registration completed.

Current state — the I2C client exists, _STA=15, but no driver is bound:

$ cat /sys/bus/acpi/devices/OVTI08F4:00/status      # 15
$ ls /sys/bus/i2c/devices/i2c-OVTI08F4:00/driver    # ENOENT
$ ls /sys/bus/i2c/drivers/ov08x40/                  # bind module uevent unbind — no device
$ media-ctl -p -d /dev/media0 | grep -i ov08x40     # nothing; only IPU7 CSI2 + ISYS entities

libcamhal then finds nothing, and icamerasrc fails on the sensor-derived
enum properties:

$ gst-inspect-1.0 icamerasrc
GLib-GObject-CRITICAL: g_param_spec_enum: assertion 'g_enum_get_value (enum_class, default_value) != NULL' failed
CamHAL[INF] CameraParserInvoker: getAvailableSensors, Found IPU: IPU7
CamHAL[WAR] CameraParserInvoker: parseSensors: No sensors available

v4l2-relayd@ipu7 then loops on a NULL element:

v4l2-relayd[...]: g_param_spec_enum: assertion 'g_enum_get_value (enum_class, default_value) != NULL' failed
v4l2-relayd[...]: gst_element_set_state: assertion 'GST_IS_ELEMENT (element)' failed

/dev/video50 is created but never receives a buffer, so Chromium opens it,
waits, and Meet reports "Camera might be blocked."

Why it fails

The suspend hook /usr/lib/systemd/system-sleep/camera-sleep-hook handles
post by running:

systemd-run --no-block --unit=camera-resume bash -c '
  systemctl restart camera-init.service ...
  systemctl reset-failed [email protected] ...
  systemctl start [email protected] ...'

camera-init.service is:

ExecStart=/bin/bash -c "modprobe intel_cvs && sleep 2 && modprobe ov08x40 && modprobe v4l2loopback"

Every module is already loaded, so this is a no-op. Nothing unbinds and
rebinds the sensor, so once a resume has dropped the ov08x40 bind it stays
dropped. The hook avoids reloading IPU7 modules on purpose — its own comment
says a "recoverable camera failure" is preferred to a fragile resume — but
the resume path then has no way to recover the sensor.

Downstream of the missing sensor: parseSensors: No sensors available →
icamerasrc builds empty enum classes → g_param_spec_enum asserts (GLib
2.88 rejects an out-of-range default that older GLib tolerated) → the element
is unusable → v4l2-relayd@ipu7 loops → no frames. The CameraShm shmget
error seen earlier came from a stale SysV segment left by a prior icamerasrc
instance; clearing it changes nothing.

Workarounds tried

  • Clear the stale CameraShm segment and restart the stack:

ipcs -m empties and the shmget error goes away, but the four
g_param_spec_enum assertions remain and no sensor appears.
- modprobe -r ov08x40 && modprobe ov08x40: blocked — modprobe -r recurses
into gpio_usbio ("Module gpio_usbio is in use"), so ov08x40 is not
reloaded.
- rmmod ov08x40 && modprobe ov08x40 (with v4l2-relayd@ipu7 and
intel-ipu7-camera stopped): runs, but does not re-bind. `media-ctl -p -d
/dev/media0 still shows only the IPU7 ISYS/CSI2 entities, no ov08x40`, and
the CRITICAL count is unchanged. Reloading the I2C sensor driver alone does
not make intel_ipu7_isys re-probe the sensor — its async subdev notifier
completed at boot ("All sensor registration completed") and does not re-fire.
- Reboot is the only known recovery, and it lasts only until the next
suspend.

Possible fixes

  1. On resume, actually restore the sensor. Reloading the ov08x40 I2C driver

is not enough — intel_ipu7_isys has to re-probe (reload the ISYS module,
re-arm its async notifier, or reload the IPU7 stack in the right order).
Gate it on the sensor being unbound so a healthy resume is untouched. This
is the case the hook's author chose to skip; it needs a real recovery path.
2. Give camera-init.service (or a new resume unit) a real check: "I2C client
present, no driver bound, no sensor entity in /dev/media0" → repair;
otherwise do nothing.
3. While touching this hook, fold in #6222's fix (`--unit=camera-resume-$$
--collect`) so the two resume paths do not collide.
4. Rebuild intel-ipu7-camera against the repo's current gstreamer/glib2
(it is a third-party prebuilt, "Unknown Packager"), and make icamerasrc
fail loudly — log an error and fall back to videotestsrc/splash instead
of looping gst_element_set_state() on NULL, so a missing sensor shows as
a test pattern rather than a black tile and a misleading "camera blocked".

Related

  • #6222 — same subsystem and the same resume hook, different mechanism.

#6222 is a --unit=camera-resume name collision under
suspend-then-hibernate. Here plain suspend/resume is enough, and the gap is
that camera-init.service's unconditional modprobe cannot rebind a sensor
whose driver a resume has dropped. May be worth merging.
- #7776, #6000 — IPU7 sensor never enumerates at all (_STA=0, wrong
sensor). Not this: here the sensor enumerates and binds at boot.
- #8843 — browser cannot see the camera though qcam/libcamera work. Portal
hand-off; not this.

Duplicate check

Searched the tracker for icamerasrc, IPU7, v4l2-relayd, camera,
suspend, camera-resume, CameraShm, XPS 16. #6222 is the closest —
same hook, adjacent mechanism. The sensor-enumeration issues (#7776, #6000,
#7697) and the portal issue (#8843) are the other neighbours. None reports the
sensor binding at boot and being lost on plain suspend/resume.

View raw text
### Summary

On this Panther Lake laptop the built-in camera works at boot and stops after
the first suspend/resume. The `ov08x40` sensor binds once, at boot; a
suspend/resume drops that bind, and nothing restores it. From then on every
browser sees the "Hardware ISP Camera" (`/dev/video50`) but gets no frames, and
Google Meet shows **"Camera might be blocked."** Only a reboot brings the
camera back — until the next suspend.

An earlier version of this issue blamed a GStreamer/GLib ABI break in
`icamerasrc` and a stale `CameraShm` segment. Both are real symptoms but
neither is the cause: they are what a missing sensor looks like from
userspace. Corrected diagnosis below.

### Environment

- **Laptop:** Dell XPS 16 DA16260
- **CPU:** Intel Core Ultra X7 358H (Panther Lake)
- **IPU:** `00:05.0 [8086:b05d]` — driver `intel-ipu7` (out-of-tree DKMS, `(OE)`)
- **Sensor:** OmniVision OV08X40, ACPI HID `OVTI08F4`; companion `INT3472:00/01`
  at `_STA=15`; Intel CVS (`INTC10E1` / `INTC10CC`) present
- **OS:** Omarchy, `VERSION_ID="4.0.2"`
- **Kernel:** `7.1.8-arch1-2-ptl`
- **Packages:** `intel-ipu7-camera 1.0.5-1` (prebuilt 2026-07-14, "Unknown
  Packager", URL `github.com/TsaiGaggery/hurrican_omarchy_enabling`),
  `v4l2-relayd 0.2.0-2.2`, `v4l2loopback-dkms 0.15.4-2`, `gstreamer 1.28.6-2`,
  `glib2 2.88.3-1`
- **Browser:** Chromium (Omarchy default), Meet as `--app=https://meet.google.com`

### Reproduction

1. Boot. The camera works in Chromium and `qcam`.
2. `systemctl suspend`, then resume.
3. The camera is gone. Meet shows "Camera might be blocked." It stays gone
   across further suspend/resume cycles.
4. Reboot restores it.

### Evidence

The sensor binds once, at boot, and never again. Full journald history (one
week, ~15 suspend/resume cycles) contains exactly one bind:

```
Aug 31 15:15:52  intel-ipu7 0000:00:05.0: Found supported sensor OVTI08F4:00
Aug 31 15:15:52  intel-ipu7 0000:00:05.0: Connected 1 cameras
Aug 31 15:15:52  intel-ipu7 0000:00:05.0: CSE authenticate_run done
Aug 31 15:15:53  Intel CVS driver i2c-INTC10E1:00: cvs_common_probe:Transfer of ownership success
Aug 31 15:15:58  ov08x40 i2c-OVTI08F4:00: supply dovdd not found, using dummy regulator
Aug 31 15:15:58  intel_ipu7_isys.isys ...: bind ov08x40 17-0036 nlanes is 2 port is 0
Aug 31 15:15:58  intel_ipu7_isys.isys ...: All sensor registration completed.
```

Current state — the I2C client exists, `_STA=15`, but no driver is bound:

```
$ cat /sys/bus/acpi/devices/OVTI08F4:00/status      # 15
$ ls /sys/bus/i2c/devices/i2c-OVTI08F4:00/driver    # ENOENT
$ ls /sys/bus/i2c/drivers/ov08x40/                  # bind module uevent unbind — no device
$ media-ctl -p -d /dev/media0 | grep -i ov08x40     # nothing; only IPU7 CSI2 + ISYS entities
```

libcamhal then finds nothing, and `icamerasrc` fails on the sensor-derived
enum properties:

```
$ gst-inspect-1.0 icamerasrc
GLib-GObject-CRITICAL: g_param_spec_enum: assertion 'g_enum_get_value (enum_class, default_value) != NULL' failed
CamHAL[INF] CameraParserInvoker: getAvailableSensors, Found IPU: IPU7
CamHAL[WAR] CameraParserInvoker: parseSensors: No sensors available
```

`v4l2-relayd@ipu7` then loops on a NULL element:

```
v4l2-relayd[...]: g_param_spec_enum: assertion 'g_enum_get_value (enum_class, default_value) != NULL' failed
v4l2-relayd[...]: gst_element_set_state: assertion 'GST_IS_ELEMENT (element)' failed
```

`/dev/video50` is created but never receives a buffer, so Chromium opens it,
waits, and Meet reports "Camera might be blocked."

### Why it fails

The suspend hook `/usr/lib/systemd/system-sleep/camera-sleep-hook` handles
`post` by running:

```
systemd-run --no-block --unit=camera-resume bash -c '
  systemctl restart camera-init.service ...
  systemctl reset-failed [email protected] ...
  systemctl start [email protected] ...'
```

`camera-init.service` is:

```
ExecStart=/bin/bash -c "modprobe intel_cvs && sleep 2 && modprobe ov08x40 && modprobe v4l2loopback"
```

Every module is already loaded, so this is a no-op. Nothing unbinds and
rebinds the sensor, so once a resume has dropped the `ov08x40` bind it stays
dropped. The hook avoids reloading IPU7 modules on purpose — its own comment
says a "recoverable camera failure" is preferred to a fragile resume — but
the resume path then has no way to recover the sensor.

Downstream of the missing sensor: `parseSensors: No sensors available` →
`icamerasrc` builds empty enum classes → `g_param_spec_enum` asserts (GLib
2.88 rejects an out-of-range default that older GLib tolerated) → the element
is unusable → `v4l2-relayd@ipu7` loops → no frames. The `CameraShm` `shmget`
error seen earlier came from a stale SysV segment left by a prior `icamerasrc`
instance; clearing it changes nothing.

### Workarounds tried

- Clear the stale `CameraShm` segment and restart the stack:
  `ipcs -m` empties and the `shmget` error goes away, but the four
  `g_param_spec_enum` assertions remain and no sensor appears.
- `modprobe -r ov08x40 && modprobe ov08x40`: blocked — `modprobe -r` recurses
  into `gpio_usbio` ("Module gpio_usbio is in use"), so `ov08x40` is not
  reloaded.
- `rmmod ov08x40 && modprobe ov08x40` (with `v4l2-relayd@ipu7` and
  `intel-ipu7-camera` stopped): runs, but does not re-bind. `media-ctl -p -d
  /dev/media0` still shows only the IPU7 ISYS/CSI2 entities, no `ov08x40`, and
  the CRITICAL count is unchanged. Reloading the I2C sensor driver alone does
  not make `intel_ipu7_isys` re-probe the sensor — its async subdev notifier
  completed at boot ("All sensor registration completed") and does not re-fire.
- **Reboot** is the only known recovery, and it lasts only until the next
  suspend.

### Possible fixes

1. On resume, actually restore the sensor. Reloading the `ov08x40` I2C driver
   is not enough — `intel_ipu7_isys` has to re-probe (reload the ISYS module,
   re-arm its async notifier, or reload the IPU7 stack in the right order).
   Gate it on the sensor being unbound so a healthy resume is untouched. This
   is the case the hook's author chose to skip; it needs a real recovery path.
2. Give `camera-init.service` (or a new resume unit) a real check: "I2C client
   present, no driver bound, no sensor entity in `/dev/media0`" → repair;
   otherwise do nothing.
3. While touching this hook, fold in #6222's fix (`--unit=camera-resume-$$
   --collect`) so the two resume paths do not collide.
4. Rebuild `intel-ipu7-camera` against the repo's current `gstreamer`/`glib2`
   (it is a third-party prebuilt, "Unknown Packager"), and make `icamerasrc`
   fail loudly — log an error and fall back to `videotestsrc`/splash instead
   of looping `gst_element_set_state()` on NULL, so a missing sensor shows as
   a test pattern rather than a black tile and a misleading "camera blocked".

### Related

- **#6222** — same subsystem and the same resume hook, different mechanism.
  #6222 is a `--unit=camera-resume` name collision under
  suspend-then-hibernate. Here plain suspend/resume is enough, and the gap is
  that `camera-init.service`'s unconditional `modprobe` cannot rebind a sensor
  whose driver a resume has dropped. May be worth merging.
- #7776, #6000 — IPU7 sensor never enumerates at all (`_STA=0`, wrong
  sensor). Not this: here the sensor enumerates and binds at boot.
- #8843 — browser cannot see the camera though `qcam`/libcamera work. Portal
  hand-off; not this.

### Duplicate check

Searched the tracker for `icamerasrc`, `IPU7`, `v4l2-relayd`, `camera`,
`suspend`, `camera-resume`, `CameraShm`, `XPS 16`. #6222 is the closest —
same hook, adjacent mechanism. The sensor-enumeration issues (#7776, #6000,
#7697) and the portal issue (#8843) are the other neighbours. None reports the
sensor binding at boot and being lost on plain suspend/resume.

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

Not linked to any known issue, other report or change yet.

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

  • Out of scopeDecided by agents · verified · 2026-10-09 11:04 UTC