]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.14
authorSasha Levin <sashal@kernel.org>
Sat, 26 Apr 2025 13:23:08 +0000 (09:23 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 26 Apr 2025 13:23:08 +0000 (09:23 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
34 files changed:
queue-6.14/drm-xe-add-performance-tunings-to-debugfs.patch [new file with mode: 0644]
queue-6.14/drm-xe-ensure-fixed_slice_mode-gets-set-after-ccs_mo.patch [new file with mode: 0644]
queue-6.14/drm-xe-ptl-apply-wa_14023061436.patch [new file with mode: 0644]
queue-6.14/drm-xe-rtp-drop-sentinels-from-arg-to-xe_rtp_process.patch [new file with mode: 0644]
queue-6.14/drm-xe-xe3lpg-add-wa_13012615864.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7768-1-fix-conversion-result-sign.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch [new file with mode: 0644]
queue-6.14/irqchip-renesas-rzv2h-add-struct-rzv2h_hw_info-with-.patch [new file with mode: 0644]
queue-6.14/irqchip-renesas-rzv2h-prevent-tint-spurious-interrup.patch [new file with mode: 0644]
queue-6.14/irqchip-renesas-rzv2h-simplify-rzv2h_icu_init.patch [new file with mode: 0644]
queue-6.14/lib-kconfig.ubsan-remove-default-ubsan-from-ubsan_in.patch [new file with mode: 0644]
queue-6.14/media-i2c-imx214-check-number-of-lanes-from-device-t.patch [new file with mode: 0644]
queue-6.14/media-i2c-imx214-convert-to-cci-register-access-help.patch [new file with mode: 0644]
queue-6.14/media-i2c-imx214-fix-link-frequency-validation.patch [new file with mode: 0644]
queue-6.14/media-i2c-imx214-replace-register-addresses-with-mac.patch [new file with mode: 0644]
queue-6.14/media-i2c-imx214-simplify-with-dev_err_probe.patch [new file with mode: 0644]
queue-6.14/media-i2c-imx214-use-subdev-active-state.patch [new file with mode: 0644]
queue-6.14/media-ov08x40-add-missing-ov08x40_identify_module-ca.patch [new file with mode: 0644]
queue-6.14/media-ov08x40-move-ov08x40_identify_module-function-.patch [new file with mode: 0644]
queue-6.14/mm-vmscan-don-t-try-to-reclaim-hwpoison-folio.patch [new file with mode: 0644]
queue-6.14/mmc-sdhci-msm-fix-dev-reference-leaked-through-of_qc.patch [new file with mode: 0644]
queue-6.14/net-niu-niu-requires-msix-entry_data-fields-touch-be.patch [new file with mode: 0644]
queue-6.14/of-resolver-fix-device-node-refcount-leakage-in-of_r.patch [new file with mode: 0644]
queue-6.14/of-resolver-simplify-of_resolve_phandles-using-__fre.patch [new file with mode: 0644]
queue-6.14/pci-msi-add-an-option-to-write-msix-entry_data-befor.patch [new file with mode: 0644]
queue-6.14/pci-msi-convert-pci_msi_ignore_mask-to-per-msi-domai.patch [new file with mode: 0644]
queue-6.14/pci-msi-handle-the-nomask-flag-correctly-for-all-pci.patch [new file with mode: 0644]
queue-6.14/pm-em-address-rcu-related-sparse-warnings.patch [new file with mode: 0644]
queue-6.14/pm-em-use-kfree_rcu-to-simplify-the-code.patch [new file with mode: 0644]
queue-6.14/s390-pci-support-mmap-of-pci-resources-except-for-is.patch [new file with mode: 0644]
queue-6.14/scsi-ufs-qcom-fix-dev-reference-leaked-through-of_qc.patch [new file with mode: 0644]
queue-6.14/series
queue-6.14/soc-qcom-ice-introduce-devm_of_qcom_ice_get.patch [new file with mode: 0644]
queue-6.14/ubsan-overflow-rework-integer-overflow-sanitizer-opt.patch [new file with mode: 0644]

diff --git a/queue-6.14/drm-xe-add-performance-tunings-to-debugfs.patch b/queue-6.14/drm-xe-add-performance-tunings-to-debugfs.patch
new file mode 100644 (file)
index 0000000..b0d8a6a
--- /dev/null
@@ -0,0 +1,218 @@
+From f5f414f7335a68fdd10b1ee0a150ff904d765c3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 10:13:04 +0000
+Subject: drm/xe: Add performance tunings to debugfs
+
+From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+
+[ Upstream commit 067a974fd8a9ea43f97ca184e2768b583f2f8c44 ]
+
+Add a list of active tunings to debugfs, analogous to the existing
+list of workarounds.
+
+Rationale being that it seems to make sense to either have both or none.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Cc: Lucas De Marchi <lucas.demarchi@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250227101304.46660-6-tvrtko.ursulin@igalia.com
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_gt.c         |  4 ++
+ drivers/gpu/drm/xe/xe_gt_debugfs.c | 11 ++++++
+ drivers/gpu/drm/xe/xe_gt_types.h   | 10 +++++
+ drivers/gpu/drm/xe/xe_tuning.c     | 59 ++++++++++++++++++++++++++++++
+ drivers/gpu/drm/xe/xe_tuning.h     |  3 ++
+ 5 files changed, 87 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
+index 8a20e6744836c..94eed1315b0f1 100644
+--- a/drivers/gpu/drm/xe/xe_gt.c
++++ b/drivers/gpu/drm/xe/xe_gt.c
+@@ -381,6 +381,10 @@ int xe_gt_init_early(struct xe_gt *gt)
+       if (err)
+               return err;
++      err = xe_tuning_init(gt);
++      if (err)
++              return err;
++
+       xe_wa_process_oob(gt);
+       xe_force_wake_init_gt(gt, gt_to_fw(gt));
+diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c
+index e7792858b1e46..2d63a69cbfa38 100644
+--- a/drivers/gpu/drm/xe/xe_gt_debugfs.c
++++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c
+@@ -30,6 +30,7 @@
+ #include "xe_reg_sr.h"
+ #include "xe_reg_whitelist.h"
+ #include "xe_sriov.h"
++#include "xe_tuning.h"
+ #include "xe_uc_debugfs.h"
+ #include "xe_wa.h"
+@@ -217,6 +218,15 @@ static int workarounds(struct xe_gt *gt, struct drm_printer *p)
+       return 0;
+ }
++static int tunings(struct xe_gt *gt, struct drm_printer *p)
++{
++      xe_pm_runtime_get(gt_to_xe(gt));
++      xe_tuning_dump(gt, p);
++      xe_pm_runtime_put(gt_to_xe(gt));
++
++      return 0;
++}
++
+ static int pat(struct xe_gt *gt, struct drm_printer *p)
+ {
+       xe_pm_runtime_get(gt_to_xe(gt));
+@@ -300,6 +310,7 @@ static const struct drm_info_list debugfs_list[] = {
+       {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info},
+       {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore},
+       {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds},
++      {"tunings", .show = xe_gt_debugfs_simple_show, .data = tunings},
+       {"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
+       {"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
+       {"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc},
+diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
+index 6e66bf0e8b3f7..dd2969a1846dd 100644
+--- a/drivers/gpu/drm/xe/xe_gt_types.h
++++ b/drivers/gpu/drm/xe/xe_gt_types.h
+@@ -413,6 +413,16 @@ struct xe_gt {
+               bool oob_initialized;
+       } wa_active;
++      /** @tuning_active: keep track of active tunings */
++      struct {
++              /** @tuning_active.gt: bitmap with active GT tunings */
++              unsigned long *gt;
++              /** @tuning_active.engine: bitmap with active engine tunings */
++              unsigned long *engine;
++              /** @tuning_active.lrc: bitmap with active LRC tunings */
++              unsigned long *lrc;
++      } tuning_active;
++
+       /** @user_engines: engines present in GT and available to userspace */
+       struct {
+               /**
+diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c
+index 3c78f3d715591..23c46dd85e149 100644
+--- a/drivers/gpu/drm/xe/xe_tuning.c
++++ b/drivers/gpu/drm/xe/xe_tuning.c
+@@ -7,6 +7,8 @@
+ #include <kunit/visibility.h>
++#include <drm/drm_managed.h>
++
+ #include "regs/xe_gt_regs.h"
+ #include "xe_gt_types.h"
+ #include "xe_platform_types.h"
+@@ -135,10 +137,44 @@ static const struct xe_rtp_entry_sr lrc_tunings[] = {
+       {}
+ };
++/**
++ * xe_tuning_init - initialize gt with tunings bookkeeping
++ * @gt: GT instance to initialize
++ *
++ * Returns 0 for success, negative error code otherwise.
++ */
++int xe_tuning_init(struct xe_gt *gt)
++{
++      struct xe_device *xe = gt_to_xe(gt);
++      size_t n_lrc, n_engine, n_gt, total;
++      unsigned long *p;
++
++      n_gt = BITS_TO_LONGS(ARRAY_SIZE(gt_tunings));
++      n_engine = BITS_TO_LONGS(ARRAY_SIZE(engine_tunings));
++      n_lrc = BITS_TO_LONGS(ARRAY_SIZE(lrc_tunings));
++      total = n_gt + n_engine + n_lrc;
++
++      p = drmm_kzalloc(&xe->drm, sizeof(*p) * total, GFP_KERNEL);
++      if (!p)
++              return -ENOMEM;
++
++      gt->tuning_active.gt = p;
++      p += n_gt;
++      gt->tuning_active.engine = p;
++      p += n_engine;
++      gt->tuning_active.lrc = p;
++
++      return 0;
++}
++ALLOW_ERROR_INJECTION(xe_tuning_init, ERRNO); /* See xe_pci_probe() */
++
+ void xe_tuning_process_gt(struct xe_gt *gt)
+ {
+       struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
++      xe_rtp_process_ctx_enable_active_tracking(&ctx,
++                                                gt->tuning_active.gt,
++                                                ARRAY_SIZE(gt_tunings));
+       xe_rtp_process_to_sr(&ctx, gt_tunings, &gt->reg_sr);
+ }
+ EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
+@@ -147,6 +183,9 @@ void xe_tuning_process_engine(struct xe_hw_engine *hwe)
+ {
+       struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
++      xe_rtp_process_ctx_enable_active_tracking(&ctx,
++                                                hwe->gt->tuning_active.engine,
++                                                ARRAY_SIZE(engine_tunings));
+       xe_rtp_process_to_sr(&ctx, engine_tunings, &hwe->reg_sr);
+ }
+ EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_engine);
+@@ -163,5 +202,25 @@ void xe_tuning_process_lrc(struct xe_hw_engine *hwe)
+ {
+       struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
++      xe_rtp_process_ctx_enable_active_tracking(&ctx,
++                                                hwe->gt->tuning_active.lrc,
++                                                ARRAY_SIZE(lrc_tunings));
+       xe_rtp_process_to_sr(&ctx, lrc_tunings, &hwe->reg_lrc);
+ }
++
++void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p)
++{
++      size_t idx;
++
++      drm_printf(p, "GT Tunings\n");
++      for_each_set_bit(idx, gt->tuning_active.gt, ARRAY_SIZE(gt_tunings))
++              drm_printf_indent(p, 1, "%s\n", gt_tunings[idx].name);
++
++      drm_printf(p, "\nEngine Tunings\n");
++      for_each_set_bit(idx, gt->tuning_active.engine, ARRAY_SIZE(engine_tunings))
++              drm_printf_indent(p, 1, "%s\n", engine_tunings[idx].name);
++
++      drm_printf(p, "\nLRC Tunings\n");
++      for_each_set_bit(idx, gt->tuning_active.lrc, ARRAY_SIZE(lrc_tunings))
++              drm_printf_indent(p, 1, "%s\n", lrc_tunings[idx].name);
++}
+diff --git a/drivers/gpu/drm/xe/xe_tuning.h b/drivers/gpu/drm/xe/xe_tuning.h
+index 4f9c3ac3b5162..dd0d3ccc9c654 100644
+--- a/drivers/gpu/drm/xe/xe_tuning.h
++++ b/drivers/gpu/drm/xe/xe_tuning.h
+@@ -6,11 +6,14 @@
+ #ifndef _XE_TUNING_
+ #define _XE_TUNING_
++struct drm_printer;
+ struct xe_gt;
+ struct xe_hw_engine;
++int xe_tuning_init(struct xe_gt *gt);
+ void xe_tuning_process_gt(struct xe_gt *gt);
+ void xe_tuning_process_engine(struct xe_hw_engine *hwe);
+ void xe_tuning_process_lrc(struct xe_hw_engine *hwe);
++void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p);
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xe-ensure-fixed_slice_mode-gets-set-after-ccs_mo.patch b/queue-6.14/drm-xe-ensure-fixed_slice_mode-gets-set-after-ccs_mo.patch
new file mode 100644 (file)
index 0000000..666cb81
--- /dev/null
@@ -0,0 +1,63 @@
+From 98dbe574df630abc958636526793cefa2a5a6921 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 11:56:04 -0700
+Subject: drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change
+
+From: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+
+[ Upstream commit 262de94a3a7ef23c326534b3d9483602b7af841e ]
+
+The RCU_MODE_FIXED_SLICE_CCS_MODE setting is not getting invoked
+in the gt reset path after the ccs_mode setting by the user.
+Add it to engine register update list (in hw_engine_setup_default_state())
+which ensures it gets set in the gt reset and engine reset paths.
+
+v2: Add register update to engine list to ensure it gets updated
+after engine reset also.
+
+Fixes: 0d97ecce16bd ("drm/xe: Enable Fixed CCS mode setting")
+Cc: stable@vger.kernel.org
+Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250327185604.18230-1-niranjana.vishwanathapura@intel.com
+(cherry picked from commit 12468e519f98e4d93370712e3607fab61df9dae9)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_hw_engine.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
+index 223b95de388cb..b26b6fb5cdb5d 100644
+--- a/drivers/gpu/drm/xe/xe_hw_engine.c
++++ b/drivers/gpu/drm/xe/xe_hw_engine.c
+@@ -386,12 +386,6 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
+                                blit_cctl_val,
+                                XE_RTP_ACTION_FLAG(ENGINE_BASE)))
+               },
+-              /* Use Fixed slice CCS mode */
+-              { XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"),
+-                XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)),
+-                XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE,
+-                                         RCU_MODE_FIXED_SLICE_CCS_MODE))
+-              },
+               /* Disable WMTP if HW doesn't support it */
+               { XE_RTP_NAME("DISABLE_WMTP_ON_UNSUPPORTED_HW"),
+                 XE_RTP_RULES(FUNC(xe_rtp_cfeg_wmtp_disabled)),
+@@ -458,6 +452,12 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
+                 XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ,
+                                    XE_RTP_ACTION_FLAG(ENGINE_BASE)))
+               },
++              /* Use Fixed slice CCS mode */
++              { XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"),
++                XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)),
++                XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE,
++                                         RCU_MODE_FIXED_SLICE_CCS_MODE))
++              },
+       };
+       xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries), &hwe->reg_sr);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xe-ptl-apply-wa_14023061436.patch b/queue-6.14/drm-xe-ptl-apply-wa_14023061436.patch
new file mode 100644 (file)
index 0000000..2109566
--- /dev/null
@@ -0,0 +1,61 @@
+From 68b1acf9351779aaac1102c2826c747fbb4a1ffb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 15:13:23 +0100
+Subject: drm/xe/ptl: Apply Wa_14023061436
+
+From: Nirmoy Das <nirmoy.das@intel.com>
+
+[ Upstream commit 92029e0baa5313ba208103f90086f59070bbf93b ]
+
+Enable WMTP for the BTD kernel to address Wa14023061436 by setting the
+proper TDL Chicken Bit.
+
+v2: Apply it on engine_was[] as this register is not part of LRC(Matt)
+    Apply it for first_render_or_compute in case this gets extended to
+    compute only platforms(Matt).
+
+Cc: Gustavo Sousa <gustavo.sousa@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250108141323.311601-1-nirmoy.das@intel.com
+Signed-off-by: Nirmoy Das <nirmoy.das@intel.com>
+Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 +++
+ drivers/gpu/drm/xe/xe_wa.c           | 5 +++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+index 162f18e975dae..b4283ac030f41 100644
+--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
++++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+@@ -500,6 +500,9 @@
+ #define   LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK      REG_GENMASK(13, 11)
+ #define   DIS_ATOMIC_CHAINING_TYPED_WRITES    REG_BIT(3)
++#define TDL_CHICKEN                           XE_REG_MCR(0xe5f4, XE_REG_OPTION_MASKED)
++#define   QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE REG_BIT(12)
++
+ #define LSC_CHICKEN_BIT_0                     XE_REG_MCR(0xe7c8)
+ #define   DISABLE_D8_D16_COASLESCE            REG_BIT(30)
+ #define   WR_REQ_CHAINING_DIS                 REG_BIT(26)
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index 2553accf8c517..ac471e2454d34 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -613,6 +613,11 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+         XE_RTP_ACTIONS(FIELD_SET(SAMPLER_MODE, SMP_WAIT_FETCH_MERGING_COUNTER,
+                                  SMP_FORCE_128B_OVERFETCH))
+       },
++      { XE_RTP_NAME("14023061436"),
++        XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001),
++                     FUNC(xe_rtp_match_first_render_or_compute)),
++        XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE))
++      },
+       {}
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xe-rtp-drop-sentinels-from-arg-to-xe_rtp_process.patch b/queue-6.14/drm-xe-rtp-drop-sentinels-from-arg-to-xe_rtp_process.patch
new file mode 100644 (file)
index 0000000..4125051
--- /dev/null
@@ -0,0 +1,282 @@
+From 65c01faede743e6ef965f56e0b7f2aa1201b924d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 20:00:05 -0800
+Subject: drm/xe/rtp: Drop sentinels from arg to xe_rtp_process_to_sr()
+
+From: Lucas De Marchi <lucas.demarchi@intel.com>
+
+[ Upstream commit cedf23842d7433eb32cb782a637bb870fb096a3b ]
+
+There's a mismatch on API: while xe_rtp_process_to_sr() processes
+entries until an entry without name, the active tracking with
+xe_rtp_process_ctx_enable_active_tracking() needs to use the number of
+elements. The number of elements is taken everywhere using ARRAY_SIZE(),
+but that will have one entry too many. This leads to the following
+warning, as reported by lkp:
+
+   drivers/gpu/drm/xe/xe_tuning.c: In function 'xe_tuning_dump':
+>> include/drm/drm_print.h:228:31: warning: '%s' directive argument is null [-Wformat-overflow=]
+     228 |         drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__)
+         |                               ^~~~~~
+   drivers/gpu/drm/xe/xe_tuning.c:226:17: note: in expansion of macro 'drm_printf_indent'
+     226 |                 drm_printf_indent(p, 1, "%s\n", engine_tunings[idx].name);
+         |                 ^~~~~~~~~~~~~~~~~
+
+That's because it will still process the last entry when tracking the
+active tunings. The same issue exists in the WAs. Change
+xe_rtp_process_to_sr() to also take the number of elements so the empty
+entry can be removed and the warning should go away. Fixing on the
+active-tracking side would more fragile as the it would need a `- 1`
+everywhere and continue to use a different approach for number of
+elements.
+
+Aside from the warning, it's a non-issue as there would always be enough
+bits allocated and the last entry would never be active since
+xe_rtp_process_to_sr() stops on the sentinel.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202503021906.P2MwAvyK-lkp@intel.com/
+Cc: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250306-fix-print-warning-v1-1-979c3dc03c0d@intel.com
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+(cherry picked from commit 8aa8c2d4214e1771c32101d70740002662d31bb7)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/tests/xe_rtp_test.c |  2 +-
+ drivers/gpu/drm/xe/xe_hw_engine.c      |  6 ++----
+ drivers/gpu/drm/xe/xe_reg_whitelist.c  |  4 ++--
+ drivers/gpu/drm/xe/xe_rtp.c            |  6 +++++-
+ drivers/gpu/drm/xe/xe_rtp.h            |  2 +-
+ drivers/gpu/drm/xe/xe_tuning.c         | 12 ++++--------
+ drivers/gpu/drm/xe/xe_wa.c             | 12 +++---------
+ 7 files changed, 18 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/tests/xe_rtp_test.c b/drivers/gpu/drm/xe/tests/xe_rtp_test.c
+index 36a3b5420fef6..b0254b014fe45 100644
+--- a/drivers/gpu/drm/xe/tests/xe_rtp_test.c
++++ b/drivers/gpu/drm/xe/tests/xe_rtp_test.c
+@@ -320,7 +320,7 @@ static void xe_rtp_process_to_sr_tests(struct kunit *test)
+               count_rtp_entries++;
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, &active, count_rtp_entries);
+-      xe_rtp_process_to_sr(&ctx, param->entries, reg_sr);
++      xe_rtp_process_to_sr(&ctx, param->entries, count_rtp_entries, reg_sr);
+       xa_for_each(&reg_sr->xa, idx, sre) {
+               if (idx == param->expected_reg.addr)
+diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
+index fc447751fe786..223b95de388cb 100644
+--- a/drivers/gpu/drm/xe/xe_hw_engine.c
++++ b/drivers/gpu/drm/xe/xe_hw_engine.c
+@@ -400,10 +400,9 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
+                                          PREEMPT_GPGPU_THREAD_GROUP_LEVEL)),
+                 XE_RTP_ENTRY_FLAG(FOREACH_ENGINE)
+               },
+-              {}
+       };
+-      xe_rtp_process_to_sr(&ctx, lrc_setup, &hwe->reg_lrc);
++      xe_rtp_process_to_sr(&ctx, lrc_setup, ARRAY_SIZE(lrc_setup), &hwe->reg_lrc);
+ }
+ static void
+@@ -459,10 +458,9 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
+                 XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ,
+                                    XE_RTP_ACTION_FLAG(ENGINE_BASE)))
+               },
+-              {}
+       };
+-      xe_rtp_process_to_sr(&ctx, engine_entries, &hwe->reg_sr);
++      xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries), &hwe->reg_sr);
+ }
+ static const struct engine_info *find_engine_info(enum xe_engine_class class, int instance)
+diff --git a/drivers/gpu/drm/xe/xe_reg_whitelist.c b/drivers/gpu/drm/xe/xe_reg_whitelist.c
+index edab5d4e3ba5e..23f6c81d99946 100644
+--- a/drivers/gpu/drm/xe/xe_reg_whitelist.c
++++ b/drivers/gpu/drm/xe/xe_reg_whitelist.c
+@@ -88,7 +88,6 @@ static const struct xe_rtp_entry_sr register_whitelist[] = {
+                                  RING_FORCE_TO_NONPRIV_ACCESS_RD |
+                                  RING_FORCE_TO_NONPRIV_RANGE_4))
+       },
+-      {}
+ };
+ static void whitelist_apply_to_hwe(struct xe_hw_engine *hwe)
+@@ -137,7 +136,8 @@ void xe_reg_whitelist_process_engine(struct xe_hw_engine *hwe)
+ {
+       struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
+-      xe_rtp_process_to_sr(&ctx, register_whitelist, &hwe->reg_whitelist);
++      xe_rtp_process_to_sr(&ctx, register_whitelist, ARRAY_SIZE(register_whitelist),
++                           &hwe->reg_whitelist);
+       whitelist_apply_to_hwe(hwe);
+ }
+diff --git a/drivers/gpu/drm/xe/xe_rtp.c b/drivers/gpu/drm/xe/xe_rtp.c
+index 7a1c78fdfc92e..13bb62d3e615e 100644
+--- a/drivers/gpu/drm/xe/xe_rtp.c
++++ b/drivers/gpu/drm/xe/xe_rtp.c
+@@ -237,6 +237,7 @@ static void rtp_mark_active(struct xe_device *xe,
+  *                        the save-restore argument.
+  * @ctx: The context for processing the table, with one of device, gt or hwe
+  * @entries: Table with RTP definitions
++ * @n_entries: Number of entries to process, usually ARRAY_SIZE(entries)
+  * @sr: Save-restore struct where matching rules execute the action. This can be
+  *      viewed as the "coalesced view" of multiple the tables. The bits for each
+  *      register set are expected not to collide with previously added entries
+@@ -247,6 +248,7 @@ static void rtp_mark_active(struct xe_device *xe,
+  */
+ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
+                         const struct xe_rtp_entry_sr *entries,
++                        size_t n_entries,
+                         struct xe_reg_sr *sr)
+ {
+       const struct xe_rtp_entry_sr *entry;
+@@ -259,7 +261,9 @@ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
+       if (IS_SRIOV_VF(xe))
+               return;
+-      for (entry = entries; entry && entry->name; entry++) {
++      xe_assert(xe, entries);
++
++      for (entry = entries; entry - entries < n_entries; entry++) {
+               bool match = false;
+               if (entry->flags & XE_RTP_ENTRY_FLAG_FOREACH_ENGINE) {
+diff --git a/drivers/gpu/drm/xe/xe_rtp.h b/drivers/gpu/drm/xe/xe_rtp.h
+index 38b9f13bba5e5..4fe736a11c42b 100644
+--- a/drivers/gpu/drm/xe/xe_rtp.h
++++ b/drivers/gpu/drm/xe/xe_rtp.h
+@@ -430,7 +430,7 @@ void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
+ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
+                         const struct xe_rtp_entry_sr *entries,
+-                        struct xe_reg_sr *sr);
++                        size_t n_entries, struct xe_reg_sr *sr);
+ void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
+                   const struct xe_rtp_entry *entries);
+diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c
+index 23c46dd85e149..a61a2917590fe 100644
+--- a/drivers/gpu/drm/xe/xe_tuning.c
++++ b/drivers/gpu/drm/xe/xe_tuning.c
+@@ -85,8 +85,6 @@ static const struct xe_rtp_entry_sr gt_tunings[] = {
+         XE_RTP_RULES(MEDIA_VERSION(2000)),
+         XE_RTP_ACTIONS(SET(XE2LPM_SCRATCH3_LBCF, RWFLUSHALLEN))
+       },
+-
+-      {}
+ };
+ static const struct xe_rtp_entry_sr engine_tunings[] = {
+@@ -95,7 +93,6 @@ static const struct xe_rtp_entry_sr engine_tunings[] = {
+                      ENGINE_CLASS(RENDER)),
+         XE_RTP_ACTIONS(SET(SAMPLER_MODE, INDIRECT_STATE_BASE_ADDR_OVERRIDE))
+       },
+-      {}
+ };
+ static const struct xe_rtp_entry_sr lrc_tunings[] = {
+@@ -133,8 +130,6 @@ static const struct xe_rtp_entry_sr lrc_tunings[] = {
+         XE_RTP_ACTIONS(FIELD_SET(FF_MODE, VS_HIT_MAX_VALUE_MASK,
+                                  REG_FIELD_PREP(VS_HIT_MAX_VALUE_MASK, 0x3f)))
+       },
+-
+-      {}
+ };
+ /**
+@@ -175,7 +170,7 @@ void xe_tuning_process_gt(struct xe_gt *gt)
+       xe_rtp_process_ctx_enable_active_tracking(&ctx,
+                                                 gt->tuning_active.gt,
+                                                 ARRAY_SIZE(gt_tunings));
+-      xe_rtp_process_to_sr(&ctx, gt_tunings, &gt->reg_sr);
++      xe_rtp_process_to_sr(&ctx, gt_tunings, ARRAY_SIZE(gt_tunings), &gt->reg_sr);
+ }
+ EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
+@@ -186,7 +181,8 @@ void xe_tuning_process_engine(struct xe_hw_engine *hwe)
+       xe_rtp_process_ctx_enable_active_tracking(&ctx,
+                                                 hwe->gt->tuning_active.engine,
+                                                 ARRAY_SIZE(engine_tunings));
+-      xe_rtp_process_to_sr(&ctx, engine_tunings, &hwe->reg_sr);
++      xe_rtp_process_to_sr(&ctx, engine_tunings, ARRAY_SIZE(engine_tunings),
++                           &hwe->reg_sr);
+ }
+ EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_engine);
+@@ -205,7 +201,7 @@ void xe_tuning_process_lrc(struct xe_hw_engine *hwe)
+       xe_rtp_process_ctx_enable_active_tracking(&ctx,
+                                                 hwe->gt->tuning_active.lrc,
+                                                 ARRAY_SIZE(lrc_tunings));
+-      xe_rtp_process_to_sr(&ctx, lrc_tunings, &hwe->reg_lrc);
++      xe_rtp_process_to_sr(&ctx, lrc_tunings, ARRAY_SIZE(lrc_tunings), &hwe->reg_lrc);
+ }
+ void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p)
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index db99663963010..65bfb2f894d00 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -279,8 +279,6 @@ static const struct xe_rtp_entry_sr gt_was[] = {
+         XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), RAMDFTUNIT_CLKGATE_DIS)),
+         XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
+       },
+-
+-      {}
+ };
+ static const struct xe_rtp_entry_sr engine_was[] = {
+@@ -623,8 +621,6 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+                      FUNC(xe_rtp_match_first_render_or_compute)),
+         XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS))
+       },
+-
+-      {}
+ };
+ static const struct xe_rtp_entry_sr lrc_was[] = {
+@@ -817,8 +813,6 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+                            DIS_PARTIAL_AUTOSTRIP |
+                            DIS_AUTOSTRIP))
+       },
+-
+-      {}
+ };
+ static __maybe_unused const struct xe_rtp_entry oob_was[] = {
+@@ -860,7 +854,7 @@ void xe_wa_process_gt(struct xe_gt *gt)
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, gt->wa_active.gt,
+                                                 ARRAY_SIZE(gt_was));
+-      xe_rtp_process_to_sr(&ctx, gt_was, &gt->reg_sr);
++      xe_rtp_process_to_sr(&ctx, gt_was, ARRAY_SIZE(gt_was), &gt->reg_sr);
+ }
+ EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
+@@ -878,7 +872,7 @@ void xe_wa_process_engine(struct xe_hw_engine *hwe)
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.engine,
+                                                 ARRAY_SIZE(engine_was));
+-      xe_rtp_process_to_sr(&ctx, engine_was, &hwe->reg_sr);
++      xe_rtp_process_to_sr(&ctx, engine_was, ARRAY_SIZE(engine_was), &hwe->reg_sr);
+ }
+ /**
+@@ -895,7 +889,7 @@ void xe_wa_process_lrc(struct xe_hw_engine *hwe)
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.lrc,
+                                                 ARRAY_SIZE(lrc_was));
+-      xe_rtp_process_to_sr(&ctx, lrc_was, &hwe->reg_lrc);
++      xe_rtp_process_to_sr(&ctx, lrc_was, ARRAY_SIZE(lrc_was), &hwe->reg_lrc);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xe-xe3lpg-add-wa_13012615864.patch b/queue-6.14/drm-xe-xe3lpg-add-wa_13012615864.patch
new file mode 100644 (file)
index 0000000..125c451
--- /dev/null
@@ -0,0 +1,52 @@
+From 70e253df8a141f3aba232f0e8c0af20988af4ff2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 16:52:00 +0530
+Subject: drm/xe/xe3lpg: Add Wa_13012615864
+
+From: Tejas Upadhyay <tejas.upadhyay@intel.com>
+
+[ Upstream commit 2399bcc07c01189737858e0a88ac4ffdd1d4b03d ]
+
+Wa_13012615864 applies to  xe3lpg
+
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250221112200.388612-1-tejas.upadhyay@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/regs/xe_gt_regs.h | 1 +
+ drivers/gpu/drm/xe/xe_wa.c           | 5 +++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+index b4283ac030f41..d0ea8a55fd9c2 100644
+--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
++++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+@@ -475,6 +475,7 @@
+ #define TDL_TSL_CHICKEN                               XE_REG_MCR(0xe4c4, XE_REG_OPTION_MASKED)
+ #define   STK_ID_RESTRICT                     REG_BIT(12)
+ #define   SLM_WMTP_RESTORE                    REG_BIT(11)
++#define   RES_CHK_SPR_DIS                     REG_BIT(6)
+ #define ROW_CHICKEN                           XE_REG_MCR(0xe4f0, XE_REG_OPTION_MASKED)
+ #define   UGM_BACKUP_MODE                     REG_BIT(13)
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index ac471e2454d34..db99663963010 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -618,6 +618,11 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+                      FUNC(xe_rtp_match_first_render_or_compute)),
+         XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE))
+       },
++      { XE_RTP_NAME("13012615864"),
++        XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001),
++                     FUNC(xe_rtp_match_first_render_or_compute)),
++        XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS))
++      },
+       {}
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7768-1-fix-conversion-result-sign.patch b/queue-6.14/iio-adc-ad7768-1-fix-conversion-result-sign.patch
new file mode 100644 (file)
index 0000000..5ccf485
--- /dev/null
@@ -0,0 +1,55 @@
+From f251bba0d699fdad2d59896495b5f3ed47e6236d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 18:00:29 -0300
+Subject: iio: adc: ad7768-1: Fix conversion result sign
+
+From: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
+
+[ Upstream commit 8236644f5ecb180e80ad92d691c22bc509b747bb ]
+
+The ad7768-1 ADC output code is two's complement, meaning that the voltage
+conversion result is a signed value.. Since the value is a 24 bit one,
+stored in a 32 bit variable, the sign should be extended in order to get
+the correct representation.
+
+Also the channel description has been updated to signed representation,
+to match the ADC specifications.
+
+Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
+Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://patch.msgid.link/505994d3b71c2aa38ba714d909a68e021f12124c.1741268122.git.Jonathan.Santos@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7768-1.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index c78243a68b6e0..157a0df97f971 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -142,7 +142,7 @@ static const struct iio_chan_spec ad7768_channels[] = {
+               .channel = 0,
+               .scan_index = 0,
+               .scan_type = {
+-                      .sign = 'u',
++                      .sign = 's',
+                       .realbits = 24,
+                       .storagebits = 32,
+                       .shift = 8,
+@@ -374,7 +374,7 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
+               iio_device_release_direct_mode(indio_dev);
+               if (ret < 0)
+                       return ret;
+-              *val = ret;
++              *val = sign_extend32(ret, chan->scan_type.realbits - 1);
+               return IIO_VAL_INT;
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch b/queue-6.14/iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch
new file mode 100644 (file)
index 0000000..7cdb41c
--- /dev/null
@@ -0,0 +1,47 @@
+From 9261fdf9bd1370d4bbea0f7efd6a1dd146932392 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 14:16:12 +0000
+Subject: iio: adc: ad7768-1: Move setting of val a bit later to avoid
+ unnecessary return value check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 0af1c801a15225304a6328258efbf2bee245c654 ]
+
+The data used is all in local variables so there is no advantage
+in setting *val = ret with the direct mode claim held.
+Move it later to after error check.
+
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250217141630.897334-13-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 8236644f5ecb ("iio: adc: ad7768-1: Fix conversion result sign")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7768-1.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index 6f8816483f1a0..c78243a68b6e0 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -370,12 +370,11 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
+                       return ret;
+               ret = ad7768_scan_direct(indio_dev);
+-              if (ret >= 0)
+-                      *val = ret;
+               iio_device_release_direct_mode(indio_dev);
+               if (ret < 0)
+                       return ret;
++              *val = ret;
+               return IIO_VAL_INT;
+-- 
+2.39.5
+
diff --git a/queue-6.14/irqchip-renesas-rzv2h-add-struct-rzv2h_hw_info-with-.patch b/queue-6.14/irqchip-renesas-rzv2h-add-struct-rzv2h_hw_info-with-.patch
new file mode 100644 (file)
index 0000000..aadb20d
--- /dev/null
@@ -0,0 +1,179 @@
+From 5a96a94b338875c0e3b145df8638f6306eafdd24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 13:11:23 +0000
+Subject: irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit 0a9d6ef64e5e917f93db98935cd09bac38507ebf ]
+
+The ICU block on the RZ/G3E SoC is almost identical to the one found on
+the RZ/V2H SoC, with the following differences:
+
+ - The TINT register base offset is 0x800 instead of zero.
+ - The number of GPIO interrupts for TINT selection is 141 instead of 86.
+ - The pin index and TINT selection index are not in the 1:1 map
+ - The number of TSSR registers is 16 instead of 8
+ - Each TSSR register can program 2 TINTs instead of 4 TINTs
+
+Introduce struct rzv2h_hw_info to describe the SoC properties and refactor
+the code by moving rzv2h_icu_init() into rzv2h_icu_init_common() and pass
+the variable containing hw difference to support both these SoCs.
+
+As a first step add t_offs to the new struct and replace the hardcoded
+constants in the code.
+
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/all/20250224131253.134199-8-biju.das.jz@bp.renesas.com
+Stable-dep-of: 28e89cdac648 ("irqchip/renesas-rzv2h: Prevent TINT spurious interrupt")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-renesas-rzv2h.c | 46 +++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
+index 6be38aa86f9b8..5fcc6ed4086cd 100644
+--- a/drivers/irqchip/irq-renesas-rzv2h.c
++++ b/drivers/irqchip/irq-renesas-rzv2h.c
+@@ -80,18 +80,28 @@
+ #define ICU_TINT_EXTRACT_GPIOINT(x)           FIELD_GET(GENMASK(31, 16), (x))
+ #define ICU_PB5_TINT                          0x55
++/**
++ * struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
++ * @t_offs:           TINT offset
++ */
++struct rzv2h_hw_info {
++      u16             t_offs;
++};
++
+ /**
+  * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
+  * @base:     Controller's base address
+  * @irqchip:  Pointer to struct irq_chip
+  * @fwspec:   IRQ firmware specific data
+  * @lock:     Lock to serialize access to hardware registers
++ * @info:     Pointer to struct rzv2h_hw_info
+  */
+ struct rzv2h_icu_priv {
+       void __iomem                    *base;
+       const struct irq_chip           *irqchip;
+       struct irq_fwspec               fwspec[ICU_NUM_IRQ];
+       raw_spinlock_t                  lock;
++      const struct rzv2h_hw_info      *info;
+ };
+ static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
+@@ -111,7 +121,7 @@ static void rzv2h_icu_eoi(struct irq_data *d)
+                       tintirq_nr = hw_irq - ICU_TINT_START;
+                       bit = BIT(tintirq_nr);
+                       if (!irqd_is_level_type(d))
+-                              writel_relaxed(bit, priv->base + ICU_TSCLR);
++                              writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR);
+               } else if (hw_irq >= ICU_IRQ_START) {
+                       tintirq_nr = hw_irq - ICU_IRQ_START;
+                       bit = BIT(tintirq_nr);
+@@ -139,12 +149,12 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
+       tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
+       guard(raw_spinlock)(&priv->lock);
+-      tssr = readl_relaxed(priv->base + ICU_TSSR(k));
++      tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k));
+       if (enable)
+               tssr |= ICU_TSSR_TIEN(tssel_n);
+       else
+               tssr &= ~ICU_TSSR_TIEN(tssel_n);
+-      writel_relaxed(tssr, priv->base + ICU_TSSR(k));
++      writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
+ }
+ static void rzv2h_icu_irq_disable(struct irq_data *d)
+@@ -247,8 +257,8 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
+       u32 bit = BIT(tint_nr);
+       int k = tint_nr / 16;
+-      tsctr = readl_relaxed(priv->base + ICU_TSCTR);
+-      titsr = readl_relaxed(priv->base + ICU_TITSR(k));
++      tsctr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSCTR);
++      titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(k));
+       titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n);
+       /*
+@@ -257,7 +267,7 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
+        */
+       if ((tsctr & bit) && ((titsel == ICU_TINT_EDGE_RISING) ||
+                             (titsel == ICU_TINT_EDGE_FALLING)))
+-              writel_relaxed(bit, priv->base + ICU_TSCLR);
++              writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR);
+ }
+ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
+@@ -308,21 +318,21 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
+       guard(raw_spinlock)(&priv->lock);
+-      tssr = readl_relaxed(priv->base + ICU_TSSR(tssr_k));
++      tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
+       tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n) | tien);
+       tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n);
+-      writel_relaxed(tssr, priv->base + ICU_TSSR(tssr_k));
++      writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
+-      titsr = readl_relaxed(priv->base + ICU_TITSR(titsr_k));
++      titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
+       titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n);
+       titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n);
+-      writel_relaxed(titsr, priv->base + ICU_TITSR(titsr_k));
++      writel_relaxed(titsr, priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
+       rzv2h_clear_tint_int(priv, hwirq);
+-      writel_relaxed(tssr | tien, priv->base + ICU_TSSR(tssr_k));
++      writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
+       return 0;
+ }
+@@ -426,7 +436,8 @@ static void rzv2h_icu_put_device(void *data)
+       put_device(data);
+ }
+-static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
++static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent,
++                               const struct rzv2h_hw_info *hw_info)
+ {
+       struct irq_domain *irq_domain, *parent_domain;
+       struct rzv2h_icu_priv *rzv2h_icu_data;
+@@ -492,6 +503,8 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
+               goto pm_put;
+       }
++      rzv2h_icu_data->info = hw_info;
++
+       /*
+        * coccicheck complains about a missing put_device call before returning, but it's a false
+        * positive. We still need &pdev->dev after successfully returning from this function.
+@@ -507,6 +520,15 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
+       return ret;
+ }
++static const struct rzv2h_hw_info rzv2h_hw_params = {
++      .t_offs         = 0,
++};
++
++static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
++{
++      return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params);
++}
++
+ IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu)
+ IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)
+ IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)
+-- 
+2.39.5
+
diff --git a/queue-6.14/irqchip-renesas-rzv2h-prevent-tint-spurious-interrup.patch b/queue-6.14/irqchip-renesas-rzv2h-prevent-tint-spurious-interrup.patch
new file mode 100644 (file)
index 0000000..291eea1
--- /dev/null
@@ -0,0 +1,47 @@
+From dd482d36ba426ba338c97dab13b91be003b10cbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 11:33:41 +0100
+Subject: irqchip/renesas-rzv2h: Prevent TINT spurious interrupt
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit 28e89cdac6482f3c980df3e2e245db7366269124 ]
+
+A spurious TINT interrupt is seen during boot on RZ/G3E SMARC EVK.
+
+A glitch in the edge detection circuit can cause a spurious interrupt.
+
+Clear the status flag after setting the ICU_TSSRk registers, which is
+recommended in the hardware manual as a countermeasure.
+
+Fixes: 0d7605e75ac2 ("irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-renesas-rzv2h.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
+index 5fcc6ed4086cd..21d01ce2da5cf 100644
+--- a/drivers/irqchip/irq-renesas-rzv2h.c
++++ b/drivers/irqchip/irq-renesas-rzv2h.c
+@@ -155,6 +155,14 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
+       else
+               tssr &= ~ICU_TSSR_TIEN(tssel_n);
+       writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
++
++      /*
++       * A glitch in the edge detection circuit can cause a spurious
++       * interrupt. Clear the status flag after setting the ICU_TSSRk
++       * registers, which is recommended by the hardware manual as a
++       * countermeasure.
++       */
++      writel_relaxed(BIT(tint_nr), priv->base + priv->info->t_offs + ICU_TSCLR);
+ }
+ static void rzv2h_icu_irq_disable(struct irq_data *d)
+-- 
+2.39.5
+
diff --git a/queue-6.14/irqchip-renesas-rzv2h-simplify-rzv2h_icu_init.patch b/queue-6.14/irqchip-renesas-rzv2h-simplify-rzv2h_icu_init.patch
new file mode 100644 (file)
index 0000000..3dde5a1
--- /dev/null
@@ -0,0 +1,110 @@
+From 1b063148ab837edfe205f3e57f3dcad16ee736c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 13:11:20 +0000
+Subject: irqchip/renesas-rzv2h: Simplify rzv2h_icu_init()
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit f5de95438834a3bc3ad747f67c9da93cd08e5008 ]
+
+Use devm_add_action_or_reset() for calling put_device in error path of
+rzv2h_icu_init() to simplify the code by using the recently added devm_*
+helpers.
+
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://lore.kernel.org/all/20250224131253.134199-5-biju.das.jz@bp.renesas.com
+Stable-dep-of: 28e89cdac648 ("irqchip/renesas-rzv2h: Prevent TINT spurious interrupt")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-renesas-rzv2h.c | 37 +++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
+index f6363246a71a0..6be38aa86f9b8 100644
+--- a/drivers/irqchip/irq-renesas-rzv2h.c
++++ b/drivers/irqchip/irq-renesas-rzv2h.c
+@@ -421,6 +421,11 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device
+       return 0;
+ }
++static void rzv2h_icu_put_device(void *data)
++{
++      put_device(data);
++}
++
+ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
+ {
+       struct irq_domain *irq_domain, *parent_domain;
+@@ -433,43 +438,41 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
+       if (!pdev)
+               return -ENODEV;
++      ret = devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device,
++                                     &pdev->dev);
++      if (ret < 0)
++              return ret;
++
+       parent_domain = irq_find_host(parent);
+       if (!parent_domain) {
+               dev_err(&pdev->dev, "cannot find parent domain\n");
+-              ret = -ENODEV;
+-              goto put_dev;
++              return -ENODEV;
+       }
+       rzv2h_icu_data = devm_kzalloc(&pdev->dev, sizeof(*rzv2h_icu_data), GFP_KERNEL);
+-      if (!rzv2h_icu_data) {
+-              ret = -ENOMEM;
+-              goto put_dev;
+-      }
++      if (!rzv2h_icu_data)
++              return -ENOMEM;
+       rzv2h_icu_data->irqchip = &rzv2h_icu_chip;
+       rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
+-      if (IS_ERR(rzv2h_icu_data->base)) {
+-              ret = PTR_ERR(rzv2h_icu_data->base);
+-              goto put_dev;
+-      }
++      if (IS_ERR(rzv2h_icu_data->base))
++              return PTR_ERR(rzv2h_icu_data->base);
+       ret = rzv2h_icu_parse_interrupts(rzv2h_icu_data, node);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret);
+-              goto put_dev;
++              return ret;
+       }
+       resetn = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+-      if (IS_ERR(resetn)) {
+-              ret = PTR_ERR(resetn);
+-              goto put_dev;
+-      }
++      if (IS_ERR(resetn))
++              return PTR_ERR(resetn);
+       ret = reset_control_deassert(resetn);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to deassert resetn pin, %d\n", ret);
+-              goto put_dev;
++              return ret;
+       }
+       pm_runtime_enable(&pdev->dev);
+@@ -500,8 +503,6 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
+ pm_disable:
+       pm_runtime_disable(&pdev->dev);
+       reset_control_assert(resetn);
+-put_dev:
+-      put_device(&pdev->dev);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/lib-kconfig.ubsan-remove-default-ubsan-from-ubsan_in.patch b/queue-6.14/lib-kconfig.ubsan-remove-default-ubsan-from-ubsan_in.patch
new file mode 100644 (file)
index 0000000..2ccfcf3
--- /dev/null
@@ -0,0 +1,53 @@
+From 559e377ae6ac36746e3d33d8d6a0f65c11bfe0fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 15:00:59 -0700
+Subject: lib/Kconfig.ubsan: Remove 'default UBSAN' from UBSAN_INTEGER_WRAP
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit cdc2e1d9d929d7f7009b3a5edca52388a2b0891f ]
+
+CONFIG_UBSAN_INTEGER_WRAP is 'default UBSAN', which is problematic for a
+couple of reasons.
+
+The first is that this sanitizer is under active development on the
+compiler side to come up with a solution that is maintainable on the
+compiler side and usable on the kernel side. As a result of this, there
+are many warnings when the sanitizer is enabled that have no clear path
+to resolution yet but users may see them and report them in the meantime.
+
+The second is that this option was renamed from
+CONFIG_UBSAN_SIGNED_WRAP, meaning that if a configuration has
+CONFIG_UBSAN=y but CONFIG_UBSAN_SIGNED_WRAP=n and it is upgraded via
+olddefconfig (common in non-interactive scenarios such as CI),
+CONFIG_UBSAN_INTEGER_WRAP will be silently enabled again.
+
+Remove 'default UBSAN' from CONFIG_UBSAN_INTEGER_WRAP until it is ready
+for regular usage and testing from a broader community than the folks
+actively working on the feature.
+
+Cc: stable@vger.kernel.org
+Fixes: 557f8c582a9b ("ubsan: Reintroduce signed overflow sanitizer")
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20250414-drop-default-ubsan-integer-wrap-v1-1-392522551d6b@kernel.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/Kconfig.ubsan | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
+index 63e5622010e0f..37b2839bd442f 100644
+--- a/lib/Kconfig.ubsan
++++ b/lib/Kconfig.ubsan
+@@ -118,7 +118,6 @@ config UBSAN_UNREACHABLE
+ config UBSAN_INTEGER_WRAP
+       bool "Perform checking for integer arithmetic wrap-around"
+-      default UBSAN
+       depends on !COMPILE_TEST
+       depends on $(cc-option,-fsanitize=signed-integer-overflow)
+       depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-i2c-imx214-check-number-of-lanes-from-device-t.patch b/queue-6.14/media-i2c-imx214-check-number-of-lanes-from-device-t.patch
new file mode 100644 (file)
index 0000000..4d0a373
--- /dev/null
@@ -0,0 +1,78 @@
+From 9811d7f6f8dbabda22c5061daec604201c1af696 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 14:26:05 +0100
+Subject: media: i2c: imx214: Check number of lanes from device tree
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit 3d55f4eb03fce69f3a72615fe9c5ca171f7b846b ]
+
+The imx214 camera is capable of either two-lane or four-lane operation.
+
+Currently only the four-lane mode is supported, as proper pixel rates
+and link frequences for the two-lane mode are unknown.
+
+Acked-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx214.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
+index 8bac5a1f1cb18..fdc2dfb4ebcdd 100644
+--- a/drivers/media/i2c/imx214.c
++++ b/drivers/media/i2c/imx214.c
+@@ -197,7 +197,6 @@ struct imx214 {
+ /*From imx214_mode_tbls.h*/
+ static const struct cci_reg_sequence mode_4096x2304[] = {
+-      { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE },
+       { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF },
+       { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH },
+       { IMX214_REG_EXPOSURE_RATIO, 1 },
+@@ -271,7 +270,6 @@ static const struct cci_reg_sequence mode_4096x2304[] = {
+ };
+ static const struct cci_reg_sequence mode_1920x1080[] = {
+-      { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE },
+       { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF },
+       { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH },
+       { IMX214_REG_EXPOSURE_RATIO, 1 },
+@@ -789,6 +787,13 @@ static int imx214_start_streaming(struct imx214 *imx214)
+               return ret;
+       }
++      ret = cci_write(imx214->regmap, IMX214_REG_CSI_LANE_MODE,
++                      IMX214_CSI_4_LANE_MODE, NULL);
++      if (ret) {
++              dev_err(imx214->dev, "failed to configure lanes\n");
++              return ret;
++      }
++
+       state = v4l2_subdev_get_locked_active_state(&imx214->sd);
+       fmt = v4l2_subdev_state_get_format(state, 0);
+       mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes),
+@@ -953,6 +958,13 @@ static int imx214_parse_fwnode(struct device *dev)
+               goto done;
+       }
++      /* Check the number of MIPI CSI2 data lanes */
++      if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
++              ret = dev_err_probe(dev, -EINVAL,
++                                  "only 4 data lanes are currently supported\n");
++              goto done;
++      }
++
+       for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
+               if (bus_cfg.link_frequencies[i] == IMX214_DEFAULT_LINK_FREQ)
+                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-i2c-imx214-convert-to-cci-register-access-help.patch b/queue-6.14/media-i2c-imx214-convert-to-cci-register-access-help.patch
new file mode 100644 (file)
index 0000000..e6c200a
--- /dev/null
@@ -0,0 +1,858 @@
+From 868252bb20620a9c5788c35232652871a8f4ff5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 14:26:02 +0100
+Subject: media: i2c: imx214: Convert to CCI register access helpers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit 4f0aeba4f1556f829f09073bf267093c5b6f1821 ]
+
+Use the new common CCI register access helpers to replace the private
+register access helpers in the imx214 driver. This simplifies the driver
+by reducing the amount of code.
+
+Acked-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/Kconfig  |   1 +
+ drivers/media/i2c/imx214.c | 672 +++++++++++++++++--------------------
+ 2 files changed, 310 insertions(+), 363 deletions(-)
+
+diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
+index 8ba096b8ebca2..85ecb2aeefdbf 100644
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -140,6 +140,7 @@ config VIDEO_IMX214
+       tristate "Sony IMX214 sensor support"
+       depends on GPIOLIB
+       select REGMAP_I2C
++      select V4L2_CCI_I2C
+       help
+         This is a Video4Linux2 sensor driver for the Sony
+         IMX214 camera.
+diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
+index db6cdc3b65e37..20d1ebebf13af 100644
+--- a/drivers/media/i2c/imx214.c
++++ b/drivers/media/i2c/imx214.c
+@@ -15,11 +15,12 @@
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ #include <media/media-entity.h>
++#include <media/v4l2-cci.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-fwnode.h>
+ #include <media/v4l2-subdev.h>
+-#define IMX214_REG_MODE_SELECT                0x0100
++#define IMX214_REG_MODE_SELECT                CCI_REG8(0x0100)
+ #define IMX214_MODE_STANDBY           0x00
+ #define IMX214_MODE_STREAMING         0x01
+@@ -30,7 +31,7 @@
+ #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
+ /* Exposure control */
+-#define IMX214_REG_EXPOSURE           0x0202
++#define IMX214_REG_EXPOSURE           CCI_REG16(0x0202)
+ #define IMX214_EXPOSURE_MIN           0
+ #define IMX214_EXPOSURE_MAX           3184
+ #define IMX214_EXPOSURE_STEP          1
+@@ -71,345 +72,324 @@ struct imx214 {
+       struct gpio_desc *enable_gpio;
+ };
+-struct reg_8 {
+-      u16 addr;
+-      u8 val;
+-};
+-
+-enum {
+-      IMX214_TABLE_WAIT_MS = 0,
+-      IMX214_TABLE_END,
+-      IMX214_MAX_RETRIES,
+-      IMX214_WAIT_MS
+-};
+-
+ /*From imx214_mode_tbls.h*/
+-static const struct reg_8 mode_4096x2304[] = {
+-      {0x0114, 0x03},
+-      {0x0220, 0x00},
+-      {0x0221, 0x11},
+-      {0x0222, 0x01},
+-      {0x0340, 0x0C},
+-      {0x0341, 0x7A},
+-      {0x0342, 0x13},
+-      {0x0343, 0x90},
+-      {0x0344, 0x00},
+-      {0x0345, 0x38},
+-      {0x0346, 0x01},
+-      {0x0347, 0x98},
+-      {0x0348, 0x10},
+-      {0x0349, 0x37},
+-      {0x034A, 0x0A},
+-      {0x034B, 0x97},
+-      {0x0381, 0x01},
+-      {0x0383, 0x01},
+-      {0x0385, 0x01},
+-      {0x0387, 0x01},
+-      {0x0900, 0x00},
+-      {0x0901, 0x00},
+-      {0x0902, 0x00},
+-      {0x3000, 0x35},
+-      {0x3054, 0x01},
+-      {0x305C, 0x11},
+-
+-      {0x0112, 0x0A},
+-      {0x0113, 0x0A},
+-      {0x034C, 0x10},
+-      {0x034D, 0x00},
+-      {0x034E, 0x09},
+-      {0x034F, 0x00},
+-      {0x0401, 0x00},
+-      {0x0404, 0x00},
+-      {0x0405, 0x10},
+-      {0x0408, 0x00},
+-      {0x0409, 0x00},
+-      {0x040A, 0x00},
+-      {0x040B, 0x00},
+-      {0x040C, 0x10},
+-      {0x040D, 0x00},
+-      {0x040E, 0x09},
+-      {0x040F, 0x00},
+-
+-      {0x0301, 0x05},
+-      {0x0303, 0x02},
+-      {0x0305, 0x03},
+-      {0x0306, 0x00},
+-      {0x0307, 0x96},
+-      {0x0309, 0x0A},
+-      {0x030B, 0x01},
+-      {0x0310, 0x00},
+-
+-      {0x0820, 0x12},
+-      {0x0821, 0xC0},
+-      {0x0822, 0x00},
+-      {0x0823, 0x00},
+-
+-      {0x3A03, 0x09},
+-      {0x3A04, 0x50},
+-      {0x3A05, 0x01},
+-
+-      {0x0B06, 0x01},
+-      {0x30A2, 0x00},
+-
+-      {0x30B4, 0x00},
+-
+-      {0x3A02, 0xFF},
+-
+-      {0x3011, 0x00},
+-      {0x3013, 0x01},
+-
+-      {0x0202, 0x0C},
+-      {0x0203, 0x70},
+-      {0x0224, 0x01},
+-      {0x0225, 0xF4},
+-
+-      {0x0204, 0x00},
+-      {0x0205, 0x00},
+-      {0x020E, 0x01},
+-      {0x020F, 0x00},
+-      {0x0210, 0x01},
+-      {0x0211, 0x00},
+-      {0x0212, 0x01},
+-      {0x0213, 0x00},
+-      {0x0214, 0x01},
+-      {0x0215, 0x00},
+-      {0x0216, 0x00},
+-      {0x0217, 0x00},
+-
+-      {0x4170, 0x00},
+-      {0x4171, 0x10},
+-      {0x4176, 0x00},
+-      {0x4177, 0x3C},
+-      {0xAE20, 0x04},
+-      {0xAE21, 0x5C},
+-
+-      {IMX214_TABLE_WAIT_MS, 10},
+-      {0x0138, 0x01},
+-      {IMX214_TABLE_END, 0x00}
++static const struct cci_reg_sequence mode_4096x2304[] = {
++      { CCI_REG8(0x0114), 0x03 },
++      { CCI_REG8(0x0220), 0x00 },
++      { CCI_REG8(0x0221), 0x11 },
++      { CCI_REG8(0x0222), 0x01 },
++      { CCI_REG8(0x0340), 0x0C },
++      { CCI_REG8(0x0341), 0x7A },
++      { CCI_REG8(0x0342), 0x13 },
++      { CCI_REG8(0x0343), 0x90 },
++      { CCI_REG8(0x0344), 0x00 },
++      { CCI_REG8(0x0345), 0x38 },
++      { CCI_REG8(0x0346), 0x01 },
++      { CCI_REG8(0x0347), 0x98 },
++      { CCI_REG8(0x0348), 0x10 },
++      { CCI_REG8(0x0349), 0x37 },
++      { CCI_REG8(0x034A), 0x0A },
++      { CCI_REG8(0x034B), 0x97 },
++      { CCI_REG8(0x0381), 0x01 },
++      { CCI_REG8(0x0383), 0x01 },
++      { CCI_REG8(0x0385), 0x01 },
++      { CCI_REG8(0x0387), 0x01 },
++      { CCI_REG8(0x0900), 0x00 },
++      { CCI_REG8(0x0901), 0x00 },
++      { CCI_REG8(0x0902), 0x00 },
++      { CCI_REG8(0x3000), 0x35 },
++      { CCI_REG8(0x3054), 0x01 },
++      { CCI_REG8(0x305C), 0x11 },
++
++      { CCI_REG8(0x0112), 0x0A },
++      { CCI_REG8(0x0113), 0x0A },
++      { CCI_REG8(0x034C), 0x10 },
++      { CCI_REG8(0x034D), 0x00 },
++      { CCI_REG8(0x034E), 0x09 },
++      { CCI_REG8(0x034F), 0x00 },
++      { CCI_REG8(0x0401), 0x00 },
++      { CCI_REG8(0x0404), 0x00 },
++      { CCI_REG8(0x0405), 0x10 },
++      { CCI_REG8(0x0408), 0x00 },
++      { CCI_REG8(0x0409), 0x00 },
++      { CCI_REG8(0x040A), 0x00 },
++      { CCI_REG8(0x040B), 0x00 },
++      { CCI_REG8(0x040C), 0x10 },
++      { CCI_REG8(0x040D), 0x00 },
++      { CCI_REG8(0x040E), 0x09 },
++      { CCI_REG8(0x040F), 0x00 },
++
++      { CCI_REG8(0x0301), 0x05 },
++      { CCI_REG8(0x0303), 0x02 },
++      { CCI_REG8(0x0305), 0x03 },
++      { CCI_REG8(0x0306), 0x00 },
++      { CCI_REG8(0x0307), 0x96 },
++      { CCI_REG8(0x0309), 0x0A },
++      { CCI_REG8(0x030B), 0x01 },
++      { CCI_REG8(0x0310), 0x00 },
++
++      { CCI_REG8(0x0820), 0x12 },
++      { CCI_REG8(0x0821), 0xC0 },
++      { CCI_REG8(0x0822), 0x00 },
++      { CCI_REG8(0x0823), 0x00 },
++
++      { CCI_REG8(0x3A03), 0x09 },
++      { CCI_REG8(0x3A04), 0x50 },
++      { CCI_REG8(0x3A05), 0x01 },
++
++      { CCI_REG8(0x0B06), 0x01 },
++      { CCI_REG8(0x30A2), 0x00 },
++
++      { CCI_REG8(0x30B4), 0x00 },
++
++      { CCI_REG8(0x3A02), 0xFF },
++
++      { CCI_REG8(0x3011), 0x00 },
++      { CCI_REG8(0x3013), 0x01 },
++
++      { CCI_REG8(0x0202), 0x0C },
++      { CCI_REG8(0x0203), 0x70 },
++      { CCI_REG8(0x0224), 0x01 },
++      { CCI_REG8(0x0225), 0xF4 },
++
++      { CCI_REG8(0x0204), 0x00 },
++      { CCI_REG8(0x0205), 0x00 },
++      { CCI_REG8(0x020E), 0x01 },
++      { CCI_REG8(0x020F), 0x00 },
++      { CCI_REG8(0x0210), 0x01 },
++      { CCI_REG8(0x0211), 0x00 },
++      { CCI_REG8(0x0212), 0x01 },
++      { CCI_REG8(0x0213), 0x00 },
++      { CCI_REG8(0x0214), 0x01 },
++      { CCI_REG8(0x0215), 0x00 },
++      { CCI_REG8(0x0216), 0x00 },
++      { CCI_REG8(0x0217), 0x00 },
++
++      { CCI_REG8(0x4170), 0x00 },
++      { CCI_REG8(0x4171), 0x10 },
++      { CCI_REG8(0x4176), 0x00 },
++      { CCI_REG8(0x4177), 0x3C },
++      { CCI_REG8(0xAE20), 0x04 },
++      { CCI_REG8(0xAE21), 0x5C },
+ };
+-static const struct reg_8 mode_1920x1080[] = {
+-      {0x0114, 0x03},
+-      {0x0220, 0x00},
+-      {0x0221, 0x11},
+-      {0x0222, 0x01},
+-      {0x0340, 0x0C},
+-      {0x0341, 0x7A},
+-      {0x0342, 0x13},
+-      {0x0343, 0x90},
+-      {0x0344, 0x04},
+-      {0x0345, 0x78},
+-      {0x0346, 0x03},
+-      {0x0347, 0xFC},
+-      {0x0348, 0x0B},
+-      {0x0349, 0xF7},
+-      {0x034A, 0x08},
+-      {0x034B, 0x33},
+-      {0x0381, 0x01},
+-      {0x0383, 0x01},
+-      {0x0385, 0x01},
+-      {0x0387, 0x01},
+-      {0x0900, 0x00},
+-      {0x0901, 0x00},
+-      {0x0902, 0x00},
+-      {0x3000, 0x35},
+-      {0x3054, 0x01},
+-      {0x305C, 0x11},
+-
+-      {0x0112, 0x0A},
+-      {0x0113, 0x0A},
+-      {0x034C, 0x07},
+-      {0x034D, 0x80},
+-      {0x034E, 0x04},
+-      {0x034F, 0x38},
+-      {0x0401, 0x00},
+-      {0x0404, 0x00},
+-      {0x0405, 0x10},
+-      {0x0408, 0x00},
+-      {0x0409, 0x00},
+-      {0x040A, 0x00},
+-      {0x040B, 0x00},
+-      {0x040C, 0x07},
+-      {0x040D, 0x80},
+-      {0x040E, 0x04},
+-      {0x040F, 0x38},
+-
+-      {0x0301, 0x05},
+-      {0x0303, 0x02},
+-      {0x0305, 0x03},
+-      {0x0306, 0x00},
+-      {0x0307, 0x96},
+-      {0x0309, 0x0A},
+-      {0x030B, 0x01},
+-      {0x0310, 0x00},
+-
+-      {0x0820, 0x12},
+-      {0x0821, 0xC0},
+-      {0x0822, 0x00},
+-      {0x0823, 0x00},
+-
+-      {0x3A03, 0x04},
+-      {0x3A04, 0xF8},
+-      {0x3A05, 0x02},
+-
+-      {0x0B06, 0x01},
+-      {0x30A2, 0x00},
+-
+-      {0x30B4, 0x00},
+-
+-      {0x3A02, 0xFF},
+-
+-      {0x3011, 0x00},
+-      {0x3013, 0x01},
+-
+-      {0x0202, 0x0C},
+-      {0x0203, 0x70},
+-      {0x0224, 0x01},
+-      {0x0225, 0xF4},
+-
+-      {0x0204, 0x00},
+-      {0x0205, 0x00},
+-      {0x020E, 0x01},
+-      {0x020F, 0x00},
+-      {0x0210, 0x01},
+-      {0x0211, 0x00},
+-      {0x0212, 0x01},
+-      {0x0213, 0x00},
+-      {0x0214, 0x01},
+-      {0x0215, 0x00},
+-      {0x0216, 0x00},
+-      {0x0217, 0x00},
+-
+-      {0x4170, 0x00},
+-      {0x4171, 0x10},
+-      {0x4176, 0x00},
+-      {0x4177, 0x3C},
+-      {0xAE20, 0x04},
+-      {0xAE21, 0x5C},
+-
+-      {IMX214_TABLE_WAIT_MS, 10},
+-      {0x0138, 0x01},
+-      {IMX214_TABLE_END, 0x00}
++static const struct cci_reg_sequence mode_1920x1080[] = {
++      { CCI_REG8(0x0114), 0x03 },
++      { CCI_REG8(0x0220), 0x00 },
++      { CCI_REG8(0x0221), 0x11 },
++      { CCI_REG8(0x0222), 0x01 },
++      { CCI_REG8(0x0340), 0x0C },
++      { CCI_REG8(0x0341), 0x7A },
++      { CCI_REG8(0x0342), 0x13 },
++      { CCI_REG8(0x0343), 0x90 },
++      { CCI_REG8(0x0344), 0x04 },
++      { CCI_REG8(0x0345), 0x78 },
++      { CCI_REG8(0x0346), 0x03 },
++      { CCI_REG8(0x0347), 0xFC },
++      { CCI_REG8(0x0348), 0x0B },
++      { CCI_REG8(0x0349), 0xF7 },
++      { CCI_REG8(0x034A), 0x08 },
++      { CCI_REG8(0x034B), 0x33 },
++      { CCI_REG8(0x0381), 0x01 },
++      { CCI_REG8(0x0383), 0x01 },
++      { CCI_REG8(0x0385), 0x01 },
++      { CCI_REG8(0x0387), 0x01 },
++      { CCI_REG8(0x0900), 0x00 },
++      { CCI_REG8(0x0901), 0x00 },
++      { CCI_REG8(0x0902), 0x00 },
++      { CCI_REG8(0x3000), 0x35 },
++      { CCI_REG8(0x3054), 0x01 },
++      { CCI_REG8(0x305C), 0x11 },
++
++      { CCI_REG8(0x0112), 0x0A },
++      { CCI_REG8(0x0113), 0x0A },
++      { CCI_REG8(0x034C), 0x07 },
++      { CCI_REG8(0x034D), 0x80 },
++      { CCI_REG8(0x034E), 0x04 },
++      { CCI_REG8(0x034F), 0x38 },
++      { CCI_REG8(0x0401), 0x00 },
++      { CCI_REG8(0x0404), 0x00 },
++      { CCI_REG8(0x0405), 0x10 },
++      { CCI_REG8(0x0408), 0x00 },
++      { CCI_REG8(0x0409), 0x00 },
++      { CCI_REG8(0x040A), 0x00 },
++      { CCI_REG8(0x040B), 0x00 },
++      { CCI_REG8(0x040C), 0x07 },
++      { CCI_REG8(0x040D), 0x80 },
++      { CCI_REG8(0x040E), 0x04 },
++      { CCI_REG8(0x040F), 0x38 },
++
++      { CCI_REG8(0x0301), 0x05 },
++      { CCI_REG8(0x0303), 0x02 },
++      { CCI_REG8(0x0305), 0x03 },
++      { CCI_REG8(0x0306), 0x00 },
++      { CCI_REG8(0x0307), 0x96 },
++      { CCI_REG8(0x0309), 0x0A },
++      { CCI_REG8(0x030B), 0x01 },
++      { CCI_REG8(0x0310), 0x00 },
++
++      { CCI_REG8(0x0820), 0x12 },
++      { CCI_REG8(0x0821), 0xC0 },
++      { CCI_REG8(0x0822), 0x00 },
++      { CCI_REG8(0x0823), 0x00 },
++
++      { CCI_REG8(0x3A03), 0x04 },
++      { CCI_REG8(0x3A04), 0xF8 },
++      { CCI_REG8(0x3A05), 0x02 },
++
++      { CCI_REG8(0x0B06), 0x01 },
++      { CCI_REG8(0x30A2), 0x00 },
++
++      { CCI_REG8(0x30B4), 0x00 },
++
++      { CCI_REG8(0x3A02), 0xFF },
++
++      { CCI_REG8(0x3011), 0x00 },
++      { CCI_REG8(0x3013), 0x01 },
++
++      { CCI_REG8(0x0202), 0x0C },
++      { CCI_REG8(0x0203), 0x70 },
++      { CCI_REG8(0x0224), 0x01 },
++      { CCI_REG8(0x0225), 0xF4 },
++
++      { CCI_REG8(0x0204), 0x00 },
++      { CCI_REG8(0x0205), 0x00 },
++      { CCI_REG8(0x020E), 0x01 },
++      { CCI_REG8(0x020F), 0x00 },
++      { CCI_REG8(0x0210), 0x01 },
++      { CCI_REG8(0x0211), 0x00 },
++      { CCI_REG8(0x0212), 0x01 },
++      { CCI_REG8(0x0213), 0x00 },
++      { CCI_REG8(0x0214), 0x01 },
++      { CCI_REG8(0x0215), 0x00 },
++      { CCI_REG8(0x0216), 0x00 },
++      { CCI_REG8(0x0217), 0x00 },
++
++      { CCI_REG8(0x4170), 0x00 },
++      { CCI_REG8(0x4171), 0x10 },
++      { CCI_REG8(0x4176), 0x00 },
++      { CCI_REG8(0x4177), 0x3C },
++      { CCI_REG8(0xAE20), 0x04 },
++      { CCI_REG8(0xAE21), 0x5C },
+ };
+-static const struct reg_8 mode_table_common[] = {
++static const struct cci_reg_sequence mode_table_common[] = {
+       /* software reset */
+       /* software standby settings */
+-      {0x0100, 0x00},
++      { CCI_REG8(0x0100), 0x00 },
+       /* ATR setting */
+-      {0x9300, 0x02},
++      { CCI_REG8(0x9300), 0x02 },
+       /* external clock setting */
+-      {0x0136, 0x18},
+-      {0x0137, 0x00},
++      { CCI_REG8(0x0136), 0x18 },
++      { CCI_REG8(0x0137), 0x00 },
+       /* global setting */
+       /* basic config */
+-      {0x0101, 0x00},
+-      {0x0105, 0x01},
+-      {0x0106, 0x01},
+-      {0x4550, 0x02},
+-      {0x4601, 0x00},
+-      {0x4642, 0x05},
+-      {0x6227, 0x11},
+-      {0x6276, 0x00},
+-      {0x900E, 0x06},
+-      {0xA802, 0x90},
+-      {0xA803, 0x11},
+-      {0xA804, 0x62},
+-      {0xA805, 0x77},
+-      {0xA806, 0xAE},
+-      {0xA807, 0x34},
+-      {0xA808, 0xAE},
+-      {0xA809, 0x35},
+-      {0xA80A, 0x62},
+-      {0xA80B, 0x83},
+-      {0xAE33, 0x00},
++      { CCI_REG8(0x0101), 0x00 },
++      { CCI_REG8(0x0105), 0x01 },
++      { CCI_REG8(0x0106), 0x01 },
++      { CCI_REG8(0x4550), 0x02 },
++      { CCI_REG8(0x4601), 0x00 },
++      { CCI_REG8(0x4642), 0x05 },
++      { CCI_REG8(0x6227), 0x11 },
++      { CCI_REG8(0x6276), 0x00 },
++      { CCI_REG8(0x900E), 0x06 },
++      { CCI_REG8(0xA802), 0x90 },
++      { CCI_REG8(0xA803), 0x11 },
++      { CCI_REG8(0xA804), 0x62 },
++      { CCI_REG8(0xA805), 0x77 },
++      { CCI_REG8(0xA806), 0xAE },
++      { CCI_REG8(0xA807), 0x34 },
++      { CCI_REG8(0xA808), 0xAE },
++      { CCI_REG8(0xA809), 0x35 },
++      { CCI_REG8(0xA80A), 0x62 },
++      { CCI_REG8(0xA80B), 0x83 },
++      { CCI_REG8(0xAE33), 0x00 },
+       /* analog setting */
+-      {0x4174, 0x00},
+-      {0x4175, 0x11},
+-      {0x4612, 0x29},
+-      {0x461B, 0x12},
+-      {0x461F, 0x06},
+-      {0x4635, 0x07},
+-      {0x4637, 0x30},
+-      {0x463F, 0x18},
+-      {0x4641, 0x0D},
+-      {0x465B, 0x12},
+-      {0x465F, 0x11},
+-      {0x4663, 0x11},
+-      {0x4667, 0x0F},
+-      {0x466F, 0x0F},
+-      {0x470E, 0x09},
+-      {0x4909, 0xAB},
+-      {0x490B, 0x95},
+-      {0x4915, 0x5D},
+-      {0x4A5F, 0xFF},
+-      {0x4A61, 0xFF},
+-      {0x4A73, 0x62},
+-      {0x4A85, 0x00},
+-      {0x4A87, 0xFF},
++      { CCI_REG8(0x4174), 0x00 },
++      { CCI_REG8(0x4175), 0x11 },
++      { CCI_REG8(0x4612), 0x29 },
++      { CCI_REG8(0x461B), 0x12 },
++      { CCI_REG8(0x461F), 0x06 },
++      { CCI_REG8(0x4635), 0x07 },
++      { CCI_REG8(0x4637), 0x30 },
++      { CCI_REG8(0x463F), 0x18 },
++      { CCI_REG8(0x4641), 0x0D },
++      { CCI_REG8(0x465B), 0x12 },
++      { CCI_REG8(0x465F), 0x11 },
++      { CCI_REG8(0x4663), 0x11 },
++      { CCI_REG8(0x4667), 0x0F },
++      { CCI_REG8(0x466F), 0x0F },
++      { CCI_REG8(0x470E), 0x09 },
++      { CCI_REG8(0x4909), 0xAB },
++      { CCI_REG8(0x490B), 0x95 },
++      { CCI_REG8(0x4915), 0x5D },
++      { CCI_REG8(0x4A5F), 0xFF },
++      { CCI_REG8(0x4A61), 0xFF },
++      { CCI_REG8(0x4A73), 0x62 },
++      { CCI_REG8(0x4A85), 0x00 },
++      { CCI_REG8(0x4A87), 0xFF },
+       /* embedded data */
+-      {0x5041, 0x04},
+-      {0x583C, 0x04},
+-      {0x620E, 0x04},
+-      {0x6EB2, 0x01},
+-      {0x6EB3, 0x00},
+-      {0x9300, 0x02},
++      { CCI_REG8(0x5041), 0x04 },
++      { CCI_REG8(0x583C), 0x04 },
++      { CCI_REG8(0x620E), 0x04 },
++      { CCI_REG8(0x6EB2), 0x01 },
++      { CCI_REG8(0x6EB3), 0x00 },
++      { CCI_REG8(0x9300), 0x02 },
+       /* imagequality */
+       /* HDR setting */
+-      {0x3001, 0x07},
+-      {0x6D12, 0x3F},
+-      {0x6D13, 0xFF},
+-      {0x9344, 0x03},
+-      {0x9706, 0x10},
+-      {0x9707, 0x03},
+-      {0x9708, 0x03},
+-      {0x9E04, 0x01},
+-      {0x9E05, 0x00},
+-      {0x9E0C, 0x01},
+-      {0x9E0D, 0x02},
+-      {0x9E24, 0x00},
+-      {0x9E25, 0x8C},
+-      {0x9E26, 0x00},
+-      {0x9E27, 0x94},
+-      {0x9E28, 0x00},
+-      {0x9E29, 0x96},
++      { CCI_REG8(0x3001), 0x07 },
++      { CCI_REG8(0x6D12), 0x3F },
++      { CCI_REG8(0x6D13), 0xFF },
++      { CCI_REG8(0x9344), 0x03 },
++      { CCI_REG8(0x9706), 0x10 },
++      { CCI_REG8(0x9707), 0x03 },
++      { CCI_REG8(0x9708), 0x03 },
++      { CCI_REG8(0x9E04), 0x01 },
++      { CCI_REG8(0x9E05), 0x00 },
++      { CCI_REG8(0x9E0C), 0x01 },
++      { CCI_REG8(0x9E0D), 0x02 },
++      { CCI_REG8(0x9E24), 0x00 },
++      { CCI_REG8(0x9E25), 0x8C },
++      { CCI_REG8(0x9E26), 0x00 },
++      { CCI_REG8(0x9E27), 0x94 },
++      { CCI_REG8(0x9E28), 0x00 },
++      { CCI_REG8(0x9E29), 0x96 },
+       /* CNR parameter setting */
+-      {0x69DB, 0x01},
++      { CCI_REG8(0x69DB), 0x01 },
+       /* Moire reduction */
+-      {0x6957, 0x01},
++      { CCI_REG8(0x6957), 0x01 },
+       /* image enhancement */
+-      {0x6987, 0x17},
+-      {0x698A, 0x03},
+-      {0x698B, 0x03},
++      { CCI_REG8(0x6987), 0x17 },
++      { CCI_REG8(0x698A), 0x03 },
++      { CCI_REG8(0x698B), 0x03 },
+       /* white balanace */
+-      {0x0B8E, 0x01},
+-      {0x0B8F, 0x00},
+-      {0x0B90, 0x01},
+-      {0x0B91, 0x00},
+-      {0x0B92, 0x01},
+-      {0x0B93, 0x00},
+-      {0x0B94, 0x01},
+-      {0x0B95, 0x00},
++      { CCI_REG8(0x0B8E), 0x01 },
++      { CCI_REG8(0x0B8F), 0x00 },
++      { CCI_REG8(0x0B90), 0x01 },
++      { CCI_REG8(0x0B91), 0x00 },
++      { CCI_REG8(0x0B92), 0x01 },
++      { CCI_REG8(0x0B93), 0x00 },
++      { CCI_REG8(0x0B94), 0x01 },
++      { CCI_REG8(0x0B95), 0x00 },
+       /* ATR setting */
+-      {0x6E50, 0x00},
+-      {0x6E51, 0x32},
+-      {0x9340, 0x00},
+-      {0x9341, 0x3C},
+-      {0x9342, 0x03},
+-      {0x9343, 0xFF},
+-      {IMX214_TABLE_END, 0x00}
++      { CCI_REG8(0x6E50), 0x00 },
++      { CCI_REG8(0x6E51), 0x32 },
++      { CCI_REG8(0x9340), 0x00 },
++      { CCI_REG8(0x9341), 0x3C },
++      { CCI_REG8(0x9342), 0x03 },
++      { CCI_REG8(0x9343), 0xFF },
+ };
+ /*
+@@ -419,16 +399,19 @@ static const struct reg_8 mode_table_common[] = {
+ static const struct imx214_mode {
+       u32 width;
+       u32 height;
+-      const struct reg_8 *reg_table;
++      unsigned int num_of_regs;
++      const struct cci_reg_sequence *reg_table;
+ } imx214_modes[] = {
+       {
+               .width = 4096,
+               .height = 2304,
++              .num_of_regs = ARRAY_SIZE(mode_4096x2304),
+               .reg_table = mode_4096x2304,
+       },
+       {
+               .width = 1920,
+               .height = 1080,
++              .num_of_regs = ARRAY_SIZE(mode_1920x1080),
+               .reg_table = mode_1920x1080,
+       },
+ };
+@@ -630,7 +613,6 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
+ {
+       struct imx214 *imx214 = container_of(ctrl->handler,
+                                            struct imx214, ctrls);
+-      u8 vals[2];
+       int ret;
+       /*
+@@ -642,12 +624,7 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
+       switch (ctrl->id) {
+       case V4L2_CID_EXPOSURE:
+-              vals[1] = ctrl->val;
+-              vals[0] = ctrl->val >> 8;
+-              ret = regmap_bulk_write(imx214->regmap, IMX214_REG_EXPOSURE, vals, 2);
+-              if (ret < 0)
+-                      dev_err(imx214->dev, "Error %d\n", ret);
+-              ret = 0;
++              cci_write(imx214->regmap, IMX214_REG_EXPOSURE, ctrl->val, &ret);
+               break;
+       default:
+@@ -733,40 +710,6 @@ static int imx214_ctrls_init(struct imx214 *imx214)
+       return 0;
+ };
+-#define MAX_CMD 4
+-static int imx214_write_table(struct imx214 *imx214,
+-                            const struct reg_8 table[])
+-{
+-      u8 vals[MAX_CMD];
+-      int i;
+-      int ret;
+-
+-      for (; table->addr != IMX214_TABLE_END ; table++) {
+-              if (table->addr == IMX214_TABLE_WAIT_MS) {
+-                      usleep_range(table->val * 1000,
+-                                   table->val * 1000 + 500);
+-                      continue;
+-              }
+-
+-              for (i = 0; i < MAX_CMD; i++) {
+-                      if (table[i].addr != (table[0].addr + i))
+-                              break;
+-                      vals[i] = table[i].val;
+-              }
+-
+-              ret = regmap_bulk_write(imx214->regmap, table->addr, vals, i);
+-
+-              if (ret) {
+-                      dev_err(imx214->dev, "write_table error: %d\n", ret);
+-                      return ret;
+-              }
+-
+-              table += i - 1;
+-      }
+-
+-      return 0;
+-}
+-
+ static int imx214_start_streaming(struct imx214 *imx214)
+ {
+       const struct v4l2_mbus_framefmt *fmt;
+@@ -774,7 +717,8 @@ static int imx214_start_streaming(struct imx214 *imx214)
+       const struct imx214_mode *mode;
+       int ret;
+-      ret = imx214_write_table(imx214, mode_table_common);
++      ret = cci_multi_reg_write(imx214->regmap, mode_table_common,
++                                ARRAY_SIZE(mode_table_common), NULL);
+       if (ret < 0) {
+               dev_err(imx214->dev, "could not sent common table %d\n", ret);
+               return ret;
+@@ -784,17 +728,24 @@ static int imx214_start_streaming(struct imx214 *imx214)
+       fmt = v4l2_subdev_state_get_format(state, 0);
+       mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes),
+                                     width, height, fmt->width, fmt->height);
+-      ret = imx214_write_table(imx214, mode->reg_table);
++      ret = cci_multi_reg_write(imx214->regmap, mode->reg_table,
++                                mode->num_of_regs, NULL);
+       if (ret < 0) {
+               dev_err(imx214->dev, "could not sent mode table %d\n", ret);
+               return ret;
+       }
++
++      usleep_range(10000, 10500);
++
++      cci_write(imx214->regmap, CCI_REG8(0x0138), 0x01, NULL);
++
+       ret = __v4l2_ctrl_handler_setup(&imx214->ctrls);
+       if (ret < 0) {
+               dev_err(imx214->dev, "could not sync v4l2 controls\n");
+               return ret;
+       }
+-      ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING);
++      ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT,
++                      IMX214_MODE_STREAMING, NULL);
+       if (ret < 0)
+               dev_err(imx214->dev, "could not sent start table %d\n", ret);
+@@ -805,7 +756,8 @@ static int imx214_stop_streaming(struct imx214 *imx214)
+ {
+       int ret;
+-      ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY);
++      ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT,
++                      IMX214_MODE_STANDBY, NULL);
+       if (ret < 0)
+               dev_err(imx214->dev, "could not sent stop table %d\n",  ret);
+@@ -906,12 +858,6 @@ static const struct v4l2_subdev_internal_ops imx214_internal_ops = {
+       .init_state = imx214_entity_init_state,
+ };
+-static const struct regmap_config sensor_regmap_config = {
+-      .reg_bits = 16,
+-      .val_bits = 8,
+-      .cache_type = REGCACHE_MAPLE,
+-};
+-
+ static int imx214_get_regulators(struct device *dev, struct imx214 *imx214)
+ {
+       unsigned int i;
+@@ -995,10 +941,10 @@ static int imx214_probe(struct i2c_client *client)
+               return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio),
+                                    "failed to get enable gpio\n");
+-      imx214->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config);
++      imx214->regmap = devm_cci_regmap_init_i2c(client, 16);
+       if (IS_ERR(imx214->regmap))
+               return dev_err_probe(dev, PTR_ERR(imx214->regmap),
+-                                   "regmap init failed\n");
++                                   "failed to initialize CCI\n");
+       v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
+       imx214->sd.internal_ops = &imx214_internal_ops;
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-i2c-imx214-fix-link-frequency-validation.patch b/queue-6.14/media-i2c-imx214-fix-link-frequency-validation.patch
new file mode 100644 (file)
index 0000000..7d21a61
--- /dev/null
@@ -0,0 +1,94 @@
+From 2b4357eb8767d5088a1f164d31df55393093e6de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 14:26:12 +0100
+Subject: media: i2c: imx214: Fix link frequency validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit acc294519f1749041e1b8c74d46bbf6c57d8b061 ]
+
+The driver defines IMX214_DEFAULT_LINK_FREQ 480000000, and then
+IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10),
+which works out as 384MPix/s. (The 8 is 4 lanes and DDR.)
+
+Parsing the PLL registers with the defined 24MHz input. We're in single
+PLL mode, so MIPI frequency is directly linked to pixel rate.  VTCK ends
+up being 1200MHz, and VTPXCK and OPPXCK both are 120MHz.  Section 5.3
+"Frame rate calculation formula" says "Pixel rate
+[pixels/s] = VTPXCK [MHz] * 4", so 120 * 4 = 480MPix/s, which basically
+agrees with my number above.
+
+3.1.4. MIPI global timing setting says "Output bitrate = OPPXCK * reg
+0x113[7:0]", so 120MHz * 10, or 1200Mbit/s. That would be a link
+frequency of 600MHz due to DDR.
+That also matches to 480MPix/s * 10bpp / 4 lanes / 2 for DDR.
+
+Keep the previous link frequency for backward compatibility.
+
+Acked-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Fixes: 436190596241 ("media: imx214: Add imx214 camera sensor driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx214.c | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
+index fdc2dfb4ebcdd..bdf2396c2482b 100644
+--- a/drivers/media/i2c/imx214.c
++++ b/drivers/media/i2c/imx214.c
+@@ -27,7 +27,9 @@
+ #define IMX214_REG_FAST_STANDBY_CTRL  CCI_REG8(0x0106)
+ #define IMX214_DEFAULT_CLK_FREQ       24000000
+-#define IMX214_DEFAULT_LINK_FREQ 480000000
++#define IMX214_DEFAULT_LINK_FREQ      600000000
++/* Keep wrong link frequency for backward compatibility */
++#define IMX214_DEFAULT_LINK_FREQ_LEGACY       480000000
+ #define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
+ #define IMX214_FPS 30
+ #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
+@@ -965,18 +967,26 @@ static int imx214_parse_fwnode(struct device *dev)
+               goto done;
+       }
+-      for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
++      if (bus_cfg.nr_of_link_frequencies != 1)
++              dev_warn(dev, "Only one link-frequency supported, please review your DT. Continuing anyway\n");
++
++      for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
+               if (bus_cfg.link_frequencies[i] == IMX214_DEFAULT_LINK_FREQ)
+                       break;
+-
+-      if (i == bus_cfg.nr_of_link_frequencies) {
+-              dev_err_probe(dev, -EINVAL,
+-                            "link-frequencies %d not supported, Please review your DT\n",
+-                            IMX214_DEFAULT_LINK_FREQ);
+-              ret = -EINVAL;
+-              goto done;
++              if (bus_cfg.link_frequencies[i] ==
++                  IMX214_DEFAULT_LINK_FREQ_LEGACY) {
++                      dev_warn(dev,
++                               "link-frequencies %d not supported, please review your DT. Continuing anyway\n",
++                               IMX214_DEFAULT_LINK_FREQ);
++                      break;
++              }
+       }
++      if (i == bus_cfg.nr_of_link_frequencies)
++              ret = dev_err_probe(dev, -EINVAL,
++                                  "link-frequencies %d not supported, please review your DT\n",
++                                  IMX214_DEFAULT_LINK_FREQ);
++
+ done:
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+       fwnode_handle_put(endpoint);
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-i2c-imx214-replace-register-addresses-with-mac.patch b/queue-6.14/media-i2c-imx214-replace-register-addresses-with-mac.patch
new file mode 100644 (file)
index 0000000..e50a969
--- /dev/null
@@ -0,0 +1,545 @@
+From 5104e0fb3eaebfe4cb7765ae2217890b37794c31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 14:26:03 +0100
+Subject: media: i2c: imx214: Replace register addresses with macros
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit 341a133beb43f9009ebdde9eff276dfacbac114a ]
+
+Define macros for all the known registers used in the register arrays,
+and use them to replace the numerical addresses. This improves
+readability.
+
+Acked-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx214.c | 407 +++++++++++++++++++++----------------
+ 1 file changed, 236 insertions(+), 171 deletions(-)
+
+diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
+index 20d1ebebf13af..8bac5a1f1cb18 100644
+--- a/drivers/media/i2c/imx214.c
++++ b/drivers/media/i2c/imx214.c
+@@ -24,18 +24,141 @@
+ #define IMX214_MODE_STANDBY           0x00
+ #define IMX214_MODE_STREAMING         0x01
++#define IMX214_REG_FAST_STANDBY_CTRL  CCI_REG8(0x0106)
++
+ #define IMX214_DEFAULT_CLK_FREQ       24000000
+ #define IMX214_DEFAULT_LINK_FREQ 480000000
+ #define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
+ #define IMX214_FPS 30
+ #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
++/* V-TIMING internal */
++#define IMX214_REG_FRM_LENGTH_LINES   CCI_REG16(0x0340)
++
+ /* Exposure control */
+ #define IMX214_REG_EXPOSURE           CCI_REG16(0x0202)
+ #define IMX214_EXPOSURE_MIN           0
+ #define IMX214_EXPOSURE_MAX           3184
+ #define IMX214_EXPOSURE_STEP          1
+ #define IMX214_EXPOSURE_DEFAULT               3184
++#define IMX214_REG_EXPOSURE_RATIO     CCI_REG8(0x0222)
++#define IMX214_REG_SHORT_EXPOSURE     CCI_REG16(0x0224)
++
++/* Analog gain control */
++#define IMX214_REG_ANALOG_GAIN                CCI_REG16(0x0204)
++#define IMX214_REG_SHORT_ANALOG_GAIN  CCI_REG16(0x0216)
++
++/* Digital gain control */
++#define IMX214_REG_DIG_GAIN_GREENR    CCI_REG16(0x020e)
++#define IMX214_REG_DIG_GAIN_RED               CCI_REG16(0x0210)
++#define IMX214_REG_DIG_GAIN_BLUE      CCI_REG16(0x0212)
++#define IMX214_REG_DIG_GAIN_GREENB    CCI_REG16(0x0214)
++
++#define IMX214_REG_ORIENTATION                CCI_REG8(0x0101)
++
++#define IMX214_REG_MASK_CORR_FRAMES   CCI_REG8(0x0105)
++#define IMX214_CORR_FRAMES_TRANSMIT   0
++#define IMX214_CORR_FRAMES_MASK               1
++
++#define IMX214_REG_CSI_DATA_FORMAT    CCI_REG16(0x0112)
++#define IMX214_CSI_DATA_FORMAT_RAW8   0x0808
++#define IMX214_CSI_DATA_FORMAT_RAW10  0x0A0A
++#define IMX214_CSI_DATA_FORMAT_COMP6  0x0A06
++#define IMX214_CSI_DATA_FORMAT_COMP8  0x0A08
++
++#define IMX214_REG_CSI_LANE_MODE      CCI_REG8(0x0114)
++#define IMX214_CSI_2_LANE_MODE                1
++#define IMX214_CSI_4_LANE_MODE                3
++
++#define IMX214_REG_EXCK_FREQ          CCI_REG16(0x0136)
++#define IMX214_EXCK_FREQ(n)           ((n) * 256)     /* n expressed in MHz */
++
++#define IMX214_REG_TEMP_SENSOR_CONTROL        CCI_REG8(0x0138)
++
++#define IMX214_REG_HDR_MODE           CCI_REG8(0x0220)
++#define IMX214_HDR_MODE_OFF           0
++#define IMX214_HDR_MODE_ON            1
++
++#define IMX214_REG_HDR_RES_REDUCTION  CCI_REG8(0x0221)
++#define IMX214_HDR_RES_REDU_THROUGH   0x11
++#define IMX214_HDR_RES_REDU_2_BINNING 0x22
++
++/* PLL settings */
++#define IMX214_REG_VTPXCK_DIV         CCI_REG8(0x0301)
++#define IMX214_REG_VTSYCK_DIV         CCI_REG8(0x0303)
++#define IMX214_REG_PREPLLCK_VT_DIV    CCI_REG8(0x0305)
++#define IMX214_REG_PLL_VT_MPY         CCI_REG16(0x0306)
++#define IMX214_REG_OPPXCK_DIV         CCI_REG8(0x0309)
++#define IMX214_REG_OPSYCK_DIV         CCI_REG8(0x030b)
++#define IMX214_REG_PLL_MULT_DRIV      CCI_REG8(0x0310)
++#define IMX214_PLL_SINGLE             0
++#define IMX214_PLL_DUAL                       1
++
++#define IMX214_REG_LINE_LENGTH_PCK    CCI_REG16(0x0342)
++#define IMX214_REG_X_ADD_STA          CCI_REG16(0x0344)
++#define IMX214_REG_Y_ADD_STA          CCI_REG16(0x0346)
++#define IMX214_REG_X_ADD_END          CCI_REG16(0x0348)
++#define IMX214_REG_Y_ADD_END          CCI_REG16(0x034a)
++#define IMX214_REG_X_OUTPUT_SIZE      CCI_REG16(0x034c)
++#define IMX214_REG_Y_OUTPUT_SIZE      CCI_REG16(0x034e)
++#define IMX214_REG_X_EVEN_INC         CCI_REG8(0x0381)
++#define IMX214_REG_X_ODD_INC          CCI_REG8(0x0383)
++#define IMX214_REG_Y_EVEN_INC         CCI_REG8(0x0385)
++#define IMX214_REG_Y_ODD_INC          CCI_REG8(0x0387)
++
++#define IMX214_REG_SCALE_MODE         CCI_REG8(0x0401)
++#define IMX214_SCALE_NONE             0
++#define IMX214_SCALE_HORIZONTAL               1
++#define IMX214_SCALE_FULL             2
++#define IMX214_REG_SCALE_M            CCI_REG16(0x0404)
++
++#define IMX214_REG_DIG_CROP_X_OFFSET  CCI_REG16(0x0408)
++#define IMX214_REG_DIG_CROP_Y_OFFSET  CCI_REG16(0x040a)
++#define IMX214_REG_DIG_CROP_WIDTH     CCI_REG16(0x040c)
++#define IMX214_REG_DIG_CROP_HEIGHT    CCI_REG16(0x040e)
++
++#define IMX214_REG_REQ_LINK_BIT_RATE  CCI_REG32(0x0820)
++#define IMX214_LINK_BIT_RATE_MBPS(n)  ((n) << 16)
++
++/* Binning mode */
++#define IMX214_REG_BINNING_MODE               CCI_REG8(0x0900)
++#define IMX214_BINNING_NONE           0
++#define IMX214_BINNING_ENABLE         1
++#define IMX214_REG_BINNING_TYPE               CCI_REG8(0x0901)
++#define IMX214_REG_BINNING_WEIGHTING  CCI_REG8(0x0902)
++#define IMX214_BINNING_AVERAGE                0x00
++#define IMX214_BINNING_SUMMED         0x01
++#define IMX214_BINNING_BAYER          0x02
++
++#define IMX214_REG_SING_DEF_CORR_EN   CCI_REG8(0x0b06)
++#define IMX214_SING_DEF_CORR_OFF      0
++#define IMX214_SING_DEF_CORR_ON               1
++
++/* AWB control */
++#define IMX214_REG_ABS_GAIN_GREENR    CCI_REG16(0x0b8e)
++#define IMX214_REG_ABS_GAIN_RED               CCI_REG16(0x0b90)
++#define IMX214_REG_ABS_GAIN_BLUE      CCI_REG16(0x0b92)
++#define IMX214_REG_ABS_GAIN_GREENB    CCI_REG16(0x0b94)
++
++#define IMX214_REG_RMSC_NR_MODE               CCI_REG8(0x3001)
++#define IMX214_REG_STATS_OUT_EN               CCI_REG8(0x3013)
++#define IMX214_STATS_OUT_OFF          0
++#define IMX214_STATS_OUT_ON           1
++
++/* Chroma noise reduction */
++#define IMX214_REG_NML_NR_EN          CCI_REG8(0x30a2)
++#define IMX214_NML_NR_OFF             0
++#define IMX214_NML_NR_ON              1
++
++#define IMX214_REG_EBD_SIZE_V         CCI_REG8(0x5041)
++#define IMX214_EBD_NO                 0
++#define IMX214_EBD_4_LINE             4
++
++#define IMX214_REG_RG_STATS_LMT               CCI_REG16(0x6d12)
++#define IMX214_RG_STATS_LMT_10_BIT    0x03FF
++#define IMX214_RG_STATS_LMT_14_BIT    0x3FFF
++
++#define IMX214_REG_ATR_FAST_MOVE      CCI_REG8(0x9300)
+ /* IMX214 native and active pixel array size */
+ #define IMX214_NATIVE_WIDTH           4224U
+@@ -74,96 +197,70 @@ struct imx214 {
+ /*From imx214_mode_tbls.h*/
+ static const struct cci_reg_sequence mode_4096x2304[] = {
+-      { CCI_REG8(0x0114), 0x03 },
+-      { CCI_REG8(0x0220), 0x00 },
+-      { CCI_REG8(0x0221), 0x11 },
+-      { CCI_REG8(0x0222), 0x01 },
+-      { CCI_REG8(0x0340), 0x0C },
+-      { CCI_REG8(0x0341), 0x7A },
+-      { CCI_REG8(0x0342), 0x13 },
+-      { CCI_REG8(0x0343), 0x90 },
+-      { CCI_REG8(0x0344), 0x00 },
+-      { CCI_REG8(0x0345), 0x38 },
+-      { CCI_REG8(0x0346), 0x01 },
+-      { CCI_REG8(0x0347), 0x98 },
+-      { CCI_REG8(0x0348), 0x10 },
+-      { CCI_REG8(0x0349), 0x37 },
+-      { CCI_REG8(0x034A), 0x0A },
+-      { CCI_REG8(0x034B), 0x97 },
+-      { CCI_REG8(0x0381), 0x01 },
+-      { CCI_REG8(0x0383), 0x01 },
+-      { CCI_REG8(0x0385), 0x01 },
+-      { CCI_REG8(0x0387), 0x01 },
+-      { CCI_REG8(0x0900), 0x00 },
+-      { CCI_REG8(0x0901), 0x00 },
+-      { CCI_REG8(0x0902), 0x00 },
++      { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE },
++      { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF },
++      { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH },
++      { IMX214_REG_EXPOSURE_RATIO, 1 },
++      { IMX214_REG_FRM_LENGTH_LINES, 3194 },
++      { IMX214_REG_LINE_LENGTH_PCK, 5008 },
++      { IMX214_REG_X_ADD_STA, 56 },
++      { IMX214_REG_Y_ADD_STA, 408 },
++      { IMX214_REG_X_ADD_END, 4151 },
++      { IMX214_REG_Y_ADD_END, 2711 },
++      { IMX214_REG_X_EVEN_INC, 1 },
++      { IMX214_REG_X_ODD_INC, 1 },
++      { IMX214_REG_Y_EVEN_INC, 1 },
++      { IMX214_REG_Y_ODD_INC, 1 },
++      { IMX214_REG_BINNING_MODE, IMX214_BINNING_NONE },
++      { IMX214_REG_BINNING_TYPE, 0 },
++      { IMX214_REG_BINNING_WEIGHTING, IMX214_BINNING_AVERAGE },
+       { CCI_REG8(0x3000), 0x35 },
+       { CCI_REG8(0x3054), 0x01 },
+       { CCI_REG8(0x305C), 0x11 },
+-      { CCI_REG8(0x0112), 0x0A },
+-      { CCI_REG8(0x0113), 0x0A },
+-      { CCI_REG8(0x034C), 0x10 },
+-      { CCI_REG8(0x034D), 0x00 },
+-      { CCI_REG8(0x034E), 0x09 },
+-      { CCI_REG8(0x034F), 0x00 },
+-      { CCI_REG8(0x0401), 0x00 },
+-      { CCI_REG8(0x0404), 0x00 },
+-      { CCI_REG8(0x0405), 0x10 },
+-      { CCI_REG8(0x0408), 0x00 },
+-      { CCI_REG8(0x0409), 0x00 },
+-      { CCI_REG8(0x040A), 0x00 },
+-      { CCI_REG8(0x040B), 0x00 },
+-      { CCI_REG8(0x040C), 0x10 },
+-      { CCI_REG8(0x040D), 0x00 },
+-      { CCI_REG8(0x040E), 0x09 },
+-      { CCI_REG8(0x040F), 0x00 },
+-
+-      { CCI_REG8(0x0301), 0x05 },
+-      { CCI_REG8(0x0303), 0x02 },
+-      { CCI_REG8(0x0305), 0x03 },
+-      { CCI_REG8(0x0306), 0x00 },
+-      { CCI_REG8(0x0307), 0x96 },
+-      { CCI_REG8(0x0309), 0x0A },
+-      { CCI_REG8(0x030B), 0x01 },
+-      { CCI_REG8(0x0310), 0x00 },
+-
+-      { CCI_REG8(0x0820), 0x12 },
+-      { CCI_REG8(0x0821), 0xC0 },
+-      { CCI_REG8(0x0822), 0x00 },
+-      { CCI_REG8(0x0823), 0x00 },
++      { IMX214_REG_CSI_DATA_FORMAT, IMX214_CSI_DATA_FORMAT_RAW10 },
++      { IMX214_REG_X_OUTPUT_SIZE, 4096 },
++      { IMX214_REG_Y_OUTPUT_SIZE, 2304 },
++      { IMX214_REG_SCALE_MODE, IMX214_SCALE_NONE },
++      { IMX214_REG_SCALE_M, 2 },
++      { IMX214_REG_DIG_CROP_X_OFFSET, 0 },
++      { IMX214_REG_DIG_CROP_Y_OFFSET, 0 },
++      { IMX214_REG_DIG_CROP_WIDTH, 4096 },
++      { IMX214_REG_DIG_CROP_HEIGHT, 2304 },
++
++      { IMX214_REG_VTPXCK_DIV, 5 },
++      { IMX214_REG_VTSYCK_DIV, 2 },
++      { IMX214_REG_PREPLLCK_VT_DIV, 3 },
++      { IMX214_REG_PLL_VT_MPY, 150 },
++      { IMX214_REG_OPPXCK_DIV, 10 },
++      { IMX214_REG_OPSYCK_DIV, 1 },
++      { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE },
++
++      { IMX214_REG_REQ_LINK_BIT_RATE, IMX214_LINK_BIT_RATE_MBPS(4800) },
+       { CCI_REG8(0x3A03), 0x09 },
+       { CCI_REG8(0x3A04), 0x50 },
+       { CCI_REG8(0x3A05), 0x01 },
+-      { CCI_REG8(0x0B06), 0x01 },
+-      { CCI_REG8(0x30A2), 0x00 },
++      { IMX214_REG_SING_DEF_CORR_EN, IMX214_SING_DEF_CORR_ON },
++      { IMX214_REG_NML_NR_EN, IMX214_NML_NR_OFF },
+       { CCI_REG8(0x30B4), 0x00 },
+       { CCI_REG8(0x3A02), 0xFF },
+       { CCI_REG8(0x3011), 0x00 },
+-      { CCI_REG8(0x3013), 0x01 },
+-
+-      { CCI_REG8(0x0202), 0x0C },
+-      { CCI_REG8(0x0203), 0x70 },
+-      { CCI_REG8(0x0224), 0x01 },
+-      { CCI_REG8(0x0225), 0xF4 },
+-
+-      { CCI_REG8(0x0204), 0x00 },
+-      { CCI_REG8(0x0205), 0x00 },
+-      { CCI_REG8(0x020E), 0x01 },
+-      { CCI_REG8(0x020F), 0x00 },
+-      { CCI_REG8(0x0210), 0x01 },
+-      { CCI_REG8(0x0211), 0x00 },
+-      { CCI_REG8(0x0212), 0x01 },
+-      { CCI_REG8(0x0213), 0x00 },
+-      { CCI_REG8(0x0214), 0x01 },
+-      { CCI_REG8(0x0215), 0x00 },
+-      { CCI_REG8(0x0216), 0x00 },
+-      { CCI_REG8(0x0217), 0x00 },
++      { IMX214_REG_STATS_OUT_EN, IMX214_STATS_OUT_ON },
++
++      { IMX214_REG_EXPOSURE, IMX214_EXPOSURE_DEFAULT },
++      { IMX214_REG_SHORT_EXPOSURE, 500 },
++
++      { IMX214_REG_ANALOG_GAIN, 0 },
++      { IMX214_REG_DIG_GAIN_GREENR, 256 },
++      { IMX214_REG_DIG_GAIN_RED, 256 },
++      { IMX214_REG_DIG_GAIN_BLUE, 256 },
++      { IMX214_REG_DIG_GAIN_GREENB, 256 },
++      { IMX214_REG_SHORT_ANALOG_GAIN, 0 },
+       { CCI_REG8(0x4170), 0x00 },
+       { CCI_REG8(0x4171), 0x10 },
+@@ -174,96 +271,70 @@ static const struct cci_reg_sequence mode_4096x2304[] = {
+ };
+ static const struct cci_reg_sequence mode_1920x1080[] = {
+-      { CCI_REG8(0x0114), 0x03 },
+-      { CCI_REG8(0x0220), 0x00 },
+-      { CCI_REG8(0x0221), 0x11 },
+-      { CCI_REG8(0x0222), 0x01 },
+-      { CCI_REG8(0x0340), 0x0C },
+-      { CCI_REG8(0x0341), 0x7A },
+-      { CCI_REG8(0x0342), 0x13 },
+-      { CCI_REG8(0x0343), 0x90 },
+-      { CCI_REG8(0x0344), 0x04 },
+-      { CCI_REG8(0x0345), 0x78 },
+-      { CCI_REG8(0x0346), 0x03 },
+-      { CCI_REG8(0x0347), 0xFC },
+-      { CCI_REG8(0x0348), 0x0B },
+-      { CCI_REG8(0x0349), 0xF7 },
+-      { CCI_REG8(0x034A), 0x08 },
+-      { CCI_REG8(0x034B), 0x33 },
+-      { CCI_REG8(0x0381), 0x01 },
+-      { CCI_REG8(0x0383), 0x01 },
+-      { CCI_REG8(0x0385), 0x01 },
+-      { CCI_REG8(0x0387), 0x01 },
+-      { CCI_REG8(0x0900), 0x00 },
+-      { CCI_REG8(0x0901), 0x00 },
+-      { CCI_REG8(0x0902), 0x00 },
++      { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE },
++      { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF },
++      { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH },
++      { IMX214_REG_EXPOSURE_RATIO, 1 },
++      { IMX214_REG_FRM_LENGTH_LINES, 3194 },
++      { IMX214_REG_LINE_LENGTH_PCK, 5008 },
++      { IMX214_REG_X_ADD_STA, 1144 },
++      { IMX214_REG_Y_ADD_STA, 1020 },
++      { IMX214_REG_X_ADD_END, 3063 },
++      { IMX214_REG_Y_ADD_END, 2099 },
++      { IMX214_REG_X_EVEN_INC, 1 },
++      { IMX214_REG_X_ODD_INC, 1 },
++      { IMX214_REG_Y_EVEN_INC, 1 },
++      { IMX214_REG_Y_ODD_INC, 1 },
++      { IMX214_REG_BINNING_MODE, IMX214_BINNING_NONE },
++      { IMX214_REG_BINNING_TYPE, 0 },
++      { IMX214_REG_BINNING_WEIGHTING, IMX214_BINNING_AVERAGE },
+       { CCI_REG8(0x3000), 0x35 },
+       { CCI_REG8(0x3054), 0x01 },
+       { CCI_REG8(0x305C), 0x11 },
+-      { CCI_REG8(0x0112), 0x0A },
+-      { CCI_REG8(0x0113), 0x0A },
+-      { CCI_REG8(0x034C), 0x07 },
+-      { CCI_REG8(0x034D), 0x80 },
+-      { CCI_REG8(0x034E), 0x04 },
+-      { CCI_REG8(0x034F), 0x38 },
+-      { CCI_REG8(0x0401), 0x00 },
+-      { CCI_REG8(0x0404), 0x00 },
+-      { CCI_REG8(0x0405), 0x10 },
+-      { CCI_REG8(0x0408), 0x00 },
+-      { CCI_REG8(0x0409), 0x00 },
+-      { CCI_REG8(0x040A), 0x00 },
+-      { CCI_REG8(0x040B), 0x00 },
+-      { CCI_REG8(0x040C), 0x07 },
+-      { CCI_REG8(0x040D), 0x80 },
+-      { CCI_REG8(0x040E), 0x04 },
+-      { CCI_REG8(0x040F), 0x38 },
+-
+-      { CCI_REG8(0x0301), 0x05 },
+-      { CCI_REG8(0x0303), 0x02 },
+-      { CCI_REG8(0x0305), 0x03 },
+-      { CCI_REG8(0x0306), 0x00 },
+-      { CCI_REG8(0x0307), 0x96 },
+-      { CCI_REG8(0x0309), 0x0A },
+-      { CCI_REG8(0x030B), 0x01 },
+-      { CCI_REG8(0x0310), 0x00 },
+-
+-      { CCI_REG8(0x0820), 0x12 },
+-      { CCI_REG8(0x0821), 0xC0 },
+-      { CCI_REG8(0x0822), 0x00 },
+-      { CCI_REG8(0x0823), 0x00 },
++      { IMX214_REG_CSI_DATA_FORMAT, IMX214_CSI_DATA_FORMAT_RAW10 },
++      { IMX214_REG_X_OUTPUT_SIZE, 1920 },
++      { IMX214_REG_Y_OUTPUT_SIZE, 1080 },
++      { IMX214_REG_SCALE_MODE, IMX214_SCALE_NONE },
++      { IMX214_REG_SCALE_M, 2 },
++      { IMX214_REG_DIG_CROP_X_OFFSET, 0 },
++      { IMX214_REG_DIG_CROP_Y_OFFSET, 0 },
++      { IMX214_REG_DIG_CROP_WIDTH, 1920 },
++      { IMX214_REG_DIG_CROP_HEIGHT, 1080 },
++
++      { IMX214_REG_VTPXCK_DIV, 5 },
++      { IMX214_REG_VTSYCK_DIV, 2 },
++      { IMX214_REG_PREPLLCK_VT_DIV, 3 },
++      { IMX214_REG_PLL_VT_MPY, 150 },
++      { IMX214_REG_OPPXCK_DIV, 10 },
++      { IMX214_REG_OPSYCK_DIV, 1 },
++      { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE },
++
++      { IMX214_REG_REQ_LINK_BIT_RATE, IMX214_LINK_BIT_RATE_MBPS(4800) },
+       { CCI_REG8(0x3A03), 0x04 },
+       { CCI_REG8(0x3A04), 0xF8 },
+       { CCI_REG8(0x3A05), 0x02 },
+-      { CCI_REG8(0x0B06), 0x01 },
+-      { CCI_REG8(0x30A2), 0x00 },
++      { IMX214_REG_SING_DEF_CORR_EN, IMX214_SING_DEF_CORR_ON },
++      { IMX214_REG_NML_NR_EN, IMX214_NML_NR_OFF },
+       { CCI_REG8(0x30B4), 0x00 },
+       { CCI_REG8(0x3A02), 0xFF },
+       { CCI_REG8(0x3011), 0x00 },
+-      { CCI_REG8(0x3013), 0x01 },
+-
+-      { CCI_REG8(0x0202), 0x0C },
+-      { CCI_REG8(0x0203), 0x70 },
+-      { CCI_REG8(0x0224), 0x01 },
+-      { CCI_REG8(0x0225), 0xF4 },
+-
+-      { CCI_REG8(0x0204), 0x00 },
+-      { CCI_REG8(0x0205), 0x00 },
+-      { CCI_REG8(0x020E), 0x01 },
+-      { CCI_REG8(0x020F), 0x00 },
+-      { CCI_REG8(0x0210), 0x01 },
+-      { CCI_REG8(0x0211), 0x00 },
+-      { CCI_REG8(0x0212), 0x01 },
+-      { CCI_REG8(0x0213), 0x00 },
+-      { CCI_REG8(0x0214), 0x01 },
+-      { CCI_REG8(0x0215), 0x00 },
+-      { CCI_REG8(0x0216), 0x00 },
+-      { CCI_REG8(0x0217), 0x00 },
++      { IMX214_REG_STATS_OUT_EN, IMX214_STATS_OUT_ON },
++
++      { IMX214_REG_EXPOSURE, IMX214_EXPOSURE_DEFAULT },
++      { IMX214_REG_SHORT_EXPOSURE, 500 },
++
++      { IMX214_REG_ANALOG_GAIN, 0 },
++      { IMX214_REG_DIG_GAIN_GREENR, 256 },
++      { IMX214_REG_DIG_GAIN_RED, 256 },
++      { IMX214_REG_DIG_GAIN_BLUE, 256 },
++      { IMX214_REG_DIG_GAIN_GREENB, 256 },
++      { IMX214_REG_SHORT_ANALOG_GAIN, 0 },
+       { CCI_REG8(0x4170), 0x00 },
+       { CCI_REG8(0x4171), 0x10 },
+@@ -277,20 +348,19 @@ static const struct cci_reg_sequence mode_table_common[] = {
+       /* software reset */
+       /* software standby settings */
+-      { CCI_REG8(0x0100), 0x00 },
++      { IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY },
+       /* ATR setting */
+-      { CCI_REG8(0x9300), 0x02 },
++      { IMX214_REG_ATR_FAST_MOVE, 2 },
+       /* external clock setting */
+-      { CCI_REG8(0x0136), 0x18 },
+-      { CCI_REG8(0x0137), 0x00 },
++      { IMX214_REG_EXCK_FREQ, IMX214_EXCK_FREQ(IMX214_DEFAULT_CLK_FREQ / 1000000) },
+       /* global setting */
+       /* basic config */
+-      { CCI_REG8(0x0101), 0x00 },
+-      { CCI_REG8(0x0105), 0x01 },
+-      { CCI_REG8(0x0106), 0x01 },
++      { IMX214_REG_ORIENTATION, 0 },
++      { IMX214_REG_MASK_CORR_FRAMES, IMX214_CORR_FRAMES_MASK },
++      { IMX214_REG_FAST_STANDBY_CTRL, 1 },
+       { CCI_REG8(0x4550), 0x02 },
+       { CCI_REG8(0x4601), 0x00 },
+       { CCI_REG8(0x4642), 0x05 },
+@@ -335,18 +405,17 @@ static const struct cci_reg_sequence mode_table_common[] = {
+       { CCI_REG8(0x4A87), 0xFF },
+       /* embedded data */
+-      { CCI_REG8(0x5041), 0x04 },
++      { IMX214_REG_EBD_SIZE_V, IMX214_EBD_4_LINE },
+       { CCI_REG8(0x583C), 0x04 },
+       { CCI_REG8(0x620E), 0x04 },
+       { CCI_REG8(0x6EB2), 0x01 },
+       { CCI_REG8(0x6EB3), 0x00 },
+-      { CCI_REG8(0x9300), 0x02 },
++      { IMX214_REG_ATR_FAST_MOVE, 2 },
+       /* imagequality */
+       /* HDR setting */
+-      { CCI_REG8(0x3001), 0x07 },
+-      { CCI_REG8(0x6D12), 0x3F },
+-      { CCI_REG8(0x6D13), 0xFF },
++      { IMX214_REG_RMSC_NR_MODE, 0x07 },
++      { IMX214_REG_RG_STATS_LMT, IMX214_RG_STATS_LMT_14_BIT },
+       { CCI_REG8(0x9344), 0x03 },
+       { CCI_REG8(0x9706), 0x10 },
+       { CCI_REG8(0x9707), 0x03 },
+@@ -374,14 +443,10 @@ static const struct cci_reg_sequence mode_table_common[] = {
+       { CCI_REG8(0x698B), 0x03 },
+       /* white balanace */
+-      { CCI_REG8(0x0B8E), 0x01 },
+-      { CCI_REG8(0x0B8F), 0x00 },
+-      { CCI_REG8(0x0B90), 0x01 },
+-      { CCI_REG8(0x0B91), 0x00 },
+-      { CCI_REG8(0x0B92), 0x01 },
+-      { CCI_REG8(0x0B93), 0x00 },
+-      { CCI_REG8(0x0B94), 0x01 },
+-      { CCI_REG8(0x0B95), 0x00 },
++      { IMX214_REG_ABS_GAIN_GREENR, 0x0100 },
++      { IMX214_REG_ABS_GAIN_RED, 0x0100 },
++      { IMX214_REG_ABS_GAIN_BLUE, 0x0100 },
++      { IMX214_REG_ABS_GAIN_GREENB, 0x0100 },
+       /* ATR setting */
+       { CCI_REG8(0x6E50), 0x00 },
+@@ -737,7 +802,7 @@ static int imx214_start_streaming(struct imx214 *imx214)
+       usleep_range(10000, 10500);
+-      cci_write(imx214->regmap, CCI_REG8(0x0138), 0x01, NULL);
++      cci_write(imx214->regmap, IMX214_REG_TEMP_SENSOR_CONTROL, 0x01, NULL);
+       ret = __v4l2_ctrl_handler_setup(&imx214->ctrls);
+       if (ret < 0) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-i2c-imx214-simplify-with-dev_err_probe.patch b/queue-6.14/media-i2c-imx214-simplify-with-dev_err_probe.patch
new file mode 100644 (file)
index 0000000..3302e30
--- /dev/null
@@ -0,0 +1,137 @@
+From 085651117d620dc25a706427daa319af18426dba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 14:26:01 +0100
+Subject: media: i2c: imx214: Simplify with dev_err_probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit 5d6dc133e6e4053b4b92a15a2e1b99d54b3f8adb ]
+
+Error handling in probe() can be a bit simpler with dev_err_probe().
+
+Acked-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx214.c | 54 +++++++++++++++++---------------------
+ 1 file changed, 24 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
+index af6a3859c3f13..db6cdc3b65e37 100644
+--- a/drivers/media/i2c/imx214.c
++++ b/drivers/media/i2c/imx214.c
+@@ -933,14 +933,12 @@ static int imx214_parse_fwnode(struct device *dev)
+       int ret;
+       endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
+-      if (!endpoint) {
+-              dev_err(dev, "endpoint node not found\n");
+-              return -EINVAL;
+-      }
++      if (!endpoint)
++              return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");
+       ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
+       if (ret) {
+-              dev_err(dev, "parsing endpoint node failed\n");
++              dev_err_probe(dev, ret, "parsing endpoint node failed\n");
+               goto done;
+       }
+@@ -949,8 +947,9 @@ static int imx214_parse_fwnode(struct device *dev)
+                       break;
+       if (i == bus_cfg.nr_of_link_frequencies) {
+-              dev_err(dev, "link-frequencies %d not supported, Please review your DT\n",
+-                      IMX214_DEFAULT_LINK_FREQ);
++              dev_err_probe(dev, -EINVAL,
++                            "link-frequencies %d not supported, Please review your DT\n",
++                            IMX214_DEFAULT_LINK_FREQ);
+               ret = -EINVAL;
+               goto done;
+       }
+@@ -978,34 +977,28 @@ static int imx214_probe(struct i2c_client *client)
+       imx214->dev = dev;
+       imx214->xclk = devm_clk_get(dev, NULL);
+-      if (IS_ERR(imx214->xclk)) {
+-              dev_err(dev, "could not get xclk");
+-              return PTR_ERR(imx214->xclk);
+-      }
++      if (IS_ERR(imx214->xclk))
++              return dev_err_probe(dev, PTR_ERR(imx214->xclk),
++                                   "failed to get xclk\n");
+       ret = clk_set_rate(imx214->xclk, IMX214_DEFAULT_CLK_FREQ);
+-      if (ret) {
+-              dev_err(dev, "could not set xclk frequency\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret,
++                                   "failed to set xclk frequency\n");
+       ret = imx214_get_regulators(dev, imx214);
+-      if (ret < 0) {
+-              dev_err(dev, "cannot get regulators\n");
+-              return ret;
+-      }
++      if (ret < 0)
++              return dev_err_probe(dev, ret, "failed to get regulators\n");
+       imx214->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+-      if (IS_ERR(imx214->enable_gpio)) {
+-              dev_err(dev, "cannot get enable gpio\n");
+-              return PTR_ERR(imx214->enable_gpio);
+-      }
++      if (IS_ERR(imx214->enable_gpio))
++              return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio),
++                                   "failed to get enable gpio\n");
+       imx214->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config);
+-      if (IS_ERR(imx214->regmap)) {
+-              dev_err(dev, "regmap init failed\n");
+-              return PTR_ERR(imx214->regmap);
+-      }
++      if (IS_ERR(imx214->regmap))
++              return dev_err_probe(dev, PTR_ERR(imx214->regmap),
++                                   "regmap init failed\n");
+       v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
+       imx214->sd.internal_ops = &imx214_internal_ops;
+@@ -1027,14 +1020,14 @@ static int imx214_probe(struct i2c_client *client)
+       ret = media_entity_pads_init(&imx214->sd.entity, 1, &imx214->pad);
+       if (ret < 0) {
+-              dev_err(dev, "could not register media entity\n");
++              dev_err_probe(dev, ret, "failed to init entity pads\n");
+               goto free_ctrl;
+       }
+       imx214->sd.state_lock = imx214->ctrls.lock;
+       ret = v4l2_subdev_init_finalize(&imx214->sd);
+       if (ret < 0) {
+-              dev_err(dev, "subdev init error: %d\n", ret);
++              dev_err_probe(dev, ret, "subdev init error\n");
+               goto free_entity;
+       }
+@@ -1043,7 +1036,8 @@ static int imx214_probe(struct i2c_client *client)
+       ret = v4l2_async_register_subdev_sensor(&imx214->sd);
+       if (ret < 0) {
+-              dev_err(dev, "could not register v4l2 device\n");
++              dev_err_probe(dev, ret,
++                            "failed to register sensor sub-device\n");
+               goto error_subdev_cleanup;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-i2c-imx214-use-subdev-active-state.patch b/queue-6.14/media-i2c-imx214-use-subdev-active-state.patch
new file mode 100644 (file)
index 0000000..b328624
--- /dev/null
@@ -0,0 +1,331 @@
+From 71b5bf5de1977e58f9f99b0a4932801748b29c57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 14:26:00 +0100
+Subject: media: i2c: imx214: Use subdev active state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit b6832ff659f55f86198bb8de40f278a20bda0920 ]
+
+Port the imx214 sensor driver to use the subdev active state.
+
+Move all the format configuration to the subdevice state and simplify
+the format handling, locking and initialization.
+
+While at it, simplify imx214_start_streaming() by removing unneeded goto
+statements and the corresponding error label.
+
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx214.c | 155 ++++++++++++-------------------------
+ 1 file changed, 50 insertions(+), 105 deletions(-)
+
+diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
+index 6a393e18267f4..af6a3859c3f13 100644
+--- a/drivers/media/i2c/imx214.c
++++ b/drivers/media/i2c/imx214.c
+@@ -59,8 +59,6 @@ struct imx214 {
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+-      struct v4l2_mbus_framefmt fmt;
+-      struct v4l2_rect crop;
+       struct v4l2_ctrl_handler ctrls;
+       struct v4l2_ctrl *pixel_rate;
+@@ -71,12 +69,6 @@ struct imx214 {
+       struct regulator_bulk_data      supplies[IMX214_NUM_SUPPLIES];
+       struct gpio_desc *enable_gpio;
+-
+-      /*
+-       * Serialize control access, get/set format, get selection
+-       * and start streaming.
+-       */
+-      struct mutex mutex;
+ };
+ struct reg_8 {
+@@ -490,6 +482,22 @@ static int __maybe_unused imx214_power_off(struct device *dev)
+       return 0;
+ }
++static void imx214_update_pad_format(struct imx214 *imx214,
++                                   const struct imx214_mode *mode,
++                                   struct v4l2_mbus_framefmt *fmt, u32 code)
++{
++      fmt->code = IMX214_MBUS_CODE;
++      fmt->width = mode->width;
++      fmt->height = mode->height;
++      fmt->field = V4L2_FIELD_NONE;
++      fmt->colorspace = V4L2_COLORSPACE_SRGB;
++      fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++      fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++                                                        fmt->colorspace,
++                                                        fmt->ycbcr_enc);
++      fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++}
++
+ static int imx214_enum_mbus_code(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_state *sd_state,
+                                struct v4l2_subdev_mbus_code_enum *code)
+@@ -549,52 +557,6 @@ static const struct v4l2_subdev_core_ops imx214_core_ops = {
+ #endif
+ };
+-static struct v4l2_mbus_framefmt *
+-__imx214_get_pad_format(struct imx214 *imx214,
+-                      struct v4l2_subdev_state *sd_state,
+-                      unsigned int pad,
+-                      enum v4l2_subdev_format_whence which)
+-{
+-      switch (which) {
+-      case V4L2_SUBDEV_FORMAT_TRY:
+-              return v4l2_subdev_state_get_format(sd_state, pad);
+-      case V4L2_SUBDEV_FORMAT_ACTIVE:
+-              return &imx214->fmt;
+-      default:
+-              return NULL;
+-      }
+-}
+-
+-static int imx214_get_format(struct v4l2_subdev *sd,
+-                           struct v4l2_subdev_state *sd_state,
+-                           struct v4l2_subdev_format *format)
+-{
+-      struct imx214 *imx214 = to_imx214(sd);
+-
+-      mutex_lock(&imx214->mutex);
+-      format->format = *__imx214_get_pad_format(imx214, sd_state,
+-                                                format->pad,
+-                                                format->which);
+-      mutex_unlock(&imx214->mutex);
+-
+-      return 0;
+-}
+-
+-static struct v4l2_rect *
+-__imx214_get_pad_crop(struct imx214 *imx214,
+-                    struct v4l2_subdev_state *sd_state,
+-                    unsigned int pad, enum v4l2_subdev_format_whence which)
+-{
+-      switch (which) {
+-      case V4L2_SUBDEV_FORMAT_TRY:
+-              return v4l2_subdev_state_get_crop(sd_state, pad);
+-      case V4L2_SUBDEV_FORMAT_ACTIVE:
+-              return &imx214->crop;
+-      default:
+-              return NULL;
+-      }
+-}
+-
+ static int imx214_set_format(struct v4l2_subdev *sd,
+                            struct v4l2_subdev_state *sd_state,
+                            struct v4l2_subdev_format *format)
+@@ -604,34 +566,20 @@ static int imx214_set_format(struct v4l2_subdev *sd,
+       struct v4l2_rect *__crop;
+       const struct imx214_mode *mode;
+-      mutex_lock(&imx214->mutex);
+-
+-      __crop = __imx214_get_pad_crop(imx214, sd_state, format->pad,
+-                                     format->which);
+-
+       mode = v4l2_find_nearest_size(imx214_modes,
+                                     ARRAY_SIZE(imx214_modes), width, height,
+                                     format->format.width,
+                                     format->format.height);
+-      __crop->width = mode->width;
+-      __crop->height = mode->height;
+-
+-      __format = __imx214_get_pad_format(imx214, sd_state, format->pad,
+-                                         format->which);
+-      __format->width = __crop->width;
+-      __format->height = __crop->height;
+-      __format->code = IMX214_MBUS_CODE;
+-      __format->field = V4L2_FIELD_NONE;
+-      __format->colorspace = V4L2_COLORSPACE_SRGB;
+-      __format->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(__format->colorspace);
+-      __format->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
+-                              __format->colorspace, __format->ycbcr_enc);
+-      __format->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(__format->colorspace);
++      imx214_update_pad_format(imx214, mode, &format->format,
++                               format->format.code);
++      __format = v4l2_subdev_state_get_format(sd_state, 0);
+-      format->format = *__format;
++      *__format = format->format;
+-      mutex_unlock(&imx214->mutex);
++      __crop = v4l2_subdev_state_get_crop(sd_state, 0);
++      __crop->width = mode->width;
++      __crop->height = mode->height;
+       return 0;
+ }
+@@ -640,14 +588,9 @@ static int imx214_get_selection(struct v4l2_subdev *sd,
+                               struct v4l2_subdev_state *sd_state,
+                               struct v4l2_subdev_selection *sel)
+ {
+-      struct imx214 *imx214 = to_imx214(sd);
+-
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP:
+-              mutex_lock(&imx214->mutex);
+-              sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad,
+-                                              sel->which);
+-              mutex_unlock(&imx214->mutex);
++              sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
+               return 0;
+       case V4L2_SEL_TGT_NATIVE_SIZE:
+@@ -826,40 +769,35 @@ static int imx214_write_table(struct imx214 *imx214,
+ static int imx214_start_streaming(struct imx214 *imx214)
+ {
++      const struct v4l2_mbus_framefmt *fmt;
++      struct v4l2_subdev_state *state;
+       const struct imx214_mode *mode;
+       int ret;
+-      mutex_lock(&imx214->mutex);
+       ret = imx214_write_table(imx214, mode_table_common);
+       if (ret < 0) {
+               dev_err(imx214->dev, "could not sent common table %d\n", ret);
+-              goto error;
++              return ret;
+       }
+-      mode = v4l2_find_nearest_size(imx214_modes,
+-                              ARRAY_SIZE(imx214_modes), width, height,
+-                              imx214->fmt.width, imx214->fmt.height);
++      state = v4l2_subdev_get_locked_active_state(&imx214->sd);
++      fmt = v4l2_subdev_state_get_format(state, 0);
++      mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes),
++                                    width, height, fmt->width, fmt->height);
+       ret = imx214_write_table(imx214, mode->reg_table);
+       if (ret < 0) {
+               dev_err(imx214->dev, "could not sent mode table %d\n", ret);
+-              goto error;
++              return ret;
+       }
+       ret = __v4l2_ctrl_handler_setup(&imx214->ctrls);
+       if (ret < 0) {
+               dev_err(imx214->dev, "could not sync v4l2 controls\n");
+-              goto error;
++              return ret;
+       }
+       ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING);
+-      if (ret < 0) {
++      if (ret < 0)
+               dev_err(imx214->dev, "could not sent start table %d\n", ret);
+-              goto error;
+-      }
+-      mutex_unlock(&imx214->mutex);
+-      return 0;
+-
+-error:
+-      mutex_unlock(&imx214->mutex);
+       return ret;
+ }
+@@ -877,6 +815,7 @@ static int imx214_stop_streaming(struct imx214 *imx214)
+ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable)
+ {
+       struct imx214 *imx214 = to_imx214(subdev);
++      struct v4l2_subdev_state *state;
+       int ret;
+       if (enable) {
+@@ -884,7 +823,9 @@ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable)
+               if (ret < 0)
+                       return ret;
++              state = v4l2_subdev_lock_and_get_active_state(subdev);
+               ret = imx214_start_streaming(imx214);
++              v4l2_subdev_unlock_state(state);
+               if (ret < 0)
+                       goto err_rpm_put;
+       } else {
+@@ -948,7 +889,7 @@ static const struct v4l2_subdev_pad_ops imx214_subdev_pad_ops = {
+       .enum_mbus_code = imx214_enum_mbus_code,
+       .enum_frame_size = imx214_enum_frame_size,
+       .enum_frame_interval = imx214_enum_frame_interval,
+-      .get_fmt = imx214_get_format,
++      .get_fmt = v4l2_subdev_get_fmt,
+       .set_fmt = imx214_set_format,
+       .get_selection = imx214_get_selection,
+       .get_frame_interval = imx214_get_frame_interval,
+@@ -1079,9 +1020,6 @@ static int imx214_probe(struct i2c_client *client)
+       if (ret < 0)
+               goto error_power_off;
+-      mutex_init(&imx214->mutex);
+-      imx214->ctrls.lock = &imx214->mutex;
+-
+       imx214->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       imx214->pad.flags = MEDIA_PAD_FL_SOURCE;
+       imx214->sd.dev = &client->dev;
+@@ -1093,7 +1031,12 @@ static int imx214_probe(struct i2c_client *client)
+               goto free_ctrl;
+       }
+-      imx214_entity_init_state(&imx214->sd, NULL);
++      imx214->sd.state_lock = imx214->ctrls.lock;
++      ret = v4l2_subdev_init_finalize(&imx214->sd);
++      if (ret < 0) {
++              dev_err(dev, "subdev init error: %d\n", ret);
++              goto free_entity;
++      }
+       pm_runtime_set_active(imx214->dev);
+       pm_runtime_enable(imx214->dev);
+@@ -1101,20 +1044,22 @@ static int imx214_probe(struct i2c_client *client)
+       ret = v4l2_async_register_subdev_sensor(&imx214->sd);
+       if (ret < 0) {
+               dev_err(dev, "could not register v4l2 device\n");
+-              goto free_entity;
++              goto error_subdev_cleanup;
+       }
+       pm_runtime_idle(imx214->dev);
+       return 0;
+-free_entity:
++error_subdev_cleanup:
+       pm_runtime_disable(imx214->dev);
+       pm_runtime_set_suspended(&client->dev);
++      v4l2_subdev_cleanup(&imx214->sd);
++
++free_entity:
+       media_entity_cleanup(&imx214->sd.entity);
+ free_ctrl:
+-      mutex_destroy(&imx214->mutex);
+       v4l2_ctrl_handler_free(&imx214->ctrls);
+ error_power_off:
+@@ -1129,9 +1074,9 @@ static void imx214_remove(struct i2c_client *client)
+       struct imx214 *imx214 = to_imx214(sd);
+       v4l2_async_unregister_subdev(&imx214->sd);
++      v4l2_subdev_cleanup(sd);
+       media_entity_cleanup(&imx214->sd.entity);
+       v4l2_ctrl_handler_free(&imx214->ctrls);
+-      mutex_destroy(&imx214->mutex);
+       pm_runtime_disable(&client->dev);
+       if (!pm_runtime_status_suspended(&client->dev)) {
+               imx214_power_off(imx214->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-ov08x40-add-missing-ov08x40_identify_module-ca.patch b/queue-6.14/media-ov08x40-add-missing-ov08x40_identify_module-ca.patch
new file mode 100644 (file)
index 0000000..5df68a4
--- /dev/null
@@ -0,0 +1,48 @@
+From ef09e79585143b3478eac27f2cc0d5f47ca27e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 15:41:28 +0100
+Subject: media: ov08x40: Add missing ov08x40_identify_module() call on
+ stream-start
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit ebf185efadb71bd5344877be683895b6b18d7edf ]
+
+The driver might skip the ov08x40_identify_module() on probe() based on
+the acpi_dev_state_d0() check done in probe().
+
+If the ov08x40_identify_module() call is skipped on probe() it should
+be done on the first stream start. Add the missing call.
+
+Note ov08x40_identify_module() will only do something on its first call,
+subsequent calls are no-ops.
+
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Fixes: b1a42fde6e07 ("media: ov08x40: Avoid sensor probing in D0 state")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov08x40.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
+index 580d902977b68..625fbcd39068e 100644
+--- a/drivers/media/i2c/ov08x40.c
++++ b/drivers/media/i2c/ov08x40.c
+@@ -1976,6 +1976,10 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
+               if (ret < 0)
+                       goto err_unlock;
++              ret = ov08x40_identify_module(ov08x);
++              if (ret)
++                      goto err_rpm_put;
++
+               /*
+                * Apply default & customized values
+                * and then start streaming.
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-ov08x40-move-ov08x40_identify_module-function-.patch b/queue-6.14/media-ov08x40-move-ov08x40_identify_module-function-.patch
new file mode 100644 (file)
index 0000000..c3066cd
--- /dev/null
@@ -0,0 +1,98 @@
+From c0c8d6ffa08c499ef8ea191c2b8d73cee393967d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 15:41:25 +0100
+Subject: media: ov08x40: Move ov08x40_identify_module() function up
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 7a39639e448f070cbe37317ac922886b6080ff43 ]
+
+Move the ov08x40_identify_module() function to above ov08x40_set_stream()
+this is a preparation patch for adding a missing ov08x40_identify_module()
+call to ov08x40_set_stream().
+
+No functional changes, just moving code around.
+
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Stable-dep-of: ebf185efadb7 ("media: ov08x40: Add missing ov08x40_identify_module() call on stream-start")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov08x40.c | 52 ++++++++++++++++++-------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
+index 83b49cf114acc..580d902977b68 100644
+--- a/drivers/media/i2c/ov08x40.c
++++ b/drivers/media/i2c/ov08x40.c
+@@ -1937,6 +1937,32 @@ static int ov08x40_stop_streaming(struct ov08x40 *ov08x)
+                                OV08X40_REG_VALUE_08BIT, OV08X40_MODE_STANDBY);
+ }
++/* Verify chip ID */
++static int ov08x40_identify_module(struct ov08x40 *ov08x)
++{
++      struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
++      int ret;
++      u32 val;
++
++      if (ov08x->identified)
++              return 0;
++
++      ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
++                             OV08X40_REG_VALUE_24BIT, &val);
++      if (ret)
++              return ret;
++
++      if (val != OV08X40_CHIP_ID) {
++              dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
++                      OV08X40_CHIP_ID, val);
++              return -ENXIO;
++      }
++
++      ov08x->identified = true;
++
++      return 0;
++}
++
+ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
+ {
+       struct ov08x40 *ov08x = to_ov08x40(sd);
+@@ -1974,32 +2000,6 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
+       return ret;
+ }
+-/* Verify chip ID */
+-static int ov08x40_identify_module(struct ov08x40 *ov08x)
+-{
+-      struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
+-      int ret;
+-      u32 val;
+-
+-      if (ov08x->identified)
+-              return 0;
+-
+-      ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
+-                             OV08X40_REG_VALUE_24BIT, &val);
+-      if (ret)
+-              return ret;
+-
+-      if (val != OV08X40_CHIP_ID) {
+-              dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+-                      OV08X40_CHIP_ID, val);
+-              return -ENXIO;
+-      }
+-
+-      ov08x->identified = true;
+-
+-      return 0;
+-}
+-
+ static const struct v4l2_subdev_video_ops ov08x40_video_ops = {
+       .s_stream = ov08x40_set_stream,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/mm-vmscan-don-t-try-to-reclaim-hwpoison-folio.patch b/queue-6.14/mm-vmscan-don-t-try-to-reclaim-hwpoison-folio.patch
new file mode 100644 (file)
index 0000000..dfbf4c5
--- /dev/null
@@ -0,0 +1,106 @@
+From 97ce8265a3bd40f0600f7888b1c51970f74a228c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 16:39:39 +0800
+Subject: mm/vmscan: don't try to reclaim hwpoison folio
+
+From: Jinjiang Tu <tujinjiang@huawei.com>
+
+[ Upstream commit 1b0449544c6482179ac84530b61fc192a6527bfd ]
+
+Syzkaller reports a bug as follows:
+
+Injecting memory failure for pfn 0x18b00e at process virtual address 0x20ffd000
+Memory failure: 0x18b00e: dirty swapcache page still referenced by 2 users
+Memory failure: 0x18b00e: recovery action for dirty swapcache page: Failed
+page: refcount:2 mapcount:0 mapping:0000000000000000 index:0x20ffd pfn:0x18b00e
+memcg:ffff0000dd6d9000
+anon flags: 0x5ffffe00482011(locked|dirty|arch_1|swapbacked|hwpoison|node=0|zone=2|lastcpupid=0xfffff)
+raw: 005ffffe00482011 dead000000000100 dead000000000122 ffff0000e232a7c9
+raw: 0000000000020ffd 0000000000000000 00000002ffffffff ffff0000dd6d9000
+page dumped because: VM_BUG_ON_FOLIO(!folio_test_uptodate(folio))
+------------[ cut here ]------------
+kernel BUG at mm/swap_state.c:184!
+Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
+Modules linked in:
+CPU: 0 PID: 60 Comm: kswapd0 Not tainted 6.6.0-gcb097e7de84e #3
+Hardware name: linux,dummy-virt (DT)
+pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : add_to_swap+0xbc/0x158
+lr : add_to_swap+0xbc/0x158
+sp : ffff800087f37340
+x29: ffff800087f37340 x28: fffffc00052c0380 x27: ffff800087f37780
+x26: ffff800087f37490 x25: ffff800087f37c78 x24: ffff800087f377a0
+x23: ffff800087f37c50 x22: 0000000000000000 x21: fffffc00052c03b4
+x20: 0000000000000000 x19: fffffc00052c0380 x18: 0000000000000000
+x17: 296f696c6f662865 x16: 7461646f7470755f x15: 747365745f6f696c
+x14: 6f6621284f494c4f x13: 0000000000000001 x12: ffff600036d8b97b
+x11: 1fffe00036d8b97a x10: ffff600036d8b97a x9 : dfff800000000000
+x8 : 00009fffc9274686 x7 : ffff0001b6c5cbd3 x6 : 0000000000000001
+x5 : ffff0000c25896c0 x4 : 0000000000000000 x3 : 0000000000000000
+x2 : 0000000000000000 x1 : ffff0000c25896c0 x0 : 0000000000000000
+Call trace:
+ add_to_swap+0xbc/0x158
+ shrink_folio_list+0x12ac/0x2648
+ shrink_inactive_list+0x318/0x948
+ shrink_lruvec+0x450/0x720
+ shrink_node_memcgs+0x280/0x4a8
+ shrink_node+0x128/0x978
+ balance_pgdat+0x4f0/0xb20
+ kswapd+0x228/0x438
+ kthread+0x214/0x230
+ ret_from_fork+0x10/0x20
+
+I can reproduce this issue with the following steps:
+
+1) When a dirty swapcache page is isolated by reclaim process and the
+   page isn't locked, inject memory failure for the page.
+   me_swapcache_dirty() clears uptodate flag and tries to delete from lru,
+   but fails.  Reclaim process will put the hwpoisoned page back to lru.
+
+2) The process that maps the hwpoisoned page exits, the page is deleted
+   the page will never be freed and will be in the lru forever.
+
+3) If we trigger a reclaim again and tries to reclaim the page,
+   add_to_swap() will trigger VM_BUG_ON_FOLIO due to the uptodate flag is
+   cleared.
+
+To fix it, skip the hwpoisoned page in shrink_folio_list().  Besides, the
+hwpoison folio may not be unmapped by hwpoison_user_mappings() yet, unmap
+it in shrink_folio_list(), otherwise the folio will fail to be unmaped by
+hwpoison_user_mappings() since the folio isn't in lru list.
+
+Link: https://lkml.kernel.org/r/20250318083939.987651-3-tujinjiang@huawei.com
+Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
+Acked-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Nanyong Sun <sunnanyong@huawei.com>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: <stable@vger,kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/vmscan.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index fada3b35aff83..e9f3ae8158a66 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -1112,6 +1112,13 @@ static unsigned int shrink_folio_list(struct list_head *folio_list,
+               if (!folio_trylock(folio))
+                       goto keep;
++              if (folio_contain_hwpoisoned_page(folio)) {
++                      unmap_poisoned_folio(folio, folio_pfn(folio), false);
++                      folio_unlock(folio);
++                      folio_put(folio);
++                      continue;
++              }
++
+               VM_BUG_ON_FOLIO(folio_test_active(folio), folio);
+               nr_pages = folio_nr_pages(folio);
+-- 
+2.39.5
+
diff --git a/queue-6.14/mmc-sdhci-msm-fix-dev-reference-leaked-through-of_qc.patch b/queue-6.14/mmc-sdhci-msm-fix-dev-reference-leaked-through-of_qc.patch
new file mode 100644 (file)
index 0000000..fc92d58
--- /dev/null
@@ -0,0 +1,42 @@
+From c8064ddd4b435aed4f9cd1846a09d429dbd352b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 14:18:51 +0000
+Subject: mmc: sdhci-msm: fix dev reference leaked through of_qcom_ice_get
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit cbef7442fba510b7eb229dcc9f39d3dde4a159a4 ]
+
+The driver leaks the device reference taken with
+of_find_device_by_node(). Fix the leak by using devm_of_qcom_ice_get().
+
+Fixes: c7eed31e235c ("mmc: sdhci-msm: Switch to the new ICE API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-2-1ffa5b6884cb@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-msm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
+index e3d39311fdc75..3fd898647237f 100644
+--- a/drivers/mmc/host/sdhci-msm.c
++++ b/drivers/mmc/host/sdhci-msm.c
+@@ -1873,7 +1873,7 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
+       if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
+               return 0;
+-      ice = of_qcom_ice_get(dev);
++      ice = devm_of_qcom_ice_get(dev);
+       if (ice == ERR_PTR(-EOPNOTSUPP)) {
+               dev_warn(dev, "Disabling inline encryption support\n");
+               ice = NULL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-niu-niu-requires-msix-entry_data-fields-touch-be.patch b/queue-6.14/net-niu-niu-requires-msix-entry_data-fields-touch-be.patch
new file mode 100644 (file)
index 0000000..cf41734
--- /dev/null
@@ -0,0 +1,86 @@
+From 355be9663f58813713f209467b486f0ff8a1020b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Nov 2024 17:48:43 -0600
+Subject: net/niu: Niu requires MSIX ENTRY_DATA fields touch before entry reads
+
+From: Jonathan Currier <dullfire@yahoo.com>
+
+[ Upstream commit fbb429ddff5c8e479edcc7dde5a542c9295944e6 ]
+
+Fix niu_try_msix() to not cause a fatal trap on sparc systems.
+
+Set PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST on the struct pci_dev to
+work around a bug in the hardware or firmware.
+
+For each vector entry in the msix table, niu chips will cause a fatal
+trap if any registers in that entry are read before that entries'
+ENTRY_DATA register is written to. Testing indicates writes to other
+registers are not sufficient to prevent the fatal trap, however the value
+does not appear to matter. This only needs to happen once after power up,
+so simply rebooting into a kernel lacking this fix will NOT cause the
+trap.
+
+NON-RESUMABLE ERROR: Reporting on cpu 64
+NON-RESUMABLE ERROR: TPC [0x00000000005f6900] <msix_prepare_msi_desc+0x90/0xa0>
+NON-RESUMABLE ERROR: RAW [4010000000000016:00000e37f93e32ff:0000000202000080:ffffffffffffffff
+NON-RESUMABLE ERROR:      0000000800000000:0000000000000000:0000000000000000:0000000000000000]
+NON-RESUMABLE ERROR: handle [0x4010000000000016] stick [0x00000e37f93e32ff]
+NON-RESUMABLE ERROR: type [precise nonresumable]
+NON-RESUMABLE ERROR: attrs [0x02000080] < ASI sp-faulted priv >
+NON-RESUMABLE ERROR: raddr [0xffffffffffffffff]
+NON-RESUMABLE ERROR: insn effective address [0x000000c50020000c]
+NON-RESUMABLE ERROR: size [0x8]
+NON-RESUMABLE ERROR: asi [0x00]
+CPU: 64 UID: 0 PID: 745 Comm: kworker/64:1 Not tainted 6.11.5 #63
+Workqueue: events work_for_cpu_fn
+TSTATE: 0000000011001602 TPC: 00000000005f6900 TNPC: 00000000005f6904 Y: 00000000    Not tainted
+TPC: <msix_prepare_msi_desc+0x90/0xa0>
+g0: 00000000000002e9 g1: 000000000000000c g2: 000000c50020000c g3: 0000000000000100
+g4: ffff8000470307c0 g5: ffff800fec5be000 g6: ffff800047a08000 g7: 0000000000000000
+o0: ffff800014feb000 o1: ffff800047a0b620 o2: 0000000000000011 o3: ffff800047a0b620
+o4: 0000000000000080 o5: 0000000000000011 sp: ffff800047a0ad51 ret_pc: 00000000005f7128
+RPC: <__pci_enable_msix_range+0x3cc/0x460>
+l0: 000000000000000d l1: 000000000000c01f l2: ffff800014feb0a8 l3: 0000000000000020
+l4: 000000000000c000 l5: 0000000000000001 l6: 0000000020000000 l7: ffff800047a0b734
+i0: ffff800014feb000 i1: ffff800047a0b730 i2: 0000000000000001 i3: 000000000000000d
+i4: 0000000000000000 i5: 0000000000000000 i6: ffff800047a0ae81 i7: 00000000101888b0
+I7: <niu_try_msix.constprop.0+0xc0/0x130 [niu]>
+Call Trace:
+[<00000000101888b0>] niu_try_msix.constprop.0+0xc0/0x130 [niu]
+[<000000001018f840>] niu_get_invariants+0x183c/0x207c [niu]
+[<00000000101902fc>] niu_pci_init_one+0x27c/0x2fc [niu]
+[<00000000005ef3e4>] local_pci_probe+0x28/0x74
+[<0000000000469240>] work_for_cpu_fn+0x8/0x1c
+[<000000000046b008>] process_scheduled_works+0x144/0x210
+[<000000000046b518>] worker_thread+0x13c/0x1c0
+[<00000000004710e0>] kthread+0xb8/0xc8
+[<00000000004060c8>] ret_from_fork+0x1c/0x2c
+[<0000000000000000>] 0x0
+Kernel panic - not syncing: Non-resumable error.
+
+Fixes: 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries")
+Signed-off-by: Jonathan Currier <dullfire@yahoo.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20241117234843.19236-3-dullfire@yahoo.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sun/niu.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
+index 72177fea1cfb3..edc3165f00774 100644
+--- a/drivers/net/ethernet/sun/niu.c
++++ b/drivers/net/ethernet/sun/niu.c
+@@ -9064,6 +9064,8 @@ static void niu_try_msix(struct niu *np, u8 *ldg_num_map)
+               msi_vec[i].entry = i;
+       }
++      pdev->dev_flags |= PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST;
++
+       num_irqs = pci_enable_msix_range(pdev, msi_vec, 1, num_irqs);
+       if (num_irqs < 0) {
+               np->flags &= ~NIU_FLAGS_MSIX;
+-- 
+2.39.5
+
diff --git a/queue-6.14/of-resolver-fix-device-node-refcount-leakage-in-of_r.patch b/queue-6.14/of-resolver-fix-device-node-refcount-leakage-in-of_r.patch
new file mode 100644 (file)
index 0000000..04da786
--- /dev/null
@@ -0,0 +1,45 @@
+From 743b33202040c68a1384b3ca76a28af0bbaebcf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 17:01:55 -0600
+Subject: of: resolver: Fix device node refcount leakage in
+ of_resolve_phandles()
+
+From: Zijun Hu <quic_zijuhu@quicinc.com>
+
+[ Upstream commit a46a0805635d07de50c2ac71588345323c13b2f9 ]
+
+In of_resolve_phandles(), refcount of device node @local_fixups will be
+increased if the for_each_child_of_node() exits early, but nowhere to
+decrease the refcount, so cause refcount leakage for the node.
+
+Fix by using __free() on @local_fixups.
+
+Fixes: da56d04c806a ("of/resolver: Switch to new local fixups format.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
+Link: https://lore.kernel.org/r/20250209-of_irq_fix-v2-9-93e3a2659aa7@quicinc.com
+[robh: Use __free() instead]
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/resolver.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
+index c871e35d49217..2caad365a665c 100644
+--- a/drivers/of/resolver.c
++++ b/drivers/of/resolver.c
+@@ -249,8 +249,9 @@ static int adjust_local_phandle_references(const struct device_node *local_fixup
+  */
+ int of_resolve_phandles(struct device_node *overlay)
+ {
+-      struct device_node *child, *local_fixups, *refnode;
++      struct device_node *child, *refnode;
+       struct device_node *overlay_fixups;
++      struct device_node __free(device_node) *local_fixups = NULL;
+       struct property *prop;
+       const char *refpath;
+       phandle phandle, phandle_delta;
+-- 
+2.39.5
+
diff --git a/queue-6.14/of-resolver-simplify-of_resolve_phandles-using-__fre.patch b/queue-6.14/of-resolver-simplify-of_resolve_phandles-using-__fre.patch
new file mode 100644 (file)
index 0000000..65be405
--- /dev/null
@@ -0,0 +1,114 @@
+From 06e459d90e3edb57fca8f381ea9afe3133d7af3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2025 20:59:02 +0800
+Subject: of: resolver: Simplify of_resolve_phandles() using __free()
+
+From: Rob Herring (Arm) <robh@kernel.org>
+
+[ Upstream commit 5275e8b5293f65cc82a5ee5eab02dd573b911d6e ]
+
+Use the __free() cleanup to simplify of_resolve_phandles() and remove
+all the goto's.
+
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Stable-dep-of: a46a0805635d ("of: resolver: Fix device node refcount leakage in of_resolve_phandles()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/resolver.c | 34 +++++++++++-----------------------
+ 1 file changed, 11 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
+index 779db058c42f5..c871e35d49217 100644
+--- a/drivers/of/resolver.c
++++ b/drivers/of/resolver.c
+@@ -250,24 +250,20 @@ static int adjust_local_phandle_references(const struct device_node *local_fixup
+ int of_resolve_phandles(struct device_node *overlay)
+ {
+       struct device_node *child, *local_fixups, *refnode;
+-      struct device_node *tree_symbols, *overlay_fixups;
++      struct device_node *overlay_fixups;
+       struct property *prop;
+       const char *refpath;
+       phandle phandle, phandle_delta;
+       int err;
+-      tree_symbols = NULL;
+-
+       if (!overlay) {
+               pr_err("null overlay\n");
+-              err = -EINVAL;
+-              goto out;
++              return -EINVAL;
+       }
+       if (!of_node_check_flag(overlay, OF_DETACHED)) {
+               pr_err("overlay not detached\n");
+-              err = -EINVAL;
+-              goto out;
++              return -EINVAL;
+       }
+       phandle_delta = live_tree_max_phandle() + 1;
+@@ -279,7 +275,7 @@ int of_resolve_phandles(struct device_node *overlay)
+       err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
+       if (err)
+-              goto out;
++              return err;
+       overlay_fixups = NULL;
+@@ -288,16 +284,13 @@ int of_resolve_phandles(struct device_node *overlay)
+                       overlay_fixups = child;
+       }
+-      if (!overlay_fixups) {
+-              err = 0;
+-              goto out;
+-      }
++      if (!overlay_fixups)
++              return 0;
+-      tree_symbols = of_find_node_by_path("/__symbols__");
++      struct device_node __free(device_node) *tree_symbols = of_find_node_by_path("/__symbols__");
+       if (!tree_symbols) {
+               pr_err("no symbols in root of device tree.\n");
+-              err = -EINVAL;
+-              goto out;
++              return -EINVAL;
+       }
+       for_each_property_of_node(overlay_fixups, prop) {
+@@ -311,14 +304,12 @@ int of_resolve_phandles(struct device_node *overlay)
+               if (err) {
+                       pr_err("node label '%s' not found in live devicetree symbols table\n",
+                              prop->name);
+-                      goto out;
++                      return err;
+               }
+               refnode = of_find_node_by_path(refpath);
+-              if (!refnode) {
+-                      err = -ENOENT;
+-                      goto out;
+-              }
++              if (!refnode)
++                      return -ENOENT;
+               phandle = refnode->phandle;
+               of_node_put(refnode);
+@@ -328,11 +319,8 @@ int of_resolve_phandles(struct device_node *overlay)
+                       break;
+       }
+-out:
+       if (err)
+               pr_err("overlay phandle fixup failed: %d\n", err);
+-      of_node_put(tree_symbols);
+-
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(of_resolve_phandles);
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-msi-add-an-option-to-write-msix-entry_data-befor.patch b/queue-6.14/pci-msi-add-an-option-to-write-msix-entry_data-befor.patch
new file mode 100644 (file)
index 0000000..07cf287
--- /dev/null
@@ -0,0 +1,59 @@
+From 99df92a026311b5b0c88f8a67b33e271210b05e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Nov 2024 17:48:42 -0600
+Subject: PCI/MSI: Add an option to write MSIX ENTRY_DATA before any reads
+
+From: Jonathan Currier <dullfire@yahoo.com>
+
+[ Upstream commit cf761e3dacc6ad5f65a4886d00da1f9681e6805a ]
+
+Commit 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries") introduced a
+readl() from ENTRY_VECTOR_CTRL before the writel() to ENTRY_DATA.
+
+This is correct, however some hardware, like the Sun Neptune chips, the NIU
+module, will cause an error and/or fatal trap if any MSIX table entry is
+read before the corresponding ENTRY_DATA field is written to.
+
+Add an optional early writel() in msix_prepare_msi_desc().
+
+Fixes: 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries")
+Signed-off-by: Jonathan Currier <dullfire@yahoo.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20241117234843.19236-2-dullfire@yahoo.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/msi/msi.c | 3 +++
+ include/linux/pci.h   | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
+index 6569ba3577fe6..8b88487886184 100644
+--- a/drivers/pci/msi/msi.c
++++ b/drivers/pci/msi/msi.c
+@@ -615,6 +615,9 @@ void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
+               void __iomem *addr = pci_msix_desc_addr(desc);
+               desc->pci.msi_attrib.can_mask = 1;
++              /* Workaround for SUN NIU insanity, which requires write before read */
++              if (dev->dev_flags & PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST)
++                      writel(0, addr + PCI_MSIX_ENTRY_DATA);
+               desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
+       }
+ }
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 47b31ad724fa5..8e028620642f3 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -245,6 +245,8 @@ enum pci_dev_flags {
+       PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11),
+       /* Device does honor MSI masking despite saying otherwise */
+       PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12),
++      /* Device requires write to PCI_MSIX_ENTRY_DATA before any MSIX reads */
++      PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST = (__force pci_dev_flags_t) (1 << 13),
+ };
+ enum pci_irq_reroute_variant {
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-msi-convert-pci_msi_ignore_mask-to-per-msi-domai.patch b/queue-6.14/pci-msi-convert-pci_msi_ignore_mask-to-per-msi-domai.patch
new file mode 100644 (file)
index 0000000..abb0c20
--- /dev/null
@@ -0,0 +1,222 @@
+From 646c2795d1777b4edc580db32cbf62dc955b7db9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 10:20:57 +0100
+Subject: PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+[ Upstream commit c3164d2e0d181027da8fc94f8179d8607c3d440f ]
+
+Setting pci_msi_ignore_mask inhibits the toggling of the mask bit for both
+MSI and MSI-X entries globally, regardless of the IRQ chip they are using.
+Only Xen sets the pci_msi_ignore_mask when routing physical interrupts over
+event channels, to prevent PCI code from attempting to toggle the maskbit,
+as it's Xen that controls the bit.
+
+However, the pci_msi_ignore_mask being global will affect devices that use
+MSI interrupts but are not routing those interrupts over event channels
+(not using the Xen pIRQ chip).  One example is devices behind a VMD PCI
+bridge.  In that scenario the VMD bridge configures MSI(-X) using the
+normal IRQ chip (the pIRQ one in the Xen case), and devices behind the
+bridge configure the MSI entries using indexes into the VMD bridge MSI
+table.  The VMD bridge then demultiplexes such interrupts and delivers to
+the destination device(s).  Having pci_msi_ignore_mask set in that scenario
+prevents (un)masking of MSI entries for devices behind the VMD bridge.
+
+Move the signaling of no entry masking into the MSI domain flags, as that
+allows setting it on a per-domain basis.  Set it for the Xen MSI domain
+that uses the pIRQ chip, while leaving it unset for the rest of the
+cases.
+
+Remove pci_msi_ignore_mask at once, since it was only used by Xen code, and
+with Xen dropping usage the variable is unneeded.
+
+This fixes using devices behind a VMD bridge on Xen PV hardware domains.
+
+Albeit Devices behind a VMD bridge are not known to Xen, that doesn't mean
+Linux cannot use them.  By inhibiting the usage of
+VMD_FEAT_CAN_BYPASS_MSI_REMAP and the removal of the pci_msi_ignore_mask
+bodge devices behind a VMD bridge do work fine when use from a Linux Xen
+hardware domain.  That's the whole point of the series.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Juergen Gross <jgross@suse.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Message-ID: <20250219092059.90850-4-roger.pau@citrix.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: cf761e3dacc6 ("PCI/MSI: Add an option to write MSIX ENTRY_DATA before any reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/pci/xen.c    |  8 ++------
+ drivers/pci/msi/msi.c | 37 +++++++++++++++++++++----------------
+ include/linux/msi.h   |  3 ++-
+ kernel/irq/msi.c      |  2 +-
+ 4 files changed, 26 insertions(+), 24 deletions(-)
+
+diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
+index 0f2fe524f60dc..b8755cde24199 100644
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -436,7 +436,8 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = {
+ };
+ static struct msi_domain_info xen_pci_msi_domain_info = {
+-      .flags                  = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS,
++      .flags                  = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS |
++                                MSI_FLAG_DEV_SYSFS | MSI_FLAG_NO_MASK,
+       .ops                    = &xen_pci_msi_domain_ops,
+ };
+@@ -484,11 +485,6 @@ static __init void xen_setup_pci_msi(void)
+        * in allocating the native domain and never use it.
+        */
+       x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain;
+-      /*
+-       * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely
+-       * controlled by the hypervisor.
+-       */
+-      pci_msi_ignore_mask = 1;
+ }
+ #else /* CONFIG_PCI_MSI */
+diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
+index 2f647cac4cae3..4c8c2b57b5f61 100644
+--- a/drivers/pci/msi/msi.c
++++ b/drivers/pci/msi/msi.c
+@@ -10,12 +10,12 @@
+ #include <linux/err.h>
+ #include <linux/export.h>
+ #include <linux/irq.h>
++#include <linux/irqdomain.h>
+ #include "../pci.h"
+ #include "msi.h"
+ int pci_msi_enable = 1;
+-int pci_msi_ignore_mask;
+ /**
+  * pci_msi_supported - check whether MSI may be enabled on a device
+@@ -285,6 +285,8 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable)
+ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
+                             struct irq_affinity_desc *masks)
+ {
++      const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
++      const struct msi_domain_info *info = d->host_data;
+       struct msi_desc desc;
+       u16 control;
+@@ -295,8 +297,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
+       /* Lies, damned lies, and MSIs */
+       if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
+               control |= PCI_MSI_FLAGS_MASKBIT;
+-      /* Respect XEN's mask disabling */
+-      if (pci_msi_ignore_mask)
++      if (info->flags & MSI_FLAG_NO_MASK)
+               control &= ~PCI_MSI_FLAGS_MASKBIT;
+       desc.nvec_used                  = nvec;
+@@ -604,12 +605,15 @@ static void __iomem *msix_map_region(struct pci_dev *dev,
+  */
+ void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
+ {
++      const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
++      const struct msi_domain_info *info = d->host_data;
++
+       desc->nvec_used                         = 1;
+       desc->pci.msi_attrib.is_msix            = 1;
+       desc->pci.msi_attrib.is_64              = 1;
+       desc->pci.msi_attrib.default_irq        = dev->irq;
+       desc->pci.mask_base                     = dev->msix_base;
+-      desc->pci.msi_attrib.can_mask           = !pci_msi_ignore_mask &&
++      desc->pci.msi_attrib.can_mask           = !(info->flags & MSI_FLAG_NO_MASK) &&
+                                                 !desc->pci.msi_attrib.is_virtual;
+       if (desc->pci.msi_attrib.can_mask) {
+@@ -659,9 +663,6 @@ static void msix_mask_all(void __iomem *base, int tsize)
+       u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT;
+       int i;
+-      if (pci_msi_ignore_mask)
+-              return;
+-
+       for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE)
+               writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL);
+ }
+@@ -714,6 +715,8 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries
+ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
+                               int nvec, struct irq_affinity *affd)
+ {
++      const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
++      const struct msi_domain_info *info = d->host_data;
+       int ret, tsize;
+       u16 control;
+@@ -744,15 +747,17 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
+       /* Disable INTX */
+       pci_intx_for_msi(dev, 0);
+-      /*
+-       * Ensure that all table entries are masked to prevent
+-       * stale entries from firing in a crash kernel.
+-       *
+-       * Done late to deal with a broken Marvell NVME device
+-       * which takes the MSI-X mask bits into account even
+-       * when MSI-X is disabled, which prevents MSI delivery.
+-       */
+-      msix_mask_all(dev->msix_base, tsize);
++      if (!(info->flags & MSI_FLAG_NO_MASK)) {
++              /*
++               * Ensure that all table entries are masked to prevent
++               * stale entries from firing in a crash kernel.
++               *
++               * Done late to deal with a broken Marvell NVME device
++               * which takes the MSI-X mask bits into account even
++               * when MSI-X is disabled, which prevents MSI delivery.
++               */
++              msix_mask_all(dev->msix_base, tsize);
++      }
+       pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
+       pcibios_free_irq(dev);
+diff --git a/include/linux/msi.h b/include/linux/msi.h
+index b10093c4d00ea..59a421fc42bf0 100644
+--- a/include/linux/msi.h
++++ b/include/linux/msi.h
+@@ -73,7 +73,6 @@ struct msi_msg {
+       };
+ };
+-extern int pci_msi_ignore_mask;
+ /* Helper functions */
+ struct msi_desc;
+ struct pci_dev;
+@@ -556,6 +555,8 @@ enum {
+       MSI_FLAG_PCI_MSIX_ALLOC_DYN     = (1 << 20),
+       /* PCI MSIs cannot be steered separately to CPU cores */
+       MSI_FLAG_NO_AFFINITY            = (1 << 21),
++      /* Inhibit usage of entry masking */
++      MSI_FLAG_NO_MASK                = (1 << 22),
+ };
+ /**
+diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
+index 396a067a8a56b..7682c36cbccc6 100644
+--- a/kernel/irq/msi.c
++++ b/kernel/irq/msi.c
+@@ -1143,7 +1143,7 @@ static bool msi_check_reservation_mode(struct irq_domain *domain,
+       if (!(info->flags & MSI_FLAG_MUST_REACTIVATE))
+               return false;
+-      if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_ignore_mask)
++      if (info->flags & MSI_FLAG_NO_MASK)
+               return false;
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-msi-handle-the-nomask-flag-correctly-for-all-pci.patch b/queue-6.14/pci-msi-handle-the-nomask-flag-correctly-for-all-pci.patch
new file mode 100644 (file)
index 0000000..8b9ef5e
--- /dev/null
@@ -0,0 +1,105 @@
+From 25159432a7b357b21bfc80f9ebeb35ad6d3df29c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 13:05:35 +0100
+Subject: PCI/MSI: Handle the NOMASK flag correctly for all PCI/MSI backends
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 3ece3e8e5976c49c3f887e5923f998eabd54ff40 ]
+
+The conversion of the XEN specific global variable pci_msi_ignore_mask to a
+MSI domain flag, missed the facts that:
+
+    1) Legacy architectures do not provide a interrupt domain
+    2) Parent MSI domains do not necessarily have a domain info attached
+
+Both cases result in an unconditional NULL pointer dereference. This was
+unfortunatly missed in review and testing revealed it late.
+
+Cure this by using the existing pci_msi_domain_supports() helper, which
+handles all possible cases correctly.
+
+Fixes: c3164d2e0d18 ("PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag")
+Reported-by: Daniel Gomez <da.gomez@kernel.org>
+Reported-by: Borislav Petkov <bp@alien8.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Borislav Petkov <bp@alien8.de>
+Tested-by: Daniel Gomez <da.gomez@kernel.org>
+Link: https://lore.kernel.org/all/87iknwyp2o.ffs@tglx
+Closes: https://lore.kernel.org/all/qn7fzggcj6qe6r6gdbwcz23pzdz2jx64aldccmsuheabhmjgrt@tawf5nfwuvw7
+Stable-dep-of: cf761e3dacc6 ("PCI/MSI: Add an option to write MSIX ENTRY_DATA before any reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/msi/msi.c | 18 ++++++------------
+ 1 file changed, 6 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
+index 4c8c2b57b5f61..6569ba3577fe6 100644
+--- a/drivers/pci/msi/msi.c
++++ b/drivers/pci/msi/msi.c
+@@ -285,8 +285,6 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable)
+ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
+                             struct irq_affinity_desc *masks)
+ {
+-      const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
+-      const struct msi_domain_info *info = d->host_data;
+       struct msi_desc desc;
+       u16 control;
+@@ -297,7 +295,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
+       /* Lies, damned lies, and MSIs */
+       if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
+               control |= PCI_MSI_FLAGS_MASKBIT;
+-      if (info->flags & MSI_FLAG_NO_MASK)
++      if (pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY))
+               control &= ~PCI_MSI_FLAGS_MASKBIT;
+       desc.nvec_used                  = nvec;
+@@ -605,20 +603,18 @@ static void __iomem *msix_map_region(struct pci_dev *dev,
+  */
+ void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
+ {
+-      const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
+-      const struct msi_domain_info *info = d->host_data;
+-
+       desc->nvec_used                         = 1;
+       desc->pci.msi_attrib.is_msix            = 1;
+       desc->pci.msi_attrib.is_64              = 1;
+       desc->pci.msi_attrib.default_irq        = dev->irq;
+       desc->pci.mask_base                     = dev->msix_base;
+-      desc->pci.msi_attrib.can_mask           = !(info->flags & MSI_FLAG_NO_MASK) &&
+-                                                !desc->pci.msi_attrib.is_virtual;
+-      if (desc->pci.msi_attrib.can_mask) {
++
++      if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY) &&
++          !desc->pci.msi_attrib.is_virtual) {
+               void __iomem *addr = pci_msix_desc_addr(desc);
++              desc->pci.msi_attrib.can_mask = 1;
+               desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
+       }
+ }
+@@ -715,8 +711,6 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries
+ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
+                               int nvec, struct irq_affinity *affd)
+ {
+-      const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
+-      const struct msi_domain_info *info = d->host_data;
+       int ret, tsize;
+       u16 control;
+@@ -747,7 +741,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
+       /* Disable INTX */
+       pci_intx_for_msi(dev, 0);
+-      if (!(info->flags & MSI_FLAG_NO_MASK)) {
++      if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) {
+               /*
+                * Ensure that all table entries are masked to prevent
+                * stale entries from firing in a crash kernel.
+-- 
+2.39.5
+
diff --git a/queue-6.14/pm-em-address-rcu-related-sparse-warnings.patch b/queue-6.14/pm-em-address-rcu-related-sparse-warnings.patch
new file mode 100644 (file)
index 0000000..34452f1
--- /dev/null
@@ -0,0 +1,252 @@
+From a70ba0e70a8457348d469243dadc4cb60121cecb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 17:49:20 +0100
+Subject: PM: EM: Address RCU-related sparse warnings
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 3ee7be9e10dd5f79448788b899591d4bd2bf0c19 ]
+
+The usage of __rcu in the Energy Model code is quite inconsistent
+which causes the following sparse warnings to trigger:
+
+kernel/power/energy_model.c:169:15: warning: incorrect type in assignment (different address spaces)
+kernel/power/energy_model.c:169:15:    expected struct em_perf_table [noderef] __rcu *table
+kernel/power/energy_model.c:169:15:    got struct em_perf_table *
+kernel/power/energy_model.c:171:9: warning: incorrect type in argument 1 (different address spaces)
+kernel/power/energy_model.c:171:9:    expected struct callback_head *head
+kernel/power/energy_model.c:171:9:    got struct callback_head [noderef] __rcu *
+kernel/power/energy_model.c:171:9: warning: cast removes address space '__rcu' of expression
+kernel/power/energy_model.c:182:19: warning: incorrect type in argument 1 (different address spaces)
+kernel/power/energy_model.c:182:19:    expected struct kref *kref
+kernel/power/energy_model.c:182:19:    got struct kref [noderef] __rcu *
+kernel/power/energy_model.c:200:15: warning: incorrect type in assignment (different address spaces)
+kernel/power/energy_model.c:200:15:    expected struct em_perf_table [noderef] __rcu *table
+kernel/power/energy_model.c:200:15:    got void *[assigned] _res
+kernel/power/energy_model.c:204:20: warning: incorrect type in argument 1 (different address spaces)
+kernel/power/energy_model.c:204:20:    expected struct kref *kref
+kernel/power/energy_model.c:204:20:    got struct kref [noderef] __rcu *
+kernel/power/energy_model.c:320:19: warning: incorrect type in argument 1 (different address spaces)
+kernel/power/energy_model.c:320:19:    expected struct kref *kref
+kernel/power/energy_model.c:320:19:    got struct kref [noderef] __rcu *
+kernel/power/energy_model.c:325:45: warning: incorrect type in argument 2 (different address spaces)
+kernel/power/energy_model.c:325:45:    expected struct em_perf_state *table
+kernel/power/energy_model.c:325:45:    got struct em_perf_state [noderef] __rcu *
+kernel/power/energy_model.c:425:45: warning: incorrect type in argument 3 (different address spaces)
+kernel/power/energy_model.c:425:45:    expected struct em_perf_state *table
+kernel/power/energy_model.c:425:45:    got struct em_perf_state [noderef] __rcu *
+kernel/power/energy_model.c:442:15: warning: incorrect type in argument 1 (different address spaces)
+kernel/power/energy_model.c:442:15:    expected void const *objp
+kernel/power/energy_model.c:442:15:    got struct em_perf_table [noderef] __rcu *[assigned] em_table
+kernel/power/energy_model.c:626:55: warning: incorrect type in argument 2 (different address spaces)
+kernel/power/energy_model.c:626:55:    expected struct em_perf_state *table
+kernel/power/energy_model.c:626:55:    got struct em_perf_state [noderef] __rcu *
+kernel/power/energy_model.c:681:16: warning: incorrect type in assignment (different address spaces)
+kernel/power/energy_model.c:681:16:    expected struct em_perf_state *new_ps
+kernel/power/energy_model.c:681:16:    got struct em_perf_state [noderef] __rcu *
+kernel/power/energy_model.c:699:37: warning: incorrect type in argument 2 (different address spaces)
+kernel/power/energy_model.c:699:37:    expected struct em_perf_state *table
+kernel/power/energy_model.c:699:37:    got struct em_perf_state [noderef] __rcu *
+kernel/power/energy_model.c:733:38: warning: incorrect type in argument 3 (different address spaces)
+kernel/power/energy_model.c:733:38:    expected struct em_perf_state *table
+kernel/power/energy_model.c:733:38:    got struct em_perf_state [noderef] __rcu *
+kernel/power/energy_model.c:855:53: warning: dereference of noderef expression
+kernel/power/energy_model.c:864:32: warning: dereference of noderef expression
+
+This is because the __rcu annotation for sparse is only applicable to
+pointers that need rcu_dereference() or equivalent for protection, which
+basically means pointers assigned with rcu_assign_pointer().
+
+Make all of the above sparse warnings go away by cleaning up the usage
+of __rcu and using rcu_dereference_protected() where applicable.
+
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://patch.msgid.link/5885405.DvuYhMxLoT@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/energy_model.h | 12 +++++------
+ kernel/power/energy_model.c  | 39 ++++++++++++++++++------------------
+ 2 files changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
+index 78318d49276dc..b3b8389e9480d 100644
+--- a/include/linux/energy_model.h
++++ b/include/linux/energy_model.h
+@@ -167,13 +167,13 @@ struct em_data_callback {
+ struct em_perf_domain *em_cpu_get(int cpu);
+ struct em_perf_domain *em_pd_get(struct device *dev);
+ int em_dev_update_perf_domain(struct device *dev,
+-                            struct em_perf_table __rcu *new_table);
++                            struct em_perf_table *new_table);
+ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
+                               struct em_data_callback *cb, cpumask_t *span,
+                               bool microwatts);
+ void em_dev_unregister_perf_domain(struct device *dev);
+-struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd);
+-void em_table_free(struct em_perf_table __rcu *table);
++struct em_perf_table *em_table_alloc(struct em_perf_domain *pd);
++void em_table_free(struct em_perf_table *table);
+ int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
+                        int nr_states);
+ int em_dev_update_chip_binning(struct device *dev);
+@@ -373,14 +373,14 @@ static inline int em_pd_nr_perf_states(struct em_perf_domain *pd)
+       return 0;
+ }
+ static inline
+-struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd)
++struct em_perf_table *em_table_alloc(struct em_perf_domain *pd)
+ {
+       return NULL;
+ }
+-static inline void em_table_free(struct em_perf_table __rcu *table) {}
++static inline void em_table_free(struct em_perf_table *table) {}
+ static inline
+ int em_dev_update_perf_domain(struct device *dev,
+-                            struct em_perf_table __rcu *new_table)
++                            struct em_perf_table *new_table)
+ {
+       return -EINVAL;
+ }
+diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
+index 72655eff6fc52..76c4343796893 100644
+--- a/kernel/power/energy_model.c
++++ b/kernel/power/energy_model.c
+@@ -163,12 +163,8 @@ static void em_debug_remove_pd(struct device *dev) {}
+ static void em_release_table_kref(struct kref *kref)
+ {
+-      struct em_perf_table __rcu *table;
+-
+       /* It was the last owner of this table so we can free */
+-      table = container_of(kref, struct em_perf_table, kref);
+-
+-      kfree_rcu(table, rcu);
++      kfree_rcu(container_of(kref, struct em_perf_table, kref), rcu);
+ }
+ /**
+@@ -177,7 +173,7 @@ static void em_release_table_kref(struct kref *kref)
+  *
+  * No return values.
+  */
+-void em_table_free(struct em_perf_table __rcu *table)
++void em_table_free(struct em_perf_table *table)
+ {
+       kref_put(&table->kref, em_release_table_kref);
+ }
+@@ -190,9 +186,9 @@ void em_table_free(struct em_perf_table __rcu *table)
+  * has a user.
+  * Returns allocated table or NULL.
+  */
+-struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd)
++struct em_perf_table *em_table_alloc(struct em_perf_domain *pd)
+ {
+-      struct em_perf_table __rcu *table;
++      struct em_perf_table *table;
+       int table_size;
+       table_size = sizeof(struct em_perf_state) * pd->nr_perf_states;
+@@ -300,9 +296,9 @@ int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
+  * Return 0 on success or an error code on failure.
+  */
+ int em_dev_update_perf_domain(struct device *dev,
+-                            struct em_perf_table __rcu *new_table)
++                            struct em_perf_table *new_table)
+ {
+-      struct em_perf_table __rcu *old_table;
++      struct em_perf_table *old_table;
+       struct em_perf_domain *pd;
+       if (!dev)
+@@ -319,7 +315,8 @@ int em_dev_update_perf_domain(struct device *dev,
+       kref_get(&new_table->kref);
+-      old_table = pd->em_table;
++      old_table = rcu_dereference_protected(pd->em_table,
++                                            lockdep_is_held(&em_pd_mutex));
+       rcu_assign_pointer(pd->em_table, new_table);
+       em_cpufreq_update_efficiencies(dev, new_table->state);
+@@ -391,7 +388,7 @@ static int em_create_pd(struct device *dev, int nr_states,
+                       struct em_data_callback *cb, cpumask_t *cpus,
+                       unsigned long flags)
+ {
+-      struct em_perf_table __rcu *em_table;
++      struct em_perf_table *em_table;
+       struct em_perf_domain *pd;
+       struct device *cpu_dev;
+       int cpu, ret, num_cpus;
+@@ -551,6 +548,7 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
+                               struct em_data_callback *cb, cpumask_t *cpus,
+                               bool microwatts)
+ {
++      struct em_perf_table *em_table;
+       unsigned long cap, prev_cap = 0;
+       unsigned long flags = 0;
+       int cpu, ret;
+@@ -623,7 +621,9 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
+       dev->em_pd->min_perf_state = 0;
+       dev->em_pd->max_perf_state = nr_states - 1;
+-      em_cpufreq_update_efficiencies(dev, dev->em_pd->em_table->state);
++      em_table = rcu_dereference_protected(dev->em_pd->em_table,
++                                           lockdep_is_held(&em_pd_mutex));
++      em_cpufreq_update_efficiencies(dev, em_table->state);
+       em_debug_create_pd(dev);
+       dev_info(dev, "EM: created perf domain\n");
+@@ -660,7 +660,8 @@ void em_dev_unregister_perf_domain(struct device *dev)
+       mutex_lock(&em_pd_mutex);
+       em_debug_remove_pd(dev);
+-      em_table_free(dev->em_pd->em_table);
++      em_table_free(rcu_dereference_protected(dev->em_pd->em_table,
++                                              lockdep_is_held(&em_pd_mutex)));
+       kfree(dev->em_pd);
+       dev->em_pd = NULL;
+@@ -668,9 +669,9 @@ void em_dev_unregister_perf_domain(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
+-static struct em_perf_table __rcu *em_table_dup(struct em_perf_domain *pd)
++static struct em_perf_table *em_table_dup(struct em_perf_domain *pd)
+ {
+-      struct em_perf_table __rcu *em_table;
++      struct em_perf_table *em_table;
+       struct em_perf_state *ps, *new_ps;
+       int ps_size;
+@@ -692,7 +693,7 @@ static struct em_perf_table __rcu *em_table_dup(struct em_perf_domain *pd)
+ }
+ static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd,
+-                              struct em_perf_table __rcu *em_table)
++                              struct em_perf_table *em_table)
+ {
+       int ret;
+@@ -723,7 +724,7 @@ static void em_adjust_new_capacity(struct device *dev,
+                                  struct em_perf_domain *pd,
+                                  u64 max_cap)
+ {
+-      struct em_perf_table __rcu *em_table;
++      struct em_perf_table *em_table;
+       em_table = em_table_dup(pd);
+       if (!em_table) {
+@@ -814,7 +815,7 @@ static void em_update_workfn(struct work_struct *work)
+  */
+ int em_dev_update_chip_binning(struct device *dev)
+ {
+-      struct em_perf_table __rcu *em_table;
++      struct em_perf_table *em_table;
+       struct em_perf_domain *pd;
+       int i, ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/pm-em-use-kfree_rcu-to-simplify-the-code.patch b/queue-6.14/pm-em-use-kfree_rcu-to-simplify-the-code.patch
new file mode 100644 (file)
index 0000000..6f88074
--- /dev/null
@@ -0,0 +1,53 @@
+From 75894af67ad0311f21e3a3e4c8159d3a0479061e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 16:20:21 +0800
+Subject: PM: EM: use kfree_rcu() to simplify the code
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 1618f635bdf56f3ac158171114e9bf18db234cbf ]
+
+The callback function of call_rcu() just calls kfree(), so use
+kfree_rcu() instead of call_rcu() + callback function.
+
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://patch.msgid.link/20250218082021.2766-1-lirongqing@baidu.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 3ee7be9e10dd ("PM: EM: Address RCU-related sparse warnings")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/energy_model.c | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
+index 3874f0e97651e..72655eff6fc52 100644
+--- a/kernel/power/energy_model.c
++++ b/kernel/power/energy_model.c
+@@ -161,14 +161,6 @@ static void em_debug_create_pd(struct device *dev) {}
+ static void em_debug_remove_pd(struct device *dev) {}
+ #endif
+-static void em_destroy_table_rcu(struct rcu_head *rp)
+-{
+-      struct em_perf_table __rcu *table;
+-
+-      table = container_of(rp, struct em_perf_table, rcu);
+-      kfree(table);
+-}
+-
+ static void em_release_table_kref(struct kref *kref)
+ {
+       struct em_perf_table __rcu *table;
+@@ -176,7 +168,7 @@ static void em_release_table_kref(struct kref *kref)
+       /* It was the last owner of this table so we can free */
+       table = container_of(kref, struct em_perf_table, kref);
+-      call_rcu(&table->rcu, em_destroy_table_rcu);
++      kfree_rcu(table, rcu);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/s390-pci-support-mmap-of-pci-resources-except-for-is.patch b/queue-6.14/s390-pci-support-mmap-of-pci-resources-except-for-is.patch
new file mode 100644 (file)
index 0000000..c490d8b
--- /dev/null
@@ -0,0 +1,155 @@
+From d04b275636d31a1ff5237a9df364ee69693d75f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 13:07:47 +0100
+Subject: s390/pci: Support mmap() of PCI resources except for ISM devices
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit aa9f168d55dc47c0de564f7dfe0e90467c9fee71 ]
+
+So far s390 does not allow mmap() of PCI resources to user-space via the
+usual mechanisms, though it does use it for RDMA. For the PCI sysfs
+resource files and /proc/bus/pci it defines neither HAVE_PCI_MMAP nor
+ARCH_GENERIC_PCI_MMAP_RESOURCE. For vfio-pci s390 previously relied on
+disabled VFIO_PCI_MMAP and now relies on setting pdev->non_mappable_bars
+for all devices.
+
+This is partly because access to mapped PCI resources from user-space
+requires special PCI load/store memory-I/O (MIO) instructions, or the
+special MMIO syscalls when these are not available. Still, such access is
+possible and useful not just for RDMA, in fact not being able to mmap() PCI
+resources has previously caused extra work when testing devices.
+
+One thing that doesn't work with PCI resources mapped to user-space though
+is the s390 specific virtual ISM device. Not only because the BAR size of
+256 TiB prevents mapping the whole BAR but also because access requires use
+of the legacy PCI instructions which are not accessible to user-space on
+systems with the newer MIO PCI instructions.
+
+Now with the pdev->non_mappable_bars flag ISM can be excluded from mapping
+its resources while making this functionality available for all other PCI
+devices. To this end introduce a minimal implementation of PCI_QUIRKS and
+use that to set pdev->non_mappable_bars for ISM devices only. Then also set
+ARCH_GENERIC_PCI_MMAP_RESOURCE to take advantage of the generic
+implementation of pci_mmap_resource_range() enabling only the newer sysfs
+mmap() interface. This follows the recommendation in
+Documentation/PCI/sysfs-pci.rst.
+
+Link: https://lore.kernel.org/r/20250226-vfio_pci_mmap-v7-3-c5c0f1d26efd@linux.ibm.com
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig           |  4 +---
+ arch/s390/include/asm/pci.h |  3 +++
+ arch/s390/pci/Makefile      |  2 +-
+ arch/s390/pci/pci_fixup.c   | 23 +++++++++++++++++++++++
+ drivers/s390/net/ism_drv.c  |  1 -
+ include/linux/pci_ids.h     |  1 +
+ 6 files changed, 29 insertions(+), 5 deletions(-)
+ create mode 100644 arch/s390/pci/pci_fixup.c
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 9c9ec08d78c71..e48741e001476 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -41,9 +41,6 @@ config AUDIT_ARCH
+ config NO_IOPORT_MAP
+       def_bool y
+-config PCI_QUIRKS
+-      def_bool n
+-
+ config ARCH_SUPPORTS_UPROBES
+       def_bool y
+@@ -258,6 +255,7 @@ config S390
+       select PCI_DOMAINS              if PCI
+       select PCI_MSI                  if PCI
+       select PCI_MSI_ARCH_FALLBACKS   if PCI_MSI
++      select PCI_QUIRKS               if PCI
+       select SPARSE_IRQ
+       select SWIOTLB
+       select SYSCTL_EXCEPTION_TRACE
+diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
+index 474e1f8d1d3c2..d2086af3434c0 100644
+--- a/arch/s390/include/asm/pci.h
++++ b/arch/s390/include/asm/pci.h
+@@ -11,6 +11,9 @@
+ #include <asm/pci_insn.h>
+ #include <asm/sclp.h>
++#define ARCH_GENERIC_PCI_MMAP_RESOURCE        1
++#define arch_can_pci_mmap_wc()                1
++
+ #define PCIBIOS_MIN_IO                0x1000
+ #define PCIBIOS_MIN_MEM               0x10000000
+diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
+index df73c5182990a..1810e0944a4ed 100644
+--- a/arch/s390/pci/Makefile
++++ b/arch/s390/pci/Makefile
+@@ -5,6 +5,6 @@
+ obj-$(CONFIG_PCI)     += pci.o pci_irq.o pci_clp.o \
+                          pci_event.o pci_debug.o pci_insn.o pci_mmio.o \
+-                         pci_bus.o pci_kvm_hook.o pci_report.o
++                         pci_bus.o pci_kvm_hook.o pci_report.o pci_fixup.o
+ obj-$(CONFIG_PCI_IOV) += pci_iov.o
+ obj-$(CONFIG_SYSFS)   += pci_sysfs.o
+diff --git a/arch/s390/pci/pci_fixup.c b/arch/s390/pci/pci_fixup.c
+new file mode 100644
+index 0000000000000..35688b6450983
+--- /dev/null
++++ b/arch/s390/pci/pci_fixup.c
+@@ -0,0 +1,23 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Exceptions for specific devices,
++ *
++ * Copyright IBM Corp. 2025
++ *
++ * Author(s):
++ *   Niklas Schnelle <schnelle@linux.ibm.com>
++ */
++#include <linux/pci.h>
++
++static void zpci_ism_bar_no_mmap(struct pci_dev *pdev)
++{
++      /*
++       * ISM's BAR is special. Drivers written for ISM know
++       * how to handle this but others need to be aware of their
++       * special nature e.g. to prevent attempts to mmap() it.
++       */
++      pdev->non_mappable_bars = 1;
++}
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM,
++                      PCI_DEVICE_ID_IBM_ISM,
++                      zpci_ism_bar_no_mmap);
+diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
+index 2f34761e64135..60ed70a39d2cc 100644
+--- a/drivers/s390/net/ism_drv.c
++++ b/drivers/s390/net/ism_drv.c
+@@ -20,7 +20,6 @@
+ MODULE_DESCRIPTION("ISM driver for s390");
+ MODULE_LICENSE("GPL");
+-#define PCI_DEVICE_ID_IBM_ISM 0x04ED
+ #define DRV_NAME "ism"
+ static const struct pci_device_id ism_device_table[] = {
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 2a9ca3dbaa0e9..5bd122a9afdc6 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -518,6 +518,7 @@
+ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM   0x0251
+ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE 0x0361
+ #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL        0x252
++#define PCI_DEVICE_ID_IBM_ISM         0x04ed
+ #define PCI_SUBVENDOR_ID_IBM          0x1014
+ #define PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT   0x03d4
+-- 
+2.39.5
+
diff --git a/queue-6.14/scsi-ufs-qcom-fix-dev-reference-leaked-through-of_qc.patch b/queue-6.14/scsi-ufs-qcom-fix-dev-reference-leaked-through-of_qc.patch
new file mode 100644 (file)
index 0000000..dad41fb
--- /dev/null
@@ -0,0 +1,42 @@
+From 9ab4f7145217a8908bafb56c7ae423f1428f0302 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 14:18:52 +0000
+Subject: scsi: ufs: qcom: fix dev reference leaked through of_qcom_ice_get
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit ded40f32b55f7f2f4ed9627dd3c37a1fe89ed8c6 ]
+
+The driver leaks the device reference taken with
+of_find_device_by_node(). Fix the leak by using devm_of_qcom_ice_get().
+
+Fixes: 56541c7c4468 ("scsi: ufs: ufs-qcom: Switch to the new ICE API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Acked-by: Martin K. Petersen <martin.petersen@oracle.com> # SCSI
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-3-1ffa5b6884cb@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/host/ufs-qcom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
+index 23b9f6efa0475..a455a95f65fc6 100644
+--- a/drivers/ufs/host/ufs-qcom.c
++++ b/drivers/ufs/host/ufs-qcom.c
+@@ -125,7 +125,7 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host)
+       int err;
+       int i;
+-      ice = of_qcom_ice_get(dev);
++      ice = devm_of_qcom_ice_get(dev);
+       if (ice == ERR_PTR(-EOPNOTSUPP)) {
+               dev_warn(dev, "Disabling inline encryption support\n");
+               ice = NULL;
+-- 
+2.39.5
+
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a946189e5748272e82a7796373c71716655f0121 100644 (file)
@@ -0,0 +1,33 @@
+mm-vmscan-don-t-try-to-reclaim-hwpoison-folio.patch
+soc-qcom-ice-introduce-devm_of_qcom_ice_get.patch
+mmc-sdhci-msm-fix-dev-reference-leaked-through-of_qc.patch
+pm-em-use-kfree_rcu-to-simplify-the-code.patch
+pm-em-address-rcu-related-sparse-warnings.patch
+media-i2c-imx214-use-subdev-active-state.patch
+media-i2c-imx214-simplify-with-dev_err_probe.patch
+media-i2c-imx214-convert-to-cci-register-access-help.patch
+media-i2c-imx214-replace-register-addresses-with-mac.patch
+media-i2c-imx214-check-number-of-lanes-from-device-t.patch
+media-i2c-imx214-fix-link-frequency-validation.patch
+media-ov08x40-move-ov08x40_identify_module-function-.patch
+media-ov08x40-add-missing-ov08x40_identify_module-ca.patch
+iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch
+iio-adc-ad7768-1-fix-conversion-result-sign.patch
+of-resolver-simplify-of_resolve_phandles-using-__fre.patch
+of-resolver-fix-device-node-refcount-leakage-in-of_r.patch
+scsi-ufs-qcom-fix-dev-reference-leaked-through-of_qc.patch
+s390-pci-support-mmap-of-pci-resources-except-for-is.patch
+pci-msi-convert-pci_msi_ignore_mask-to-per-msi-domai.patch
+pci-msi-handle-the-nomask-flag-correctly-for-all-pci.patch
+pci-msi-add-an-option-to-write-msix-entry_data-befor.patch
+ubsan-overflow-rework-integer-overflow-sanitizer-opt.patch
+lib-kconfig.ubsan-remove-default-ubsan-from-ubsan_in.patch
+irqchip-renesas-rzv2h-simplify-rzv2h_icu_init.patch
+irqchip-renesas-rzv2h-add-struct-rzv2h_hw_info-with-.patch
+irqchip-renesas-rzv2h-prevent-tint-spurious-interrup.patch
+net-niu-niu-requires-msix-entry_data-fields-touch-be.patch
+drm-xe-ptl-apply-wa_14023061436.patch
+drm-xe-xe3lpg-add-wa_13012615864.patch
+drm-xe-add-performance-tunings-to-debugfs.patch
+drm-xe-rtp-drop-sentinels-from-arg-to-xe_rtp_process.patch
+drm-xe-ensure-fixed_slice_mode-gets-set-after-ccs_mo.patch
diff --git a/queue-6.14/soc-qcom-ice-introduce-devm_of_qcom_ice_get.patch b/queue-6.14/soc-qcom-ice-introduce-devm_of_qcom_ice_get.patch
new file mode 100644 (file)
index 0000000..61a0185
--- /dev/null
@@ -0,0 +1,107 @@
+From 759b595dfe0f3d671a4c3a02fc54240a739e9738 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 14:18:50 +0000
+Subject: soc: qcom: ice: introduce devm_of_qcom_ice_get
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit 1c13d6060d612601a61423f2e8fbf9e48126acca ]
+
+Callers of of_qcom_ice_get() leak the device reference taken by
+of_find_device_by_node(). Introduce devm variant for of_qcom_ice_get().
+Existing consumers need the ICE instance for the entire life of their
+device, thus exporting qcom_ice_put() is not required.
+
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-1-1ffa5b6884cb@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: cbef7442fba5 ("mmc: sdhci-msm: fix dev reference leaked through of_qcom_ice_get")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/ice.c | 48 ++++++++++++++++++++++++++++++++++++++++++
+ include/soc/qcom/ice.h |  2 ++
+ 2 files changed, 50 insertions(+)
+
+diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c
+index 393d2d1d275f1..79e04bff3e331 100644
+--- a/drivers/soc/qcom/ice.c
++++ b/drivers/soc/qcom/ice.c
+@@ -11,6 +11,7 @@
+ #include <linux/cleanup.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
++#include <linux/device.h>
+ #include <linux/iopoll.h>
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
+@@ -324,6 +325,53 @@ struct qcom_ice *of_qcom_ice_get(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(of_qcom_ice_get);
++static void qcom_ice_put(const struct qcom_ice *ice)
++{
++      struct platform_device *pdev = to_platform_device(ice->dev);
++
++      if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "ice"))
++              platform_device_put(pdev);
++}
++
++static void devm_of_qcom_ice_put(struct device *dev, void *res)
++{
++      qcom_ice_put(*(struct qcom_ice **)res);
++}
++
++/**
++ * devm_of_qcom_ice_get() - Devres managed helper to get an ICE instance from
++ * a DT node.
++ * @dev: device pointer for the consumer device.
++ *
++ * This function will provide an ICE instance either by creating one for the
++ * consumer device if its DT node provides the 'ice' reg range and the 'ice'
++ * clock (for legacy DT style). On the other hand, if consumer provides a
++ * phandle via 'qcom,ice' property to an ICE DT, the ICE instance will already
++ * be created and so this function will return that instead.
++ *
++ * Return: ICE pointer on success, NULL if there is no ICE data provided by the
++ * consumer or ERR_PTR() on error.
++ */
++struct qcom_ice *devm_of_qcom_ice_get(struct device *dev)
++{
++      struct qcom_ice *ice, **dr;
++
++      dr = devres_alloc(devm_of_qcom_ice_put, sizeof(*dr), GFP_KERNEL);
++      if (!dr)
++              return ERR_PTR(-ENOMEM);
++
++      ice = of_qcom_ice_get(dev);
++      if (!IS_ERR_OR_NULL(ice)) {
++              *dr = ice;
++              devres_add(dev, dr);
++      } else {
++              devres_free(dr);
++      }
++
++      return ice;
++}
++EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get);
++
+ static int qcom_ice_probe(struct platform_device *pdev)
+ {
+       struct qcom_ice *engine;
+diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h
+index 5870a94599a25..d5f6a228df659 100644
+--- a/include/soc/qcom/ice.h
++++ b/include/soc/qcom/ice.h
+@@ -34,4 +34,6 @@ int qcom_ice_program_key(struct qcom_ice *ice,
+                        int slot);
+ int qcom_ice_evict_key(struct qcom_ice *ice, int slot);
+ struct qcom_ice *of_qcom_ice_get(struct device *dev);
++struct qcom_ice *devm_of_qcom_ice_get(struct device *dev);
++
+ #endif /* __QCOM_ICE_H__ */
+-- 
+2.39.5
+
diff --git a/queue-6.14/ubsan-overflow-rework-integer-overflow-sanitizer-opt.patch b/queue-6.14/ubsan-overflow-rework-integer-overflow-sanitizer-opt.patch
new file mode 100644 (file)
index 0000000..bfa4ced
--- /dev/null
@@ -0,0 +1,277 @@
+From fb97229c8a9bdfc8d6a35894f08aa20b22b9a932 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 20:19:09 -0800
+Subject: ubsan/overflow: Rework integer overflow sanitizer option to turn on
+ everything
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit ed2b548f1017586c44f50654ef9febb42d491f31 ]
+
+Since we're going to approach integer overflow mitigation a type at a
+time, we need to enable all of the associated sanitizers, and then opt
+into types one at a time.
+
+Rename the existing "signed wrap" sanitizer to just the entire topic area:
+"integer wrap". Enable the implicit integer truncation sanitizers, with
+required callbacks and tests.
+
+Notably, this requires features (currently) only available in Clang,
+so we can depend on the cc-option tests to determine availability
+instead of doing version tests.
+
+Link: https://lore.kernel.org/r/20250307041914.937329-1-kees@kernel.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Stable-dep-of: cdc2e1d9d929 ("lib/Kconfig.ubsan: Remove 'default UBSAN' from UBSAN_INTEGER_WRAP")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/compiler_types.h  |  2 +-
+ kernel/configs/hardening.config |  2 +-
+ lib/Kconfig.ubsan               | 23 +++++++++++------------
+ lib/test_ubsan.c                | 18 ++++++++++++++----
+ lib/ubsan.c                     | 28 ++++++++++++++++++++++++++--
+ lib/ubsan.h                     |  8 ++++++++
+ scripts/Makefile.lib            |  4 ++--
+ scripts/Makefile.ubsan          |  8 ++++++--
+ 8 files changed, 69 insertions(+), 24 deletions(-)
+
+diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
+index 981cc3d7e3aa5..352ad20830733 100644
+--- a/include/linux/compiler_types.h
++++ b/include/linux/compiler_types.h
+@@ -360,7 +360,7 @@ struct ftrace_likely_data {
+ #endif
+ /* Do not trap wrapping arithmetic within an annotated function. */
+-#ifdef CONFIG_UBSAN_SIGNED_WRAP
++#ifdef CONFIG_UBSAN_INTEGER_WRAP
+ # define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))
+ #else
+ # define __signed_wrap
+diff --git a/kernel/configs/hardening.config b/kernel/configs/hardening.config
+index 3fabb8f55ef6e..dd7c32fb5ac1b 100644
+--- a/kernel/configs/hardening.config
++++ b/kernel/configs/hardening.config
+@@ -46,7 +46,7 @@ CONFIG_UBSAN_BOUNDS=y
+ # CONFIG_UBSAN_SHIFT is not set
+ # CONFIG_UBSAN_DIV_ZERO is not set
+ # CONFIG_UBSAN_UNREACHABLE is not set
+-# CONFIG_UBSAN_SIGNED_WRAP is not set
++# CONFIG_UBSAN_INTEGER_WRAP is not set
+ # CONFIG_UBSAN_BOOL is not set
+ # CONFIG_UBSAN_ENUM is not set
+ # CONFIG_UBSAN_ALIGNMENT is not set
+diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
+index 1d4aa7a83b3a5..63e5622010e0f 100644
+--- a/lib/Kconfig.ubsan
++++ b/lib/Kconfig.ubsan
+@@ -116,21 +116,20 @@ config UBSAN_UNREACHABLE
+         This option enables -fsanitize=unreachable which checks for control
+         flow reaching an expected-to-be-unreachable position.
+-config UBSAN_SIGNED_WRAP
+-      bool "Perform checking for signed arithmetic wrap-around"
++config UBSAN_INTEGER_WRAP
++      bool "Perform checking for integer arithmetic wrap-around"
+       default UBSAN
+       depends on !COMPILE_TEST
+-      # The no_sanitize attribute was introduced in GCC with version 8.
+-      depends on !CC_IS_GCC || GCC_VERSION >= 80000
+       depends on $(cc-option,-fsanitize=signed-integer-overflow)
+-      help
+-        This option enables -fsanitize=signed-integer-overflow which checks
+-        for wrap-around of any arithmetic operations with signed integers.
+-        This currently performs nearly no instrumentation due to the
+-        kernel's use of -fno-strict-overflow which converts all would-be
+-        arithmetic undefined behavior into wrap-around arithmetic. Future
+-        sanitizer versions will allow for wrap-around checking (rather than
+-        exclusively undefined behavior).
++      depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
++      depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation)
++      depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation)
++      help
++        This option enables all of the sanitizers involved in integer overflow
++        (wrap-around) mitigation: signed-integer-overflow, unsigned-integer-overflow,
++        implicit-signed-integer-truncation, and implicit-unsigned-integer-truncation.
++        This is currently limited only to the size_t type while testing and
++        compiler development continues.
+ config UBSAN_BOOL
+       bool "Perform checking for non-boolean values used as boolean"
+diff --git a/lib/test_ubsan.c b/lib/test_ubsan.c
+index 5d7b10e986107..8772e5edaa4fa 100644
+--- a/lib/test_ubsan.c
++++ b/lib/test_ubsan.c
+@@ -15,7 +15,7 @@ static void test_ubsan_add_overflow(void)
+ {
+       volatile int val = INT_MAX;
+-      UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
++      UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);
+       val += 2;
+ }
+@@ -24,7 +24,7 @@ static void test_ubsan_sub_overflow(void)
+       volatile int val = INT_MIN;
+       volatile int val2 = 2;
+-      UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
++      UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);
+       val -= val2;
+ }
+@@ -32,7 +32,7 @@ static void test_ubsan_mul_overflow(void)
+ {
+       volatile int val = INT_MAX / 2;
+-      UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
++      UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);
+       val *= 3;
+ }
+@@ -40,7 +40,7 @@ static void test_ubsan_negate_overflow(void)
+ {
+       volatile int val = INT_MIN;
+-      UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
++      UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);
+       val = -val;
+ }
+@@ -53,6 +53,15 @@ static void test_ubsan_divrem_overflow(void)
+       val /= val2;
+ }
++static void test_ubsan_truncate_signed(void)
++{
++      volatile long val = LONG_MAX;
++      volatile int val2 = 0;
++
++      UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);
++      val2 = val;
++}
++
+ static void test_ubsan_shift_out_of_bounds(void)
+ {
+       volatile int neg = -1, wrap = 4;
+@@ -127,6 +136,7 @@ static const test_ubsan_fp test_ubsan_array[] = {
+       test_ubsan_sub_overflow,
+       test_ubsan_mul_overflow,
+       test_ubsan_negate_overflow,
++      test_ubsan_truncate_signed,
+       test_ubsan_shift_out_of_bounds,
+       test_ubsan_out_of_bounds,
+       test_ubsan_load_invalid_value,
+diff --git a/lib/ubsan.c b/lib/ubsan.c
+index a1c983d148f16..cdc1d31c3821b 100644
+--- a/lib/ubsan.c
++++ b/lib/ubsan.c
+@@ -44,7 +44,7 @@ const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
+       case ubsan_shift_out_of_bounds:
+               return "UBSAN: shift out of bounds";
+ #endif
+-#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_UBSAN_SIGNED_WRAP)
++#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_UBSAN_INTEGER_WRAP)
+       /*
+        * SanitizerKind::IntegerDivideByZero and
+        * SanitizerKind::SignedIntegerOverflow emit
+@@ -79,7 +79,7 @@ const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
+       case ubsan_type_mismatch:
+               return "UBSAN: type mismatch";
+ #endif
+-#ifdef CONFIG_UBSAN_SIGNED_WRAP
++#ifdef CONFIG_UBSAN_INTEGER_WRAP
+       /*
+        * SanitizerKind::SignedIntegerOverflow emits
+        * SanitizerHandler::AddOverflow, SanitizerHandler::SubOverflow,
+@@ -303,6 +303,30 @@ void __ubsan_handle_negate_overflow(void *_data, void *old_val)
+ }
+ EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
++void __ubsan_handle_implicit_conversion(void *_data, void *from_val, void *to_val)
++{
++      struct implicit_conversion_data *data = _data;
++      char from_val_str[VALUE_LENGTH];
++      char to_val_str[VALUE_LENGTH];
++
++      if (suppress_report(&data->location))
++              return;
++
++      val_to_string(from_val_str, sizeof(from_val_str), data->from_type, from_val);
++      val_to_string(to_val_str, sizeof(to_val_str), data->to_type, to_val);
++
++      ubsan_prologue(&data->location, "implicit-conversion");
++
++      pr_err("cannot represent %s value %s during %s %s, truncated to %s\n",
++              data->from_type->type_name,
++              from_val_str,
++              type_check_kinds[data->type_check_kind],
++              data->to_type->type_name,
++              to_val_str);
++
++      ubsan_epilogue();
++}
++EXPORT_SYMBOL(__ubsan_handle_implicit_conversion);
+ void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
+ {
+diff --git a/lib/ubsan.h b/lib/ubsan.h
+index 07e37d4429b4b..b37e22374e774 100644
+--- a/lib/ubsan.h
++++ b/lib/ubsan.h
+@@ -62,6 +62,13 @@ struct overflow_data {
+       struct type_descriptor *type;
+ };
++struct implicit_conversion_data {
++      struct source_location location;
++      struct type_descriptor *from_type;
++      struct type_descriptor *to_type;
++      unsigned char type_check_kind;
++};
++
+ struct type_mismatch_data {
+       struct source_location location;
+       struct type_descriptor *type;
+@@ -142,6 +149,7 @@ void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs)
+ void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
+ void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val);
+ void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
++void ubsan_linkage __ubsan_handle_implicit_conversion(void *_data, void *lhs, void *rhs);
+ void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr);
+ void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr);
+ void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index);
+diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
+index cad20f0e66ee9..981d14ef9db29 100644
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -166,8 +166,8 @@ _c_flags += $(if $(patsubst n%,, \
+               $(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)$(is-kernel-object)), \
+               $(CFLAGS_UBSAN))
+ _c_flags += $(if $(patsubst n%,, \
+-              $(UBSAN_SIGNED_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \
+-              $(CFLAGS_UBSAN_SIGNED_WRAP))
++              $(UBSAN_INTEGER_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_INTEGER_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \
++              $(CFLAGS_UBSAN_INTEGER_WRAP))
+ endif
+ ifeq ($(CONFIG_KCOV),y)
+diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
+index b2d3b273b8028..4fad9afed24cf 100644
+--- a/scripts/Makefile.ubsan
++++ b/scripts/Makefile.ubsan
+@@ -14,5 +14,9 @@ ubsan-cflags-$(CONFIG_UBSAN_TRAP)            += $(call cc-option,-fsanitize-trap=undefined
+ export CFLAGS_UBSAN := $(ubsan-cflags-y)
+-ubsan-signed-wrap-cflags-$(CONFIG_UBSAN_SIGNED_WRAP)     += -fsanitize=signed-integer-overflow
+-export CFLAGS_UBSAN_SIGNED_WRAP := $(ubsan-signed-wrap-cflags-y)
++ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP)     += \
++      -fsanitize=signed-integer-overflow                      \
++      -fsanitize=unsigned-integer-overflow                    \
++      -fsanitize=implicit-signed-integer-truncation           \
++      -fsanitize=implicit-unsigned-integer-truncation
++export CFLAGS_UBSAN_INTEGER_WRAP := $(ubsan-integer-wrap-cflags-y)
+-- 
+2.39.5
+