summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Zagursky <gvozdoder@gmail.com>2026-09-02 22:15:24 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2026-09-13 10:15:16 -0700
commit856c562c94964a74f63c6d5f38a1509a59a2357d (patch)
treeaccfd28199fc30b26ecd833a5ef905932f7ad510
parent7825de3f75d184612d77655669a04ea0da252c17 (diff)
media: ipu-bridge: do not use the CVS device lookup for IVSC
Since commit c6b1b34b5090 ("media: pci: intel: Add CVS support for IPU bridge driver") the internal camera no longer works on laptops where the sensor sits behind an IVSC, for example a Dell XPS 16 9640 (IPU6, INTC10CF, ov02c10): intel-ipu6 0000:00:05.0: Found supported sensor OVTI02C1:00 intel-ipu6 0000:00:05.0: Connected 1 cameras ivsc_csi intel_vsc-92335fcf-3203-4472-af93-7b4453ac29da: mei-csi probed without device fwnode! No sensor subdevice is registered, the media graph has no sensor entity and userspace finds no camera at all. ipu_bridge_get_ivsc_csi_dev() first looks for the platform device named "intel_vsc" and returns its mei-csi child. That device is created by mei_vsc, which on this machine only appears once the LJCA USB bridge and its SPI controller have probed, about a second after the IPU6 probe that runs the bridge: 07:59:29.297 platform INTC10CF:00 created (ACPI scan) 07:59:41 intel-ipu6 probe -> ipu_bridge_init() 07:59:42.391 platform intel_vsc created (mei_vsc) The commit above added two fallbacks for CVS which match on the ACPI companion alone. They are reached for every entry of ivsc_acpi_ids[], IVSC IDs included. The IVSC ACPI device has two physical nodes: INTC10CF:00/physical_node -> platform/INTC10CF:00 (no driver bound) INTC10CF:00/physical_node1 -> platform/intel_vsc (mei_vsc) so bus_find_device_by_acpi_dev(&platform_bus_type, adev) returns the bare platform device. ipu_bridge_instantiate_ivsc() then attaches the IVSC software node to that device instead of to the mei-csi client, the bridge reports success, and the probe is never retried. mei_csi later probes without a fwnode, the CSI-2 link is never described, and the sensor ACPI device, which has an honoured _DEP on the IVSC device, is never enumerated. Before those fallbacks existed the lookup returned NULL here, the bridge failed with -ENODEV and the probe was retried once the IVSC device had shown up. Skip those fallbacks for IVSC devices, keying on the IVSC IDs rather than the CVS ones: new CVS IDs keep being added, whereas the IVSC list is complete. CVS binds a driver to the ACPI device itself, so matching on the companion stays unambiguous there. Fixes: c6b1b34b5090 ("media: pci: intel: Add CVS support for IPU bridge driver") Link: https://lore.kernel.org/linux-media/20260901194526.6369-1-gvozdoder@gmail.com/ Cc: stable@vger.kernel.org Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Sergey Zagursky <gvozdoder@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/media/pci/intel/ipu-bridge.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
index 1bb3a3e98d6b..bd64c0400c0d 100644
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -232,6 +232,19 @@ static const struct acpi_device_id ivsc_acpi_ids[] = {
{ "INTC10FA" }, /* NVL */
};
+/*
+ * The subset of ivsc_acpi_ids[] which are IVSC, rather than CVS, devices. The
+ * CVS IDs are deliberately not listed here: new ones keep being added, whereas
+ * this list is complete.
+ */
+static const struct acpi_device_id ivsc_only_acpi_ids[] = {
+ { "INTC1059" },
+ { "INTC1095" },
+ { "INTC100A" },
+ { "INTC10CF" },
+ { }
+};
+
static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
{
unsigned int i;
@@ -283,6 +296,17 @@ static struct device *ipu_bridge_get_ivsc_csi_dev(struct acpi_device *adev)
return csi_dev;
}
+ /*
+ * The lookups below match on the ACPI companion alone. That is fine for
+ * CVS, which binds a driver to that very device, but not for IVSC: there
+ * the ACPI device also has a driverless platform device, which would be
+ * returned instead of the mei-csi client. Return NULL for IVSC so that
+ * the caller fails and the probe is retried once the IVSC device shows
+ * up.
+ */
+ if (!acpi_match_device_ids(adev, ivsc_only_acpi_ids))
+ return NULL;
+
/* Try to locate CVS device on the I2C bus */
csi_dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
if (csi_dev)