public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/kernel] f43: kernel-7.1.13-100
@ 2026-09-02 13:38 Justin M. Forbes
  0 siblings, 0 replies; only message in thread
From: Justin M. Forbes @ 2026-09-02 13:38 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/kernel
            Branch : f43
            Commit : d07de2fb68a0382304102bfbebd1543f11be4362
            Author : Justin M. Forbes <jforbes@fedoraproject.org>
            Date   : 2026-09-02T07:38:39-06:00
            Stats  : +2651/-160 in 44 file(s)
            URL    : https://src.fedoraproject.org/rpms/kernel/c/d07de2fb68a0382304102bfbebd1543f11be4362?branch=f43

            Log:
            kernel-7.1.13-100

* Wed Sep 02 2026 Justin M. Forbes <jforbes@fedoraproject.org> [7.1.13-0]
- New config item for 7.1.13 stable update (Justin M. Forbes)
- Add more bugs to BugsFixed (Justin M. Forbes)
- page_pool: keep frag_offset aligned for odd-sized requests (Florian Schauer) [2521546 2521847]
- ACPI: scan: Do not combine resources that overlap completely (Rafael J. Wysocki) [2514390]
- ACPI: scan: Avoid registering platform devices with resource overlaps (Rafael J. Wysocki) [2514390]
- Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728 (Junjie Cao) [2521504]
- redhat: configs: fedora: Enable Intel CVS (Kate Hsuan)
- media: i2c: cvs: Pass link frequency explicitly to csi_set_link_cfg() (Laurent Pinchart)
- media: i2c: cvs: Add NVL ACPI ID (Arun T)
- media: i2c: cvs: Add IPU8 PCI device ID (Arun T)
- media: i2c: cvs: Add driver of Intel Computer Vision Sensing Controller(CVS) (Miguel Vadillo)
- Add bugs to BugsFixed for 7.1.13 (Justin M. Forbes)
- random: Drop the extrng module reference when import_ubuf() fails (Junjie Cao) [2524262]
- Linux v7.1.13
Resolves: rhbz#2514390, rhbz#2521504, rhbz#2521546, rhbz#2521847, rhbz#2524262

Signed-off-by: Justin M. Forbes <jforbes@fedoraproject.org>

---
diff --git a/Patchlist.changelog b/Patchlist.changelog
index db61288..8cf67ab 100644
--- a/Patchlist.changelog
+++ b/Patchlist.changelog
@@ -1,3 +1,30 @@
+https://gitlab.com/cki-project/kernel-ark/-/commit/3422066c3e6e8aac3af2bd34d8d94ae714892681
+ 3422066c3e6e8aac3af2bd34d8d94ae714892681 Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/5b8b38f2720bb3efb35804dc8f82181c6b7ea43e
+ 5b8b38f2720bb3efb35804dc8f82181c6b7ea43e ACPI: scan: Do not combine resources that overlap completely
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/d1bd63f803ce4a7b60de63ed3973265c6d778929
+ d1bd63f803ce4a7b60de63ed3973265c6d778929 ACPI: scan: Avoid registering platform devices with resource overlaps
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/aa4becccf866c958edcd8e24b9dbf42acf213a6e
+ aa4becccf866c958edcd8e24b9dbf42acf213a6e page_pool: keep frag_offset aligned for odd-sized requests
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/02e162bf79251e9f46e429e79eff37a4f1318f5e
+ 02e162bf79251e9f46e429e79eff37a4f1318f5e random: Drop the extrng module reference when import_ubuf() fails
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/17e52fd689161d7083178b64d190e36ef0f0aff2
+ 17e52fd689161d7083178b64d190e36ef0f0aff2 media: i2c: cvs: Pass link frequency explicitly to csi_set_link_cfg()
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/d68b88fd64658e5c08eb608090472c7fb7199802
+ d68b88fd64658e5c08eb608090472c7fb7199802 media: i2c: cvs: Add NVL ACPI ID
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/70d3e18bfadbdc057daa983a97599c3cd93ab000
+ 70d3e18bfadbdc057daa983a97599c3cd93ab000 media: i2c: cvs: Add IPU8 PCI device ID
+
+https://gitlab.com/cki-project/kernel-ark/-/commit/222f96a48d5a774afa4846989b68b5941b950b3f
+ 222f96a48d5a774afa4846989b68b5941b950b3f media: i2c: cvs: Add driver of Intel Computer Vision Sensing Controller(CVS)
+
 https://gitlab.com/cki-project/kernel-ark/-/commit/366f0a4f8abcf72481ac40f6752754b8d2092c9a
  366f0a4f8abcf72481ac40f6752754b8d2092c9a ALSA: hda/realtek: add quirk for Framework F111:0010
 

diff --git a/kernel-aarch64-16k-debug-fedora.config b/kernel-aarch64-16k-debug-fedora.config
index 8cb7466..144f22c 100644
--- a/kernel-aarch64-16k-debug-fedora.config
+++ b/kernel-aarch64-16k-debug-fedora.config
@@ -10384,6 +10384,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-16k-fedora.config b/kernel-aarch64-16k-fedora.config
index 6013021..f9b04a4 100644
--- a/kernel-aarch64-16k-fedora.config
+++ b/kernel-aarch64-16k-fedora.config
@@ -10350,6 +10350,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-64k-debug-rhel.config b/kernel-aarch64-64k-debug-rhel.config
index c0d78ef..f847be2 100644
--- a/kernel-aarch64-64k-debug-rhel.config
+++ b/kernel-aarch64-64k-debug-rhel.config
@@ -8456,6 +8456,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-64k-rhel.config b/kernel-aarch64-64k-rhel.config
index 31de59e..fe9d984 100644
--- a/kernel-aarch64-64k-rhel.config
+++ b/kernel-aarch64-64k-rhel.config
@@ -8427,6 +8427,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-debug-fedora.config b/kernel-aarch64-debug-fedora.config
index c3b6bfa..ad711bb 100644
--- a/kernel-aarch64-debug-fedora.config
+++ b/kernel-aarch64-debug-fedora.config
@@ -10383,6 +10383,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-debug-rhel.config b/kernel-aarch64-debug-rhel.config
index 727d26e..04ead4c 100644
--- a/kernel-aarch64-debug-rhel.config
+++ b/kernel-aarch64-debug-rhel.config
@@ -8453,6 +8453,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-fedora.config b/kernel-aarch64-fedora.config
index eb14a0a..bf8b347 100644
--- a/kernel-aarch64-fedora.config
+++ b/kernel-aarch64-fedora.config
@@ -10349,6 +10349,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-rhel.config b/kernel-aarch64-rhel.config
index 6ce1f06..b6c1b02 100644
--- a/kernel-aarch64-rhel.config
+++ b/kernel-aarch64-rhel.config
@@ -8424,6 +8424,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-rt-64k-debug-fedora.config b/kernel-aarch64-rt-64k-debug-fedora.config
index ee43729..06db339 100644
--- a/kernel-aarch64-rt-64k-debug-fedora.config
+++ b/kernel-aarch64-rt-64k-debug-fedora.config
@@ -10399,6 +10399,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-rt-64k-debug-rhel.config b/kernel-aarch64-rt-64k-debug-rhel.config
index 00f99e9..7ce267c 100644
--- a/kernel-aarch64-rt-64k-debug-rhel.config
+++ b/kernel-aarch64-rt-64k-debug-rhel.config
@@ -8503,6 +8503,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-rt-64k-fedora.config b/kernel-aarch64-rt-64k-fedora.config
index d825c60..3b28aaa 100644
--- a/kernel-aarch64-rt-64k-fedora.config
+++ b/kernel-aarch64-rt-64k-fedora.config
@@ -10365,6 +10365,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-rt-64k-rhel.config b/kernel-aarch64-rt-64k-rhel.config
index 521374e..409eb1d 100644
--- a/kernel-aarch64-rt-64k-rhel.config
+++ b/kernel-aarch64-rt-64k-rhel.config
@@ -8474,6 +8474,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-rt-debug-fedora.config b/kernel-aarch64-rt-debug-fedora.config
index 8b08082..c6032f2 100644
--- a/kernel-aarch64-rt-debug-fedora.config
+++ b/kernel-aarch64-rt-debug-fedora.config
@@ -10395,6 +10395,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-rt-debug-rhel.config b/kernel-aarch64-rt-debug-rhel.config
index fa68ddf..a268909 100644
--- a/kernel-aarch64-rt-debug-rhel.config
+++ b/kernel-aarch64-rt-debug-rhel.config
@@ -8499,6 +8499,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-aarch64-rt-fedora.config b/kernel-aarch64-rt-fedora.config
index 75c6ac2..b85e86b 100644
--- a/kernel-aarch64-rt-fedora.config
+++ b/kernel-aarch64-rt-fedora.config
@@ -10361,6 +10361,7 @@ CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
 # CONFIG_VIDEO_IMX_MEDIA is not set
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX_PXP=m
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-aarch64-rt-rhel.config b/kernel-aarch64-rt-rhel.config
index 1d7ba87..20c89fb 100644
--- a/kernel-aarch64-rt-rhel.config
+++ b/kernel-aarch64-rt-rhel.config
@@ -8470,6 +8470,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX8_ISI is not set
 # CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
 # CONFIG_VIDEO_IMX_MIPI_CSIS is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-ppc64le-debug-fedora.config b/kernel-ppc64le-debug-fedora.config
index 740a719..47ef809 100644
--- a/kernel-ppc64le-debug-fedora.config
+++ b/kernel-ppc64le-debug-fedora.config
@@ -8387,6 +8387,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-ppc64le-debug-rhel.config b/kernel-ppc64le-debug-rhel.config
index 6199b8a..eae2101 100644
--- a/kernel-ppc64le-debug-rhel.config
+++ b/kernel-ppc64le-debug-rhel.config
@@ -7827,6 +7827,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-ppc64le-fedora.config b/kernel-ppc64le-fedora.config
index 22ad315..2495cf6 100644
--- a/kernel-ppc64le-fedora.config
+++ b/kernel-ppc64le-fedora.config
@@ -8352,6 +8352,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-ppc64le-rhel.config b/kernel-ppc64le-rhel.config
index b3dd27a..c3cc82d 100644
--- a/kernel-ppc64le-rhel.config
+++ b/kernel-ppc64le-rhel.config
@@ -7800,6 +7800,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-riscv64-debug-fedora.config b/kernel-riscv64-debug-fedora.config
index a5cc134..3b5719b 100644
--- a/kernel-riscv64-debug-fedora.config
+++ b/kernel-riscv64-debug-fedora.config
@@ -8564,6 +8564,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-riscv64-debug-rhel.config b/kernel-riscv64-debug-rhel.config
index 084b51e..ec12d49 100644
--- a/kernel-riscv64-debug-rhel.config
+++ b/kernel-riscv64-debug-rhel.config
@@ -7908,6 +7908,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-riscv64-fedora.config b/kernel-riscv64-fedora.config
index 38ccfab..c1efd99 100644
--- a/kernel-riscv64-fedora.config
+++ b/kernel-riscv64-fedora.config
@@ -8529,6 +8529,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-riscv64-rhel.config b/kernel-riscv64-rhel.config
index 65db2b1..7164544 100644
--- a/kernel-riscv64-rhel.config
+++ b/kernel-riscv64-rhel.config
@@ -7881,6 +7881,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-riscv64-rt-debug-fedora.config b/kernel-riscv64-rt-debug-fedora.config
index 2b89028..6ccf652 100644
--- a/kernel-riscv64-rt-debug-fedora.config
+++ b/kernel-riscv64-rt-debug-fedora.config
@@ -8576,6 +8576,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-riscv64-rt-fedora.config b/kernel-riscv64-rt-fedora.config
index f2d5e5b..2bf2b95 100644
--- a/kernel-riscv64-rt-fedora.config
+++ b/kernel-riscv64-rt-fedora.config
@@ -8541,6 +8541,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-s390x-debug-fedora.config b/kernel-s390x-debug-fedora.config
index 5682fe1..cce9b66 100644
--- a/kernel-s390x-debug-fedora.config
+++ b/kernel-s390x-debug-fedora.config
@@ -8343,6 +8343,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-s390x-debug-rhel.config b/kernel-s390x-debug-rhel.config
index c947c80..f3ae1f2 100644
--- a/kernel-s390x-debug-rhel.config
+++ b/kernel-s390x-debug-rhel.config
@@ -7821,6 +7821,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-s390x-fedora.config b/kernel-s390x-fedora.config
index 50a0186..0de5c01 100644
--- a/kernel-s390x-fedora.config
+++ b/kernel-s390x-fedora.config
@@ -8308,6 +8308,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 CONFIG_VIDEO_IR_I2C=m
 CONFIG_VIDEO_ISL7998X=m

diff --git a/kernel-s390x-rhel.config b/kernel-s390x-rhel.config
index 8b5c3ed..a58fc77 100644
--- a/kernel-s390x-rhel.config
+++ b/kernel-s390x-rhel.config
@@ -7794,6 +7794,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-s390x-zfcpdump-rhel.config b/kernel-s390x-zfcpdump-rhel.config
index 3dea26a..e9ae382 100644
--- a/kernel-s390x-zfcpdump-rhel.config
+++ b/kernel-s390x-zfcpdump-rhel.config
@@ -7815,6 +7815,7 @@ CONFIG_VIDEO_FB_IVTV=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 # CONFIG_VIDEO_INTEL_IPU6 is not set
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-x86_64-debug-fedora.config b/kernel-x86_64-debug-fedora.config
index 31ad46f..b1234cf 100644
--- a/kernel-x86_64-debug-fedora.config
+++ b/kernel-x86_64-debug-fedora.config
@@ -8986,6 +8986,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 CONFIG_VIDEO_IMX471=m
+CONFIG_VIDEO_INTEL_CVS=m
 CONFIG_VIDEO_INTEL_IPU6=m
 CONFIG_VIDEO_INTEL_IPU7=m
 CONFIG_VIDEO_IPU3_CIO2=m

diff --git a/kernel-x86_64-debug-rhel.config b/kernel-x86_64-debug-rhel.config
index 589fe9a..8b12d8a 100644
--- a/kernel-x86_64-debug-rhel.config
+++ b/kernel-x86_64-debug-rhel.config
@@ -8208,6 +8208,7 @@ CONFIG_VIDEO_HI556=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 CONFIG_VIDEO_INTEL_IPU6=m
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-x86_64-fedora.config b/kernel-x86_64-fedora.config
index 14dbe28..15e0ab0 100644
--- a/kernel-x86_64-fedora.config
+++ b/kernel-x86_64-fedora.config
@@ -8952,6 +8952,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 CONFIG_VIDEO_IMX471=m
+CONFIG_VIDEO_INTEL_CVS=m
 CONFIG_VIDEO_INTEL_IPU6=m
 CONFIG_VIDEO_INTEL_IPU7=m
 CONFIG_VIDEO_IPU3_CIO2=m

diff --git a/kernel-x86_64-rhel.config b/kernel-x86_64-rhel.config
index caaedd5..6221b8f 100644
--- a/kernel-x86_64-rhel.config
+++ b/kernel-x86_64-rhel.config
@@ -8180,6 +8180,7 @@ CONFIG_VIDEO_HI556=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 CONFIG_VIDEO_INTEL_IPU6=m
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-x86_64-rt-debug-fedora.config b/kernel-x86_64-rt-debug-fedora.config
index 05af665..59875cc 100644
--- a/kernel-x86_64-rt-debug-fedora.config
+++ b/kernel-x86_64-rt-debug-fedora.config
@@ -8998,6 +8998,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 CONFIG_VIDEO_IMX471=m
+CONFIG_VIDEO_INTEL_CVS=m
 CONFIG_VIDEO_INTEL_IPU6=m
 CONFIG_VIDEO_INTEL_IPU7=m
 CONFIG_VIDEO_IPU3_CIO2=m

diff --git a/kernel-x86_64-rt-debug-rhel.config b/kernel-x86_64-rt-debug-rhel.config
index caf8d48..96a0604 100644
--- a/kernel-x86_64-rt-debug-rhel.config
+++ b/kernel-x86_64-rt-debug-rhel.config
@@ -8254,6 +8254,7 @@ CONFIG_VIDEO_HI556=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 CONFIG_VIDEO_INTEL_IPU6=m
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel-x86_64-rt-fedora.config b/kernel-x86_64-rt-fedora.config
index de47f4f..6f3c768 100644
--- a/kernel-x86_64-rt-fedora.config
+++ b/kernel-x86_64-rt-fedora.config
@@ -8964,6 +8964,7 @@ CONFIG_VIDEO_IMX355=m
 CONFIG_VIDEO_IMX412=m
 CONFIG_VIDEO_IMX415=m
 CONFIG_VIDEO_IMX471=m
+CONFIG_VIDEO_INTEL_CVS=m
 CONFIG_VIDEO_INTEL_IPU6=m
 CONFIG_VIDEO_INTEL_IPU7=m
 CONFIG_VIDEO_IPU3_CIO2=m

diff --git a/kernel-x86_64-rt-rhel.config b/kernel-x86_64-rt-rhel.config
index 72e3315..d6ba281 100644
--- a/kernel-x86_64-rt-rhel.config
+++ b/kernel-x86_64-rt-rhel.config
@@ -8226,6 +8226,7 @@ CONFIG_VIDEO_HI556=m
 # CONFIG_VIDEO_IMX412 is not set
 # CONFIG_VIDEO_IMX415 is not set
 # CONFIG_VIDEO_IMX471 is not set
+# CONFIG_VIDEO_INTEL_CVS is not set
 CONFIG_VIDEO_INTEL_IPU6=m
 # CONFIG_VIDEO_IPU3_CIO2 is not set
 # CONFIG_VIDEO_ISL7998X is not set

diff --git a/kernel.changelog b/kernel.changelog
index 3a427a4..0952d26 100644
--- a/kernel.changelog
+++ b/kernel.changelog
@@ -1,3 +1,20 @@
+* Wed Sep 02 2026 Justin M. Forbes <jforbes@fedoraproject.org> [7.1.13-0]
+- New config item for 7.1.13 stable update (Justin M. Forbes)
+- Add more bugs to BugsFixed (Justin M. Forbes)
+- page_pool: keep frag_offset aligned for odd-sized requests (Florian Schauer) [2521546 2521847]
+- ACPI: scan: Do not combine resources that overlap completely (Rafael J. Wysocki) [2514390]
+- ACPI: scan: Avoid registering platform devices with resource overlaps (Rafael J. Wysocki) [2514390]
+- Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728 (Junjie Cao) [2521504]
+- redhat: configs: fedora: Enable Intel CVS (Kate Hsuan)
+- media: i2c: cvs: Pass link frequency explicitly to csi_set_link_cfg() (Laurent Pinchart)
+- media: i2c: cvs: Add NVL ACPI ID (Arun T)
+- media: i2c: cvs: Add IPU8 PCI device ID (Arun T)
+- media: i2c: cvs: Add driver of Intel Computer Vision Sensing Controller(CVS) (Miguel Vadillo)
+- Add bugs to BugsFixed for 7.1.13 (Justin M. Forbes)
+- random: Drop the extrng module reference when import_ubuf() fails (Junjie Cao) [2524262]
+- Linux v7.1.13
+Resolves: rhbz#2514390, rhbz#2521504, rhbz#2521546, rhbz#2521847, rhbz#2524262
+
 * Fri Aug 28 2026 Justin M. Forbes <jforbes@fedoraproject.org> [7.1.12-0]
 - Linux v7.1.12
 Resolves: 

diff --git a/kernel.spec b/kernel.spec
index a4275e1..e22f292 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -187,18 +187,18 @@ Summary: The Linux kernel
 #  the --with-release option overrides this setting.)
 %define debugbuildsenabled 1
 # define buildid .local
-%define specrpmversion 7.1.12
-%define specversion 7.1.12
+%define specrpmversion 7.1.13
+%define specversion 7.1.13
 %define patchversion 7.1
 %define pkgrelease 100
 %define kversion 7
-%define tarfile_release 7.1.12
+%define tarfile_release 7.1.13
 # This is needed to do merge window version magic
 %define patchlevel 1
 # This allows pkg_release to have configurable %%{?dist} tag
 %define specrelease 100%{?buildid}%{?dist}
 # This defines the kabi tarball version
-%define kabiversion 7.1.12
+%define kabiversion 7.1.13
 
 # If this variable is set to 1, a bpf selftests build failure will cause a
 # fatal kernel package build error
@@ -4865,6 +4865,22 @@ fi\
 #
 #
 %changelog
+* Wed Sep 02 2026 Justin M. Forbes <jforbes@fedoraproject.org> [7.1.13-0]
+- New config item for 7.1.13 stable update (Justin M. Forbes)
+- Add more bugs to BugsFixed (Justin M. Forbes)
+- page_pool: keep frag_offset aligned for odd-sized requests (Florian Schauer) [2521546 2521847]
+- ACPI: scan: Do not combine resources that overlap completely (Rafael J. Wysocki) [2514390]
+- ACPI: scan: Avoid registering platform devices with resource overlaps (Rafael J. Wysocki) [2514390]
+- Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728 (Junjie Cao) [2521504]
+- redhat: configs: fedora: Enable Intel CVS (Kate Hsuan)
+- media: i2c: cvs: Pass link frequency explicitly to csi_set_link_cfg() (Laurent Pinchart)
+- media: i2c: cvs: Add NVL ACPI ID (Arun T)
+- media: i2c: cvs: Add IPU8 PCI device ID (Arun T)
+- media: i2c: cvs: Add driver of Intel Computer Vision Sensing Controller(CVS) (Miguel Vadillo)
+- Add bugs to BugsFixed for 7.1.13 (Justin M. Forbes)
+- random: Drop the extrng module reference when import_ubuf() fails (Junjie Cao) [2524262]
+- Linux v7.1.13
+
 * Fri Aug 28 2026 Justin M. Forbes <jforbes@fedoraproject.org> [7.1.12-0]
 - Linux v7.1.12
 

diff --git a/patch-7.1-redhat.patch b/patch-7.1-redhat.patch
index a9d65ed..9148a0c 100644
--- a/patch-7.1-redhat.patch
+++ b/patch-7.1-redhat.patch
@@ -1,4 +1,4 @@
- MAINTAINERS                                        |   29 +
+ MAINTAINERS                                        |   35 +
  Makefile                                           |   30 +
  arch/arm/Kconfig                                   |    4 +-
  arch/arm64/Kconfig                                 |    2 +-
@@ -13,14 +13,17 @@
  crypto/seqiv.c                                     |   15 +-
  crypto/sig.c                                       |    3 +-
  crypto/testmgr.c                                   |    6 +-
+ drivers/acpi/acpi_platform.c                       |   45 +-
  drivers/acpi/apei/hest.c                           |    8 +
  drivers/acpi/battery.c                             |   14 +
  drivers/acpi/irq.c                                 |   17 +-
  drivers/acpi/scan.c                                |    9 +
  drivers/ata/libahci.c                              |   18 +
+ drivers/bluetooth/btrtl.c                          |   13 -
+ drivers/bluetooth/btusb.c                          |    8 +
  drivers/char/ipmi/ipmi_dmi.c                       |   15 +
  drivers/char/ipmi/ipmi_msghandler.c                |   16 +-
- drivers/char/random.c                              |  126 ++-
+ drivers/char/random.c                              |  128 ++-
  drivers/firmware/efi/Makefile                      |    1 +
  drivers/firmware/efi/efi.c                         |  124 ++-
  drivers/firmware/efi/libstub/fdt.c                 |    5 +
@@ -28,8 +31,13 @@
  drivers/firmware/efi/secureboot.c                  |   38 +
  drivers/hwtracing/coresight/coresight-etm4x-core.c |   19 +
  drivers/iommu/iommu.c                              |   22 +
- drivers/media/i2c/Kconfig                          |   10 +
- drivers/media/i2c/Makefile                         |    1 +
+ drivers/media/i2c/Kconfig                          |   12 +
+ drivers/media/i2c/Makefile                         |    2 +
+ drivers/media/i2c/cvs/Kconfig                      |   21 +
+ drivers/media/i2c/cvs/Makefile                     |    4 +
+ drivers/media/i2c/cvs/core.c                       | 1046 +++++++++++++++++++
+ drivers/media/i2c/cvs/icvs.h                       |  493 +++++++++
+ drivers/media/i2c/cvs/v4l2.c                       |  617 ++++++++++++
  drivers/media/i2c/imx471.c                         |  957 ++++++++++++++++++
  drivers/media/pci/intel/ipu-bridge.c               |   41 +
  drivers/media/platform/Kconfig                     |    1 +
@@ -60,6 +68,7 @@
  include/linux/random.h                             |   10 +
  include/linux/security.h                           |    9 +
  kernel/module/signing.c                            |    9 +-
+ net/core/page_pool.c                               |    3 +-
  scripts/Makefile.lib                               |    3 +
  scripts/tags.sh                                    |    2 +
  security/integrity/platform_certs/load_uefi.c      |    6 +-
@@ -71,10 +80,10 @@
  tools/testing/selftests/bpf/DENYLIST.rhel          |   76 ++
  tools/testing/selftests/bpf/Makefile               |    2 +-
  tools/testing/selftests/bpf/prog_tests/ksyms_btf.c |   31 -
- 73 files changed, 5897 insertions(+), 128 deletions(-)
+ 82 files changed, 8142 insertions(+), 144 deletions(-)
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 624cfb6cf1d4..f9bcd152b09b 100644
+index 624cfb6cf1d4..a096848918d2 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
 @@ -1159,6 +1159,29 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
@@ -107,7 +116,20 @@ index 624cfb6cf1d4..f9bcd152b09b 100644
  AMD KFD
  M:	Felix Kuehling <Felix.Kuehling@amd.com>
  L:	amd-gfx@lists.freedesktop.org
-@@ -24969,6 +24992,12 @@ T:	git git://linuxtv.org/media.git
+@@ -12835,6 +12858,12 @@ S:	Orphan
+ T:	git git://git.code.sf.net/p/intel-sas/isci
+ F:	drivers/scsi/isci/
+ 
++INTEL COMPUTER VISION SENSING (CVS) DRIVER
++M:	Miguel Vadillo <miguel.vadillo@intel.com>
++L:	linux-media@vger.kernel.org
++S:	Maintained
++F:	drivers/media/i2c/cvs/
++
+ INTEL CPU family model numbers
+ M:	Tony Luck <tony.luck@intel.com>
+ M:	x86@kernel.org
+@@ -24969,6 +24998,12 @@ T:	git git://linuxtv.org/media.git
  F:	Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
  F:	drivers/media/i2c/imx415.c
  
@@ -121,7 +143,7 @@ index 624cfb6cf1d4..f9bcd152b09b 100644
  M:	Maxim Levitsky <maximlevitsky@gmail.com>
  M:	Alex Dubov <oakad@yahoo.com>
 diff --git a/Makefile b/Makefile
-index af34c633b796..0c8d0b412f67 100644
+index f535c37d6fe9..159c38108bbc 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -356,6 +356,17 @@ ifneq ($(filter install,$(MAKECMDGOALS)),)
@@ -500,6 +522,78 @@ index 4d86efae65b2..31c6372c50dd 100644
  		.suite = {
  			.kpp = __VECS(ecdh_p384_tv_template)
  		}
+diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
+index a09636a4168e..e3c77a65f61c 100644
+--- a/drivers/acpi/acpi_platform.c
++++ b/drivers/acpi/acpi_platform.c
+@@ -12,6 +12,7 @@
+ #include <linux/bits.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
++#include <linux/ioport.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/dma-mapping.h>
+@@ -71,6 +72,42 @@ static struct notifier_block acpi_platform_notifier = {
+ 	.notifier_call = acpi_platform_device_remove_notify,
+ };
+ 
++static unsigned int acpi_platform_adjust_resources(struct acpi_device *adev,
++						   struct resource *new_res,
++						   struct resource *resources,
++						   unsigned int count)
++{
++	unsigned int i;
++
++	if (!(new_res->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
++		return count;
++
++	for (i = 0; i < count; ) {
++		struct resource *res = &resources[i];
++
++		/*
++		 * Look for overlaps of resources of the same type that would
++		 * cause resource insertion to fail down the road.
++		 */
++		if (__resource_contains_unbound(res, new_res) ||
++		    __resource_contains_unbound(new_res, res) ||
++		    resource_type(new_res) != resource_type(res) ||
++		    !resource_union(new_res, res, new_res)) {
++			i++;
++			continue;
++		}
++
++		dev_info(&adev->dev, "%pR expanded due to overlap\n", new_res);
++		/*
++		 * Eliminate the previously processed resource that overlapped
++		 * with the new one because it is not necessary any more.
++		 */
++		memmove(res, res + 1, (--count - i) * sizeof(*res));
++	}
++
++	return count;
++}
++
+ static void acpi_platform_fill_resource(struct acpi_device *adev,
+ 	const struct resource *src, struct resource *dest)
+ {
+@@ -151,10 +188,14 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
+ 				return ERR_PTR(-ENOMEM);
+ 			}
+ 			count = 0;
+-			list_for_each_entry(rentry, &resource_list, node)
++			list_for_each_entry(rentry, &resource_list, node) {
++				count = acpi_platform_adjust_resources(adev,
++								       rentry->res,
++								       resources,
++								       count);
+ 				acpi_platform_fill_resource(adev, rentry->res,
+ 							    &resources[count++]);
+-
++			}
+ 			acpi_dev_free_resource_list(&resource_list);
+ 		}
+ 	}
 diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
 index 20d757687e3d..90a13f20f052 100644
 --- a/drivers/acpi/apei/hest.c
@@ -650,6 +744,63 @@ index c79abdfcd7a9..e23bfb7f94c7 100644
  	/* wait for engine to stop. This could be as long as 500 msec */
  	tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
  				PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index 7f54d2d2d13a..03fa9409e3ee 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -1343,19 +1343,6 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ 	if (!btrtl_dev->ic_info)
+ 		return;
+ 
+-	switch (btrtl_dev->project_id) {
+-	case CHIP_ID_8761B:
+-		/* RTL8761B/BU reports HCI version 5.1 but does not support
+-		 * the LE Extended Scan commands (Opcode 0x2042), causing
+-		 * repeated -EBUSY failures when BlueZ attempts extended
+-		 * scanning while a connection is active.
+-		 */
+-		hci_set_quirk(hdev, HCI_QUIRK_BROKEN_EXT_SCAN);
+-		break;
+-	default:
+-		break;
+-	}
+-
+ 	switch (btrtl_dev->ic_info->lmp_subver) {
+ 	case RTL_ROM_LMP_8703B:
+ 		/* 8723CS reports two pages for local ext features,
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 4a356f720e1f..e20695ac1c25 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -67,6 +67,7 @@ static struct usb_driver btusb_driver;
+ #define BTUSB_INTEL_NO_WBS_SUPPORT	BIT(26)
+ #define BTUSB_ACTIONS_SEMI		BIT(27)
+ #define BTUSB_BARROT			BIT(28)
++#define BTUSB_BROKEN_EXT_SCAN		BIT(29)
+ 
+ static const struct usb_device_id btusb_table[] = {
+ 	/* Generic Bluetooth USB device */
+@@ -610,6 +611,10 @@ static const struct usb_device_id quirks_table[] = {
+ 	{ USB_DEVICE(0x0489, 0xe130), .driver_info = BTUSB_REALTEK |
+ 						     BTUSB_WIDEBAND_SPEECH },
+ 
++	/* Realtek 8761BU Bluetooth devices */
++	{ USB_DEVICE(0x0bda, 0xa728), .driver_info = BTUSB_REALTEK |
++						     BTUSB_BROKEN_EXT_SCAN },
++
+ 	/* Realtek Bluetooth devices */
+ 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
+ 	  .driver_info = BTUSB_REALTEK },
+@@ -4347,6 +4352,9 @@ static int btusb_probe(struct usb_interface *intf,
+ 	if (id->driver_info & BTUSB_INVALID_LE_STATES)
+ 		hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES);
+ 
++	if (id->driver_info & BTUSB_BROKEN_EXT_SCAN)
++		hci_set_quirk(hdev, HCI_QUIRK_BROKEN_EXT_SCAN);
++
+ 	if (id->driver_info & BTUSB_DIGIANSWER) {
+ 		data->cmdreq_type = USB_TYPE_VENDOR;
+ 		hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
 diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c
 index 505e32911c34..26f7ee0ccf40 100644
 --- a/drivers/char/ipmi/ipmi_dmi.c
@@ -712,7 +863,7 @@ index 3e0b7d60269d..8317d264426a 100644
  	rv = ipmi_register_driver();
  	mutex_unlock(&ipmi_interfaces_mutex);
 diff --git a/drivers/char/random.c b/drivers/char/random.c
-index b4da1fb976c1..1e112e2b405b 100644
+index b4da1fb976c1..7ff4dd4d9836 100644
 --- a/drivers/char/random.c
 +++ b/drivers/char/random.c
 @@ -51,9 +51,11 @@
@@ -787,7 +938,7 @@ index b4da1fb976c1..1e112e2b405b 100644
  
  	if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
  		return -EINVAL;
-@@ -1392,6 +1417,21 @@ SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags
+@@ -1392,6 +1417,23 @@ SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags
  	if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
  		return -EINVAL;
  
@@ -799,8 +950,10 @@ index b4da1fb976c1..1e112e2b405b 100644
 +
 +	if (rng) {
 +		ret = import_ubuf(ITER_DEST, ubuf, len, &iter);
-+		if (unlikely(ret))
++		if (unlikely(ret)) {
++			module_put(rng->owner);
 +			return ret;
++		}
 +		ret = rng->extrng_read_iter(&iter, !!(flags & GRND_RANDOM));
 +		module_put(rng->owner);
 +		return ret;
@@ -809,7 +962,7 @@ index b4da1fb976c1..1e112e2b405b 100644
  	if (!crng_ready() && !(flags & GRND_INSECURE)) {
  		if (flags & GRND_NONBLOCK)
  			return -EAGAIN;
-@@ -1412,6 +1452,12 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
+@@ -1412,6 +1454,12 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
  	return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
  }
  
@@ -822,7 +975,7 @@ index b4da1fb976c1..1e112e2b405b 100644
  static ssize_t write_pool_user(struct iov_iter *iter)
  {
  	u8 block[BLAKE2S_BLOCK_SIZE];
-@@ -1552,7 +1598,58 @@ static int random_fasync(int fd, struct file *filp, int on)
+@@ -1552,7 +1600,58 @@ static int random_fasync(int fd, struct file *filp, int on)
  	return fasync_helper(fd, filp, on, &fasync);
  }
  
@@ -881,7 +1034,7 @@ index b4da1fb976c1..1e112e2b405b 100644
  	.read_iter = random_read_iter,
  	.write_iter = random_write_iter,
  	.poll = random_poll,
-@@ -1565,6 +1662,7 @@ const struct file_operations random_fops = {
+@@ -1565,6 +1664,7 @@ const struct file_operations random_fops = {
  };
  
  const struct file_operations urandom_fops = {
@@ -889,7 +1042,7 @@ index b4da1fb976c1..1e112e2b405b 100644
  	.read_iter = urandom_read_iter,
  	.write_iter = random_write_iter,
  	.unlocked_ioctl = random_ioctl,
-@@ -1575,6 +1673,32 @@ const struct file_operations urandom_fops = {
+@@ -1575,6 +1675,32 @@ const struct file_operations urandom_fops = {
  	.splice_write = iter_file_splice_write,
  };
  
@@ -1139,166 +1292,2391 @@ index 000000000000..de0a3714a5d4
 @@ -0,0 +1,38 @@
 +/* Core kernel secure boot support.
 + *
-+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
++ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/efi.h>
++#include <linux/kernel.h>
++#include <linux/printk.h>
++
++/*
++ * Decide what to do when UEFI secure boot mode is enabled.
++ */
++void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
++{
++	if (efi_enabled(EFI_BOOT)) {
++		switch (mode) {
++		case efi_secureboot_mode_disabled:
++			pr_info("Secure boot disabled\n");
++			break;
++		case efi_secureboot_mode_enabled:
++			set_bit(EFI_SECURE_BOOT, &efi.flags);
++			pr_info("Secure boot enabled\n");
++			break;
++		default:
++			pr_warn("Secure boot could not be determined (mode %u)\n",
++				   mode);
++			break;
++		}
++	}
++}
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index a251375db24b..2b5337eaeb6d 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -12,6 +12,7 @@
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/device.h>
++#include <linux/dmi.h>
+ #include <linux/io.h>
+ #include <linux/err.h>
+ #include <linux/fs.h>
+@@ -2547,6 +2548,16 @@ static const struct amba_id etm4_ids[] = {
+ 	{},
+ };
+ 
++static const struct dmi_system_id broken_coresight[] = {
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "HPE"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Apollo 70"),
++		},
++	},
++	{ }	/* terminating entry */
++};
++
+ MODULE_DEVICE_TABLE(amba, etm4_ids);
+ 
+ static struct amba_driver etm4x_amba_driver = {
+@@ -2621,6 +2632,11 @@ static int __init etm4x_init(void)
+ {
+ 	int ret;
+ 
++	if (dmi_check_system(broken_coresight)) {
++		pr_info("ETM4 disabled due to firmware bug\n");
++		return 0;
++	}
++
+ 	ret = etm4_pm_setup();
+ 
+ 	/* etm4_pm_setup() does its own cleanup - exit on error */
+@@ -2647,6 +2663,9 @@ static int __init etm4x_init(void)
+ 
+ static void __exit etm4x_exit(void)
+ {
++	if (dmi_check_system(broken_coresight))
++		return;
++
+ 	amba_driver_unregister(&etm4x_amba_driver);
+ 	platform_driver_unregister(&etm4_platform_driver);
+ 	etm4_pm_clear();
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
+index d1a9e713d3a0..940458370730 100644
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -8,6 +8,7 @@
+ 
+ #include <linux/amba/bus.h>
+ #include <linux/device.h>
++#include <linux/dmi.h>
+ #include <linux/kernel.h>
+ #include <linux/bits.h>
+ #include <linux/bug.h>
+@@ -3136,6 +3137,27 @@ int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids)
+ }
+ EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
+ 
++#ifdef CONFIG_ARM64
++static int __init iommu_quirks(void)
++{
++	const char *vendor, *name;
++
++	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
++	name = dmi_get_system_info(DMI_PRODUCT_NAME);
++
++	if (vendor &&
++	    (strncmp(vendor, "GIGABYTE", 8) == 0 && name &&
++	     (strncmp(name, "R120", 4) == 0 ||
++	      strncmp(name, "R270", 4) == 0))) {
++		pr_warn("Gigabyte %s detected, force iommu passthrough mode", name);
++		iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
++	}
++
++	return 0;
++}
++arch_initcall(iommu_quirks);
++#endif
++
+ /**
+  * iommu_setup_default_domain - Set the default_domain for the group
+  * @group: Group to change
+diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
+index 8f2ba4121586..8592be53bb75 100644
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -287,6 +287,16 @@ config VIDEO_IMX415
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called imx415.
+ 
++config VIDEO_IMX471
++	tristate "Sony IMX471 sensor support"
++	select V4L2_CCI_I2C
++	help
++	  This is a Video4Linux2 sensor driver for the Sony
++	  IMX471 camera.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called imx471.
++
+ config VIDEO_MAX9271_LIB
+ 	tristate
+ 
+@@ -1659,6 +1669,8 @@ endmenu
+ menu "Miscellaneous helper chips"
+ 	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
+ 
++source "drivers/media/i2c/cvs/Kconfig"
++
+ config VIDEO_I2C
+ 	tristate "I2C transport video support"
+ 	depends on VIDEO_DEV && I2C
+diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
+index 90b276a7417a..acbd321fc12e 100644
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_IMX335) += imx335.o
+ obj-$(CONFIG_VIDEO_IMX355) += imx355.o
+ obj-$(CONFIG_VIDEO_IMX412) += imx412.o
+ obj-$(CONFIG_VIDEO_IMX415) += imx415.o
++obj-$(CONFIG_VIDEO_IMX471) += imx471.o
+ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
+ obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
+ obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+@@ -171,3 +172,4 @@ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
+ obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
+ obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+ obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
++obj-$(CONFIG_VIDEO_INTEL_CVS) += cvs/
+diff --git a/drivers/media/i2c/cvs/Kconfig b/drivers/media/i2c/cvs/Kconfig
+new file mode 100644
+index 000000000000..4309d20dd726
+--- /dev/null
++++ b/drivers/media/i2c/cvs/Kconfig
+@@ -0,0 +1,21 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++config VIDEO_INTEL_CVS
++	tristate "Intel CVS CSI-2 bridge support"
++	depends on I2C && ACPI && VIDEO_DEV
++	depends on IPU_BRIDGE || !IPU_BRIDGE
++	select MEDIA_CONTROLLER
++	select VIDEO_V4L2_SUBDEV_API
++	select V4L2_FWNODE
++	help
++	  This adds support for the Intel Computer Vision Sensing (CVS).
++
++	  The driver registers a V4L2 sub-device to arbitrate CSI-2 link
++	  ownership between the host and CVS firmware, and configures the
++	  device for camera sensor streaming.
++
++	  The driver can operate with full I2C transport or in a reduced
++	  platform (GPIO-only) mode when I2C is unavailable.
++
++	  Say Y to build into the kernel, or M to build as a module.
++	  The module will be named intel_cvs. If unsure, say N.
+diff --git a/drivers/media/i2c/cvs/Makefile b/drivers/media/i2c/cvs/Makefile
+new file mode 100644
+index 000000000000..0aeb2c2e3100
+--- /dev/null
++++ b/drivers/media/i2c/cvs/Makefile
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0-only
++intel_cvs-y := core.o v4l2.o
++
++obj-$(CONFIG_VIDEO_INTEL_CVS) += intel_cvs.o
+diff --git a/drivers/media/i2c/cvs/core.c b/drivers/media/i2c/cvs/core.c
+new file mode 100644
+index 000000000000..7486815b16bd
+--- /dev/null
++++ b/drivers/media/i2c/cvs/core.c
+@@ -0,0 +1,1046 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2026 Intel Corporation
++ */
++
++#include <linux/acpi.h>
++#include <linux/cleanup.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/jiffies.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/time64.h>
++#include <linux/workqueue.h>
++
++#include <media/ipu-bridge.h>
++#include <media/ipu6-pci-table.h>
++
++#include "icvs.h"
++
++/* Command timeouts determined experimentally */
++#define CMD_TIMEOUT (5 * HZ)
++#define FW_READY_DELAY_MS 100
++
++#define PCI_DEVICE_ID_INTEL_IPU7		0x645d	/* MTL / LNL */
++#define PCI_DEVICE_ID_INTEL_IPU7P5		0xb05d	/* ARL / PTL */
++#define PCI_DEVICE_ID_INTEL_IPU8		0xd719	/* NVL */
++
++/*
++ * IPU7 PCI device IDs not covered by ipu6_pci_tbl in ipu6-pci-table.h.
++ * Once the IPU6 driver gains support for IPU7, this table can be dropped.
++ */
++static const struct pci_device_id icvs_ipu7_tbl[] = {
++	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7) },
++	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7P5) },
++	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU8) },
++	{ }
++};
++
++static const struct acpi_gpio_params gpio_wake = { 0, 0, false };
++static const struct acpi_gpio_params gpio_rst  = { 1, 0, false };
++static const struct acpi_gpio_params gpio_req  = { 2, 0, false };
++static const struct acpi_gpio_params gpio_resp = { 3, 0, false };
++static const struct acpi_gpio_mapping icvs_acpi_gpios[] = {
++	{ "wake-gpio", &gpio_wake, 1 },
++	{ "rst-gpio",  &gpio_rst,  1 },
++	{ "req-gpio",  &gpio_req,  1 },
++	{ "resp-gpio", &gpio_resp, 1 },
++	{ }
++};
++
++static const struct acpi_gpio_params lgpio_req  = { 0, 0, false };
++static const struct acpi_gpio_params lgpio_resp = { 1, 0, false };
++static const struct acpi_gpio_mapping icvs_acpi_lgpios[] = {
++	{ "req-gpio",  &lgpio_req,  1 },
++	{ "resp-gpio", &lgpio_resp, 1 },
++	{ }
++};
++
++/* Device quirk table */
++static const struct icvs_device_quirk cvs_quirk_table[] = {
++	{ 0x2ac1, 0x20d0, ICVS_NO_MIPI_CONFIG |
++			  ICVS_NO_CAPS |
++			  ICVS_NO_FW_UPDATE
++	},	/* Lattice NX33 */
++	{ 0x06CB, 0x0701, ICVS_SKIP_FW_RESET |
++			  ICVS_HOST_SENSOR_PWR_CTRL |
++			  ICVS_HOST_PRIV_CTRL |
++			  ICVS_FW_BUF_SIZE_256 |
++			  ICVS_FW_HEADER_SIZE_256
++	},	/* Synaptics SVP7xxx */
++	{ }
++};
++
++/**
++ * cvs_set_quirks - Match device VID/PID and set quirks
++ * @ctx: CVS device context
++ * @vid: Vendor ID
++ * @pid: Product ID
++ *
++ * Searches the quirk table for a matching VID/PID and populates ctx->quirks
++ * with the corresponding quirk flags.
++ * If no match is found, quirks is set to 0.
++ */
++static void cvs_set_quirks(struct icvs *ctx, u16 vid, u16 pid)
++{
++	ctx->quirks = 0;
++
++	for (unsigned int i = 0; i < ARRAY_SIZE(cvs_quirk_table); i++) {
++		if (cvs_quirk_table[i].vid == vid &&
++		    cvs_quirk_table[i].pid == pid) {
++			ctx->quirks = cvs_quirk_table[i].quirks;
++			dev_info(cvs_dev(ctx),
++				 "Quirks: 0x%lx (VID:0x%04x PID:0x%04x)\n",
++				 ctx->quirks, vid, pid);
++			return;
++		}
++	}
++
++	dev_info(cvs_dev(ctx),
++		 "No quirks for device (VID:0x%04x PID:0x%04x)\n", vid, pid);
++}
++
++/* I2C transport helpers */
++
++/**
++ * cvs_read_i2c - Issue a read-type command and fetch device response
++ * @ctx: CVS device context
++ * @cmd_id: Command identifier (big endian)
++ * @resp: Destination buffer for response payload
++ * @size: Size of payload to read into @resp (without prefix)
++ *
++ * Sends @cmd_id and reads back the response in a single I2C transaction.
++ * When the device prepends a 4-byte protocol prefix, the combined
++ * prefix+payload is read into a temporary buffer and only the payload is
++ * copied to @resp, avoiding any dependency on the layout of the caller's
++ * buffer.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_read_i2c(struct icvs *ctx, __be16 cmd_id, void *resp,
++			size_t size)
++{
++	size_t prefix_size = ctx->prefix ? sizeof(u32) : 0;
++	size_t read_size = size + prefix_size;
++	struct i2c_client *i2c = ctx->i2c_client;
++	u8 *buf __free(kfree) = NULL;
++	int cnt;
++
++	if (!resp || !size)
++		return -EINVAL;
++
++	cnt = i2c_master_send(i2c, (const char *)&cmd_id, sizeof(cmd_id));
++	if (cnt != sizeof(cmd_id))
++		return cnt < 0 ? cnt : -EIO;
++
++	buf = kmalloc(read_size, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++
++	cnt = i2c_master_recv(i2c, buf, read_size);
++	if (cnt != read_size) {
++		dev_dbg(cvs_dev(ctx), "recv cmd 0x%04x short read (%d/%zu)\n",
++			be16_to_cpu(cmd_id), cnt, read_size);
++		return cnt < 0 ? cnt : -EIO;
++	}
++
++	memcpy(resp, buf + prefix_size, size);
++
++	return 0;
++}
++
++/**
++ * cvs_write_i2c - Write a raw command buffer to the device over I2C
++ * @ctx: CVS device context
++ * @data: Buffer containing command + payload
++ * @size: Total bytes to write
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_write_i2c(struct icvs *ctx, const void *data, int size)
++{
++	struct i2c_client *i2c = ctx->i2c_client;
++	int cnt;
++
++	if (size < 0 || !data)
++		return -EINVAL;
++
++	cnt = i2c_master_send(i2c, data, size);
++	if (cnt != size) {
++		dev_dbg(cvs_dev(ctx), "send short (%d/%d)\n", cnt, size);
++		return cnt < 0 ? cnt : -EIO;
++	}
++
++	return 0;
++}
++
++/**
++ * cvs_checksum - Simple additive checksum helper
++ * @data: 32-bit aligned data buffer
++ * @len: Length in bytes (multiple of 4)
++ *
++ * Return: 32-bit additive checksum of the dwords in @data.
++ */
++static u32 cvs_checksum(const void *data, size_t len)
++{
++	const u32 *words = data;
++	u32 csum = 0;
++
++	if (WARN_ON_ONCE(len % sizeof(u32)))
++		return 0;
++
++	for (unsigned int i = 0; i < len / sizeof(u32); i++)
++		csum += words[i];
++
++	return csum;
++}
++
++/**
++ * cvs_schedule_and_wait - Schedule polling work then wait for completion
++ * @ctx: CVS device context
++ * @work_delay_ms: Delay in milliseconds before polling work executes
++ * @wait_jiffies: Timeout (jiffies) to wait for cmd completion
++ *
++ * Queues ctx->work to run after @work_delay_ms and then waits up to
++ * @wait_jiffies for ctx->cmd_completion.
++ *
++ * Return: 0 on success, -ETIMEDOUT on timeout, negative errno on error.
++ */
++static int cvs_schedule_and_wait(struct icvs *ctx, unsigned int work_delay_ms,
++				 unsigned long wait_jiffies)
++{
++	int ret;
++
++	schedule_delayed_work(&ctx->work, msecs_to_jiffies(work_delay_ms));
++	ret = wait_for_completion_killable_timeout(&ctx->cmd_completion,
++						   wait_jiffies);
++	if (ret < 0)
++		return ret;
++	if (!ret)
++		return -ETIMEDOUT;
++
++	return 0;
++}
++
++/**
++ * cvs_wait_wake_or_sleep - Wait for wake IRQ or sleep fallback
++ * @ctx: CVS device context
++ * @timeout_jiffies: Timeout (jiffies) for wake event on full-cap devices
++ * @sleep_ms: Milliseconds to sleep on light-cap devices
++ *
++ * For full capability devices (ICVS_FULLCAP) waits interruptibly on
++ * ctx->hostwake_event until ctx->hostwake_event_arg becomes true or
++ * @timeout_jiffies elapses. The flag is cleared after the wait.
++ * For light capability devices performs a blocking msleep(@sleep_ms).
++ *
++ * Return codes normalized for caller switch handling:
++ *	<0		: error / interrupted
++ *	-ETIMEDOUT	: timeout (wake event not observed)
++ *	0		: success (wake observed OR light-cap sleep elapsed)
++ *
++ * Return: negative errno, -ETIMEDOUT on timeout, 0 on success.
++ */
++static int cvs_wait_wake_or_sleep(struct icvs *ctx,
++				  unsigned long timeout_jiffies,
++				  unsigned int sleep_ms)
++{
++	int ret;
++
++	if (ctx->res == ICVS_FULLCAP) {
++		ret = wait_event_interruptible_timeout(ctx->hostwake_event,
++						       ctx->hostwake_event_arg,
++						       timeout_jiffies);
++		ctx->hostwake_event_arg = false;
++		if (ret < 0)
++			return ret;
++		if (!ret)
++			return -ETIMEDOUT;
++		return 0;
++	}
++
++	msleep(sleep_ms);
++
++	return 0; /* treat sleep path as success */
++}
++
++/**
++ * cvs_config_mipi - Send a HOST_SET_MIPI_CONFIG command
++ * @ctx: CVS device context
++ * @c: Command container with conf field populated
++ * @len: Length of original command structure (unused except for symmetry)
++ *
++ * Packages @c->param.conf into a cvs_mipi_data_packet including size and
++ * checksum, then writes it to the device.
++ *
++ * Firmware note: the CVS firmware expects the MIPI configuration to be
++ * sent as a single transaction, including all relevant parameters and checksum.
++ *
++ * Return: 0 on success, NO_MIPI_CONFIG or negative errno from I2C write.
++ */
++static int cvs_config_mipi(struct icvs *ctx, struct icvs_cmd *c, size_t len)
++{
++	struct icvs_mipi_data_packet pkt = {
++		.cmd_id = c->cmd_id,
++		.size = sizeof(c->param.conf),
++		.crc = cvs_checksum(&c->param.conf, sizeof(c->param.conf)),
++		.conf = c->param.conf,
++	};
++
++	if (ctx->quirks & ICVS_NO_MIPI_CONFIG)
++		return 0;
++
++	return cvs_write_i2c(ctx, &pkt, sizeof(pkt));
++}
++
++/**
++ * cvs_get_device_state - Query current device state bitfield
++ * @ctx: CVS device context
++ * @state: Returned state value
++ *
++ * Issues GET_DEV_STATE and fills @state.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_get_device_state(struct icvs *ctx, u8 *state)
++{
++	struct icvs_resp n = {
++		.cmd_id = cpu_to_be16(ICVS_GET_DEV_STATE),
++	};
++	int ret;
++
++	ret = cvs_read_i2c(ctx, n.cmd_id, &n.resp.state, sizeof(n.resp.state));
++	if (ret)
++		return ret;
++
++	*state = n.resp.state;
++
++	return 0;
++}
++
++/**
++ * cvs_get_device_caps - Read protocol capabilities
++ * @ctx: CVS device context
++ * @caps: Capability structure to populate
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_get_device_caps(struct icvs *ctx,
++			       struct icvs_dev_capabilities *caps)
++{
++	struct icvs_resp n = {
++		.cmd_id = cpu_to_be16(ICVS_GET_DEV_CAPABILITY),
++	};
++	int ret;
++
++	if (ctx->quirks & ICVS_NO_CAPS)
++		return 0;
++
++	ret = cvs_read_i2c(ctx, n.cmd_id, &n.resp.cap, sizeof(n.resp.cap));
++	if (ret)
++		return ret;
++
++	*caps = n.resp.cap;
++
++	return 0;
++}
++
++/**
++ * cvs_hw_init - Probe device for prefix support and apply quirks
++ * @ctx: CVS device context
++ *
++ * Sends GET_DEV_VID_PID and probes for a 32-bit prefix.
++ * If it matches ICVS_PREFIX_VAL, sets ctx->prefix for subsequent reads.
++ * Then reads VID/PID and applies matching quirks.
++ * GET_DEV_VID_PID is supported by all protocol versions.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_hw_init(struct icvs *ctx)
++{
++	struct icvs_resp n = { };
++	__be16 cmd = cpu_to_be16(ICVS_GET_DEV_VID_PID);
++	u32 resp;
++	int ret;
++
++	/*
++	 * Clear prefix so cvs_read_i2c always reads exactly sizeof(u32) bytes
++	 * here, regardless of any value left over from a previous call (e.g.
++	 * on resume).
++	 */
++	ctx->prefix = false;
++	ret = cvs_read_i2c(ctx, cmd, &resp, sizeof(resp));
++	if (ret)
++		return ret;
++
++	ctx->prefix = resp == ICVS_PREFIX_VAL;
++
++	/* Now read VID/PID to apply quirks */
++	ret = cvs_read_i2c(ctx, cmd,
++			   &n.resp.vid_pid, sizeof(n.resp.vid_pid));
++	if (ret)
++		return ret;
++
++	cvs_set_quirks(ctx, n.resp.vid_pid.v_id, n.resp.vid_pid.p_id);
++
++	return 0;
++}
++
++/**
++ * cvs_irq_handler - Wake IRQ handler (full capability devices)
++ * @irq: IRQ number
++ * @dev_id: Device context pointer
++ *
++ * Sets a waitqueue flag and wakes up sleeping waiters.
++ *
++ * Return: IRQ_HANDLED always.
++ */
++static irqreturn_t cvs_irq_handler(int irq, void *dev_id)
++{
++	struct icvs *ctx = dev_id;
++
++	ctx->hostwake_event_arg = true;
++	wake_up_interruptible(&ctx->hostwake_event);
++
++	return IRQ_HANDLED;
++}
++
++/**
++ * cvs_reset - Toggle reset GPIO for full capability devices
++ * @ctx: CVS device context
++ *
++ * Drives reset low briefly then high if device resources indicate full
++ * capability. Light devices have no reset line.
++ */
++static void cvs_reset(struct icvs *ctx)
++{
++	if (ctx->quirks & ICVS_SKIP_FW_RESET)
++		return;
++
++	if (ctx->res == ICVS_FULLCAP) {
++		gpiod_set_value(ctx->rst, 0);
++		fsleep(2000);
++		gpiod_set_value(ctx->rst, 1);
++	}
++}
++
++/**
++ * cvs_recv - Delayed work handler polling for command completion
++ * @work: Embedded delayed_work member
++ *
++ * Re-reads device state; if device_busy remains set, re-schedules itself.
++ * Otherwise stores state into wq_resp and completes the command.
++ */
++static void cvs_recv(struct work_struct *work)
++{
++	struct icvs *ctx = container_of(work, struct icvs, work.work);
++	u8 state = 0;
++	int ret;
++
++	ret = cvs_get_device_state(ctx, &state);
++	if (ret < 0) {
++		dev_dbg(cvs_dev(ctx), "state read failed: %d\n", ret);
++		return;
++	}
++
++	if (state & ICVS_DEV_STATE_BUSY) {
++		dev_dbg(cvs_dev(ctx), "device busy, reschedule\n");
++		schedule_delayed_work(&ctx->work,
++				      msecs_to_jiffies(FW_READY_DELAY_MS));
++		return;
++	}
++
++	ctx->wq_resp.resp.state = state;
++	complete(&ctx->cmd_completion);
++}
++
++/**
++ * cvs_send - Common command submission path
++ * @ctx: CVS device context
++ * @cmd: Command buffer (icvs_cmd) with cmd_id and param populated
++ * @len: Buffer length
++ *
++ * Dispatches a set of supported commands:
++ * - ICVS_SET_DEV_HOST_ID,
++ * - ICVS_HOST_SENSOR_OWNER,
++ * - ICVS_HOST_SET_MIPI_CONFIG
++ * - ICVS_FW_LOADER_*
++ *
++ * For I2C based commands it sets big-endian cmd ids, writes to the device
++ * and waits (via delayed work) for completion or timeout.
++ * GPIO based ownership toggles are handled locally.
++ *
++ * Caller must hold ctx->lock when invoking this function and check for i2c
++ * bus availability.
++ *
++ * Return: 0 on success, negative errno, -EINVAL for unsupported command
++ * or status from device in ctx->wq_resp.
++ */
++int cvs_send(struct icvs *ctx, struct icvs_cmd *cmd, size_t len)
++{
++	int ret, status = 0;
++
++	lockdep_assert_held(&ctx->lock);
++
++	dev_dbg(cvs_dev(ctx), "send cmd = 0x%04x", be16_to_cpu(cmd->cmd_id));
++
++	reinit_completion(&ctx->cmd_completion);
++
++	switch (be16_to_cpu(cmd->cmd_id)) {
++	case ICVS_SET_DEV_HOST_ID:
++		cmd->cmd_id = cpu_to_be16(ICVS_SET_DEV_HOST_ID);
++		ret = cvs_write_i2c(ctx, cmd, len);
++		if (ret < 0)
++			break;
++
++		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
++					    CMD_TIMEOUT);
++		if (ret < 0)
++			break;
++
++		status = ctx->wq_resp.resp.state &
++			  ICVS_DEV_STATE_ERROR ? -EINVAL : 0;
++		break;
++	case ICVS_HOST_SENSOR_OWNER:
++		gpiod_set_value_cansleep(ctx->req, cmd->param.param);
++		fsleep(FW_READY_DELAY_MS * USEC_PER_MSEC);
++		ret = gpiod_get_value_cansleep(ctx->resp);
++		status = cmd->param.param == ret ? 0 : -EINVAL;
++		ret = 0; /* success */
++		break;
++	case ICVS_HOST_SET_MIPI_CONFIG:
++		cmd->cmd_id = cpu_to_be16(ICVS_HOST_SET_MIPI_CONFIG);
++		ret = cvs_config_mipi(ctx, cmd, len);
++		if (ret < 0)
++			break;
++
++		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
++					    CMD_TIMEOUT);
++		status = (ctx->wq_resp.resp.state &
++			  ICVS_DEV_STATE_ERROR) ? -EINVAL : 0;
++		break;
++	case ICVS_FW_LOADER_START:
++		cmd->cmd_id = cpu_to_be16(ICVS_FW_LOADER_START);
++		ret = cvs_write_i2c(ctx, cmd, len);
++		if (ret < 0)
++			break;
++
++		ret = cvs_wait_wake_or_sleep(ctx, CMD_TIMEOUT,
++					     FW_READY_DELAY_MS);
++		if (ret)
++			break;
++
++		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
++					    CMD_TIMEOUT);
++		status = (ctx->wq_resp.resp.state &
++			  ICVS_DEV_STATE_DOWNLOAD) ? 0 : -EINVAL;
++		break;
++	case ICVS_FW_LOADER_DATA:
++		/* Quirk for older protocols */
++		if (ctx->caps.protocol_version_major >= 2 &&
++		    ctx->caps.protocol_version_minor >= 2) {
++			cmd->cmd_id = cpu_to_be16(ICVS_FW_LOADER_DATA);
++			ret = cvs_write_i2c(ctx, cmd, len);
++		} else {
++			ret = cvs_write_i2c(ctx, &cmd->param,
++					    len - sizeof(cmd->cmd_id));
++		}
++
++		if (ret < 0)
++			return ret;
++
++		ret = cvs_wait_wake_or_sleep(ctx, FW_READY_DELAY_MS,
++					     FW_READY_DELAY_MS);
++		if (ret)
++			break;
++
++		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
++					    CMD_TIMEOUT);
++		status = ctx->wq_resp.resp.state &
++			  ICVS_DEV_STATE_ERROR ? -EINVAL : 0;
++		break;
++	case ICVS_FW_LOADER_END:
++		cmd->cmd_id = cpu_to_be16(ICVS_FW_LOADER_END);
++		ret = cvs_write_i2c(ctx, cmd, len);
++		if (ret < 0)
++			break;
++
++		ret = cvs_wait_wake_or_sleep(ctx, CMD_TIMEOUT,
++					     FW_READY_DELAY_MS);
++		if (ret)
++			break;
++
++		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
++					    CMD_TIMEOUT);
++		status = !(ctx->wq_resp.resp.state &
++			   ICVS_DEV_STATE_DOWNLOAD) ? 0 : -EINVAL;
++		break;
++	default:
++		ret = -EINVAL;
++		break;
++	}
++
++	if (ret < 0)
++		return ret;
++
++	return ctx->wq_resp.status = status;
++}
++
++/**
++ * cvs_set_link_owner - Switch CSI-2 link ownership between host and device
++ * @ctx: CVS device context
++ * @owner: Desired owner (ICVS_CSI_LINK_HOST or ICVS_CSI_LINK_CVS)
++ *
++ * Called from runtime PM callbacks to claim or release the CSI-2 link.
++ * Also callable directly for error recovery paths.
++ *
++ * Return: 0 on success or negative errno.
++ */
++int cvs_set_link_owner(struct icvs *ctx, enum icvs_csi_link_owner owner)
++{
++	struct icvs_cmd cmd = {
++		.cmd_id = cpu_to_be16(ICVS_HOST_SENSOR_OWNER),
++		.param.param = owner,
++	};
++	size_t cmd_size = sizeof(cmd.cmd_id) + sizeof(cmd.param.param);
++
++	guard(mutex)(&ctx->lock);
++	return cvs_send(ctx, &cmd, cmd_size);
++}
++
++/**
++ * cvs_configure_dev_caps - Configure device capability ownership bits
++ * @ctx: CVS device context
++ *
++ * Tells the CVS device which of its features (privacy LED, RGB camera
++ * power-up, vision sensing) are controlled by the host, then sends
++ * SET_DEV_HOST_ID.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_configure_dev_caps(struct icvs *ctx)
++{
++	struct icvs_cmd cmd = { .cmd_id = cpu_to_be16(ICVS_SET_DEV_HOST_ID) };
++	size_t sz = sizeof(cmd.cmd_id) + sizeof(cmd.param.host_id);
++
++	if (ctx->quirks & ICVS_NO_CAPS)
++		return 0;
++
++	if (ctx->quirks & ICVS_HOST_VISION_SENSING)
++		cmd.param.host_id |= ICVS_HOST_ID_VISION_SENSING;
++	if (ctx->quirks & ICVS_HOST_PRIV_CTRL)
++		cmd.param.host_id |= ICVS_HOST_ID_PRIVACY_LED;
++	if (ctx->quirks & ICVS_HOST_SENSOR_PWR_CTRL)
++		cmd.param.host_id |= ICVS_HOST_ID_RGBCAMERA_PWRUP;
++
++	guard(mutex)(&ctx->lock);
++	return cvs_send(ctx, &cmd, sz);
++}
++
++/**
++ * cvs_core_probe - Shared probe path for I2C & platform instantiation
++ * @dev: Parent device
++ * @i2c: I2C client (NULL for platform devices)
++ *
++ * Discovers IPU, parses ACPI resources, sets up GPIOs/IRQs, initializes
++ * sub-device (CSI) and host identifier, and exposes sysfs firmware interface.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_core_probe(struct device *dev, struct i2c_client *i2c)
++{
++	struct pci_dev *ipu = NULL;
++	struct icvs *ctx;
++	int ret;
++
++	/* Locate IPU device */
++	for (unsigned int i = 0; !ipu && ipu6_pci_tbl[i].vendor; i++)
++		ipu = pci_get_device(ipu6_pci_tbl[i].vendor,
++				     ipu6_pci_tbl[i].device, NULL);
++	for (unsigned int i = 0; !ipu && icvs_ipu7_tbl[i].vendor; i++)
++		ipu = pci_get_device(icvs_ipu7_tbl[i].vendor,
++				     icvs_ipu7_tbl[i].device, NULL);
++	if (!ipu)
++		return -ENODEV;
++
++	ret = ipu_bridge_init(&ipu->dev, ipu_bridge_parse_ssdb);
++	if (ret < 0)
++		goto err_put_ipu;
++
++	if (!dev_fwnode(dev)) {
++		ret = -ENXIO;
++		goto err_put_ipu;
++	}
++
++	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
++	if (!ctx) {
++		ret = -ENOMEM;
++		goto err_put_ipu;
++	}
++
++	ctx->i2c_client = i2c;
++
++	ret = gpiod_count(dev, NULL);
++	switch (ret) {
++	case ICVS_GPIO_SYNC:
++		ctx->res = ICVS_LIGHTCAP;
++		break;
++	case ICVS_GPIO_ASYNC:
++		ctx->res = ICVS_FULLCAP;
++		break;
++	default:
++		dev_err(dev, "unexpected GPIO count %d\n", ret);
++		ret = -EINVAL;
++		goto err_put_ipu;
++	}
++
++	ret = devm_acpi_dev_add_driver_gpios(dev,
++					     ctx->res == ICVS_FULLCAP ?
++					     icvs_acpi_gpios :
++					     icvs_acpi_lgpios);
++	if (ret) {
++		dev_err_probe(dev, ret, "failed to add ACPI GPIOs\n");
++		goto err_put_ipu;
++	}
++
++	ctx->req = devm_gpiod_get(dev, "req", GPIOD_OUT_HIGH);
++	if (IS_ERR(ctx->req)) {
++		ret = dev_err_probe(dev, PTR_ERR(ctx->req),
++				    "failed to get req GPIO\n");
++		goto err_put_ipu;
++	}
++
++	ctx->resp = devm_gpiod_get(dev, "resp", GPIOD_IN);
++	if (IS_ERR(ctx->resp)) {
++		ret = dev_err_probe(dev, PTR_ERR(ctx->resp),
++				    "failed to get resp GPIO\n");
++		goto err_put_ipu;
++	}
++
++	if (ctx->res == ICVS_FULLCAP) {
++		struct gpio_desc *wake;
++
++		ctx->rst = devm_gpiod_get(dev, "rst", GPIOD_OUT_HIGH);
++		if (IS_ERR(ctx->rst)) {
++			ret = dev_err_probe(dev, PTR_ERR(ctx->rst),
++					    "failed to get rst GPIO\n");
++			goto err_put_ipu;
++		}
++
++		wake = devm_gpiod_get(dev, "wake", GPIOD_IN);
++		if (IS_ERR(wake)) {
++			ret = dev_err_probe(dev, PTR_ERR(wake),
++					    "failed to get wake GPIO\n");
++			goto err_put_ipu;
++		}
++
++		ctx->irq = gpiod_to_irq(wake);
++		if (ctx->irq < 0) {
++			ret = dev_err_probe(dev, ctx->irq,
++					    "failed to get wake IRQ\n");
++			goto err_put_ipu;
++		}
++
++		ret = devm_request_threaded_irq(dev, ctx->irq, NULL,
++						cvs_irq_handler,
++						IRQF_ONESHOT | IRQF_NO_SUSPEND,
++						"cvs_wake", ctx);
++		if (ret) {
++			dev_err_probe(dev, ret, "failed to request IRQ\n");
++			goto err_put_ipu;
++		}
++	}
++
++	ret = devm_mutex_init(dev, &ctx->lock);
++	if (ret)
++		goto err_put_ipu;
++
++	init_completion(&ctx->cmd_completion);
++	init_waitqueue_head(&ctx->hostwake_event);
++	INIT_DELAYED_WORK(&ctx->work, cvs_recv);
++
++	if (i2c) {
++		ret = cvs_hw_init(ctx);
++		if (ret) {
++			dev_err(dev, "HW init failed (%d)\n", ret);
++			/*
++			 * Fallback to GPIO-only mode.
++			 * Some BIOS show the device on the I2C bus, however,
++			 * the device is not accessible via I2C.
++			 */
++			ctx->i2c_client = NULL;
++			goto fail_i2c;
++		}
++
++		ret = cvs_get_device_caps(ctx, &ctx->caps);
++		if (ret) {
++			dev_err_probe(dev, ret, "get caps failed\n");
++			goto err_put_ipu;
++		}
++
++		ret = cvs_configure_dev_caps(ctx);
++		if (ret) {
++			dev_err_probe(dev, ret,
++				      "configure dev caps failed\n");
++			goto err_put_ipu;
++		}
++	}
++
++fail_i2c:
++	ret = cvs_csi_init(ctx, dev, i2c);
++	if (ret) {
++		dev_err_probe(dev, ret, "CSI init failed\n");
++		goto err_put_ipu;
++	}
++
++	dev_set_drvdata(dev, ctx);
++	pm_runtime_set_autosuspend_delay(dev, 1000);
++	pm_runtime_use_autosuspend(dev);
++	pm_runtime_enable(dev);
++	pm_runtime_idle(dev);
++
++	/*
++	 * Create a PM runtime device link with IPU as consumer and CVS as
++	 * supplier. When the IPU runtime-resumes to start streaming, the PM
++	 * framework automatically resumes CVS first, triggering
++	 * cvs_runtime_resume() which hands CSI-2 link ownership to the host.
++	 */
++	ctx->ipu_link = device_link_add(&ipu->dev, dev,
++					DL_FLAG_PM_RUNTIME |
++					DL_FLAG_RPM_ACTIVE |
++					DL_FLAG_STATELESS);
++	if (!ctx->ipu_link) {
++		dev_err(dev, "IPU device link failed\n");
++		ret = -ENODEV;
++		goto err_csi_remove;
++	}
++
++	if (has_acpi_companion(dev))
++		acpi_dev_clear_dependencies(ACPI_COMPANION(dev));
++
++	put_device(&ipu->dev);
++
++	return 0;
++
++err_csi_remove:
++	if (ctx->ipu_link)
++		device_link_del(ctx->ipu_link);
++	cvs_csi_remove(ctx);
++	pm_runtime_dont_use_autosuspend(dev);
++	pm_runtime_disable(dev);
++	pm_runtime_set_suspended(dev);
++
++err_put_ipu:
++	put_device(&ipu->dev);
++
++	return ret;
++}
++
++/**
++ * cvs_probe - I2C driver probe entry
++ * @i2c: I2C client
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_probe(struct i2c_client *i2c)
++{
++	return cvs_core_probe(&i2c->dev, i2c);
++}
++
++/**
++ * cvs_core_remove - Shared remove logic
++ * @dev: Device
++ */
++static void cvs_core_remove(struct device *dev)
++{
++	struct icvs *ctx = dev_get_drvdata(dev);
++
++	cancel_delayed_work_sync(&ctx->work);
++	cvs_csi_remove(ctx);
++
++	if (ctx->ipu_link)
++		device_link_del(ctx->ipu_link);
++
++	pm_runtime_put_noidle(dev);
++	pm_runtime_disable(dev);
++	pm_runtime_set_suspended(dev);
++
++	cvs_reset(ctx);
++}
++
++/**
++ * cvs_remove - I2C driver remove
++ * @client: I2C client
++ */
++static void cvs_remove(struct i2c_client *client)
++{
++	cvs_core_remove(&client->dev);
++}
++
++/**
++ * cvs_suspend - System suspend callback
++ * @dev: Device
++ *
++ * Return: 0.
++ */
++static int __maybe_unused cvs_suspend(struct device *dev)
++{
++	struct icvs *ctx = dev_get_drvdata(dev);
++
++	cancel_delayed_work_sync(&ctx->work);
++
++	return 0;
++}
++
++/**
++ * cvs_resume - System resume callback
++ * @dev: Device
++ *
++ * Re-validates I2C link prefix and re-sends host id if transport available.
++ *
++ * Return: 0 on success or negative errno if I2C check fails.
++ */
++static int __maybe_unused cvs_resume(struct device *dev)
++{
++	struct icvs *ctx = dev_get_drvdata(dev);
++	int ret;
++
++	if (ctx->i2c_client) {
++		ret = cvs_hw_init(ctx);
++		if (ret)
++			return ret;
++		return cvs_configure_dev_caps(ctx);
++	}
++
++	return 0;
++}
++
++/**
++ * cvs_runtime_resume - Runtime PM resume: claim CSI-2 link ownership
++ * @dev: Device
++ *
++ * Triggered automatically when the IPU (consumer) runtime-resumes, because
++ * a DL_FLAG_PM_RUNTIME device link makes CVS the supplier. Transfers CSI-2
++ * link ownership to the host so the IPU can start receiving sensor frames.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int __maybe_unused cvs_runtime_resume(struct device *dev)
++{
++	struct icvs *ctx = dev_get_drvdata(dev);
++
++	return cvs_set_link_owner(ctx, ICVS_CSI_LINK_HOST);
++}
++
++/**
++ * cvs_runtime_suspend - Runtime PM suspend: release CSI-2 link ownership
++ * @dev: Device
++ *
++ * Called when the streaming reference is dropped by cvs_csi_disable_streams
++ * via pm_runtime_put_autosuspend. Returns CSI-2 link ownership to CVS firmware.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int __maybe_unused cvs_runtime_suspend(struct device *dev)
++{
++	struct icvs *ctx = dev_get_drvdata(dev);
++
++	return cvs_set_link_owner(ctx, ICVS_CSI_LINK_CVS);
++}
++
++static const struct dev_pm_ops __maybe_unused cvs_pm_ops = {
++	SET_SYSTEM_SLEEP_PM_OPS(cvs_suspend, cvs_resume)
++	SET_RUNTIME_PM_OPS(cvs_runtime_suspend, cvs_runtime_resume, NULL)
++};
++
++static const struct acpi_device_id intel_cvs_acpi_match[] = {
++	{ "INTC10DE" }, /* LNL */
++	{ "INTC10E0" }, /* ARL */
++	{ "INTC10E1" }, /* PTL */
++	{ "INTC10FA" }, /* NVL */
++	{ }
++};
++MODULE_DEVICE_TABLE(acpi, intel_cvs_acpi_match);
++
++static struct i2c_driver cvs_driver = {
++	.driver = {
++		.name = "intel_cvs",
++		.acpi_match_table = intel_cvs_acpi_match,
++		.pm = pm_ptr(&cvs_pm_ops),
++	},
++	.probe = cvs_probe,
++	.remove = cvs_remove,
++};
++
++static int cvs_platform_probe(struct platform_device *pdev)
++{
++	return cvs_core_probe(&pdev->dev, NULL);
++}
++
++static void cvs_platform_remove(struct platform_device *pdev)
++{
++	cvs_core_remove(&pdev->dev);
++}
++
++/*
++ * Platform driver structure.
++ *
++ * Some platforms may instantiate the CVS device as a platform device
++ * without I2C support. This driver binding allows such platforms to use the
++ * CVS core functionality (GPIOs, CSI sub-device) without I2C.
++ */
++static struct platform_driver cvs_platform_driver = {
++	.driver = {
++		.name = "cvs_platform",
++		.acpi_match_table = intel_cvs_acpi_match,
++		.pm = pm_ptr(&cvs_pm_ops),
++	},
++	.probe = cvs_platform_probe,
++	.remove = cvs_platform_remove,
++};
++
++/**
++ * cvs_init - Module init registering I2C and platform drivers
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int __init cvs_init(void)
++{
++	int ret;
++
++	ret = i2c_add_driver(&cvs_driver);
++	if (ret)
++		return ret;
++
++	ret = platform_driver_register(&cvs_platform_driver);
++	if (ret) {
++		i2c_del_driver(&cvs_driver);
++		return ret;
++	}
++
++	return 0;
++}
++
++/**
++ * cvs_exit - Module exit unregistering drivers
++ */
++static void __exit cvs_exit(void)
++{
++	platform_driver_unregister(&cvs_platform_driver);
++	i2c_del_driver(&cvs_driver);
++}
++module_init(cvs_init);
++module_exit(cvs_exit);
++
++MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
++MODULE_AUTHOR("Miguel Vadillo <miguel.vadillo@intel.com>");
++MODULE_DESCRIPTION("Intel Vision Sensing Controller driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/cvs/icvs.h b/drivers/media/i2c/cvs/icvs.h
+new file mode 100644
+index 000000000000..17beb0920dd2
+--- /dev/null
++++ b/drivers/media/i2c/cvs/icvs.h
+@@ -0,0 +1,493 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (c) 2026 Intel Corporation
++ */
++
++#ifndef _ICVS_H
++#define _ICVS_H
++
++#include <linux/bits.h>
++#include <linux/completion.h>
++#include <linux/mutex.h>
++#include <linux/workqueue.h>
++#include <linux/types.h>
++#include <linux/wait.h>
++
++#include <media/media-entity.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-subdev.h>
++
++/*
++ * PCI device IDs for all IPU generations that co-exist with the CVS bridge.
++ * IPU7 (0x645d) is shared by MTL and LNL; IPU7P5 (0xb05d) is shared by
++ * ARL and PTL. These are not yet in the shared ipu6-pci-table so they are
++ * listed here alongside the IPU6 family for probe-time IPU discovery.
++ */
++struct gpio_desc;
++struct i2c_client;
++
++/*
++ * GPIO resource counts (ACPI enumerated).
++ *
++ * 4-GPIO configuration has a wake IRQ and supports asynchronous messaging.
++ * 2-GPIO configuration has no IRQ, so communication is synchronous only.
++ */
++#define ICVS_GPIO_ASYNC	4
++#define ICVS_GPIO_SYNC	2
++
++/* Firmware response prefix (optional, for protocol revision 2.x or newer) */
++#define ICVS_PREFIX_VAL	0xCAFEB0BA
++
++/*
++ * CSI bridge sub-device definitions
++ */
++/**
++ * enum icvs_csi_cmd_id - Low-level CSI bridge command identifiers
++ *
++ * These numeric IDs are part of the legacy CSI-side protocol not mapped
++ * directly to the higher level firmware opcodes in enum icvs_command. Only
++ * a minimal subset is presently issued/handled by the driver. Others are
++ * reserved for future expansion of the CSI bridge feature set.
++ *
++ * @ICVS_CSI_SET_OWNER:     Set CSI sensor ownership between host and CVS
++ * @ICVS_CSI_SET_CONF:      Apply CSI link configuration parameters
++ * @ICVS_CSI_PRIVACY_NOTIF: Notify host of a privacy state transition
++ */
++enum icvs_csi_cmd_id {
++	ICVS_CSI_SET_OWNER = 0,
++	ICVS_CSI_SET_CONF = 2,
++	ICVS_CSI_PRIVACY_NOTIF = 6,
++};
++
++/**
++ * enum icvs_csi_link_owner - CSI-2 link / sensor ownership
++ *
++ * Ownership reflects which endpoint currently controls the attached image
++ * sensor over the CSI-2 link. Transitions may gate streaming or reconfigure
++ * link parameters. The host requests ownership changes via protocol opcodes
++ * and may need to assert GPIO signals on platforms without full capability.
++ *
++ * @ICVS_CSI_LINK_HOST: Host (Linux) owns the sensor and may start streaming
++ * @ICVS_CSI_LINK_CVS:  CVS firmware owns the sensor (host must not stream)
++ */
++enum icvs_csi_link_owner {
++	ICVS_CSI_LINK_HOST,
++	ICVS_CSI_LINK_CVS,
++};
++
++/**
++ * enum icvs_csi_privacy_status - Reported privacy state
++ *
++ * Reflects user privacy (e.g. camera LED assertion and stream gating). The
++ * MAX value is a sentinel used for bounds checking and is not a real state.
++ *
++ * @ICVS_CSI_PRIVACY_OFF: Privacy not asserted (LED off, streaming permitted)
++ * @ICVS_CSI_PRIVACY_ON:  Privacy asserted (LED on and/or stream gated)
++ * @ICVS_CSI_PRIVACY_MAX: Sentinel; not a valid operational value
++ */
++enum icvs_csi_privacy_status {
++	ICVS_CSI_PRIVACY_OFF,
++	ICVS_CSI_PRIVACY_ON,
++	ICVS_CSI_PRIVACY_MAX
++};
++
++/**
++ * enum icvs_csi_pads - Media pads exposed by the CVS sub-device
++ *
++ * The bridge presents a single sink (from the remote sensor) and a single
++ * source (toward the rest of the media graph / consumers). NUM_PADS is used
++ * for sizing arrays and iteration; it is not a real pad index.
++ *
++ * @ICVS_CSI_PAD_SINK:   Sink pad receiving frames from remote sensor
++ * @ICVS_CSI_PAD_SOURCE: Source pad emitting frames to downstream entities
++ * @ICVS_CSI_NUM_PADS:   Count sentinel (array size / iteration bound)
++ */
++enum icvs_csi_pads {
++	ICVS_CSI_PAD_SINK,
++	ICVS_CSI_PAD_SOURCE,
++	ICVS_CSI_NUM_PADS
++};
++
++/*
++ * Core driver structures and functions used by both I2C and platform modes
++ */
++
++/**
++ * DOC: CVS device quirk flags
++ *
++ * These bit flag macros describe per-device behavioral adjustments applied
++ * after VID/PID matching (see cvs_i2c_check() and cvs_apply_quirks()). They
++ * allow the driver to selectively alter logic paths for firmware / hardware
++ * variants without introducing hard-coded conditionals at each call site.
++ *
++ * @ICVS_NO_MIPI_CONFIG: Device firmware performs its own MIPI link setup;
++ *                       skip sending HOST_SET_MIPI_CONFIG.
++ * @ICVS_SKIP_FW_RESET:  Skip issuing a post firmware-update reset sequence.
++ * @ICVS_NO_CAPS:        Device firmware does not support GET_DEV_CAPABILITY;
++ *                       skip capability query and treat caps as unsupported.
++ * @ICVS_FW_BUF_SIZE_256: Firmware expects chunk transfer buffer size of 256
++ *                        bytes (override defaults if they differ).
++ * @ICVS_FW_HEADER_SIZE_256: Firmware header size fixed at 256 bytes offset
++ *                           for start of payload data.
++ * @ICVS_HOST_SENSOR_PWR_CTRL: Host must control sensor power sequencing.
++ * @ICVS_HOST_PRIV_CTRL: Host owns privacy LED gating.
++ * @ICVS_HOST_VISION_SENSING: Host enables vision sensing capability bit
++ * @ICVS_NO_FW_UPDATE:   Device does not support firmware update.
++ */
++#define ICVS_NO_MIPI_CONFIG		BIT(0)
++#define ICVS_SKIP_FW_RESET		BIT(1)
++#define ICVS_NO_CAPS			BIT(2)
++#define ICVS_FW_BUF_SIZE_256		BIT(3)
++#define ICVS_FW_HEADER_SIZE_256		BIT(4)
++#define ICVS_HOST_SENSOR_PWR_CTRL	BIT(5)
++#define ICVS_HOST_PRIV_CTRL		BIT(6)
++#define ICVS_HOST_VISION_SENSING	BIT(7)
++#define ICVS_NO_FW_UPDATE		BIT(8)
++
++/**
++ * struct icvs_device_quirk - Device-specific quirk entry
++ * @vid: Vendor ID
++ * @pid: Product ID
++ * @quirks: Quirk flags for this device
++ */
++struct icvs_device_quirk {
++	u16 vid;
++	u16 pid;
++	unsigned long quirks;
++};
++
++/**
++ * struct icvs_dt_config - Data type configuration for a virtual channel
++ * @pixel_width: Pixel width in pixels
++ * @pixel_height: Pixel height in pixels
++ * @data_type: MIPI CSI-2 data type (RAW10, RAW12, etc.)
++ * @reserved: Reserved for future use
++ */
++struct icvs_dt_config {
++	u16	pixel_width;
++	u16	pixel_height;
++	u8	data_type;
++	u8	reserved[3];
++};
++
++/**
++ * struct icvs_vc_config - Virtual channel configuration
++ * @vc: Virtual channel index (0-31)
++ * @dt_count: Number of data types configured
++ * @dt_configs: Array of data type configurations (up to 4)
++ * @reserved: Reserved for future use
++ */
++struct icvs_vc_config {
++	u8	vc;
++	u8	dt_count;
++	struct icvs_dt_config dt_configs[4];
++	u8	reserved[6];
++};
++
++/**
++ * struct icvs_link_cfg - Host to CVS CSI link configuration
++ * @fps: Frames per second
++ * @nr_of_lanes: Number of CSI-2 data lanes used
++ * @phy_mode: 0 = DPHY, 1 = CPHY
++ * @vc_count: Number of virtual channels enabled
++ * @vc_configs: Per-VC configuration
++ * @link_freq: Link frequency in Hz
++ * @reserved: Reserved for future use
++ */
++struct icvs_link_cfg {
++	u8	fps;
++	u8	nr_of_lanes;
++	u8	phy_mode;
++	u8	vc_count;
++	struct icvs_vc_config vc_configs[4];
++	u32	link_freq;
++	u8	reserved[8];
++};
++
++/**
++ * struct icvs_fw_version - Firmware version tuple
++ * @major: Major version
++ * @minor: Minor version
++ * @hotfix: Hotfix/patch level
++ * @build: Build number
++ */
++struct icvs_fw_version {
++	u32	major;
++	u32	minor;
++	u32	hotfix;
++	u32	build;
++};
++
++/**
++ * struct icvs_vid_pid - Device vendor/product IDs
++ * @v_id: Vendor ID
++ * @p_id: Product ID
++ */
++struct icvs_vid_pid {
++	u16	v_id;
++	u16	p_id;
++};
++
++/**
++ * struct icvs_mipi_data_packet - Encapsulated MIPI link configuration packet
++ * @cmd_id: Command identifier
++ * @size: Payload size (bytes)
++ * @crc: Checksum over payload
++ * @conf: CSI link configuration
++ * @reserved: Reserved for future use
++ */
++struct icvs_mipi_data_packet {
++	__be16	cmd_id;
++	u32	size;
++	u32	crc;
++	struct icvs_link_cfg conf;
++	u8	reserved[70];
++} __packed;
++
++/**
++ * struct icvs_mipi_read_packet - Read-back MIPI configuration
++ * @size: Payload size
++ * @crc: Payload checksum
++ * @conf: CSI link configuration
++ */
++struct icvs_mipi_read_packet {
++	u32	size;
++	u32	crc;
++	struct icvs_link_cfg conf;
++};
++
++/* Host identifier bitfield masks */
++#define ICVS_HOST_ID_RGBCAMERA_PWRUP	BIT(31)
++#define ICVS_HOST_ID_PRIVACY_LED	BIT(30)
++#define ICVS_HOST_ID_DEVICE_POWER	GENMASK(29, 28)
++#define ICVS_HOST_ID_VISION_SENSING	BIT(27)
++
++/* Device state bitfield masks (u8) */
++#define ICVS_DEV_STATE_PRIVACY		BIT(0)
++#define ICVS_DEV_STATE_ON		BIT(1)
++#define ICVS_DEV_STATE_SENSOR_OWNER	BIT(2)
++#define ICVS_DEV_STATE_DOWNLOAD		BIT(4)
++#define ICVS_DEV_STATE_ERROR		BIT(6)
++#define ICVS_DEV_STATE_BUSY		BIT(7)
++
++/* Device capability bitfield masks (u16) */
++#define ICVS_CAP_HOST_MIPI_REQUIRED	BIT(15)
++#define ICVS_CAP_FW_ANTIROLLBACK	BIT(14)
++#define ICVS_CAP_PRIVACY2VISIONDRIVER	BIT(13)
++#define ICVS_CAP_FWUPDATE_RESET_HOST	BIT(12)
++#define ICVS_CAP_NO_CAMERA_FWUPDATE	BIT(11)
++#define ICVS_CAP_POWER_DOMAIN_SUPPORT	BIT(10)
++#define ICVS_CAP_FW_FLASHED_IN_PLACE	BIT(9)
++#define ICVS_CAP_IO_CONTEXT_HOT		BIT(8)
++
++/**
++ * struct icvs_dev_capabilities - Protocol capabilities reported by device
++ * @protocol_version_major: Major protocol version
++ * @protocol_version_minor: Minor protocol version
++ * @capability: Capability bitfield - use ICVS_CAP_* masks
++ * @max_packet_time: Max packet processing time (ms)
++ * @max_post_dl_time: Max post-download time (s)
++ */
++struct icvs_dev_capabilities {
++	u8 protocol_version_major;
++	u8 protocol_version_minor;
++	u16 capability;
++	u16 max_packet_time;
++	u16 max_post_dl_time;
++};
++
++/**
++ * struct icvs_cmd - Generic command container
++ * @cmd_id: Command identifier
++ * @param: Parameter union providing multiple variants
++ * @param.param: Raw parameter
++ * @param.host_id: Host identifier (ICVS_SET_DEV_HOST_ID) - use
++ *		   ICVS_HOST_ID_* masks
++ * @param.conf: CSI link configuration (ICVS_HOST_SET_MIPI_CONFIG)
++ */
++struct icvs_cmd {
++	__be16 cmd_id;
++	union {
++		u32 param;
++		u32 host_id;
++		struct icvs_link_cfg conf;
++	} param;
++} __packed;
++
++/**
++ * struct icvs_resp - Firmware response container
++ * @status: Internal status code
++ * @cmd_id: Original command identifier
++ * @resp: Response union containing variant payload
++ * @resp.state: Device state response (u8, use ICVS_DEV_STATE_* masks)
++ * @resp.cap: Capability response
++ * @resp.conf: Link configuration response
++ * @resp.mipi_read: Raw link config read-back
++ * @resp.vid_pid: Vendor/product identifiers
++ * @resp.fw_version: Firmware version tuple
++ */
++struct icvs_resp {
++	u32 status;
++	__be16 cmd_id;
++	union {
++		u8 state;
++		struct icvs_dev_capabilities cap;
++		struct icvs_link_cfg conf;
++		struct icvs_mipi_read_packet mipi_read;
++		struct icvs_vid_pid vid_pid;
++		struct icvs_fw_version fw_version;
++	} resp;
++};
++
++/**
++ * enum icvs_resources - Device capability / resource category
++ *
++ * Categorizes hardware resource availability which influences protocol
++ * features (e.g. reset control, wake IRQ, GPIO mediated ownership). Light
++ * capability devices expose a reduced set of control GPIOs; full capability
++ * devices provide all optional signals and features. NOTSUP represents an
++ * unsupported or uninitialized state.
++ *
++ * @ICVS_NOTSUP:   Capability not supported / not yet determined
++ * @ICVS_LIGHTCAP: Light capability (limited GPIO / no dedicated wake IRQ)
++ * @ICVS_FULLCAP:  Full capability (reset GPIO, wake IRQ, extended protocol)
++ */
++enum icvs_resources {
++	ICVS_NOTSUP,
++	ICVS_LIGHTCAP,
++	ICVS_FULLCAP,
++};
++
++/**
++ * enum icvs_command - Protocol command opcodes (firmware space 0x0800+)
++ * @ICVS_GET_DEV_STATE:        Query current device state bitfield
++ * @ICVS_GET_DEV_FW_VERSION:   Retrieve firmware version tuple
++ * @ICVS_GET_DEV_VID_PID:      Read vendor / product identifiers
++ * @ICVS_GET_DEV_ERR_CODE:     Fetch last error code (if any)
++ * @ICVS_GET_DEV_CAPABILITY:   Read protocol capability structure
++ * @ICVS_SET_DEV_HOST_ID:      Set host identity / ownership bits
++ * @ICVS_GET_DEV_HOST_ID:      Read back host identity
++ * @ICVS_FW_LOADER_START:      Begin firmware download sequence
++ * @ICVS_FW_LOADER_DATA:       Stream a chunk of firmware payload
++ * @ICVS_FW_LOADER_END:        End firmware download / trigger flash
++ * @ICVS_HOST_GET_MIPI_CONFIG: Request current MIPI CSI link configuration
++ * @ICVS_HOST_SET_MIPI_CONFIG: Apply new MIPI CSI link configuration
++ * @ICVS_HOST_SENSOR_OWNER:    Toggle CSI sensor ownership (GPIO assist)
++ */
++enum icvs_command {
++	ICVS_GET_DEV_STATE		= 0x0800,
++	ICVS_GET_DEV_FW_VERSION		= 0x0801,
++	ICVS_GET_DEV_VID_PID		= 0x0802,
++	ICVS_GET_DEV_ERR_CODE		= 0x0803,
++	ICVS_GET_DEV_CAPABILITY		= 0x0804,
++	ICVS_SET_DEV_HOST_ID		= 0x0805,
++	ICVS_GET_DEV_HOST_ID		= 0x0806,
++	ICVS_FW_LOADER_START		= 0x0820,
++	ICVS_FW_LOADER_DATA		= 0x0821,
++	ICVS_FW_LOADER_END		= 0x0822,
++	ICVS_HOST_GET_MIPI_CONFIG	= 0x082F,
++	ICVS_HOST_SET_MIPI_CONFIG	= 0x0830,
++	ICVS_HOST_SENSOR_OWNER		= 0x0831,
++};
++
++/**
++ * enum icvs_state - Device state bitfield flags
++ *
++ * These flags correspond to bits in the device state byte returned via
++ * GET_DEV_STATE and decoded in union icvs_dev_state. Multiple bits may be
++ * asserted simultaneously. Reserved bits are omitted.
++ *
++ * @ICVS_DEVICE_OFF_STATE: Raw zero value; device is powered off or
++ *			   not yet ready
++ * @ICVS_DEVICE_PRIVACY_ON: Privacy mode active (LED asserted and/or
++ *			    stream gated)
++ * @ICVS_DEVICE_ON_STATE: Device powered and responsive to protocol commands
++ * @ICVS_DEVICE_SENSOR_OWNER: CVS currently owns the attached CSI sensor
++ * @ICVS_DEVICE_DWNLD_STATE: Firmware download / flash operation in progress
++ * @ICVS_DEVICE_ERROR_STATE: Device has reported an error (query
++ *			     ICVS_GET_DEV_ERR_CODE)
++ * @ICVS_DEVICE_BUSY_STATE: Device is busy processing a prior command
++ */
++enum icvs_state {
++	ICVS_DEVICE_OFF_STATE		= 0x00,
++	ICVS_DEVICE_PRIVACY_ON		= BIT(0),
++	ICVS_DEVICE_ON_STATE		= BIT(1),
++	ICVS_DEVICE_SENSOR_OWNER	= BIT(2),
++	ICVS_DEVICE_DWNLD_STATE		= BIT(4),
++	ICVS_DEVICE_ERROR_STATE		= BIT(6),
++	ICVS_DEVICE_BUSY_STATE		= BIT(7),
++};
++
++/**
++ * struct icvs - Core CVS device context
++ * @i2c_client: I2C client (NULL in platform-only mode)
++ * @work: Delayed work for polling device state / completion
++ * @wq_resp: Last response container populated by workqueue
++ * @cmd_completion: Completion for command waiters
++ * @lock: Mutex protecting command submission & shared state
++ * @subdev: V4L2 sub-device representing the CSI bridge entity
++ * @remote: Remote media pad connected to upstream camera sensor
++ * @notifier: Async notifier for remote sensor discovery
++ * @ctrl_handler: V4L2 control handler
++ * @freq_ctrl: (future) frequency control pointer
++ * @pads: Local media pads (sink/source)
++ * @nr_of_lanes: Active CSI-2 lane count
++ * @ipu_link: PM runtime device link (IPU consumer, CVS supplier)
++ * @res: Resource capability (light/full)
++ * @caps: Reported device protocol capabilities
++ * @prefix: Firmware response prefix present
++ * @quirks: Device-specific quirk flags
++ * @rst: Reset GPIO (full capability only)
++ * @req: Request GPIO (ownership signaling)
++ * @resp: Response GPIO (ownership signaling)
++ * @irq: Wake IRQ (full capability)
++ * @hostwake_event: Waitqueue for wake events
++ * @hostwake_event_arg: Wake event flag
++ */
++struct icvs {
++	struct i2c_client *i2c_client;
++	struct delayed_work work;
++	struct icvs_resp wq_resp;
++	struct completion cmd_completion;
++	struct mutex lock; /* Protects command execution and device state */
++	struct v4l2_subdev subdev;
++	struct media_pad *remote;
++	struct v4l2_async_notifier notifier;
++	struct v4l2_ctrl_handler ctrl_handler;
++	struct v4l2_ctrl *freq_ctrl;
++	struct media_pad pads[ICVS_CSI_NUM_PADS];
++	u32 nr_of_lanes;
++	struct device_link *ipu_link;
++	enum icvs_resources res;
++	struct icvs_dev_capabilities caps;
++	bool prefix;
++	unsigned long quirks;
++	struct gpio_desc *rst;
++	struct gpio_desc *req;
++	struct gpio_desc *resp;
++	int irq;
++	wait_queue_head_t hostwake_event;
++	bool hostwake_event_arg;
++};
++
++/**
++ * cvs_dev - Helper returning the struct device for a CVS context
++ * @ctx: CVS context
++ *
++ * Avoids repeating transport conditional logic at each call site when
++ * acquiring the device pointer for logging or PM operations.
++ *
++ * Return: Device pointer (never NULL if @ctx is valid).
++ */
++static inline struct device *cvs_dev(struct icvs *ctx)
++{
++	return ctx->i2c_client ? &ctx->i2c_client->dev : ctx->subdev.dev;
++}
++
++/* Cross-unit interfaces */
++int cvs_send(struct icvs *ctx, struct icvs_cmd *cmd, size_t len);
++int cvs_set_link_owner(struct icvs *ctx, enum icvs_csi_link_owner owner);
++int cvs_csi_init(struct icvs *ctx, struct device *dev, struct i2c_client *i2c);
++void cvs_csi_remove(struct icvs *ctx);
++
++#endif /* _ICVS_H */
+diff --git a/drivers/media/i2c/cvs/v4l2.c b/drivers/media/i2c/cvs/v4l2.c
+new file mode 100644
+index 000000000000..9fadca7a3bee
+--- /dev/null
++++ b/drivers/media/i2c/cvs/v4l2.c
+@@ -0,0 +1,617 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2026 Intel Corporation
++ * CVS driver - CSI/V4L2 subdev support
++ */
++
++#include <linux/cleanup.h>
++#include <linux/device.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/property.h>
++
++#include <media/v4l2-async.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-mc.h>
++#include <media/v4l2-subdev.h>
++
++#include "icvs.h"
++
++/*
++ * Helpers
++ */
++static inline struct icvs *notifier_to_csi(struct v4l2_async_notifier *n)
++{
++	return container_of(n, struct icvs, notifier);
++}
++
++static inline struct icvs *sd_to_csi(struct v4l2_subdev *sd)
++{
++	return container_of(sd, struct icvs, subdev);
++}
++
++/*
++ * Default formats
++ */
++static const struct v4l2_mbus_framefmt cvs_csi_format_mbus_default = {
++	.width = 1,
++	.height = 1,
++	.code = MEDIA_BUS_FMT_Y8_1X8,
++	.field = V4L2_FIELD_NONE,
++};
++
++/**
++ * csi_set_link_cfg - Program default CSI-2 link parameters
++ * @ctx: CVS device context
++ * @link_freq: Link frequency (Hz)
++ *
++ * Populates a HOST_SET_MIPI_CONFIG command using current lane count and
++ * link frequency, then submits it to the device.
++ * Rest of the link parameters are left at firmware defaults.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int csi_set_link_cfg(struct icvs *ctx, u64 link_freq)
++{
++	struct icvs_cmd cmd = {
++		.cmd_id = cpu_to_be16(ICVS_HOST_SET_MIPI_CONFIG),
++		.param.conf.nr_of_lanes = ctx->nr_of_lanes,
++		.param.conf.link_freq = link_freq,
++	};
++	size_t cmd_size = sizeof(cmd.cmd_id) + sizeof(cmd.param.conf);
++
++	guard(mutex)(&ctx->lock);
++	return cvs_send(ctx, &cmd, cmd_size);
++}
++
++/*
++ * Streaming
++ */
++
++/**
++ * cvs_csi_enable_streams - Start streaming through the bridge
++ * @sd: Sub-device pointer
++ * @state: Active state
++ * @pad: Pad identifier (must be ICVS_CSI_PAD_SOURCE)
++ * @streams_mask: Streams to enable (bit 0 supported)
++ *
++ * Runtime-resumes the bridge (triggering cvs_runtime_resume() to claim CSI-2
++ * link ownership), fetches the link frequency, programs the MIPI configuration,
++ * and forwards the enable request downstream.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_csi_enable_streams(struct v4l2_subdev *sd,
++				  struct v4l2_subdev_state *state,
++				  u32 pad, u64 streams_mask)
++{
++	struct icvs *ctx = sd_to_csi(sd);
++	struct v4l2_subdev *remote_sd =
++			    media_entity_to_v4l2_subdev(ctx->remote->entity);
++	struct device *dev = cvs_dev(ctx);
++	s64 link_freq;
++	int ret;
++
++	/* cvs_set_link_owner(ICVS_CSI_LINK_HOST) */
++	ret = pm_runtime_resume_and_get(dev);
++	if (ret < 0)
++		return ret;
++
++	link_freq = v4l2_get_link_freq(ctx->remote, 0, 0);
++	if (link_freq < 0) {
++		ret = link_freq;
++		goto err_rpm_put;
++	}
++
++	if (ctx->i2c_client) {
++		ret = csi_set_link_cfg(ctx, link_freq);
++		if (ret < 0)
++			goto err_rpm_put_sync;
++	}
++
++	ret = v4l2_subdev_enable_streams(remote_sd,
++					 ctx->remote->index,
++					 streams_mask);
++	if (ret)
++		goto err_rpm_put_sync;
++
++	return 0;
++
++err_rpm_put_sync:
++	/* Bypass autosuspend to immediately release ownership on error */
++	pm_runtime_put_sync(dev);
++	return ret;
++err_rpm_put:
++	pm_runtime_put_autosuspend(dev);
++	return ret;
++}
++
++/**
++ * cvs_csi_disable_streams - Stop streaming through the bridge
++ * @sd: Sub-device pointer
++ * @state: Active state
++ * @pad: Pad identifier (must be ICVS_CSI_PAD_SOURCE)
++ * @streams_mask: Streams to disable (bit 0 supported)
++ *
++ * Disables the remote sensor stream then drops the PM reference acquired
++ * during enable. After the autosuspend delay, cvs_runtime_suspend() will
++ * return CSI-2 link ownership to CVS firmware.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_csi_disable_streams(struct v4l2_subdev *sd,
++				   struct v4l2_subdev_state *state,
++				   u32 pad, u64 streams_mask)
++{
++	struct icvs *ctx = sd_to_csi(sd);
++	struct v4l2_subdev *remote_sd =
++			    media_entity_to_v4l2_subdev(ctx->remote->entity);
++	struct device *dev = cvs_dev(ctx);
++	int ret;
++
++	ret = v4l2_subdev_disable_streams(remote_sd,
++					  ctx->remote->index,
++					  streams_mask);
++	if (ret)
++		dev_err(dev, "disable streams failed: %d\n", ret);
++
++	/* cvs_set_link_owner(ICVS_CSI_LINK_CVS) */
++	pm_runtime_put_autosuspend(dev);
++
++	return ret;
++}
++
++/*
++ * Pad operations / formats
++ */
++/**
++ * cvs_csi_init_state - Initialize pad formats in subdev state
++ * @sd: Sub-device
++ * @state: State container
++ *
++ * Sets all pad formats to a minimal 1x1 default.
++ *
++ * Return: 0.
++ */
++static int cvs_csi_init_state(struct v4l2_subdev *sd,
++			      struct v4l2_subdev_state *state)
++{
++	for (unsigned int i = 0; i < sd->entity.num_pads; i++)
++		*v4l2_subdev_state_get_format(state, i) =
++			cvs_csi_format_mbus_default;
++
++	return 0;
++}
++
++/**
++ * cvs_csi_set_fmt - Negotiate pad format
++ * @sd: Sub-device
++ * @state: State
++ * @format: Desired / returned format
++ *
++ * Mirrors sink format onto source pad. Accepts many media bus codes, falling
++ * back to Y8 if unsupported. Normalizes field setting.
++ *
++ * Return: 0.
++ */
++static int cvs_csi_set_fmt(struct v4l2_subdev *sd,
++			   struct v4l2_subdev_state *state,
++			   struct v4l2_subdev_format *format)
++{
++	struct v4l2_mbus_framefmt *src =
++		v4l2_subdev_state_get_format(state, ICVS_CSI_PAD_SOURCE);
++	struct v4l2_mbus_framefmt *sink =
++		v4l2_subdev_state_get_format(state, ICVS_CSI_PAD_SINK);
++
++	if (format->pad == ICVS_CSI_PAD_SOURCE) { /* source pad mirrors sink */
++		*src = *sink;
++		return 0;
++	}
++
++	v4l_bound_align_image(&format->format.width, 1, 65536, 0,
++			      &format->format.height, 1, 65536, 0, 0);
++
++	switch (format->format.code) {
++	/* Accept a large list; default fallback to Y8 */
++	case MEDIA_BUS_FMT_RGB444_1X12:
++	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE:
++	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE:
++	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
++	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
++	case MEDIA_BUS_FMT_RGB565_1X16:
++	case MEDIA_BUS_FMT_BGR565_2X8_BE:
++	case MEDIA_BUS_FMT_BGR565_2X8_LE:
++	case MEDIA_BUS_FMT_RGB565_2X8_BE:
++	case MEDIA_BUS_FMT_RGB565_2X8_LE:
++	case MEDIA_BUS_FMT_RGB666_1X18:
++	case MEDIA_BUS_FMT_RBG888_1X24:
++	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
++	case MEDIA_BUS_FMT_BGR888_1X24:
++	case MEDIA_BUS_FMT_GBR888_1X24:
++	case MEDIA_BUS_FMT_RGB888_1X24:
++	case MEDIA_BUS_FMT_RGB888_2X12_BE:
++	case MEDIA_BUS_FMT_RGB888_2X12_LE:
++	case MEDIA_BUS_FMT_ARGB8888_1X32:
++	case MEDIA_BUS_FMT_RGB888_1X32_PADHI:
++	case MEDIA_BUS_FMT_RGB101010_1X30:
++	case MEDIA_BUS_FMT_RGB121212_1X36:
++	case MEDIA_BUS_FMT_RGB161616_1X48:
++	case MEDIA_BUS_FMT_Y8_1X8:
++	case MEDIA_BUS_FMT_UV8_1X8:
++	case MEDIA_BUS_FMT_UYVY8_1_5X8:
++	case MEDIA_BUS_FMT_VYUY8_1_5X8:
++	case MEDIA_BUS_FMT_YUYV8_1_5X8:
++	case MEDIA_BUS_FMT_YVYU8_1_5X8:
++	case MEDIA_BUS_FMT_UYVY8_2X8:
++	case MEDIA_BUS_FMT_VYUY8_2X8:
++	case MEDIA_BUS_FMT_YUYV8_2X8:
++	case MEDIA_BUS_FMT_YVYU8_2X8:
++	case MEDIA_BUS_FMT_Y10_1X10:
++	case MEDIA_BUS_FMT_UYVY10_2X10:
++	case MEDIA_BUS_FMT_VYUY10_2X10:
++	case MEDIA_BUS_FMT_YUYV10_2X10:
++	case MEDIA_BUS_FMT_YVYU10_2X10:
++	case MEDIA_BUS_FMT_Y12_1X12:
++	case MEDIA_BUS_FMT_UYVY12_2X12:
++	case MEDIA_BUS_FMT_VYUY12_2X12:
++	case MEDIA_BUS_FMT_YUYV12_2X12:
++	case MEDIA_BUS_FMT_YVYU12_2X12:
++	case MEDIA_BUS_FMT_UYVY8_1X16:
++	case MEDIA_BUS_FMT_VYUY8_1X16:
++	case MEDIA_BUS_FMT_YUYV8_1X16:
++	case MEDIA_BUS_FMT_YVYU8_1X16:
++	case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
++	case MEDIA_BUS_FMT_UYVY10_1X20:
++	case MEDIA_BUS_FMT_VYUY10_1X20:
++	case MEDIA_BUS_FMT_YUYV10_1X20:
++	case MEDIA_BUS_FMT_YVYU10_1X20:
++	case MEDIA_BUS_FMT_VUY8_1X24:
++	case MEDIA_BUS_FMT_YUV8_1X24:
++	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
++	case MEDIA_BUS_FMT_UYVY12_1X24:
++	case MEDIA_BUS_FMT_VYUY12_1X24:
++	case MEDIA_BUS_FMT_YUYV12_1X24:
++	case MEDIA_BUS_FMT_YVYU12_1X24:
++	case MEDIA_BUS_FMT_YUV10_1X30:
++	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
++	case MEDIA_BUS_FMT_AYUV8_1X32:
++	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
++	case MEDIA_BUS_FMT_YUV12_1X36:
++	case MEDIA_BUS_FMT_YUV16_1X48:
++	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
++	case MEDIA_BUS_FMT_JPEG_1X8:
++	case MEDIA_BUS_FMT_AHSV8888_1X32:
++	case MEDIA_BUS_FMT_SBGGR8_1X8:
++	case MEDIA_BUS_FMT_SGBRG8_1X8:
++	case MEDIA_BUS_FMT_SGRBG8_1X8:
++	case MEDIA_BUS_FMT_SRGGB8_1X8:
++	case MEDIA_BUS_FMT_SBGGR10_1X10:
++	case MEDIA_BUS_FMT_SGBRG10_1X10:
++	case MEDIA_BUS_FMT_SGRBG10_1X10:
++	case MEDIA_BUS_FMT_SRGGB10_1X10:
++	case MEDIA_BUS_FMT_SBGGR12_1X12:
++	case MEDIA_BUS_FMT_SGBRG12_1X12:
++	case MEDIA_BUS_FMT_SGRBG12_1X12:
++	case MEDIA_BUS_FMT_SRGGB12_1X12:
++	case MEDIA_BUS_FMT_SBGGR14_1X14:
++	case MEDIA_BUS_FMT_SGBRG14_1X14:
++	case MEDIA_BUS_FMT_SGRBG14_1X14:
++	case MEDIA_BUS_FMT_SRGGB14_1X14:
++	case MEDIA_BUS_FMT_SBGGR16_1X16:
++	case MEDIA_BUS_FMT_SGBRG16_1X16:
++	case MEDIA_BUS_FMT_SGRBG16_1X16:
++	case MEDIA_BUS_FMT_SRGGB16_1X16:
++		break;
++	default:
++		format->format.code = MEDIA_BUS_FMT_Y8_1X8;
++		break;
++	}
++
++	if (format->format.field == V4L2_FIELD_ANY)
++		format->format.field = V4L2_FIELD_NONE;
++
++	*sink = format->format;
++	*src = *sink;
++
++	return 0;
++}
++
++/**
++ * cvs_csi_get_mbus_config - Provide current CSI-2 bus configuration
++ * @sd: Sub-device
++ * @pad: Pad index
++ * @cfg: Returned bus config
++ *
++ * Fills lane ordering and number of lanes; retrieves link frequency from
++ * remote entity.
 + *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
++ * Return: 0 on success or negative errno.
 + */
++static int cvs_csi_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
++				   struct v4l2_mbus_config *cfg)
++{
++	struct icvs *ctx = sd_to_csi(sd);
++	s64 freq;
 +
-+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++	cfg->type = V4L2_MBUS_CSI2_DPHY;
++	for (unsigned int i = 0; i < V4L2_MBUS_CSI2_MAX_DATA_LANES; i++)
++		cfg->bus.mipi_csi2.data_lanes[i] = i + 1;
++	cfg->bus.mipi_csi2.num_data_lanes = ctx->nr_of_lanes;
 +
-+#include <linux/efi.h>
-+#include <linux/kernel.h>
-+#include <linux/printk.h>
++	freq = v4l2_get_link_freq(ctx->remote, 0, 0);
++	if (freq < 0)
++		return -EINVAL;
++
++	cfg->link_freq = freq;
++
++	return 0;
++}
++
++static const struct v4l2_subdev_core_ops cvs_csi_subdev_core_ops = {
++	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops cvs_csi_video_ops = {
++	.s_stream = v4l2_subdev_s_stream_helper,
++};
++
++static const struct v4l2_subdev_pad_ops cvs_csi_pad_ops = {
++	.get_fmt = v4l2_subdev_get_fmt,
++	.set_fmt = cvs_csi_set_fmt,
++	.get_mbus_config = cvs_csi_get_mbus_config,
++	.enable_streams = cvs_csi_enable_streams,
++	.disable_streams = cvs_csi_disable_streams,
++};
++
++static const struct v4l2_subdev_ops cvs_csi_subdev_ops = {
++	.core = &cvs_csi_subdev_core_ops,
++	.video = &cvs_csi_video_ops,
++	.pad = &cvs_csi_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops cvs_csi_internal_ops = {
++	.init_state = cvs_csi_init_state,
++};
++
++static const struct media_entity_operations cvs_csi_entity_ops = {
++	.link_validate = v4l2_subdev_link_validate,
++};
 +
 +/*
-+ * Decide what to do when UEFI secure boot mode is enabled.
++ * Async notifier
 + */
-+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
++/**
++ * cvs_csi_notify_bound - Remote sensor bound callback
++ * @notifier: Async notifier
++ * @sd: Remote subdev
++ * @asc: Async match connection
++ *
++ * Locates the source pad of the remote sensor and creates a media link to
++ * the CVS bridge sink pad enabling it by default.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_csi_notify_bound(struct v4l2_async_notifier *notifier,
++				struct v4l2_subdev *sd,
++				struct v4l2_async_connection *asc)
 +{
-+	if (efi_enabled(EFI_BOOT)) {
-+		switch (mode) {
-+		case efi_secureboot_mode_disabled:
-+			pr_info("Secure boot disabled\n");
-+			break;
-+		case efi_secureboot_mode_enabled:
-+			set_bit(EFI_SECURE_BOOT, &efi.flags);
-+			pr_info("Secure boot enabled\n");
-+			break;
-+		default:
-+			pr_warn("Secure boot could not be determined (mode %u)\n",
-+				   mode);
-+			break;
-+		}
-+	}
++	struct icvs *ctx = notifier_to_csi(notifier);
++	int pad;
++
++	pad = media_entity_get_fwnode_pad(&sd->entity, asc->match.fwnode,
++					  MEDIA_PAD_FL_SOURCE);
++	if (pad < 0)
++		return pad;
++
++	ctx->remote = &sd->entity.pads[pad];
++
++	return media_create_pad_link(&sd->entity, pad, &ctx->subdev.entity,
++				     ICVS_CSI_PAD_SINK, MEDIA_LNK_FL_ENABLED |
++				     MEDIA_LNK_FL_IMMUTABLE);
 +}
-diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
-index a251375db24b..2b5337eaeb6d 100644
---- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
-+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
-@@ -12,6 +12,7 @@
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/device.h>
-+#include <linux/dmi.h>
- #include <linux/io.h>
- #include <linux/err.h>
- #include <linux/fs.h>
-@@ -2547,6 +2548,16 @@ static const struct amba_id etm4_ids[] = {
- 	{},
- };
- 
-+static const struct dmi_system_id broken_coresight[] = {
-+	{
-+		.matches = {
-+			DMI_MATCH(DMI_SYS_VENDOR, "HPE"),
-+			DMI_MATCH(DMI_PRODUCT_NAME, "Apollo 70"),
-+		},
-+	},
-+	{ }	/* terminating entry */
++
++/**
++ * cvs_csi_notify_unbind - Remote sensor unbind callback
++ * @notifier: Notifier
++ * @sd: Remote subdev
++ * @asc: Connection
++ */
++static void cvs_csi_notify_unbind(struct v4l2_async_notifier *notifier,
++				  struct v4l2_subdev *sd,
++				  struct v4l2_async_connection *asc)
++{
++	struct icvs *ctx = notifier_to_csi(notifier);
++
++	ctx->remote = NULL;
++}
++
++static const struct v4l2_async_notifier_operations cvs_csi_notify_ops = {
++	.bound = cvs_csi_notify_bound,
++	.unbind = cvs_csi_notify_unbind,
 +};
 +
- MODULE_DEVICE_TABLE(amba, etm4_ids);
- 
- static struct amba_driver etm4x_amba_driver = {
-@@ -2621,6 +2632,11 @@ static int __init etm4x_init(void)
- {
- 	int ret;
- 
-+	if (dmi_check_system(broken_coresight)) {
-+		pr_info("ETM4 disabled due to firmware bug\n");
-+		return 0;
++/*
++ * Controls
++ */
++/**
++ * cvs_csi_init_controls - Initialize V4L2 controls
++ * @ctx: CVS context
++ *
++ * Currently sets up a read-only privacy control placeholder.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_csi_init_controls(struct icvs *ctx)
++{
++	struct v4l2_ctrl *privacy_ctrl;
++
++	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
++
++	privacy_ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler, NULL,
++					 V4L2_CID_PRIVACY, 0, 1, 1, 0);
++	if (privacy_ctrl)
++		privacy_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++	if (ctx->ctrl_handler.error) {
++		v4l2_ctrl_handler_free(&ctx->ctrl_handler);
++		return ctx->ctrl_handler.error;
 +	}
 +
- 	ret = etm4_pm_setup();
- 
- 	/* etm4_pm_setup() does its own cleanup - exit on error */
-@@ -2647,6 +2663,9 @@ static int __init etm4x_init(void)
- 
- static void __exit etm4x_exit(void)
- {
-+	if (dmi_check_system(broken_coresight))
-+		return;
++	ctx->subdev.ctrl_handler = &ctx->ctrl_handler;
 +
- 	amba_driver_unregister(&etm4x_amba_driver);
- 	platform_driver_unregister(&etm4_platform_driver);
- 	etm4_pm_clear();
-diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
-index d1a9e713d3a0..940458370730 100644
---- a/drivers/iommu/iommu.c
-+++ b/drivers/iommu/iommu.c
-@@ -8,6 +8,7 @@
- 
- #include <linux/amba/bus.h>
- #include <linux/device.h>
-+#include <linux/dmi.h>
- #include <linux/kernel.h>
- #include <linux/bits.h>
- #include <linux/bug.h>
-@@ -3136,6 +3137,27 @@ int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids)
- }
- EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
- 
-+#ifdef CONFIG_ARM64
-+static int __init iommu_quirks(void)
++	return 0;
++}
++
++/*
++ * Firmware (graph) parsing
++ */
++/**
++ * cvs_csi_parse_firmware - Parse firmware (ACPI graph) endpoints
++ * @ctx: CVS context
++ *
++ * Discovers sink and remote source endpoints, validates lane counts and
++ * registers an async notifier for the remote sensor.
++ *
++ * Return: 0 on success or negative errno.
++ */
++static int cvs_csi_parse_firmware(struct icvs *ctx)
 +{
-+	const char *vendor, *name;
++	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
++	struct device *dev = cvs_dev(ctx);
++	struct fwnode_handle *sink_ep, *source_ep;
++	struct v4l2_async_connection *asc;
++	int ret;
 +
-+	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
-+	name = dmi_get_system_info(DMI_PRODUCT_NAME);
++	sink_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
++	v4l2_async_subdev_nf_init(&ctx->notifier, &ctx->subdev);
++	ctx->notifier.ops = &cvs_csi_notify_ops;
 +
-+	if (vendor &&
-+	    (strncmp(vendor, "GIGABYTE", 8) == 0 && name &&
-+	     (strncmp(name, "R120", 4) == 0 ||
-+	      strncmp(name, "R270", 4) == 0))) {
-+		pr_warn("Gigabyte %s detected, force iommu passthrough mode", name);
-+		iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
++	ret = v4l2_fwnode_endpoint_parse(sink_ep, &ep);
++	if (ret)
++		goto err_nf_cleanup;
++
++	ctx->nr_of_lanes = ep.bus.mipi_csi2.num_data_lanes;
++	source_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 1, 0, 0);
++	ret = v4l2_fwnode_endpoint_parse(source_ep, &ep);
++	fwnode_handle_put(source_ep);
++	if (ret)
++		goto err_nf_cleanup;
++
++	if (ctx->nr_of_lanes != ep.bus.mipi_csi2.num_data_lanes) {
++		ret = -EINVAL;
++		goto err_nf_cleanup;
 +	}
 +
++	asc = v4l2_async_nf_add_fwnode_remote(&ctx->notifier, sink_ep,
++					      struct v4l2_async_connection);
++	if (IS_ERR(asc)) {
++		ret = PTR_ERR(asc);
++		goto err_nf_cleanup;
++	}
++
++	ret = v4l2_async_nf_register(&ctx->notifier);
++	if (ret)
++		goto err_nf_cleanup;
++
++	fwnode_handle_put(sink_ep);
++
 +	return 0;
++
++err_nf_cleanup:
++	v4l2_async_nf_cleanup(&ctx->notifier);
++	fwnode_handle_put(sink_ep);
++
++	return ret;
 +}
-+arch_initcall(iommu_quirks);
-+#endif
 +
- /**
-  * iommu_setup_default_domain - Set the default_domain for the group
-  * @group: Group to change
-diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
-index 8f2ba4121586..e1143579ae3d 100644
---- a/drivers/media/i2c/Kconfig
-+++ b/drivers/media/i2c/Kconfig
-@@ -287,6 +287,16 @@ config VIDEO_IMX415
- 	  To compile this driver as a module, choose M here: the
- 	  module will be called imx415.
- 
-+config VIDEO_IMX471
-+	tristate "Sony IMX471 sensor support"
-+	select V4L2_CCI_I2C
-+	help
-+	  This is a Video4Linux2 sensor driver for the Sony
-+	  IMX471 camera.
++/*
++ * Public CSI init/cleanup used by core probe/remove
++ */
++/**
++ * cvs_csi_init - Initialize CSI/V4L2 sub-device side of bridge
++ * @ctx: CVS context
++ * @dev: Parent device
++ * @i2c: I2C client (may be NULL for platform mode)
++ *
++ * Sets up sub-device, media entity pads, async notifier, controls and
++ * registers with the V4L2 framework.
++ *
++ * Return: 0 on success or negative errno.
++ */
++int cvs_csi_init(struct icvs *ctx, struct device *dev, struct i2c_client *i2c)
++{
++	int ret;
 +
-+	  To compile this driver as a module, choose M here: the
-+	  module will be called imx471.
++	if (i2c) {
++		v4l2_i2c_subdev_init(&ctx->subdev, i2c, &cvs_csi_subdev_ops);
++	} else {
++		v4l2_subdev_init(&ctx->subdev, &cvs_csi_subdev_ops);
++		ctx->subdev.dev = dev;
++	}
 +
- config VIDEO_MAX9271_LIB
- 	tristate
- 
-diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
-index 90b276a7417a..f5c9fa93dc47 100644
---- a/drivers/media/i2c/Makefile
-+++ b/drivers/media/i2c/Makefile
-@@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_IMX335) += imx335.o
- obj-$(CONFIG_VIDEO_IMX355) += imx355.o
- obj-$(CONFIG_VIDEO_IMX412) += imx412.o
- obj-$(CONFIG_VIDEO_IMX415) += imx415.o
-+obj-$(CONFIG_VIDEO_IMX471) += imx471.o
- obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
- obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
- obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
++	ctx->subdev.internal_ops = &cvs_csi_internal_ops;
++	v4l2_set_subdevdata(&ctx->subdev, ctx);
++	ctx->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++	ctx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
++	ctx->subdev.entity.ops = &cvs_csi_entity_ops;
++	snprintf(ctx->subdev.name, sizeof(ctx->subdev.name), "Intel CVS");
++
++	ret = cvs_csi_parse_firmware(ctx);
++	if (ret)
++		return ret;
++
++	ret = cvs_csi_init_controls(ctx);
++	if (ret)
++		goto err_nf_unreg;
++
++	ctx->pads[ICVS_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
++	ctx->pads[ICVS_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++	ret = media_entity_pads_init(&ctx->subdev.entity, ICVS_CSI_NUM_PADS,
++				     ctx->pads);
++	if (ret)
++		goto err_ctrl_cleanup;
++
++	ctx->subdev.state_lock = ctx->ctrl_handler.lock;
++	ret = v4l2_subdev_init_finalize(&ctx->subdev);
++	if (ret)
++		goto err_entity_cleanup;
++
++	ret = v4l2_async_register_subdev(&ctx->subdev);
++	if (ret)
++		goto err_entity_cleanup;
++
++	return 0;
++
++err_entity_cleanup:
++	media_entity_cleanup(&ctx->subdev.entity);
++
++err_ctrl_cleanup:
++	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
++
++err_nf_unreg:
++	v4l2_async_nf_unregister(&ctx->notifier);
++	v4l2_async_nf_cleanup(&ctx->notifier);
++
++	return ret;
++}
++
++/**
++ * cvs_csi_remove - Cleanup CSI/V4L2 sub-device
++ * @ctx: CVS context
++ */
++void cvs_csi_remove(struct icvs *ctx)
++{
++	v4l2_async_nf_unregister(&ctx->notifier);
++	v4l2_async_nf_cleanup(&ctx->notifier);
++	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
++	v4l2_async_unregister_subdev(&ctx->subdev);
++	v4l2_subdev_cleanup(&ctx->subdev);
++	media_entity_cleanup(&ctx->subdev.entity);
++}
++
++MODULE_AUTHOR("Miguel Vadillo <miguel.vadillo@intel.com>");
++MODULE_DESCRIPTION("CSI/V4L2 support for Intel Vision Sensing Controller");
++MODULE_LICENSE("GPL");
 diff --git a/drivers/media/i2c/imx471.c b/drivers/media/i2c/imx471.c
 new file mode 100644
 index 000000000000..6d358b11e96d
@@ -6581,10 +8959,10 @@ index 115bb37577a1..4b9b86742d6a 100644
  	default:
  		*con_id = "unknown";
 diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index 24960ba9caa9..32597cdb72ef 100644
+index 54c091cb3661..e2a72d62a1d9 100644
 --- a/drivers/usb/core/hub.c
 +++ b/drivers/usb/core/hub.c
-@@ -5894,6 +5894,13 @@ static void hub_event(struct work_struct *work)
+@@ -5899,6 +5899,13 @@ static void hub_event(struct work_struct *work)
  			(u16) hub->change_bits[0],
  			(u16) hub->event_bits[0]);
  
@@ -6773,6 +9151,20 @@ index 590ba29c85ab..02153d857531 100644
  }
  
  int module_sig_check(struct load_info *info, int flags)
+diff --git a/net/core/page_pool.c b/net/core/page_pool.c
+index 8171d1173221..1cdb0a80e8b3 100644
+--- a/net/core/page_pool.c
++++ b/net/core/page_pool.c
+@@ -1065,7 +1065,8 @@ netmem_ref page_pool_alloc_frag_netmem(struct page_pool *pool,
+ 	if (WARN_ON(size > max_size))
+ 		return 0;
+ 
+-	size = ALIGN(size, dma_get_cache_alignment());
++	size = ALIGN(size, max_t(unsigned int, dma_get_cache_alignment(),
++				 __alignof__(struct skb_shared_info)));
+ 	*offset = pool->frag_offset;
+ 
+ 	if (netmem && *offset + size > max_size) {
 diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
 index 0718e39cedda..10e94a1b8b6e 100644
 --- a/scripts/Makefile.lib

diff --git a/sources b/sources
index f360d05..d97c581 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
-SHA512 (linux-7.1.12.tar.xz) = a7acfe8d6c39f0d9c537eb0360fbe4df835003bc6944a5b987c2246dc06cff3349a9c0d6200d550ede37510129c79c297f6c28afbb31ebda7620690e5e02f8e4
-SHA512 (kernel-abi-stablelists-7.1.12.tar.xz) = 6e4ad0d850a50a1e30fcfcd4a7bb9c585228a6d0edd48ce7ac833790fd0ae5fbcc014c80a5d8ca51ab6cf5d3ee6ddd37fb9848ed00a18159b90b173cccc3deec
-SHA512 (kernel-kabi-dw-7.1.12.tar.xz) = 12791da7c3fd756fab70a70fbd91b27fb7aa7fd6b46f59e3cd883fee0d1c36dbf2fba861088e60bf7519641c94bfedf11dbea51a60e490ade095219140ea569a
+SHA512 (linux-7.1.13.tar.xz) = 9e0cb10b62256f6609bd50435fb78f9221dc58bbdcdd27952975f38df5ed201e7416cc9e556ad22da25e78b97475555415477ac7c887420b0b3c97bc4c12954f
+SHA512 (kernel-abi-stablelists-7.1.13.tar.xz) = 61117f4521afbe011250a896f01193cdecbc5c8bcd6108fc454b8eb57714eaecc6553bb116675e51c36522b9da8e10f0370c4e924fdfc98e714c09c0e803fa40
+SHA512 (kernel-kabi-dw-7.1.13.tar.xz) = 3aa66a108e53cafc7de7316e68c79ec31fb522a69f85412cd4ae8768b1eb41ee39b268dafde8038fb89cc95e8c909a75fb5f62ead38ea5de3d6832cf0967ee54

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-02 13:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-02 13:38 [rpms/kernel] f43: kernel-7.1.13-100 Justin M. Forbes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox