Skip to content

[BUG] Ov8856 bug report - Lenovo ThinkPad X12 Detachable Gen 1 #455

Description

@davidkeeton

Summary

ov8856 fails to probe on a Lenovo ThinkPad X12 Detachable Gen 1 (Tiger Lake-UP4, OV8856 rear/main camera behind IPU6). The I2C bus never receives any response from the sensor (full controller timeout, not a NACK), and the sensor's int3472-provided clock is confirmed to never be enabled during the probe attempt. With dynamic debug enabled on ov8856, the probe additionally triggers a kernel NULL pointer dereference, suggesting the driver dereferences a resource (regulator/GPIO/clock-related struct) that isn't populated for this board's ACPI configuration.

System
Model: Lenovo ThinkPad X12 Detachable Gen 1 (20UW0013US)
BIOS: R1GET65W (1.40), 05/16/2025
CPU: Intel Core i7-1160G7 (Tiger Lake-UP4)
Distro: CachyOS
Kernel: 7.1.4-1-cachyos (PREEMPT_DYNAMIC, clang-built)
Sensor: OmniVision OV8856, ACPI HID OVTI8856, on i2c_designware.2 / i2c-2
GPIO/clock/regulator handler: int3472-discrete bound to INT3472:01 (status 15, active)
IPU6: intel-ipu6 PCI device 0000:00:05.0, in secure mode, CSE authentication succeeds, firmware loads correctly (FW version: 20230925), reports Found supported sensor OVTI8856:00, Connected 1 cameras
Steps to reproduce
Boot normally. intel-ipu6, intel-ipu6-isys, intel-ipu6-psys, intel_skl_int3472_discrete, intel_skl_int3472_common, and ov8856 all load automatically.
Observe ov8856 probe failure in dmesg (see below).
i2cdetect -y 2 shows a completely empty bus (no ACK, no NACK — full silence).
Confirm INT3472:01-clk (the sensor's XVCLK source) never transitions to enabled: clk_enable_count and clk_prepare_count both remain 0 throughout a fresh probe attempt, polled at high frequency during modprobe ov8856.
Confirm INT3472:01-avdd regulator use=0 throughout.
Enable dynamic debug (echo -n 'module ov8856 +p' > /sys/kernel/debug/dynamic_debug/control, likewise for intel_skl_int3472_discrete/_common) and reprobe → kernel NULL pointer dereference inside ov8856_probe itself (see oops below). Without dynamic debug enabled, probe fails "cleanly" with -5/EIO and no crash.
dmesg (relevant excerpts)

Normal (non-debug) probe failure:

[ 5.154040] intel-ipu6 0000:00:05.0: enabling device (0000 -> 0002)
[ 5.172941] intel-ipu6 0000:00:05.0: Found supported sensor OVTI8856:00
[ 5.172972] intel-ipu6 0000:00:05.0: Connected 1 cameras
[ 5.186779] intel-ipu6 0000:00:05.0: Sending BOOT_LOAD to CSE
[ 5.196587] intel-ipu6 0000:00:05.0: Sending AUTHENTICATE_RUN to CSE
[ 5.269092] intel-ipu6 0000:00:05.0: CSE authenticate_run done
[ 5.269107] intel-ipu6 0000:00:05.0: IPU6-v0[9a19] hardware version 1
[ 6.017269] intel_ipu6_psys.psys intel_ipu6.psys.40: pkg_dir entry count:8
[ 6.017699] intel_ipu6_psys.psys intel_ipu6.psys.40: psys probe minor: 0
...
[ 863.881229] i2c_designware i2c_designware.2: controller timed out
[ 863.881280] ov8856 i2c-OVTI8856:00: failed to find sensor: -5
[ 863.881310] ov8856 i2c-OVTI8856:00: probe with driver ov8856 failed with error -5

I2C transaction trace (with i2c_designware_core dynamic debug on):

[ 1271.013311] i2c_designware i2c_designware.2: msgs: 2
[ 1271.013417] i2c_designware i2c_designware.2: enabled=0x1 stat=0x10
[ 1272.071051] i2c_designware i2c_designware.2: controller timed out

stat=0x10 is TX_EMPTY only — no TX_ABRT was ever raised, meaning no acknowledgment activity of any kind occurred on the bus (consistent with an unpowered/unclocked sensor rather than a present-but-non-responsive one).

Kernel oops (triggered only with dynamic debug enabled on ov8856):

[ 1415.000543] BUG: kernel NULL pointer dereference, address: 0000000000000028
[ 1415.000554] #PF: supervisor read access in kernel mode
[ 1415.000558] #PF: error_code(0x0000) - not-present page
[ 1415.000562] PGD 0 P4D 0
[ 1415.000568] Oops: Oops: 0000 [#1] SMP NOPTI
[ 1415.000575] CPU: 2 UID: 0 PID: 6311 Comm: modprobe Tainted: G OE 7.1.4-1-cachyos #1 PREEMPT(full)
[ 1415.000587] Hardware name: LENOVO 20UW0013US/20UW0013US, BIOS R1GET65W (1.40 ) 05/16/2025
[ 1415.000591] RIP: 0010:ov8856_probe+0x8dd/0x910 [ov8856]
[ 1415.000606] Code: ... 48 8b 83 10 03 00 00 <0f> b6 48 28 48 c7 c7 18 82 50 c1 4c 89 f6 48 c7 c2 1e b3 50 c1 e8
[ 1415.000616] RAX: 0000000000000000 RBX: ffff8a17a9537038 RCX: 0000000000000002
[ 1415.000645] Call Trace:
[ 1415.000657]
[ 1415.000667] i2c_device_probe+0x229/0x350
[ 1415.000675] really_probe+0x1bc/0x510
[ 1415.000682] __driver_probe_device+0xa1/0x140
[ 1415.000689] driver_probe_device+0x1e/0x190
[ 1415.000695] __driver_attach+0xe6/0x290
[ 1415.000702] bus_for_each_dev+0x117/0x160
[ 1415.000707] bus_add_driver+0x16a/0x2c0
[ 1415.000712] driver_register+0x69/0x110
[ 1415.000719] i2c_register_driver+0x45/0xc0
[ 1415.000733] do_one_initcall+0x135/0x330
[ 1415.000838] do_init_module+0x62/0x350
[ 1415.000850] __se_sys_finit_module+0x273/0x3e0
[ 1415.000866] do_syscall_64+0xa6/0x3d0
[ 1415.000988] ---[ end trace 0000000000000000 ]---

RAX=0 at the point of the faulting movzbl 0x28(%rax), %ecx-style instruction (offset 0x28 into a NULL struct pointer). The disassembly context (48 8b 83 10 03 00 00 loading a pointer from +0x310 of some base struct just before the fault) suggests a resource struct held elsewhere (regulator/gpio-desc/clk-related) is itself NULL, and a debug print dereferences a field of it unconditionally — only reached because dynamic debug forces that print statement's arguments to be evaluated.

Clock/regulator state during probe (polled, not just before/after)

Polled continuously across a full rmmod ov8856; modprobe ov8856 cycle:

INT3472:01-clk clk_enable_count: 0 (never transitions from 0)
INT3472:01-clk clk_rate: 19200000 (registered correctly, just never enabled)
INT3472:01-avdd use: 0 (never transitions from 0)
What's been ruled out
Not a timing race — polled continuously through the whole probe window, clock/regulator stay at 0 the entire time, not just in before/after snapshots.
Not the GPIO-DSM pin-mismatch bug from #292 — no matching warning appears anywhere in dmesg for this board.
Not a missing kernel config — CONFIG_VIDEO_INTEL_IPU6, CONFIG_INTEL_VSC, CONFIG_INTEL_SKL_INT3472 are all built as modules and load correctly; int3472-discrete is bound to INT3472:01 successfully.
Not a DKMS/build issue — ov8856.ko ships in-tree for this kernel and loads without error (until it hits the fault above).
Related reports (not exact duplicates, but same hardware/failure class)
Ubuntu Launchpad #2114878 — same hardware (X12 Detachable Gen 1), webcam regressed between kernel versions, no oops captured.
intel/ipu6-drivers #344 — different sensor (OVTI02C1 on Dell XPS 13), different failure mode (IPU6 bridge init failed), referenced by the Launchpad report above as a possible related cause.
intel/ipu6-drivers #23 — original, still-open request asking whether the in-tree ov8856 driver is expected to work with IPU6 at all (originally raised for a Dell Latitude 7320 Detachable, also Tiger Lake + OV8856).
Ask
Is ov8856's in-tree driver expected to work behind IPU6's ACPI bridge on Tiger Lake at all, or does it still assume an IPU3-style resource graph (per #23)?
Can someone confirm what struct/offset ov8856_probe+0x8dd corresponds to in the current tree, to identify which resource is unexpectedly NULL?
Is there a known ACPI/DSDT quirk needed for the X12 Detachable Gen 1 specifically to get int3472-discrete to actually enable the sensor's clock/regulator before probe?

Happy to provide additional dmesg captures, acpidump, or test patches.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions