From nobody Sat Sep 26 19:34:28 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFAE33B9DB6 for ; Mon, 31 Aug 2026 09:43:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788169384; cv=none; b=aKCBaFi4Tq2JHaiIzHkGMciAIimB++kO4VZKsd0MvbrQ7kGWoaeNPrlRm/0fx/Jt7dRXk3FzU3H9oB8fZDRgDzOqdvoRh/Rtg3wAuMfSNKwPFoDVox15fH8mFoEEUoaz/F7p7VwmSVhaXgF85XfoJwhuOfbZnLPMyhw+fUAyXPM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788169384; c=relaxed/simple; bh=ko4cw16f99m3bXM3uqOEu5/e9zfYbbBGR8a/p6uy5j4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OpWDtUcqpKwqz4m/WXJFDxIBbOB69liY0ARSYKK35MzU64jUEuEsoEHoelWyO3Evb1cS+JLx91FW7OB+mne5GDTa/ZznIM1gyhcKkctF/QaoAOa/zIthPHfXIY3f+iGpodiCrrQ7IHmb9ts3LXiCFkS+cIGtSNxddeYN58b4jug= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=J9PJXW/i; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J9PJXW/i" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-49b8be0409fso19290285e9.2 for ; Mon, 31 Aug 2026 02:43:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788169380; x=1788774180; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=qyxH6K2QecJlBQEE5JUS/GU1pODnZuTNjd4rRu1hR8k=; b=J9PJXW/iOJGPf1l35P/xvFyU3ltjc0WV47KFD44EXuTHDYkWN41aAEyUcHfnEoGQwh YRzrWEQzWwrL72DXcTRs8tRvHb8lXiIU4R9JScZph7/DXCYF8ZZW8MOQF8fxd5YhuH13 BKt/oMNLcx4dDOqDICNU0fhWC/7tOcYnyy0ZDeSocmVcIlTq0muurMw59Omx0jsNlu7J MUcRBFo8Ci9pz2JXUM3Q1pZLJz9vnSt66rQz71005eWiMl39LuV39rorZexRtendwOm3 frjDIuPtZZ4/CC6mQ7HA8+niF11LaraNYf7vnptrm1TZxlmzf2Nfs3EWZ86m3i7bZXgK AutA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788169380; x=1788774180; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=qyxH6K2QecJlBQEE5JUS/GU1pODnZuTNjd4rRu1hR8k=; b=M8i1vROvBrfRM/SJt1gO6L0Qti7caJQ64qL8Yz+DZabxa7vxldcMbnHhYqXW8Leui0 7etayfkYVgieiy6gGvhvTvfFNUU6njl94ZTsXgCNGFl69ARU4BOqZxFLwSZYuGwy7uZ3 f5A7jnIigedxUbNc/BdA6eUZxtKhD4nG71VNuE9Nx8P2cM4tonkDqIaAh35ma/7EnGDR PvUzQA2lQ4w+kKUmt1aO/xWPf+lEo9JZA855VsiMBqtHXCKQUCmEKRkBG4eXyKUtEHoM akkiZg5wOlywwnjcMuXU8NKUkttbrv0Xkll11LEXUOadNTPnHHj5/L1qjGdY+11/O5oq gfcg== X-Forwarded-Encrypted: i=1; AHgh+Rqk+Y8xWxAl1T3PediwYKM5lDNOlGfMVVwMhUTgANeTTy1AJNm/5ZgtzUvB0mxQysNp4PzLJykUUhb7Ig4=@vger.kernel.org X-Gm-Message-State: AFuF++kHUMtNJeKIpMKQLke87MLF8WQfbX54uQ9FD/MbW4/bhZUl1XtA dptk2P6t9lr3aycMHtI01ORFFtMYT43uyzmo++Cr8Mf+lGgZIiIR7GEYhnKzyVN6bg== X-Gm-Gg: AR+sD12IUIfgpdFdi9VDlh+aYo2mt0x2lfo9OWKItX6l+qemOBS/m85jnHRQCQmSXvj 7DUqMtXsLPIgLc5JO6H7uIWgbKEaafQaONyemCveIMif6xZvjXKe86kw+r87U0kRbA2cGNBZKDJ oCI+px9OWYYqJGxhSDyKiShXCh7Jw9Q31dKbp1dqttQekCub8gWFUvCk41P4mW0JdsHPHn/XSqU z03oqMe5qGtj+oFT16alzjyQxWjmJQ4Fn07uCGOJW8B0/GHuePj7W4psJVUwAMRi9o9bt+1J4SJ ybOqu9dVEykdHGKATO6Xa+PjCekCCbp2NfpIzOI2SjZO0NlxqE4j+V1z2h47+l85bNwjSO5ATkm WSZTuuogRe37DtavT961MCzLQZBpUFtOEsyUp0N0zWX/Yv5JFtR5+IuGrvpehL3UwTzWJVjYWI2 VbaYtwUd7tvP6G2MX8jntPwBMfAK+aOrd4O/DCEWJRNtRBHgDKbDxZ3F8w37meZI0QYEgEVZBdF wedCFxm1WmD5Kia1OnF2taPwPj6cNRmYJcEN77ei8XS X-Received: by 2002:a05:600c:4592:b0:495:5890:8f6c with SMTP id 5b1f17b1804b1-49b91c290c1mr290212825e9.7.1788169380078; Mon, 31 Aug 2026 02:43:00 -0700 (PDT) Received: from surface.. (84.124.213.91.dyn.user.ono.com. [84.124.213.91]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49b9267c369sm189932125e9.3.2026.08.31.02.42.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 02:42:59 -0700 (PDT) From: "D. Manresa" To: Sakari Ailus , Hans de Goede , Daniel Scally Cc: Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, "D . Manresa" Subject: [PATCH 1/2] media: ipu-bridge: don't reference the module image from software nodes Date: Mon, 31 Aug 2026 11:42:55 +0200 Message-ID: <20260831094257.29398-2-dmanresa@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260831094257.29398-1-dmanresa@gmail.com> References: <20260827232636.93145-1-dmanresa@gmail.com> <20260831094257.29398-1-dmanresa@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The software nodes registered by ipu_bridge_init() are deliberately never unregistered: sensor drivers and the fwnode graph keep references to them, so they are left registered when the ipu-bridge module is unloaded and a later rebind is intended to reuse the already registered nodes. For that to work, nothing reachable from the registered nodes may point into the ipu-bridge module image. Most of the data already lives in the dedicated, never freed, struct ipu_bridge allocation: the property name strings in struct ipu_property_names are character arrays copied into the per-sensor struct, the node name strings are likewise character arrays inside the struct, and the data-lanes array is a struct ipu_bridge member precisely so that "it survives if the module is unloaded along with the rest of the struct". Two references into the module image remain, though: 1. The values of the "link-frequencies" endpoint property point at cfg->link_freqs inside the const ipu_supported_sensors[] table in module rodata. 2. The name of the "lens-focus" device property is a string literal in module rodata. Both dangle as soon as the module is unloaded, while the properties that carry them stay registered and readable. In practice, after unloading and reloading the IPU modules on a Surface Pro 7+ (IPU6, ov8865 + ov5693 + ov7251), re-probing sensor drivers read poisoned link-frequencies from the surviving nodes and fail to probe: ov8865: failed to find 360000000 clk rate in endpoint link-frequencies ov5693: supported link freq 419200000 not found where 419200000/360000000 are exactly the values the bridge had originally published for those sensors, i.e. the properties no longer return their original contents. Depending on what happens to the freed module mapping, reading the properties can also fault. Similarly, a VCM lookup through the "lens-focus" reference can no longer match (or faults) once the property's name pointer is dangling. Copy the link frequencies and the "lens-focus" property name into struct ipu_bridge, next to the data-lanes array kept there for the same reason, and make the registered properties point at those copies, so the nodes survive module unload intact. These were the only remaining references from the registered nodes into the module image (the sensor->vcm_type pointer into ipu_vcm_types[] is only dereferenced during ipu_bridge_init() itself and is not reachable from the nodes). Developed with the assistance of an AI tool (Claude) Fixes: 803abec64ef9 ("media: ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver= ") Fixes: 68b9bcc8a534 ("media: ipu3-cio2: Add support for instantiating i2c-c= lients for VCMs") Signed-off-by: D. Manresa --- drivers/media/pci/intel/ipu-bridge.c | 14 +++++++++++--- include/media/ipu-bridge.h | 9 +++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel= /ipu-bridge.c index 1bb3a3e..4de42ed 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -503,7 +503,8 @@ static void ipu_bridge_create_fwnode_properties( sensor->vcm_ref[0] =3D SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_VCM]); sensor->dev_properties[3] =3D - PROPERTY_ENTRY_REF_ARRAY("lens-focus", sensor->vcm_ref); + PROPERTY_ENTRY_REF_ARRAY(bridge->lens_focus, + sensor->vcm_ref); } =20 sensor->ep_properties[0] =3D PROPERTY_ENTRY_U32( @@ -516,11 +517,17 @@ static void ipu_bridge_create_fwnode_properties( sensor->prop_names.remote_endpoint, sensor->local_ref); =20 - if (cfg->nr_link_freqs > 0) + if (cfg->nr_link_freqs > 0) { + u64 *link_freqs =3D bridge->link_freqs[sensor - bridge->sensors]; + + memcpy(link_freqs, cfg->link_freqs, + cfg->nr_link_freqs * sizeof(*link_freqs)); + sensor->ep_properties[3] =3D PROPERTY_ENTRY_U64_ARRAY_LEN( sensor->prop_names.link_frequencies, - cfg->link_freqs, + link_freqs, cfg->nr_link_freqs); + } =20 sensor->ipu_properties[0] =3D PROPERTY_ENTRY_U32_ARRAY_LEN( sensor->prop_names.data_lanes, @@ -943,6 +950,7 @@ int ipu_bridge_init(struct device *dev, =20 strscpy(bridge->ipu_node_name, IPU_HID, sizeof(bridge->ipu_node_name)); + strscpy(bridge->lens_focus, "lens-focus", sizeof(bridge->lens_focus)); bridge->ipu_hid_node.name =3D bridge->ipu_node_name; bridge->dev =3D dev; bridge->parse_sensor_fwnode =3D parse_sensor_fwnode; diff --git a/include/media/ipu-bridge.h b/include/media/ipu-bridge.h index 16fac76..4e91ec3 100644 --- a/include/media/ipu-bridge.h +++ b/include/media/ipu-bridge.h @@ -164,6 +164,15 @@ struct ipu_bridge { char ipu_node_name[ACPI_ID_LEN]; struct software_node ipu_hid_node; u32 data_lanes[4]; + /* + * The software nodes registered by the bridge are deliberately never + * unregistered (see ipu_bridge_init()), so every string and array + * they reference must live in this never freed struct rather than in + * the module image, so that the nodes stay intact if the module is + * unloaded. + */ + char lens_focus[sizeof("lens-focus")]; + u64 link_freqs[IPU_MAX_PORTS][MAX_NUM_LINK_FREQS]; unsigned int n_sensors; struct ipu_sensor sensors[IPU_MAX_PORTS]; }; --=20 2.43.0 From nobody Sat Sep 26 19:34:28 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A41E3E00B5 for ; Mon, 31 Aug 2026 09:43:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788169385; cv=none; b=a/6OwV171Xp+fvxGsUxe2fnvtgQ3JyAQ271/4HgX4Ohw4XWvSf4vkxpgDuD+3rAODdJUE9FS2wrvpBtmKOognBTBLICsNcm7GlKlE/+UeLVC21EunTW97BSy0yMOwSRKQDOS8iCAlw7E7YWkMeIApxf/2gQoKt236p3tX2z7IVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788169385; c=relaxed/simple; bh=LuYj6EwIqV6NwexPQcbrO0D0onCO94TVcOKZPJJBWb4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kwq0yQT/nbVLhc9VnGz43rRUWl9U4W5NyzRO46lfXsg1Yn5tFGcSR9y9IVKqaN5q+lGebyI1FU+NBYv+u6pRHsSddwDJXEBRZfMgK4LjDhkxOT0+w5I4GHMPqUaGxbeR67Sb4R/Fa78N8EpsfrUXmuh2L9PfGz9OS+UliDO7GF8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jp9oxMo9; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jp9oxMo9" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-499ae1c6471so23312785e9.3 for ; Mon, 31 Aug 2026 02:43:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788169382; x=1788774182; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=mNQxdTkzGD83pNFUYAGZDFb9hsIN1sZQHskMcBDnWv4=; b=jp9oxMo9aphNlZnBGXpZTBVDAGlj83XN6Cu77NXc9JiuvHYqmQSYFb5zsNHVrn1kU5 5zq1vR+vUNAhEPSIYn/bq5JtxU+isqQ8uB9G/3+1BEJn+9GzVLSgExs/CVwE6NTHXCh8 cxc+fSV+r/kp7dqAGwLCj5I+M9OgMj/XmDcL1p228LmNY9GZaiG97ft8zHq+LBz0ptCz kkPvDQONtV4K3EaimDy4tCwyJDbgd8RTpvoWAi8IuJFAg38QuIcSN5SuUL4CIOv9B5KK aBsQJe8p1enkD/3xLzfKQv4INmvg/57rj85OAcdJaE3bgz2FCookRaW4vfxaaDx+xdup qFrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788169382; x=1788774182; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=mNQxdTkzGD83pNFUYAGZDFb9hsIN1sZQHskMcBDnWv4=; b=RZL5lTewBaC0WeQEnwMt235VN0JTE9UGXGCBIv1IKrBIY8BZyaZCkHYhTjG2YiWGe+ xz1Z4eB5u7gjG29a/gd1Fk3N2xeWF8hDNxXFNancp0bhtJj5sDLZPegbw219H1lOMGmo RUXtjYa9t24Jh/YcCm1eWAKil/WJRi4fFg7uGw6G29MH0TuR2/xNssUYdR51YgjtRwh/ JRWgDNaGD5lGqpFncaPsO3qWcPkiwWt4K2hTxvldir8SYsKfhPM1DcZgp1SKz9QObjri 0tXgCN4I7V9ku42PqPwa5Gkb/28UPfW8UCDvFtEOhOO6L0cg6DhmhKlIow0X89zyAF2x pDPA== X-Forwarded-Encrypted: i=1; AHgh+RqN+LkX5kSBi/FFLwkPksc6aUfTovmJv3D2Q7binirUTtHCVihLZGwmT1UAV7DLMIqqHwtE2/sIhoHvydo=@vger.kernel.org X-Gm-Message-State: AFuF++mwn6MiXdkctljUGXof8y+ypQMR2ATGpON+adPTRIaW18x/YsNU cLfAarLQHO9dD3SngqI2Qdz+G6a/1zNDDoG9oQMp/xAZAdqI2PMYjos= X-Gm-Gg: AR+sD12puE3ww/ZZAS4fTT3QHgJwbQmNh70itjTrZapWOa9cxm2RftdvPvb1p4gyQM9 6qtpVmapW9TOMjwMpOCqqD3RTetiWtQZHkk4WOviWOcodOOIZCD9HnEAnCIuRJAXe6LiFib9PRg mZrIDc0vSXG5uvRf53QvvPBnl4eoPVcrsFo+mkiyhwXz+t4BSbjl4agxO/wMxiGdAjbtCF8+vVK UnD6/Ta57QBHp4vRJPHCgZ/RP4i5CZh+tY6cgaC/kV528GWiOpJpKqPPyQz1uONcJn6jmw8Y/dU sFNGxvCE1273oj39Q0SDXNlbfxbDOBCALPRLY6CEslHQ10A2yfmgGRTyre/OwE7SZpE2CWm0PFB zmllXSWGmooKCto+7Yg0fqFFBH8rfGeuWH2SbVZkG/a+SA3jBvhxUpxYvrercjvaBoA4+XSV+1E v8FLc+ky21wXBBRneUMClTxrhkAhpQyUYvCEs56AjZVyXTI5eROenEaCtCzzR/yiZJFZ5pH9bv0 t3FHA/5wxYCiPiP5atIF5h2qinAlxwYOaPduGVUrzx9 X-Received: by 2002:a05:600c:3b01:b0:49b:9105:cdaf with SMTP id 5b1f17b1804b1-49cd943d074mr34361125e9.8.1788169381375; Mon, 31 Aug 2026 02:43:01 -0700 (PDT) Received: from surface.. (84.124.213.91.dyn.user.ono.com. [84.124.213.91]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49b9267c369sm189932125e9.3.2026.08.31.02.43.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 02:43:00 -0700 (PDT) From: "D. Manresa" To: Sakari Ailus , Hans de Goede , Daniel Scally Cc: Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, "D . Manresa" Subject: [PATCH 2/2] media: ipu-bridge: reuse the software nodes on rebind Date: Mon, 31 Aug 2026 11:42:56 +0200 Message-ID: <20260831094257.29398-3-dmanresa@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260831094257.29398-1-dmanresa@gmail.com> References: <20260827232636.93145-1-dmanresa@gmail.com> <20260831094257.29398-1-dmanresa@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The software nodes registered by ipu_bridge_init() are deliberately never unregistered, and the intended design is for a rebind to reuse the already registered nodes. That reuse path however only exists for the case where the IPU device kept its secondary fwnode link, which the fwnode graph check at the top of ipu_bridge_init() detects: then the function returns early. When the link is gone, ipu_bridge_init() unconditionally registers the IPU HID software node again, which fails with -EEXIST on the sysfs name (the node from the previous bind is still registered) and the IPU driver fails to probe. That is exactly what happens when the IPU PCI device is removed and re-scanned: device_del() unsets the ACPI companion, and set_primary_fwnode(dev, NULL) then clears the ACPI fwnode's ->secondary pointer, so the fwnode graph check on the next probe finds no endpoints and falls through to registration. Observed on a Surface Pro 7+ (IPU6): echo 1 > /sys/bus/pci/devices/0000:00:05.0/remove modprobe -r intel_ipu6_isys intel_ipu6 # ipu-bridge unloads too echo 1 > /sys/bus/pci/rescan modprobe intel_ipu6 sysfs: cannot create duplicate filename '/kernel/software_nodes/INT343E' intel-ipu6 0000:00:05.0: Failed to register the IPU HID node intel-ipu6: probe of 0000:00:05.0 failed with error -17 after which the cameras are unusable until reboot. Add the missing reuse path: if the IPU software node is already registered, look it up with software_node_find_by_name(), point the device's secondary fwnode at it and return success. Restoring the IPU's secondary fwnode is all a rebind needs: the sensors' ACPI fwnodes still carry their secondary fwnode pointers from the first bind (the sensor devices are not removed by an IPU unbind, so nothing clears those), and the IVSC and VCM links likewise live on devices that survive an IPU rebind. The previous commit made the registered nodes self-contained in the never freed bridge allocation, so their properties are still valid here. The IVSC readiness check is intentionally skipped on this path, as the IVSC links were already established by the first bind. software_node_find_by_name() takes a reference on the node it returns; drop it right away since the node is kept alive by its never dropped registration, matching the reference handling of the initial-bind path. Developed with the assistance of an AI tool (Claude) Fixes: 803abec64ef9 ("media: ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver= ") Signed-off-by: D. Manresa --- drivers/media/pci/intel/ipu-bridge.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel= /ipu-bridge.c index 4de42ed..6fa1c3c 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -930,6 +930,7 @@ static DEFINE_MUTEX(ipu_bridge_mutex); int ipu_bridge_init(struct device *dev, ipu_parse_sensor_fwnode_t parse_sensor_fwnode) { + const struct software_node *ipu_node; struct fwnode_handle *fwnode; struct ipu_bridge *bridge; unsigned int i; @@ -940,6 +941,29 @@ int ipu_bridge_init(struct device *dev, if (!ipu_bridge_check_fwnode_graph(dev_fwnode(dev))) return 0; =20 + /* + * The software nodes registered by a previous ipu_bridge_init() call + * are deliberately kept registered when the module is unloaded, and + * the sensors' ACPI fwnodes still have them as their secondary + * fwnodes. If the IPU software node is already registered this is a + * rebind, e.g. after the PCI device was removed and re-scanned, + * which drops the IPU's secondary fwnode link. Registering the nodes + * again would fail with -EEXIST, so instead reuse them and just + * restore the IPU's secondary fwnode link. + */ + ipu_node =3D software_node_find_by_name(NULL, IPU_HID); + if (ipu_node) { + fwnode =3D software_node_fwnode(ipu_node); + set_secondary_fwnode(dev, fwnode); + /* + * The node stays registered, it does not need the reference + * software_node_find_by_name() took to stay alive. + */ + fwnode_handle_put(fwnode); + dev_info(dev, "Reusing the previously registered software nodes\n"); + return 0; + } + if (!ipu_bridge_ivsc_is_ready()) return dev_err_probe(dev, -EPROBE_DEFER, "waiting for IVSC to become ready\n"); --=20 2.43.0