]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.12
authorSasha Levin <sashal@kernel.org>
Tue, 8 Apr 2025 00:42:37 +0000 (20:42 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 8 Apr 2025 00:42:37 +0000 (20:42 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
16 files changed:
queue-6.12/arm64-dts-rockchip-add-missing-pcie-supplies-to-rock.patch [new file with mode: 0644]
queue-6.12/cgroup-rstat-fix-forceidle-time-in-cpu.stat.patch [new file with mode: 0644]
queue-6.12/cgroup-rstat-tracking-cgroup-level-niced-cpu-time.patch [new file with mode: 0644]
queue-6.12/drm-amdgpu-gfx11-fix-num_mec.patch [new file with mode: 0644]
queue-6.12/drm-amdgpu-gfx12-fix-num_mec.patch [new file with mode: 0644]
queue-6.12/kbuild-deb-pkg-don-t-set-kbuild_build_version-uncond.patch [new file with mode: 0644]
queue-6.12/perf-core-fix-child_total_time_enabled-accounting-bu.patch [new file with mode: 0644]
queue-6.12/series
queue-6.12/tools-power-turbostat-report-corethr-per-measurement.patch [new file with mode: 0644]
queue-6.12/tracing-correct-the-refcount-if-the-hist-hist_debug-.patch [new file with mode: 0644]
queue-6.12/tracing-hist-add-poll-pollin-support-on-hist-file.patch [new file with mode: 0644]
queue-6.12/tracing-hist-support-pollpri-event-for-poll-on-histo.patch [new file with mode: 0644]
queue-6.12/tracing-switch-trace_events_hist.c-code-over-to-use-.patch [new file with mode: 0644]
queue-6.12/tty-serial-fsl_lpuart-use-port-struct-directly-to-si.patch [new file with mode: 0644]
queue-6.12/tty-serial-fsl_lpuart-use-u32-and-u8-for-register-va.patch [new file with mode: 0644]
queue-6.12/tty-serial-lpuart-only-disable-cts-instead-of-overwr.patch [new file with mode: 0644]

diff --git a/queue-6.12/arm64-dts-rockchip-add-missing-pcie-supplies-to-rock.patch b/queue-6.12/arm64-dts-rockchip-add-missing-pcie-supplies-to-rock.patch
new file mode 100644 (file)
index 0000000..c3a8db4
--- /dev/null
@@ -0,0 +1,91 @@
+From 8aee6471dd6b35fc567fb1629dbeb376bfd80a93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Mar 2025 19:48:04 +0100
+Subject: arm64: dts: rockchip: Add missing PCIe supplies to RockPro64 board
+ dtsi
+
+From: Dragan Simic <dsimic@manjaro.org>
+
+[ Upstream commit ffcef3df680c437ca33ff434be18ec24d72907c2 ]
+
+Add missing "vpcie0v9-supply" and "vpcie1v8-supply" properties to the "pcie0"
+node in the Pine64 RockPro64 board dtsi file.  This eliminates the following
+warnings from the kernel log:
+
+  rockchip-pcie f8000000.pcie: supply vpcie1v8 not found, using dummy regulator
+  rockchip-pcie f8000000.pcie: supply vpcie0v9 not found, using dummy regulator
+
+These additions improve the accuracy of hardware description of the RockPro64
+and, in theory, they should result in no functional changes to the way board
+works after the changes, because the "vcca_0v9" and "vcca_1v8" regulators are
+always enabled. [1][2]  However, extended reliability testing, performed by
+Chris, [3] has proven that the age-old issues with some PCI Express cards,
+when used with a Pine64 RockPro64, are also resolved.
+
+Those issues were already mentioned in the commit 43853e843aa6 (arm64: dts:
+rockchip: Remove unsupported node from the Pinebook Pro dts, 2024-04-01),
+together with a brief description of the out-of-tree enumeration delay patch
+that reportedly resolves those issues.  In a nutshell, booting a RockPro64
+with some PCI Express cards attached to it caused a kernel oops. [4]
+
+Symptomatically enough, to the commit author's best knowledge, only the Pine64
+RockPro64, out of all RK3399-based boards and devices supported upstream, has
+been reported to suffer from those PCI Express issues, and only the RockPro64
+had some of the PCI Express supplies missing in its DT.  Thus, perhaps some
+weird timing issues exist that caused the "vcca_1v8" always-on regulator,
+which is part of the RK808 PMIC, to actually not be enabled before the PCI
+Express is initialized and enumerated on the RockPro64, causing oopses with
+some PCIe cards, and the aforementioned enumeration delay patch [4] probably
+acted as just a workaround for the underlying timing issue.
+
+Admittedly, the Pine64 RockPro64 is a bit specific board by having a standard
+PCI Express slot, allowing use of various standard cards, but pretty much
+standard PCI Express cards have been attached to other RK3399 boards as well,
+and the commit author is unaware ot such issues reported for them.
+
+It's quite hard to be sure that the PCI Express issues are fully resolved by
+these additions to the DT, without some really extensive and time-consuming
+testing.  However, these additions to the DT can result in good things and
+improvements anyway, making them perfectly safe from the standpoint of being
+unable to do any harm or cause some unforeseen regressions.
+
+These changes apply to the both supported hardware revisions of the Pine64
+RockPro64, i.e. to the production-run revisions 2.0 and 2.1. [1][2]
+
+[1] https://files.pine64.org/doc/rockpro64/rockpro64_v21-SCH.pdf
+[2] https://files.pine64.org/doc/rockpro64/rockpro64_v20-SCH.pdf
+[3] https://z9.de/hedgedoc/s/nF4d5G7rg#reboot-tests-for-PCIe-improvements
+[4] https://lore.kernel.org/lkml/20230509153912.515218-1-vincenzopalazzodev@gmail.com/T/#u
+
+Fixes: bba821f5479e ("arm64: dts: rockchip: add PCIe nodes on rk3399-rockpro64")
+Cc: stable@vger.kernel.org
+Cc: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
+Cc: Peter Geis <pgwipeout@gmail.com>
+Cc: Bjorn Helgaas <helgaas@kernel.org>
+Reported-by: Diederik de Haas <didi.debian@cknow.org>
+Tested-by: Chris Vogel <chris@z9.de>
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Tested-by: Diederik de Haas <didi.debian@cknow.org>
+Link: https://lore.kernel.org/r/b39cfd7490d8194f053bf3971f13a43472d1769e.1740941097.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
+index 11d99d8b34a2b..fd8296c1d3fad 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
+@@ -661,6 +661,8 @@ &pcie0 {
+       num-lanes = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_perst>;
++      vpcie0v9-supply = <&vcca_0v9>;
++      vpcie1v8-supply = <&vcca_1v8>;
+       vpcie12v-supply = <&vcc12v_dcin>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+-- 
+2.39.5
+
diff --git a/queue-6.12/cgroup-rstat-fix-forceidle-time-in-cpu.stat.patch b/queue-6.12/cgroup-rstat-fix-forceidle-time-in-cpu.stat.patch
new file mode 100644 (file)
index 0000000..5244262
--- /dev/null
@@ -0,0 +1,81 @@
+From 3688c3d36624a88b385f6329bce71f9dbad5e560 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2025 14:13:11 +0800
+Subject: cgroup/rstat: Fix forceidle time in cpu.stat
+
+From: Abel Wu <wuyun.abel@bytedance.com>
+
+[ Upstream commit c4af66a95aa3bc1d4f607ebd4eea524fb58946e3 ]
+
+The commit b824766504e4 ("cgroup/rstat: add force idle show helper")
+retrieves forceidle_time outside cgroup_rstat_lock for non-root cgroups
+which can be potentially inconsistent with other stats.
+
+Rather than reverting that commit, fix it in a way that retains the
+effort of cleaning up the ifdef-messes.
+
+Fixes: b824766504e4 ("cgroup/rstat: add force idle show helper")
+Signed-off-by: Abel Wu <wuyun.abel@bytedance.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/rstat.c | 29 +++++++++++++----------------
+ 1 file changed, 13 insertions(+), 16 deletions(-)
+
+diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c
+index aac91466279f1..3e01781aeb7bd 100644
+--- a/kernel/cgroup/rstat.c
++++ b/kernel/cgroup/rstat.c
+@@ -612,36 +612,33 @@ static void cgroup_force_idle_show(struct seq_file *seq, struct cgroup_base_stat
+ void cgroup_base_stat_cputime_show(struct seq_file *seq)
+ {
+       struct cgroup *cgrp = seq_css(seq)->cgroup;
+-      u64 usage, utime, stime, ntime;
++      struct cgroup_base_stat bstat;
+       if (cgroup_parent(cgrp)) {
+               cgroup_rstat_flush_hold(cgrp);
+-              usage = cgrp->bstat.cputime.sum_exec_runtime;
++              bstat = cgrp->bstat;
+               cputime_adjust(&cgrp->bstat.cputime, &cgrp->prev_cputime,
+-                             &utime, &stime);
+-              ntime = cgrp->bstat.ntime;
++                             &bstat.cputime.utime, &bstat.cputime.stime);
+               cgroup_rstat_flush_release(cgrp);
+       } else {
+-              /* cgrp->bstat of root is not actually used, reuse it */
+-              root_cgroup_cputime(&cgrp->bstat);
+-              usage = cgrp->bstat.cputime.sum_exec_runtime;
+-              utime = cgrp->bstat.cputime.utime;
+-              stime = cgrp->bstat.cputime.stime;
+-              ntime = cgrp->bstat.ntime;
++              root_cgroup_cputime(&bstat);
+       }
+-      do_div(usage, NSEC_PER_USEC);
+-      do_div(utime, NSEC_PER_USEC);
+-      do_div(stime, NSEC_PER_USEC);
+-      do_div(ntime, NSEC_PER_USEC);
++      do_div(bstat.cputime.sum_exec_runtime, NSEC_PER_USEC);
++      do_div(bstat.cputime.utime, NSEC_PER_USEC);
++      do_div(bstat.cputime.stime, NSEC_PER_USEC);
++      do_div(bstat.ntime, NSEC_PER_USEC);
+       seq_printf(seq, "usage_usec %llu\n"
+                       "user_usec %llu\n"
+                       "system_usec %llu\n"
+                       "nice_usec %llu\n",
+-                      usage, utime, stime, ntime);
++                      bstat.cputime.sum_exec_runtime,
++                      bstat.cputime.utime,
++                      bstat.cputime.stime,
++                      bstat.ntime);
+-      cgroup_force_idle_show(seq, &cgrp->bstat);
++      cgroup_force_idle_show(seq, &bstat);
+ }
+ /* Add bpf kfuncs for cgroup_rstat_updated() and cgroup_rstat_flush() */
+-- 
+2.39.5
+
diff --git a/queue-6.12/cgroup-rstat-tracking-cgroup-level-niced-cpu-time.patch b/queue-6.12/cgroup-rstat-tracking-cgroup-level-niced-cpu-time.patch
new file mode 100644 (file)
index 0000000..e7b4598
--- /dev/null
@@ -0,0 +1,121 @@
+From 81eb252d83568dc0a16a2b00105bf563ff5bdcb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Oct 2024 11:47:16 -0700
+Subject: cgroup/rstat: Tracking cgroup-level niced CPU time
+
+From: Joshua Hahn <joshua.hahn6@gmail.com>
+
+[ Upstream commit aefa398d93d5db7c555be78a605ff015357f127d ]
+
+Cgroup-level CPU statistics currently include time spent on
+user/system processes, but do not include niced CPU time (despite
+already being tracked). This patch exposes niced CPU time to the
+userspace, allowing users to get a better understanding of their
+hardware limits and can facilitate more informed workload distribution.
+
+A new field 'ntime' is added to struct cgroup_base_stat as opposed to
+struct task_cputime to minimize footprint.
+
+Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Stable-dep-of: c4af66a95aa3 ("cgroup/rstat: Fix forceidle time in cpu.stat")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cgroup-defs.h |  1 +
+ kernel/cgroup/rstat.c       | 19 ++++++++++++++-----
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
+index a32eebcd23da4..38b2af336e4a0 100644
+--- a/include/linux/cgroup-defs.h
++++ b/include/linux/cgroup-defs.h
+@@ -324,6 +324,7 @@ struct cgroup_base_stat {
+ #ifdef CONFIG_SCHED_CORE
+       u64 forceidle_sum;
+ #endif
++      u64 ntime;
+ };
+ /*
+diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c
+index ce295b73c0a36..aac91466279f1 100644
+--- a/kernel/cgroup/rstat.c
++++ b/kernel/cgroup/rstat.c
+@@ -444,6 +444,7 @@ static void cgroup_base_stat_add(struct cgroup_base_stat *dst_bstat,
+ #ifdef CONFIG_SCHED_CORE
+       dst_bstat->forceidle_sum += src_bstat->forceidle_sum;
+ #endif
++      dst_bstat->ntime += src_bstat->ntime;
+ }
+ static void cgroup_base_stat_sub(struct cgroup_base_stat *dst_bstat,
+@@ -455,6 +456,7 @@ static void cgroup_base_stat_sub(struct cgroup_base_stat *dst_bstat,
+ #ifdef CONFIG_SCHED_CORE
+       dst_bstat->forceidle_sum -= src_bstat->forceidle_sum;
+ #endif
++      dst_bstat->ntime -= src_bstat->ntime;
+ }
+ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu)
+@@ -534,8 +536,10 @@ void __cgroup_account_cputime_field(struct cgroup *cgrp,
+       rstatc = cgroup_base_stat_cputime_account_begin(cgrp, &flags);
+       switch (index) {
+-      case CPUTIME_USER:
+       case CPUTIME_NICE:
++              rstatc->bstat.ntime += delta_exec;
++              fallthrough;
++      case CPUTIME_USER:
+               rstatc->bstat.cputime.utime += delta_exec;
+               break;
+       case CPUTIME_SYSTEM:
+@@ -590,6 +594,7 @@ static void root_cgroup_cputime(struct cgroup_base_stat *bstat)
+ #ifdef CONFIG_SCHED_CORE
+               bstat->forceidle_sum += cpustat[CPUTIME_FORCEIDLE];
+ #endif
++              bstat->ntime += cpustat[CPUTIME_NICE];
+       }
+ }
+@@ -607,13 +612,14 @@ static void cgroup_force_idle_show(struct seq_file *seq, struct cgroup_base_stat
+ void cgroup_base_stat_cputime_show(struct seq_file *seq)
+ {
+       struct cgroup *cgrp = seq_css(seq)->cgroup;
+-      u64 usage, utime, stime;
++      u64 usage, utime, stime, ntime;
+       if (cgroup_parent(cgrp)) {
+               cgroup_rstat_flush_hold(cgrp);
+               usage = cgrp->bstat.cputime.sum_exec_runtime;
+               cputime_adjust(&cgrp->bstat.cputime, &cgrp->prev_cputime,
+                              &utime, &stime);
++              ntime = cgrp->bstat.ntime;
+               cgroup_rstat_flush_release(cgrp);
+       } else {
+               /* cgrp->bstat of root is not actually used, reuse it */
+@@ -621,16 +627,19 @@ void cgroup_base_stat_cputime_show(struct seq_file *seq)
+               usage = cgrp->bstat.cputime.sum_exec_runtime;
+               utime = cgrp->bstat.cputime.utime;
+               stime = cgrp->bstat.cputime.stime;
++              ntime = cgrp->bstat.ntime;
+       }
+       do_div(usage, NSEC_PER_USEC);
+       do_div(utime, NSEC_PER_USEC);
+       do_div(stime, NSEC_PER_USEC);
++      do_div(ntime, NSEC_PER_USEC);
+       seq_printf(seq, "usage_usec %llu\n"
+-                 "user_usec %llu\n"
+-                 "system_usec %llu\n",
+-                 usage, utime, stime);
++                      "user_usec %llu\n"
++                      "system_usec %llu\n"
++                      "nice_usec %llu\n",
++                      usage, utime, stime, ntime);
+       cgroup_force_idle_show(seq, &cgrp->bstat);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-amdgpu-gfx11-fix-num_mec.patch b/queue-6.12/drm-amdgpu-gfx11-fix-num_mec.patch
new file mode 100644 (file)
index 0000000..44c961a
--- /dev/null
@@ -0,0 +1,35 @@
+From 1dcbcfc8cecd06b4d17ea40725c5b01045bbff70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 09:35:02 -0400
+Subject: drm/amdgpu/gfx11: fix num_mec
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 4161050d47e1b083a7e1b0b875c9907e1a6f1f1f ]
+
+GC11 only has 1 mec.
+
+Fixes: 3d879e81f0f9 ("drm/amdgpu: add init support for GFX11 (v2)")
+Reviewed-by: Sunil Khatri <sunil.khatri@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+index d3e8be82a1727..84cf5fd297b7f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+@@ -1549,7 +1549,7 @@ static int gfx_v11_0_sw_init(void *handle)
+               adev->gfx.me.num_me = 1;
+               adev->gfx.me.num_pipe_per_me = 1;
+               adev->gfx.me.num_queue_per_pipe = 1;
+-              adev->gfx.mec.num_mec = 2;
++              adev->gfx.mec.num_mec = 1;
+               adev->gfx.mec.num_pipe_per_mec = 4;
+               adev->gfx.mec.num_queue_per_pipe = 4;
+               break;
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-amdgpu-gfx12-fix-num_mec.patch b/queue-6.12/drm-amdgpu-gfx12-fix-num_mec.patch
new file mode 100644 (file)
index 0000000..7f37869
--- /dev/null
@@ -0,0 +1,35 @@
+From e26545b909edce0ef0d297d5b8c1dcde8ae836d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 12:09:11 -0400
+Subject: drm/amdgpu/gfx12: fix num_mec
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit dce8bd9137b88735dd0efc4e2693213d98c15913 ]
+
+GC12 only has 1 mec.
+
+Fixes: 52cb80c12e8a ("drm/amdgpu: Add gfx v12_0 ip block support (v6)")
+Reviewed-by: Sunil Khatri <sunil.khatri@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+index d3798a333d1f8..b259e217930c7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+@@ -1332,7 +1332,7 @@ static int gfx_v12_0_sw_init(void *handle)
+               adev->gfx.me.num_me = 1;
+               adev->gfx.me.num_pipe_per_me = 1;
+               adev->gfx.me.num_queue_per_pipe = 1;
+-              adev->gfx.mec.num_mec = 2;
++              adev->gfx.mec.num_mec = 1;
+               adev->gfx.mec.num_pipe_per_mec = 2;
+               adev->gfx.mec.num_queue_per_pipe = 4;
+               break;
+-- 
+2.39.5
+
diff --git a/queue-6.12/kbuild-deb-pkg-don-t-set-kbuild_build_version-uncond.patch b/queue-6.12/kbuild-deb-pkg-don-t-set-kbuild_build_version-uncond.patch
new file mode 100644 (file)
index 0000000..baec79b
--- /dev/null
@@ -0,0 +1,64 @@
+From fcc1c27fce9bf7cc20ea2e56bd15ba1d69f3a7ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 13:10:53 +0000
+Subject: kbuild: deb-pkg: don't set KBUILD_BUILD_VERSION unconditionally
+
+From: Alexandru Gagniuc <alexandru.gagniuc@hp.com>
+
+[ Upstream commit 62604063621fb075c7966286bdddcb057d883fa8 ]
+
+In ThinPro, we use the convention <upstream_ver>+hp<patchlevel> for
+the kernel package. This does not have a dash in the name or version.
+This is built by editing ".version" before a build, and setting
+EXTRAVERSION="+hp" and KDEB_PKGVERSION make variables:
+
+    echo 68 > .version
+    make -j<n> EXTRAVERSION="+hp" bindeb-pkg KDEB_PKGVERSION=6.12.2+hp69
+
+    .deb name: linux-image-6.12.2+hp_6.12.2+hp69_amd64.deb
+
+Since commit 7d4f07d5cb71 ("kbuild: deb-pkg: squash
+scripts/package/deb-build-option to debian/rules"), this no longer
+works. The deb build logic changed, even though, the commit message
+implies that the logic should be unmodified.
+
+Before, KBUILD_BUILD_VERSION was not set if the KDEB_PKGVERSION did
+not contain a dash. After the change KBUILD_BUILD_VERSION is always
+set to KDEB_PKGVERSION. Since this determines UTS_VERSION, the uname
+output to look off:
+
+    (now)      uname -a: version 6.12.2+hp ... #6.12.2+hp69
+    (expected) uname -a: version 6.12.2+hp ... #69
+
+Update the debian/rules logic to restore the original behavior.
+
+Fixes: 7d4f07d5cb71 ("kbuild: deb-pkg: squash scripts/package/deb-build-option to debian/rules")
+Signed-off-by: Alexandru Gagniuc <alexandru.gagniuc@hp.com>
+Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/package/debian/rules | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/package/debian/rules b/scripts/package/debian/rules
+index ca07243bd5cdf..2b3f9a0bd6c40 100755
+--- a/scripts/package/debian/rules
++++ b/scripts/package/debian/rules
+@@ -21,9 +21,11 @@ ifeq ($(origin KBUILD_VERBOSE),undefined)
+     endif
+ endif
+-revision = $(lastword $(subst -, ,$(shell dpkg-parsechangelog -S Version)))
++revision = $(shell dpkg-parsechangelog -S Version | sed -n 's/.*-//p')
+ CROSS_COMPILE ?= $(filter-out $(DEB_BUILD_GNU_TYPE)-, $(DEB_HOST_GNU_TYPE)-)
+-make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) KBUILD_BUILD_VERSION=$(revision) $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE))
++make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) \
++    $(addprefix KBUILD_BUILD_VERSION=,$(revision)) \
++    $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE))
+ binary-targets := $(addprefix binary-, image image-dbg headers libc-dev)
+-- 
+2.39.5
+
diff --git a/queue-6.12/perf-core-fix-child_total_time_enabled-accounting-bu.patch b/queue-6.12/perf-core-fix-child_total_time_enabled-accounting-bu.patch
new file mode 100644 (file)
index 0000000..1828c56
--- /dev/null
@@ -0,0 +1,143 @@
+From 7c391d34740d24cf6351da8d3ac4a2a0aeafffa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 08:20:03 +0000
+Subject: perf/core: Fix child_total_time_enabled accounting bug at task exit
+
+From: Yeoreum Yun <yeoreum.yun@arm.com>
+
+[ Upstream commit a3c3c66670cee11eb13aa43905904bf29cb92d32 ]
+
+The perf events code fails to account for total_time_enabled of
+inactive events.
+
+Here is a failure case for accounting total_time_enabled for
+CPU PMU events:
+
+  sudo ./perf stat -vvv -e armv8_pmuv3_0/event=0x08/ -e armv8_pmuv3_1/event=0x08/ -- stress-ng --pthread=2 -t 2s
+  ...
+
+  armv8_pmuv3_0/event=0x08/: 1138698008 2289429840 2174835740
+  armv8_pmuv3_1/event=0x08/: 1826791390 1950025700 847648440
+                             `          `          `
+                             `          `          > total_time_running with child
+                             `          > total_time_enabled with child
+                             > count with child
+
+  Performance counter stats for 'stress-ng --pthread=2 -t 2s':
+
+       1,138,698,008      armv8_pmuv3_0/event=0x08/                                               (94.99%)
+       1,826,791,390      armv8_pmuv3_1/event=0x08/                                               (43.47%)
+
+The two events above are opened on two different CPU PMUs, for example,
+each event is opened for a cluster in an Arm big.LITTLE system, they
+will never run on the same CPU.  In theory, the total enabled time should
+be same for both events, as two events are opened and closed together.
+
+As the result show, the two events' total enabled time including
+child event is different (2289429840 vs 1950025700).
+
+This is because child events are not accounted properly
+if a event is INACTIVE state when the task exits:
+
+  perf_event_exit_event()
+   `> perf_remove_from_context()
+     `> __perf_remove_from_context()
+       `> perf_child_detach()   -> Accumulate child_total_time_enabled
+         `> list_del_event()    -> Update child event's time
+
+The problem is the time accumulation happens prior to child event's
+time updating. Thus, it misses to account the last period's time when
+the event exits.
+
+The perf core layer follows the rule that timekeeping is tied to state
+change. To address the issue, make __perf_remove_from_context()
+handle the task exit case by passing 'DETACH_EXIT' to it and
+invoke perf_event_state() for state alongside with accounting the time.
+
+Then, perf_child_detach() populates the time into the parent's time metrics.
+
+After this patch, the bug is fixed:
+
+  sudo ./perf stat -vvv -e armv8_pmuv3_0/event=0x08/ -e armv8_pmuv3_1/event=0x08/ -- stress-ng --pthread=2 -t 10s
+  ...
+  armv8_pmuv3_0/event=0x08/: 15396770398 32157963940 21898169000
+  armv8_pmuv3_1/event=0x08/: 22428964974 32157963940 10259794940
+
+   Performance counter stats for 'stress-ng --pthread=2 -t 10s':
+
+      15,396,770,398      armv8_pmuv3_0/event=0x08/                                               (68.10%)
+      22,428,964,974      armv8_pmuv3_1/event=0x08/                                               (31.90%)
+
+[ mingo: Clarified the changelog. ]
+
+Fixes: ef54c1a476aef ("perf: Rework perf_event_exit_event()")
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Leo Yan <leo.yan@arm.com>
+Link: https://lore.kernel.org/r/20250326082003.1630986-1-yeoreum.yun@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index cf2ec0a1582fd..b5ccf52bb71ba 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2407,6 +2407,7 @@ ctx_time_update_event(struct perf_event_context *ctx, struct perf_event *event)
+ #define DETACH_GROUP  0x01UL
+ #define DETACH_CHILD  0x02UL
+ #define DETACH_DEAD   0x04UL
++#define DETACH_EXIT   0x08UL
+ /*
+  * Cross CPU call to remove a performance event
+@@ -2421,6 +2422,7 @@ __perf_remove_from_context(struct perf_event *event,
+                          void *info)
+ {
+       struct perf_event_pmu_context *pmu_ctx = event->pmu_ctx;
++      enum perf_event_state state = PERF_EVENT_STATE_OFF;
+       unsigned long flags = (unsigned long)info;
+       ctx_time_update(cpuctx, ctx);
+@@ -2429,16 +2431,19 @@ __perf_remove_from_context(struct perf_event *event,
+        * Ensure event_sched_out() switches to OFF, at the very least
+        * this avoids raising perf_pending_task() at this time.
+        */
+-      if (flags & DETACH_DEAD)
++      if (flags & DETACH_EXIT)
++              state = PERF_EVENT_STATE_EXIT;
++      if (flags & DETACH_DEAD) {
+               event->pending_disable = 1;
++              state = PERF_EVENT_STATE_DEAD;
++      }
+       event_sched_out(event, ctx);
++      perf_event_set_state(event, min(event->state, state));
+       if (flags & DETACH_GROUP)
+               perf_group_detach(event);
+       if (flags & DETACH_CHILD)
+               perf_child_detach(event);
+       list_del_event(event, ctx);
+-      if (flags & DETACH_DEAD)
+-              event->state = PERF_EVENT_STATE_DEAD;
+       if (!pmu_ctx->nr_events) {
+               pmu_ctx->rotate_necessary = 0;
+@@ -13343,12 +13348,7 @@ perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
+               mutex_lock(&parent_event->child_mutex);
+       }
+-      perf_remove_from_context(event, detach_flags);
+-
+-      raw_spin_lock_irq(&ctx->lock);
+-      if (event->state > PERF_EVENT_STATE_EXIT)
+-              perf_event_set_state(event, PERF_EVENT_STATE_EXIT);
+-      raw_spin_unlock_irq(&ctx->lock);
++      perf_remove_from_context(event, detach_flags | DETACH_EXIT);
+       /*
+        * Child events can be freed.
+-- 
+2.39.5
+
index db22a24bb89a04054fd1c59876a4cd79bbc9198b..f3116a7f48b2cf0f53b97467f5a5d7d0090b02be 100644 (file)
@@ -342,3 +342,18 @@ ipv6-start-path-selection-from-the-first-nexthop.patch
 ipv6-do-not-consider-link-down-nexthops-in-path-sele.patch
 arcnet-add-null-check-in-com20020pci_probe.patch
 net-ibmveth-make-veth_pool_store-stop-hanging.patch
+kbuild-deb-pkg-don-t-set-kbuild_build_version-uncond.patch
+drm-amdgpu-gfx11-fix-num_mec.patch
+drm-amdgpu-gfx12-fix-num_mec.patch
+perf-core-fix-child_total_time_enabled-accounting-bu.patch
+tools-power-turbostat-report-corethr-per-measurement.patch
+tracing-switch-trace_events_hist.c-code-over-to-use-.patch
+tracing-hist-add-poll-pollin-support-on-hist-file.patch
+tracing-hist-support-pollpri-event-for-poll-on-histo.patch
+tracing-correct-the-refcount-if-the-hist-hist_debug-.patch
+arm64-dts-rockchip-add-missing-pcie-supplies-to-rock.patch
+cgroup-rstat-tracking-cgroup-level-niced-cpu-time.patch
+cgroup-rstat-fix-forceidle-time-in-cpu.stat.patch
+tty-serial-fsl_lpuart-use-u32-and-u8-for-register-va.patch
+tty-serial-fsl_lpuart-use-port-struct-directly-to-si.patch
+tty-serial-lpuart-only-disable-cts-instead-of-overwr.patch
diff --git a/queue-6.12/tools-power-turbostat-report-corethr-per-measurement.patch b/queue-6.12/tools-power-turbostat-report-corethr-per-measurement.patch
new file mode 100644 (file)
index 0000000..a6948a3
--- /dev/null
@@ -0,0 +1,59 @@
+From 881de3425a604dcd1706578f93f1e9a3ffbdaa06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Apr 2025 11:18:39 -0400
+Subject: tools/power turbostat: report CoreThr per measurement interval
+
+From: Len Brown <len.brown@intel.com>
+
+[ Upstream commit f729775f79a9c942c6c82ed6b44bd030afe10423 ]
+
+The CoreThr column displays total thermal throttling events
+since boot time.
+
+Change it to report events during the measurement interval.
+
+This is more useful for showing a user the current conditions.
+Total events since boot time are still available to the user via
+/sys/devices/system/cpu/cpu*/thermal_throttle/*
+
+Document CoreThr on turbostat.8
+
+Fixes: eae97e053fe30 ("turbostat: Support thermal throttle count print")
+Reported-by: Arjan van de Ven <arjan@linux.intel.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/turbostat/turbostat.8 | 2 ++
+ tools/power/x86/turbostat/turbostat.c | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
+index 56c7ff6efcdab..a3cf1d17163ae 100644
+--- a/tools/power/x86/turbostat/turbostat.8
++++ b/tools/power/x86/turbostat/turbostat.8
+@@ -168,6 +168,8 @@ The system configuration dump (if --quiet is not used) is followed by statistics
+ .PP
+ \fBPkgTmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
+ .PP
++\fBCoreThr\fP Core Thermal Throttling events during the measurement interval.  Note that events since boot can be find in /sys/devices/system/cpu/cpu*/thermal_throttle/*
++.PP
+ \fBGFX%rc6\fP The percentage of time the GPU is in the "render C6" state, rc6, during the measurement interval. From /sys/class/drm/card0/power/rc6_residency_ms or /sys/class/drm/card0/gt/gt0/rc6_residency_ms or /sys/class/drm/card0/device/tile0/gtN/gtidle/idle_residency_ms depending on the graphics driver being used.
+ .PP
+ \fBGFXMHz\fP Instantaneous snapshot of what sysfs presents at the end of the measurement interval. From /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz or /sys/class/drm/card0/gt_cur_freq_mhz or /sys/class/drm/card0/gt/gt0/rps_cur_freq_mhz or /sys/class/drm/card0/device/tile0/gtN/freq0/cur_freq depending on the graphics driver being used.
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index 235e82fe7d0a5..77ef60980ee58 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -3242,7 +3242,7 @@ void delta_core(struct core_data *new, struct core_data *old)
+       old->c6 = new->c6 - old->c6;
+       old->c7 = new->c7 - old->c7;
+       old->core_temp_c = new->core_temp_c;
+-      old->core_throt_cnt = new->core_throt_cnt;
++      old->core_throt_cnt = new->core_throt_cnt - old->core_throt_cnt;
+       old->mc6_us = new->mc6_us - old->mc6_us;
+       DELTA_WRAP32(new->core_energy.raw_value, old->core_energy.raw_value);
+-- 
+2.39.5
+
diff --git a/queue-6.12/tracing-correct-the-refcount-if-the-hist-hist_debug-.patch b/queue-6.12/tracing-correct-the-refcount-if-the-hist-hist_debug-.patch
new file mode 100644 (file)
index 0000000..2668aaf
--- /dev/null
@@ -0,0 +1,92 @@
+From bee63bfc84c5002560f57a76806247a786cd2932 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 06:53:35 +0000
+Subject: tracing: Correct the refcount if the hist/hist_debug file fails to
+ open
+
+From: Tengda Wu <wutengda@huaweicloud.com>
+
+[ Upstream commit 0b4ffbe4888a2c71185eaf5c1a02dd3586a9bc04 ]
+
+The function event_{hist,hist_debug}_open() maintains the refcount of
+'file->tr' and 'file' through tracing_open_file_tr(). However, it does
+not roll back these counts on subsequent failure paths, resulting in a
+refcount leak.
+
+A very obvious case is that if the hist/hist_debug file belongs to a
+specific instance, the refcount leak will prevent the deletion of that
+instance, as it relies on the condition 'tr->ref == 1' within
+__remove_instance().
+
+Fix this by calling tracing_release_file_tr() on all failure paths in
+event_{hist,hist_debug}_open() to correct the refcount.
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Link: https://lore.kernel.org/20250314065335.1202817-1-wutengda@huaweicloud.com
+Fixes: 1cc111b9cddc ("tracing: Fix uaf issue when open the hist or hist_debug file")
+Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_hist.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index e07d75adab8e3..4ebafc655223a 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5692,12 +5692,16 @@ static int event_hist_open(struct inode *inode, struct file *file)
+       guard(mutex)(&event_mutex);
+       event_file = event_file_data(file);
+-      if (!event_file)
+-              return -ENODEV;
++      if (!event_file) {
++              ret = -ENODEV;
++              goto err;
++      }
+       hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL);
+-      if (!hist_file)
+-              return -ENOMEM;
++      if (!hist_file) {
++              ret = -ENOMEM;
++              goto err;
++      }
+       hist_file->file = file;
+       hist_file->last_act = get_hist_hit_count(event_file);
+@@ -5705,9 +5709,14 @@ static int event_hist_open(struct inode *inode, struct file *file)
+       /* Clear private_data to avoid warning in single_open() */
+       file->private_data = NULL;
+       ret = single_open(file, hist_show, hist_file);
+-      if (ret)
++      if (ret) {
+               kfree(hist_file);
++              goto err;
++      }
++      return 0;
++err:
++      tracing_release_file_tr(inode, file);
+       return ret;
+ }
+@@ -5982,7 +5991,10 @@ static int event_hist_debug_open(struct inode *inode, struct file *file)
+       /* Clear private_data to avoid warning in single_open() */
+       file->private_data = NULL;
+-      return single_open(file, hist_debug_show, file);
++      ret = single_open(file, hist_debug_show, file);
++      if (ret)
++              tracing_release_file_tr(inode, file);
++      return ret;
+ }
+ const struct file_operations event_hist_debug_fops = {
+-- 
+2.39.5
+
diff --git a/queue-6.12/tracing-hist-add-poll-pollin-support-on-hist-file.patch b/queue-6.12/tracing-hist-add-poll-pollin-support-on-hist-file.patch
new file mode 100644 (file)
index 0000000..48021f3
--- /dev/null
@@ -0,0 +1,216 @@
+From 53017ac3bba8fd7b36949e6eab5c60eafd6cf56a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Dec 2024 13:07:57 +0900
+Subject: tracing/hist: Add poll(POLLIN) support on hist file
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit 1bd13edbbed6e7e396f1aab92b224a4775218e68 ]
+
+Add poll syscall support on the `hist` file. The Waiter will be waken
+up when the histogram is updated with POLLIN.
+
+Currently, there is no way to wait for a specific event in userspace.
+So user needs to peek the `trace` periodicaly, or wait on `trace_pipe`.
+But it is not a good idea to peek at the `trace` for an event that
+randomly happens. And `trace_pipe` is not coming back until a page is
+filled with events.
+
+This allows a user to wait for a specific event on the `hist` file. User
+can set a histogram trigger on the event which they want to monitor
+and poll() on its `hist` file. Since this poll() returns POLLIN, the next
+poll() will return soon unless a read() happens on that hist file.
+
+NOTE: To read the hist file again, you must set the file offset to 0,
+but just for monitoring the event, you may not need to read the
+histogram.
+
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/173527247756.464571.14236296701625509931.stgit@devnote2
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reviewed-by: Tom Zanussi <zanussi@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 0b4ffbe4888a ("tracing: Correct the refcount if the hist/hist_debug file fails to open")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/trace_events.h     | 14 +++++++
+ kernel/trace/trace_events.c      | 14 +++++++
+ kernel/trace/trace_events_hist.c | 70 ++++++++++++++++++++++++++++++--
+ 3 files changed, 95 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
+index 77769ff505444..fcf5a64d5cfe2 100644
+--- a/include/linux/trace_events.h
++++ b/include/linux/trace_events.h
+@@ -689,6 +689,20 @@ struct trace_event_file {
+       atomic_t                tm_ref; /* trigger-mode reference counter */
+ };
++#ifdef CONFIG_HIST_TRIGGERS
++extern struct irq_work hist_poll_work;
++extern wait_queue_head_t hist_poll_wq;
++
++static inline void hist_poll_wakeup(void)
++{
++      if (wq_has_sleeper(&hist_poll_wq))
++              irq_work_queue(&hist_poll_work);
++}
++
++#define hist_poll_wait(file, wait)    \
++      poll_wait(file, &hist_poll_wq, wait)
++#endif
++
+ #define __TRACE_EVENT_FLAGS(name, value)                              \
+       static int __init trace_init_flags_##name(void)                 \
+       {                                                               \
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index ea9b44847ce6b..29eba68e07859 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -3111,6 +3111,20 @@ static bool event_in_systems(struct trace_event_call *call,
+       return !*p || isspace(*p) || *p == ',';
+ }
++#ifdef CONFIG_HIST_TRIGGERS
++/*
++ * Wake up waiter on the hist_poll_wq from irq_work because the hist trigger
++ * may happen in any context.
++ */
++static void hist_poll_event_irq_work(struct irq_work *work)
++{
++      wake_up_all(&hist_poll_wq);
++}
++
++DEFINE_IRQ_WORK(hist_poll_work, hist_poll_event_irq_work);
++DECLARE_WAIT_QUEUE_HEAD(hist_poll_wq);
++#endif
++
+ static struct trace_event_file *
+ trace_create_new_event(struct trace_event_call *call,
+                      struct trace_array *tr)
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 5d344bc690d99..9e33cd2a73b5c 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5314,6 +5314,8 @@ static void event_hist_trigger(struct event_trigger_data *data,
+       if (resolve_var_refs(hist_data, key, var_ref_vals, true))
+               hist_trigger_actions(hist_data, elt, buffer, rec, rbe, key, var_ref_vals);
++
++      hist_poll_wakeup();
+ }
+ static void hist_trigger_stacktrace_print(struct seq_file *m,
+@@ -5593,15 +5595,36 @@ static void hist_trigger_show(struct seq_file *m,
+                  n_entries, (u64)atomic64_read(&hist_data->map->drops));
+ }
++struct hist_file_data {
++      struct file *file;
++      u64 last_read;
++};
++
++static u64 get_hist_hit_count(struct trace_event_file *event_file)
++{
++      struct hist_trigger_data *hist_data;
++      struct event_trigger_data *data;
++      u64 ret = 0;
++
++      list_for_each_entry(data, &event_file->triggers, list) {
++              if (data->cmd_ops->trigger_type == ETT_EVENT_HIST) {
++                      hist_data = data->private_data;
++                      ret += atomic64_read(&hist_data->map->hits);
++              }
++      }
++      return ret;
++}
++
+ static int hist_show(struct seq_file *m, void *v)
+ {
++      struct hist_file_data *hist_file = m->private;
+       struct event_trigger_data *data;
+       struct trace_event_file *event_file;
+       int n = 0;
+       guard(mutex)(&event_mutex);
+-      event_file = event_file_file(m->private);
++      event_file = event_file_file(hist_file->file);
+       if (unlikely(!event_file))
+               return -ENODEV;
+@@ -5609,27 +5632,68 @@ static int hist_show(struct seq_file *m, void *v)
+               if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
+                       hist_trigger_show(m, data, n++);
+       }
++      hist_file->last_read = get_hist_hit_count(event_file);
++
+       return 0;
+ }
++static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wait)
++{
++      struct trace_event_file *event_file;
++      struct seq_file *m = file->private_data;
++      struct hist_file_data *hist_file = m->private;
++
++      guard(mutex)(&event_mutex);
++
++      event_file = event_file_data(file);
++      if (!event_file)
++              return EPOLLERR;
++
++      hist_poll_wait(file, wait);
++
++      if (hist_file->last_read != get_hist_hit_count(event_file))
++              return EPOLLIN | EPOLLRDNORM;
++
++      return 0;
++}
++
++static int event_hist_release(struct inode *inode, struct file *file)
++{
++      struct seq_file *m = file->private_data;
++      struct hist_file_data *hist_file = m->private;
++
++      kfree(hist_file);
++      return tracing_single_release_file_tr(inode, file);
++}
++
+ static int event_hist_open(struct inode *inode, struct file *file)
+ {
++      struct hist_file_data *hist_file;
+       int ret;
+       ret = tracing_open_file_tr(inode, file);
+       if (ret)
+               return ret;
++      hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL);
++      if (!hist_file)
++              return -ENOMEM;
++      hist_file->file = file;
++
+       /* Clear private_data to avoid warning in single_open() */
+       file->private_data = NULL;
+-      return single_open(file, hist_show, file);
++      ret = single_open(file, hist_show, hist_file);
++      if (ret)
++              kfree(hist_file);
++      return ret;
+ }
+ const struct file_operations event_hist_fops = {
+       .open = event_hist_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+-      .release = tracing_single_release_file_tr,
++      .release = event_hist_release,
++      .poll = event_hist_poll,
+ };
+ #ifdef CONFIG_HIST_TRIGGERS_DEBUG
+-- 
+2.39.5
+
diff --git a/queue-6.12/tracing-hist-support-pollpri-event-for-poll-on-histo.patch b/queue-6.12/tracing-hist-support-pollpri-event-for-poll-on-histo.patch
new file mode 100644 (file)
index 0000000..ef08cd4
--- /dev/null
@@ -0,0 +1,119 @@
+From 5f46ffca965a46d46f287ae82f0d9744b78fd823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Dec 2024 13:08:07 +0900
+Subject: tracing/hist: Support POLLPRI event for poll on histogram
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit 66fc6f521a0b91051ce6968a216a30bc52267bf8 ]
+
+Since POLLIN will not be flushed until the hist file is read, the user
+needs to repeatedly read() and poll() on the hist file for monitoring the
+event continuously. But the read() is somewhat redundant when the user is
+only monitoring for event updates.
+
+Add POLLPRI poll event on the hist file so the event returns when a
+histogram is updated after open(), poll() or read(). Thus it is possible
+to wait for the next event without having to issue a read().
+
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/173527248770.464571.2536902137325258133.stgit@devnote2
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reviewed-by: Tom Zanussi <zanussi@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 0b4ffbe4888a ("tracing: Correct the refcount if the hist/hist_debug file fails to open")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_hist.c | 29 ++++++++++++++++++++++++++---
+ 1 file changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 9e33cd2a73b5c..e07d75adab8e3 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5598,6 +5598,7 @@ static void hist_trigger_show(struct seq_file *m,
+ struct hist_file_data {
+       struct file *file;
+       u64 last_read;
++      u64 last_act;
+ };
+ static u64 get_hist_hit_count(struct trace_event_file *event_file)
+@@ -5633,6 +5634,11 @@ static int hist_show(struct seq_file *m, void *v)
+                       hist_trigger_show(m, data, n++);
+       }
+       hist_file->last_read = get_hist_hit_count(event_file);
++      /*
++       * Update last_act too so that poll()/POLLPRI can wait for the next
++       * event after any syscall on hist file.
++       */
++      hist_file->last_act = hist_file->last_read;
+       return 0;
+ }
+@@ -5642,6 +5648,8 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai
+       struct trace_event_file *event_file;
+       struct seq_file *m = file->private_data;
+       struct hist_file_data *hist_file = m->private;
++      __poll_t ret = 0;
++      u64 cnt;
+       guard(mutex)(&event_mutex);
+@@ -5651,10 +5659,15 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai
+       hist_poll_wait(file, wait);
+-      if (hist_file->last_read != get_hist_hit_count(event_file))
+-              return EPOLLIN | EPOLLRDNORM;
++      cnt = get_hist_hit_count(event_file);
++      if (hist_file->last_read != cnt)
++              ret |= EPOLLIN | EPOLLRDNORM;
++      if (hist_file->last_act != cnt) {
++              hist_file->last_act = cnt;
++              ret |= EPOLLPRI;
++      }
+-      return 0;
++      return ret;
+ }
+ static int event_hist_release(struct inode *inode, struct file *file)
+@@ -5668,6 +5681,7 @@ static int event_hist_release(struct inode *inode, struct file *file)
+ static int event_hist_open(struct inode *inode, struct file *file)
+ {
++      struct trace_event_file *event_file;
+       struct hist_file_data *hist_file;
+       int ret;
+@@ -5675,16 +5689,25 @@ static int event_hist_open(struct inode *inode, struct file *file)
+       if (ret)
+               return ret;
++      guard(mutex)(&event_mutex);
++
++      event_file = event_file_data(file);
++      if (!event_file)
++              return -ENODEV;
++
+       hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL);
+       if (!hist_file)
+               return -ENOMEM;
++
+       hist_file->file = file;
++      hist_file->last_act = get_hist_hit_count(event_file);
+       /* Clear private_data to avoid warning in single_open() */
+       file->private_data = NULL;
+       ret = single_open(file, hist_show, hist_file);
+       if (ret)
+               kfree(hist_file);
++
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/tracing-switch-trace_events_hist.c-code-over-to-use-.patch b/queue-6.12/tracing-switch-trace_events_hist.c-code-over-to-use-.patch
new file mode 100644 (file)
index 0000000..6426db2
--- /dev/null
@@ -0,0 +1,99 @@
+From 1eb6498abff861ae18309f8c57be3b4f98425ce0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Dec 2024 15:12:05 -0500
+Subject: tracing: Switch trace_events_hist.c code over to use guard()
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 2b36a97aeeb71b1e4a48bfedc7f21f44aeb1e6fb ]
+
+There are a couple functions in trace_events_hist.c that have "goto out" or
+equivalent on error in order to release locks that were taken. This can be
+error prone or just simply make the code more complex.
+
+Switch every location that ends with unlocking a mutex on error over to
+using the guard(mutex)() infrastructure to let the compiler worry about
+releasing locks. This makes the code easier to read and understand.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/20241219201345.694601480@goodmis.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 0b4ffbe4888a ("tracing: Correct the refcount if the hist/hist_debug file fails to open")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_hist.c | 32 ++++++++++----------------------
+ 1 file changed, 10 insertions(+), 22 deletions(-)
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 31f5ad322fab0..5d344bc690d99 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5597,25 +5597,19 @@ static int hist_show(struct seq_file *m, void *v)
+ {
+       struct event_trigger_data *data;
+       struct trace_event_file *event_file;
+-      int n = 0, ret = 0;
++      int n = 0;
+-      mutex_lock(&event_mutex);
++      guard(mutex)(&event_mutex);
+       event_file = event_file_file(m->private);
+-      if (unlikely(!event_file)) {
+-              ret = -ENODEV;
+-              goto out_unlock;
+-      }
++      if (unlikely(!event_file))
++              return -ENODEV;
+       list_for_each_entry(data, &event_file->triggers, list) {
+               if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
+                       hist_trigger_show(m, data, n++);
+       }
+-
+- out_unlock:
+-      mutex_unlock(&event_mutex);
+-
+-      return ret;
++      return 0;
+ }
+ static int event_hist_open(struct inode *inode, struct file *file)
+@@ -5876,25 +5870,19 @@ static int hist_debug_show(struct seq_file *m, void *v)
+ {
+       struct event_trigger_data *data;
+       struct trace_event_file *event_file;
+-      int n = 0, ret = 0;
++      int n = 0;
+-      mutex_lock(&event_mutex);
++      guard(mutex)(&event_mutex);
+       event_file = event_file_file(m->private);
+-      if (unlikely(!event_file)) {
+-              ret = -ENODEV;
+-              goto out_unlock;
+-      }
++      if (unlikely(!event_file))
++              return -ENODEV;
+       list_for_each_entry(data, &event_file->triggers, list) {
+               if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
+                       hist_trigger_debug_show(m, data, n++);
+       }
+-
+- out_unlock:
+-      mutex_unlock(&event_mutex);
+-
+-      return ret;
++      return 0;
+ }
+ static int event_hist_debug_open(struct inode *inode, struct file *file)
+-- 
+2.39.5
+
diff --git a/queue-6.12/tty-serial-fsl_lpuart-use-port-struct-directly-to-si.patch b/queue-6.12/tty-serial-fsl_lpuart-use-port-struct-directly-to-si.patch
new file mode 100644 (file)
index 0000000..d2086ab
--- /dev/null
@@ -0,0 +1,523 @@
+From 937ce975f6fc60b4ad00a4759e55b66820814c4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 10:39:03 +0800
+Subject: tty: serial: fsl_lpuart: use port struct directly to simply code
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit 3cc16ae096f164ae0c6b98416c25a01db5f3a529 ]
+
+Most lpuart functions have the parameter struct uart_port *port, but
+still use the &sport->port to get the uart_port instead of use it
+directly, let's simply the code logic, directly use this struct instead
+of covert it from struct sport.
+
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20250312023904.1343351-3-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: e98ab45ec518 ("tty: serial: lpuart: only disable CTS instead of overwriting the whole UARTMODIR register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 213 +++++++++++++++-----------------
+ 1 file changed, 102 insertions(+), 111 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index e86fb9c60f1c3..c2b522843b72c 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -580,7 +580,7 @@ static int lpuart_dma_tx_request(struct uart_port *port)
+       ret = dmaengine_slave_config(sport->dma_tx_chan, &dma_tx_sconfig);
+       if (ret) {
+-              dev_err(sport->port.dev,
++              dev_err(port->dev,
+                               "DMA slave config failed, err = %d\n", ret);
+               return ret;
+       }
+@@ -610,13 +610,13 @@ static void lpuart_flush_buffer(struct uart_port *port)
+       }
+       if (lpuart_is_32(sport)) {
+-              val = lpuart32_read(&sport->port, UARTFIFO);
++              val = lpuart32_read(port, UARTFIFO);
+               val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
+-              lpuart32_write(&sport->port, val, UARTFIFO);
++              lpuart32_write(port, val, UARTFIFO);
+       } else {
+-              val = readb(sport->port.membase + UARTCFIFO);
++              val = readb(port->membase + UARTCFIFO);
+               val |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH;
+-              writeb(val, sport->port.membase + UARTCFIFO);
++              writeb(val, port->membase + UARTCFIFO);
+       }
+ }
+@@ -638,38 +638,36 @@ static void lpuart32_wait_bit_set(struct uart_port *port, unsigned int offset,
+ static int lpuart_poll_init(struct uart_port *port)
+ {
+-      struct lpuart_port *sport = container_of(port,
+-                                      struct lpuart_port, port);
+       unsigned long flags;
+       u8 temp;
+-      sport->port.fifosize = 0;
++      port->fifosize = 0;
+-      uart_port_lock_irqsave(&sport->port, &flags);
++      uart_port_lock_irqsave(port, &flags);
+       /* Disable Rx & Tx */
+-      writeb(0, sport->port.membase + UARTCR2);
++      writeb(0, port->membase + UARTCR2);
+-      temp = readb(sport->port.membase + UARTPFIFO);
++      temp = readb(port->membase + UARTPFIFO);
+       /* Enable Rx and Tx FIFO */
+       writeb(temp | UARTPFIFO_RXFE | UARTPFIFO_TXFE,
+-                      sport->port.membase + UARTPFIFO);
++                      port->membase + UARTPFIFO);
+       /* flush Tx and Rx FIFO */
+       writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
+-                      sport->port.membase + UARTCFIFO);
++                      port->membase + UARTCFIFO);
+       /* explicitly clear RDRF */
+-      if (readb(sport->port.membase + UARTSR1) & UARTSR1_RDRF) {
+-              readb(sport->port.membase + UARTDR);
+-              writeb(UARTSFIFO_RXUF, sport->port.membase + UARTSFIFO);
++      if (readb(port->membase + UARTSR1) & UARTSR1_RDRF) {
++              readb(port->membase + UARTDR);
++              writeb(UARTSFIFO_RXUF, port->membase + UARTSFIFO);
+       }
+-      writeb(0, sport->port.membase + UARTTWFIFO);
+-      writeb(1, sport->port.membase + UARTRWFIFO);
++      writeb(0, port->membase + UARTTWFIFO);
++      writeb(1, port->membase + UARTRWFIFO);
+       /* Enable Rx and Tx */
+-      writeb(UARTCR2_RE | UARTCR2_TE, sport->port.membase + UARTCR2);
+-      uart_port_unlock_irqrestore(&sport->port, flags);
++      writeb(UARTCR2_RE | UARTCR2_TE, port->membase + UARTCR2);
++      uart_port_unlock_irqrestore(port, flags);
+       return 0;
+ }
+@@ -692,33 +690,32 @@ static int lpuart_poll_get_char(struct uart_port *port)
+ static int lpuart32_poll_init(struct uart_port *port)
+ {
+       unsigned long flags;
+-      struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+       u32 temp;
+-      sport->port.fifosize = 0;
++      port->fifosize = 0;
+-      uart_port_lock_irqsave(&sport->port, &flags);
++      uart_port_lock_irqsave(port, &flags);
+       /* Disable Rx & Tx */
+-      lpuart32_write(&sport->port, 0, UARTCTRL);
++      lpuart32_write(port, 0, UARTCTRL);
+-      temp = lpuart32_read(&sport->port, UARTFIFO);
++      temp = lpuart32_read(port, UARTFIFO);
+       /* Enable Rx and Tx FIFO */
+-      lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
++      lpuart32_write(port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
+       /* flush Tx and Rx FIFO */
+-      lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
++      lpuart32_write(port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
+       /* explicitly clear RDRF */
+-      if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) {
+-              lpuart32_read(&sport->port, UARTDATA);
+-              lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO);
++      if (lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF) {
++              lpuart32_read(port, UARTDATA);
++              lpuart32_write(port, UARTFIFO_RXUF, UARTFIFO);
+       }
+       /* Enable Rx and Tx */
+-      lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
+-      uart_port_unlock_irqrestore(&sport->port, flags);
++      lpuart32_write(port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
++      uart_port_unlock_irqrestore(port, flags);
+       return 0;
+ }
+@@ -1448,12 +1445,9 @@ static void lpuart_dma_rx_free(struct uart_port *port)
+ static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios,
+                       struct serial_rs485 *rs485)
+ {
+-      struct lpuart_port *sport = container_of(port,
+-                      struct lpuart_port, port);
+-
+-      u8 modem = readb(sport->port.membase + UARTMODEM) &
++      u8 modem = readb(port->membase + UARTMODEM) &
+               ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE);
+-      writeb(modem, sport->port.membase + UARTMODEM);
++      writeb(modem, port->membase + UARTMODEM);
+       if (rs485->flags & SER_RS485_ENABLED) {
+               /* Enable auto RS-485 RTS mode */
+@@ -1471,32 +1465,29 @@ static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios,
+                       modem &= ~UARTMODEM_TXRTSPOL;
+       }
+-      writeb(modem, sport->port.membase + UARTMODEM);
++      writeb(modem, port->membase + UARTMODEM);
+       return 0;
+ }
+ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termios,
+                       struct serial_rs485 *rs485)
+ {
+-      struct lpuart_port *sport = container_of(port,
+-                      struct lpuart_port, port);
+-
+-      u32 modem = lpuart32_read(&sport->port, UARTMODIR)
++      u32 modem = lpuart32_read(port, UARTMODIR)
+                               & ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
+       u32 ctrl;
+       /* TXRTSE and TXRTSPOL only can be changed when transmitter is disabled. */
+-      ctrl = lpuart32_read(&sport->port, UARTCTRL);
++      ctrl = lpuart32_read(port, UARTCTRL);
+       if (ctrl & UARTCTRL_TE) {
+               /* wait for the transmit engine to complete */
+-              lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
+-              lpuart32_write(&sport->port, ctrl & ~UARTCTRL_TE, UARTCTRL);
++              lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC);
++              lpuart32_write(port, ctrl & ~UARTCTRL_TE, UARTCTRL);
+-              while (lpuart32_read(&sport->port, UARTCTRL) & UARTCTRL_TE)
++              while (lpuart32_read(port, UARTCTRL) & UARTCTRL_TE)
+                       cpu_relax();
+       }
+-      lpuart32_write(&sport->port, modem, UARTMODIR);
++      lpuart32_write(port, modem, UARTMODIR);
+       if (rs485->flags & SER_RS485_ENABLED) {
+               /* Enable auto RS-485 RTS mode */
+@@ -1514,10 +1505,10 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
+                       modem &= ~UARTMODIR_TXRTSPOL;
+       }
+-      lpuart32_write(&sport->port, modem, UARTMODIR);
++      lpuart32_write(port, modem, UARTMODIR);
+       if (ctrl & UARTCTRL_TE)
+-              lpuart32_write(&sport->port, ctrl, UARTCTRL);
++              lpuart32_write(port, ctrl, UARTCTRL);
+       return 0;
+ }
+@@ -1828,11 +1819,11 @@ static int lpuart_startup(struct uart_port *port)
+       u8 temp;
+       /* determine FIFO size and enable FIFO mode */
+-      temp = readb(sport->port.membase + UARTPFIFO);
++      temp = readb(port->membase + UARTPFIFO);
+       sport->txfifo_size = UARTFIFO_DEPTH((temp >> UARTPFIFO_TXSIZE_OFF) &
+                                           UARTPFIFO_FIFOSIZE_MASK);
+-      sport->port.fifosize = sport->txfifo_size;
++      port->fifosize = sport->txfifo_size;
+       sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTPFIFO_RXSIZE_OFF) &
+                                           UARTPFIFO_FIFOSIZE_MASK);
+@@ -1888,11 +1879,11 @@ static int lpuart32_startup(struct uart_port *port)
+       u32 temp;
+       /* determine FIFO size */
+-      temp = lpuart32_read(&sport->port, UARTFIFO);
++      temp = lpuart32_read(port, UARTFIFO);
+       sport->txfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_TXSIZE_OFF) &
+                                           UARTFIFO_FIFOSIZE_MASK);
+-      sport->port.fifosize = sport->txfifo_size;
++      port->fifosize = sport->txfifo_size;
+       sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_RXSIZE_OFF) &
+                                           UARTFIFO_FIFOSIZE_MASK);
+@@ -1905,7 +1896,7 @@ static int lpuart32_startup(struct uart_port *port)
+       if (is_layerscape_lpuart(sport)) {
+               sport->rxfifo_size = 16;
+               sport->txfifo_size = 16;
+-              sport->port.fifosize = sport->txfifo_size;
++              port->fifosize = sport->txfifo_size;
+       }
+       lpuart_request_dma(sport);
+@@ -1965,8 +1956,8 @@ static void lpuart32_shutdown(struct uart_port *port)
+       uart_port_lock_irqsave(port, &flags);
+       /* clear status */
+-      temp = lpuart32_read(&sport->port, UARTSTAT);
+-      lpuart32_write(&sport->port, temp, UARTSTAT);
++      temp = lpuart32_read(port, UARTSTAT);
++      lpuart32_write(port, temp, UARTSTAT);
+       /* disable Rx/Tx DMA */
+       temp = lpuart32_read(port, UARTBAUD);
+@@ -1995,12 +1986,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
+       unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+       unsigned int sbr, brfa;
+-      cr1 = old_cr1 = readb(sport->port.membase + UARTCR1);
+-      old_cr2 = readb(sport->port.membase + UARTCR2);
+-      cr3 = readb(sport->port.membase + UARTCR3);
+-      cr4 = readb(sport->port.membase + UARTCR4);
+-      bdh = readb(sport->port.membase + UARTBDH);
+-      modem = readb(sport->port.membase + UARTMODEM);
++      cr1 = old_cr1 = readb(port->membase + UARTCR1);
++      old_cr2 = readb(port->membase + UARTCR2);
++      cr3 = readb(port->membase + UARTCR3);
++      cr4 = readb(port->membase + UARTCR4);
++      bdh = readb(port->membase + UARTBDH);
++      modem = readb(port->membase + UARTMODEM);
+       /*
+        * only support CS8 and CS7, and for CS7 must enable PE.
+        * supported mode:
+@@ -2032,7 +2023,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
+        * When auto RS-485 RTS mode is enabled,
+        * hardware flow control need to be disabled.
+        */
+-      if (sport->port.rs485.flags & SER_RS485_ENABLED)
++      if (port->rs485.flags & SER_RS485_ENABLED)
+               termios->c_cflag &= ~CRTSCTS;
+       if (termios->c_cflag & CRTSCTS)
+@@ -2073,59 +2064,59 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
+        * Need to update the Ring buffer length according to the selected
+        * baud rate and restart Rx DMA path.
+        *
+-       * Since timer function acqures sport->port.lock, need to stop before
++       * Since timer function acqures port->lock, need to stop before
+        * acquring same lock because otherwise del_timer_sync() can deadlock.
+        */
+       if (old && sport->lpuart_dma_rx_use)
+-              lpuart_dma_rx_free(&sport->port);
++              lpuart_dma_rx_free(port);
+-      uart_port_lock_irqsave(&sport->port, &flags);
++      uart_port_lock_irqsave(port, &flags);
+-      sport->port.read_status_mask = 0;
++      port->read_status_mask = 0;
+       if (termios->c_iflag & INPCK)
+-              sport->port.read_status_mask |= UARTSR1_FE | UARTSR1_PE;
++              port->read_status_mask |= UARTSR1_FE | UARTSR1_PE;
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
+-              sport->port.read_status_mask |= UARTSR1_FE;
++              port->read_status_mask |= UARTSR1_FE;
+       /* characters to ignore */
+-      sport->port.ignore_status_mask = 0;
++      port->ignore_status_mask = 0;
+       if (termios->c_iflag & IGNPAR)
+-              sport->port.ignore_status_mask |= UARTSR1_PE;
++              port->ignore_status_mask |= UARTSR1_PE;
+       if (termios->c_iflag & IGNBRK) {
+-              sport->port.ignore_status_mask |= UARTSR1_FE;
++              port->ignore_status_mask |= UARTSR1_FE;
+               /*
+                * if we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (termios->c_iflag & IGNPAR)
+-                      sport->port.ignore_status_mask |= UARTSR1_OR;
++                      port->ignore_status_mask |= UARTSR1_OR;
+       }
+       /* update the per-port timeout */
+       uart_update_timeout(port, termios->c_cflag, baud);
+       /* wait transmit engin complete */
+-      lpuart_wait_bit_set(&sport->port, UARTSR1, UARTSR1_TC);
++      lpuart_wait_bit_set(port, UARTSR1, UARTSR1_TC);
+       /* disable transmit and receive */
+       writeb(old_cr2 & ~(UARTCR2_TE | UARTCR2_RE),
+-                      sport->port.membase + UARTCR2);
++                      port->membase + UARTCR2);
+-      sbr = sport->port.uartclk / (16 * baud);
+-      brfa = ((sport->port.uartclk - (16 * sbr * baud)) * 2) / baud;
++      sbr = port->uartclk / (16 * baud);
++      brfa = ((port->uartclk - (16 * sbr * baud)) * 2) / baud;
+       bdh &= ~UARTBDH_SBR_MASK;
+       bdh |= (sbr >> 8) & 0x1F;
+       cr4 &= ~UARTCR4_BRFA_MASK;
+       brfa &= UARTCR4_BRFA_MASK;
+-      writeb(cr4 | brfa, sport->port.membase + UARTCR4);
+-      writeb(bdh, sport->port.membase + UARTBDH);
+-      writeb(sbr & 0xFF, sport->port.membase + UARTBDL);
+-      writeb(cr3, sport->port.membase + UARTCR3);
+-      writeb(cr1, sport->port.membase + UARTCR1);
+-      writeb(modem, sport->port.membase + UARTMODEM);
++      writeb(cr4 | brfa, port->membase + UARTCR4);
++      writeb(bdh, port->membase + UARTBDH);
++      writeb(sbr & 0xFF, port->membase + UARTBDL);
++      writeb(cr3, port->membase + UARTCR3);
++      writeb(cr1, port->membase + UARTCR1);
++      writeb(modem, port->membase + UARTMODEM);
+       /* restore control register */
+-      writeb(old_cr2, sport->port.membase + UARTCR2);
++      writeb(old_cr2, port->membase + UARTCR2);
+       if (old && sport->lpuart_dma_rx_use) {
+               if (!lpuart_start_rx_dma(sport))
+@@ -2134,7 +2125,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
+                       sport->lpuart_dma_rx_use = false;
+       }
+-      uart_port_unlock_irqrestore(&sport->port, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void __lpuart32_serial_setbrg(struct uart_port *port,
+@@ -2232,9 +2223,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+       unsigned int  baud;
+       unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+-      ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL);
+-      bd = lpuart32_read(&sport->port, UARTBAUD);
+-      modem = lpuart32_read(&sport->port, UARTMODIR);
++      ctrl = old_ctrl = lpuart32_read(port, UARTCTRL);
++      bd = lpuart32_read(port, UARTBAUD);
++      modem = lpuart32_read(port, UARTMODIR);
+       sport->is_cs7 = false;
+       /*
+        * only support CS8 and CS7, and for CS7 must enable PE.
+@@ -2267,7 +2258,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+        * When auto RS-485 RTS mode is enabled,
+        * hardware flow control need to be disabled.
+        */
+-      if (sport->port.rs485.flags & SER_RS485_ENABLED)
++      if (port->rs485.flags & SER_RS485_ENABLED)
+               termios->c_cflag &= ~CRTSCTS;
+       if (termios->c_cflag & CRTSCTS)
+@@ -2308,32 +2299,32 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+        * Need to update the Ring buffer length according to the selected
+        * baud rate and restart Rx DMA path.
+        *
+-       * Since timer function acqures sport->port.lock, need to stop before
++       * Since timer function acqures port->lock, need to stop before
+        * acquring same lock because otherwise del_timer_sync() can deadlock.
+        */
+       if (old && sport->lpuart_dma_rx_use)
+-              lpuart_dma_rx_free(&sport->port);
++              lpuart_dma_rx_free(port);
+-      uart_port_lock_irqsave(&sport->port, &flags);
++      uart_port_lock_irqsave(port, &flags);
+-      sport->port.read_status_mask = 0;
++      port->read_status_mask = 0;
+       if (termios->c_iflag & INPCK)
+-              sport->port.read_status_mask |= UARTSTAT_FE | UARTSTAT_PE;
++              port->read_status_mask |= UARTSTAT_FE | UARTSTAT_PE;
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
+-              sport->port.read_status_mask |= UARTSTAT_FE;
++              port->read_status_mask |= UARTSTAT_FE;
+       /* characters to ignore */
+-      sport->port.ignore_status_mask = 0;
++      port->ignore_status_mask = 0;
+       if (termios->c_iflag & IGNPAR)
+-              sport->port.ignore_status_mask |= UARTSTAT_PE;
++              port->ignore_status_mask |= UARTSTAT_PE;
+       if (termios->c_iflag & IGNBRK) {
+-              sport->port.ignore_status_mask |= UARTSTAT_FE;
++              port->ignore_status_mask |= UARTSTAT_FE;
+               /*
+                * if we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (termios->c_iflag & IGNPAR)
+-                      sport->port.ignore_status_mask |= UARTSTAT_OR;
++                      port->ignore_status_mask |= UARTSTAT_OR;
+       }
+       /* update the per-port timeout */
+@@ -2345,22 +2336,22 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+        * asserted.
+        */
+       if (!(old_ctrl & UARTCTRL_SBK)) {
+-              lpuart32_write(&sport->port, 0, UARTMODIR);
+-              lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
++              lpuart32_write(port, 0, UARTMODIR);
++              lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC);
+       }
+       /* disable transmit and receive */
+-      lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
++      lpuart32_write(port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
+                      UARTCTRL);
+-      lpuart32_write(&sport->port, bd, UARTBAUD);
++      lpuart32_write(port, bd, UARTBAUD);
+       lpuart32_serial_setbrg(sport, baud);
+       /* disable CTS before enabling UARTCTRL_TE to avoid pending idle preamble */
+-      lpuart32_write(&sport->port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
++      lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
+       /* restore control register */
+-      lpuart32_write(&sport->port, ctrl, UARTCTRL);
++      lpuart32_write(port, ctrl, UARTCTRL);
+       /* re-enable the CTS if needed */
+-      lpuart32_write(&sport->port, modem, UARTMODIR);
++      lpuart32_write(port, modem, UARTMODIR);
+       if ((ctrl & (UARTCTRL_PE | UARTCTRL_M)) == UARTCTRL_PE)
+               sport->is_cs7 = true;
+@@ -2372,7 +2363,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+                       sport->lpuart_dma_rx_use = false;
+       }
+-      uart_port_unlock_irqrestore(&sport->port, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static const char *lpuart_type(struct uart_port *port)
+@@ -2810,7 +2801,7 @@ static int lpuart_global_reset(struct lpuart_port *sport)
+       ret = clk_prepare_enable(sport->ipg_clk);
+       if (ret) {
+-              dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
++              dev_err(port->dev, "failed to enable uart ipg clk: %d\n", ret);
+               return ret;
+       }
+@@ -2821,10 +2812,10 @@ static int lpuart_global_reset(struct lpuart_port *sport)
+                */
+               ctrl = lpuart32_read(port, UARTCTRL);
+               if (ctrl & UARTCTRL_TE) {
+-                      bd = lpuart32_read(&sport->port, UARTBAUD);
++                      bd = lpuart32_read(port, UARTBAUD);
+                       if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, 100000, false,
+                                             port)) {
+-                              dev_warn(sport->port.dev,
++                              dev_warn(port->dev,
+                                        "timeout waiting for transmit engine to complete\n");
+                               clk_disable_unprepare(sport->ipg_clk);
+                               return 0;
+@@ -3176,7 +3167,7 @@ static void lpuart_console_fixup(struct lpuart_port *sport)
+        * in VLLS mode, or restore console setting here.
+        */
+       if (is_imx7ulp_lpuart(sport) && lpuart_uport_is_active(sport) &&
+-          console_suspend_enabled && uart_console(&sport->port)) {
++          console_suspend_enabled && uart_console(uport)) {
+               mutex_lock(&port->mutex);
+               memset(&termios, 0, sizeof(struct ktermios));
+-- 
+2.39.5
+
diff --git a/queue-6.12/tty-serial-fsl_lpuart-use-u32-and-u8-for-register-va.patch b/queue-6.12/tty-serial-fsl_lpuart-use-u32-and-u8-for-register-va.patch
new file mode 100644 (file)
index 0000000..e3c1137
--- /dev/null
@@ -0,0 +1,407 @@
+From e081c64f1c74ae9b29e61979af91680a8a962185 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 10:39:02 +0800
+Subject: tty: serial: fsl_lpuart: Use u32 and u8 for register variables
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit b6a8f6ab2c53e5ea3c7f2a3978db378a89bb7595 ]
+
+Use u32 and u8 rather than unsigned long or unsigned char for register
+variables for clarity and consistency.
+
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20250312023904.1343351-2-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: e98ab45ec518 ("tty: serial: lpuart: only disable CTS instead of overwriting the whole UARTMODIR register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 93 ++++++++++++++++-----------------
+ 1 file changed, 46 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 9f9fc733eb2c1..e86fb9c60f1c3 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -440,7 +440,7 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport)
+ static void lpuart_stop_tx(struct uart_port *port)
+ {
+-      unsigned char temp;
++      u8 temp;
+       temp = readb(port->membase + UARTCR2);
+       temp &= ~(UARTCR2_TIE | UARTCR2_TCIE);
+@@ -449,7 +449,7 @@ static void lpuart_stop_tx(struct uart_port *port)
+ static void lpuart32_stop_tx(struct uart_port *port)
+ {
+-      unsigned long temp;
++      u32 temp;
+       temp = lpuart32_read(port, UARTCTRL);
+       temp &= ~(UARTCTRL_TIE | UARTCTRL_TCIE);
+@@ -458,7 +458,7 @@ static void lpuart32_stop_tx(struct uart_port *port)
+ static void lpuart_stop_rx(struct uart_port *port)
+ {
+-      unsigned char temp;
++      u8 temp;
+       temp = readb(port->membase + UARTCR2);
+       writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2);
+@@ -466,7 +466,7 @@ static void lpuart_stop_rx(struct uart_port *port)
+ static void lpuart32_stop_rx(struct uart_port *port)
+ {
+-      unsigned long temp;
++      u32 temp;
+       temp = lpuart32_read(port, UARTCTRL);
+       lpuart32_write(port, temp & ~UARTCTRL_RE, UARTCTRL);
+@@ -641,7 +641,7 @@ static int lpuart_poll_init(struct uart_port *port)
+       struct lpuart_port *sport = container_of(port,
+                                       struct lpuart_port, port);
+       unsigned long flags;
+-      unsigned char temp;
++      u8 temp;
+       sport->port.fifosize = 0;
+@@ -751,7 +751,7 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
+ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
+ {
+       struct tty_port *tport = &sport->port.state->port;
+-      unsigned long txcnt;
++      u32 txcnt;
+       unsigned char c;
+       if (sport->port.x_char) {
+@@ -788,7 +788,7 @@ static void lpuart_start_tx(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port,
+                       struct lpuart_port, port);
+-      unsigned char temp;
++      u8 temp;
+       temp = readb(port->membase + UARTCR2);
+       writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
+@@ -805,7 +805,7 @@ static void lpuart_start_tx(struct uart_port *port)
+ static void lpuart32_start_tx(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+-      unsigned long temp;
++      u32 temp;
+       if (sport->lpuart_dma_tx_use) {
+               if (!lpuart_stopped_or_empty(port))
+@@ -838,8 +838,8 @@ static unsigned int lpuart_tx_empty(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port,
+                       struct lpuart_port, port);
+-      unsigned char sr1 = readb(port->membase + UARTSR1);
+-      unsigned char sfifo = readb(port->membase + UARTSFIFO);
++      u8 sr1 = readb(port->membase + UARTSR1);
++      u8 sfifo = readb(port->membase + UARTSFIFO);
+       if (sport->dma_tx_in_progress)
+               return 0;
+@@ -854,9 +854,9 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port,
+                       struct lpuart_port, port);
+-      unsigned long stat = lpuart32_read(port, UARTSTAT);
+-      unsigned long sfifo = lpuart32_read(port, UARTFIFO);
+-      unsigned long ctrl = lpuart32_read(port, UARTCTRL);
++      u32 stat = lpuart32_read(port, UARTSTAT);
++      u32 sfifo = lpuart32_read(port, UARTFIFO);
++      u32 ctrl = lpuart32_read(port, UARTCTRL);
+       if (sport->dma_tx_in_progress)
+               return 0;
+@@ -883,7 +883,7 @@ static void lpuart_rxint(struct lpuart_port *sport)
+ {
+       unsigned int flg, ignored = 0, overrun = 0;
+       struct tty_port *port = &sport->port.state->port;
+-      unsigned char rx, sr;
++      u8 rx, sr;
+       uart_port_lock(&sport->port);
+@@ -960,7 +960,7 @@ static void lpuart32_rxint(struct lpuart_port *sport)
+ {
+       unsigned int flg, ignored = 0;
+       struct tty_port *port = &sport->port.state->port;
+-      unsigned long rx, sr;
++      u32 rx, sr;
+       bool is_break;
+       uart_port_lock(&sport->port);
+@@ -1038,7 +1038,7 @@ static void lpuart32_rxint(struct lpuart_port *sport)
+ static irqreturn_t lpuart_int(int irq, void *dev_id)
+ {
+       struct lpuart_port *sport = dev_id;
+-      unsigned char sts;
++      u8 sts;
+       sts = readb(sport->port.membase + UARTSR1);
+@@ -1112,7 +1112,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
+       int count, copied;
+       if (lpuart_is_32(sport)) {
+-              unsigned long sr = lpuart32_read(&sport->port, UARTSTAT);
++              u32 sr = lpuart32_read(&sport->port, UARTSTAT);
+               if (sr & (UARTSTAT_PE | UARTSTAT_FE)) {
+                       /* Clear the error flags */
+@@ -1124,10 +1124,10 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
+                               sport->port.icount.frame++;
+               }
+       } else {
+-              unsigned char sr = readb(sport->port.membase + UARTSR1);
++              u8 sr = readb(sport->port.membase + UARTSR1);
+               if (sr & (UARTSR1_PE | UARTSR1_FE)) {
+-                      unsigned char cr2;
++                      u8 cr2;
+                       /* Disable receiver during this operation... */
+                       cr2 = readb(sport->port.membase + UARTCR2);
+@@ -1278,7 +1278,7 @@ static void lpuart32_dma_idleint(struct lpuart_port *sport)
+ static irqreturn_t lpuart32_int(int irq, void *dev_id)
+ {
+       struct lpuart_port *sport = dev_id;
+-      unsigned long sts, rxcount;
++      u32 sts, rxcount;
+       sts = lpuart32_read(&sport->port, UARTSTAT);
+       rxcount = lpuart32_read(&sport->port, UARTWATER);
+@@ -1410,12 +1410,12 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
+       dma_async_issue_pending(chan);
+       if (lpuart_is_32(sport)) {
+-              unsigned long temp = lpuart32_read(&sport->port, UARTBAUD);
++              u32 temp = lpuart32_read(&sport->port, UARTBAUD);
+               lpuart32_write(&sport->port, temp | UARTBAUD_RDMAE, UARTBAUD);
+               if (sport->dma_idle_int) {
+-                      unsigned long ctrl = lpuart32_read(&sport->port, UARTCTRL);
++                      u32 ctrl = lpuart32_read(&sport->port, UARTCTRL);
+                       lpuart32_write(&sport->port, ctrl | UARTCTRL_ILIE, UARTCTRL);
+               }
+@@ -1481,7 +1481,7 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
+       struct lpuart_port *sport = container_of(port,
+                       struct lpuart_port, port);
+-      unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
++      u32 modem = lpuart32_read(&sport->port, UARTMODIR)
+                               & ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
+       u32 ctrl;
+@@ -1576,7 +1576,7 @@ static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ static void lpuart_break_ctl(struct uart_port *port, int break_state)
+ {
+-      unsigned char temp;
++      u8 temp;
+       temp = readb(port->membase + UARTCR2) & ~UARTCR2_SBK;
+@@ -1588,7 +1588,7 @@ static void lpuart_break_ctl(struct uart_port *port, int break_state)
+ static void lpuart32_break_ctl(struct uart_port *port, int break_state)
+ {
+-      unsigned long temp;
++      u32 temp;
+       temp = lpuart32_read(port, UARTCTRL);
+@@ -1622,8 +1622,7 @@ static void lpuart32_break_ctl(struct uart_port *port, int break_state)
+ static void lpuart_setup_watermark(struct lpuart_port *sport)
+ {
+-      unsigned char val, cr2;
+-      unsigned char cr2_saved;
++      u8 val, cr2, cr2_saved;
+       cr2 = readb(sport->port.membase + UARTCR2);
+       cr2_saved = cr2;
+@@ -1656,7 +1655,7 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
+ static void lpuart_setup_watermark_enable(struct lpuart_port *sport)
+ {
+-      unsigned char cr2;
++      u8 cr2;
+       lpuart_setup_watermark(sport);
+@@ -1667,8 +1666,7 @@ static void lpuart_setup_watermark_enable(struct lpuart_port *sport)
+ static void lpuart32_setup_watermark(struct lpuart_port *sport)
+ {
+-      unsigned long val, ctrl;
+-      unsigned long ctrl_saved;
++      u32 val, ctrl, ctrl_saved;
+       ctrl = lpuart32_read(&sport->port, UARTCTRL);
+       ctrl_saved = ctrl;
+@@ -1777,7 +1775,7 @@ static void lpuart_tx_dma_startup(struct lpuart_port *sport)
+ static void lpuart_rx_dma_startup(struct lpuart_port *sport)
+ {
+       int ret;
+-      unsigned char cr3;
++      u8 cr3;
+       if (uart_console(&sport->port))
+               goto err;
+@@ -1827,7 +1825,7 @@ static void lpuart_hw_setup(struct lpuart_port *sport)
+ static int lpuart_startup(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+-      unsigned char temp;
++      u8 temp;
+       /* determine FIFO size and enable FIFO mode */
+       temp = readb(sport->port.membase + UARTPFIFO);
+@@ -1847,7 +1845,7 @@ static int lpuart_startup(struct uart_port *port)
+ static void lpuart32_hw_disable(struct lpuart_port *sport)
+ {
+-      unsigned long temp;
++      u32 temp;
+       temp = lpuart32_read(&sport->port, UARTCTRL);
+       temp &= ~(UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE |
+@@ -1857,7 +1855,7 @@ static void lpuart32_hw_disable(struct lpuart_port *sport)
+ static void lpuart32_configure(struct lpuart_port *sport)
+ {
+-      unsigned long temp;
++      u32 temp;
+       temp = lpuart32_read(&sport->port, UARTCTRL);
+       if (!sport->lpuart_dma_rx_use)
+@@ -1887,7 +1885,7 @@ static void lpuart32_hw_setup(struct lpuart_port *sport)
+ static int lpuart32_startup(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+-      unsigned long temp;
++      u32 temp;
+       /* determine FIFO size */
+       temp = lpuart32_read(&sport->port, UARTFIFO);
+@@ -1941,7 +1939,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
+ static void lpuart_shutdown(struct uart_port *port)
+ {
+       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+-      unsigned char temp;
++      u8 temp;
+       unsigned long flags;
+       uart_port_lock_irqsave(port, &flags);
+@@ -1961,7 +1959,7 @@ static void lpuart32_shutdown(struct uart_port *port)
+ {
+       struct lpuart_port *sport =
+               container_of(port, struct lpuart_port, port);
+-      unsigned long temp;
++      u32 temp;
+       unsigned long flags;
+       uart_port_lock_irqsave(port, &flags);
+@@ -1992,7 +1990,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
+ {
+       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+       unsigned long flags;
+-      unsigned char cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem;
++      u8 cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem;
+       unsigned int  baud;
+       unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+       unsigned int sbr, brfa;
+@@ -2230,7 +2228,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+ {
+       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+       unsigned long flags;
+-      unsigned long ctrl, old_ctrl, bd, modem;
++      u32 ctrl, old_ctrl, bd, modem;
+       unsigned int  baud;
+       unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
+@@ -2487,7 +2485,7 @@ static void
+ lpuart_console_write(struct console *co, const char *s, unsigned int count)
+ {
+       struct lpuart_port *sport = lpuart_ports[co->index];
+-      unsigned char  old_cr2, cr2;
++      u8  old_cr2, cr2;
+       unsigned long flags;
+       int locked = 1;
+@@ -2517,7 +2515,7 @@ static void
+ lpuart32_console_write(struct console *co, const char *s, unsigned int count)
+ {
+       struct lpuart_port *sport = lpuart_ports[co->index];
+-      unsigned long  old_cr, cr;
++      u32 old_cr, cr;
+       unsigned long flags;
+       int locked = 1;
+@@ -2551,7 +2549,7 @@ static void __init
+ lpuart_console_get_options(struct lpuart_port *sport, int *baud,
+                          int *parity, int *bits)
+ {
+-      unsigned char cr, bdh, bdl, brfa;
++      u8 cr, bdh, bdl, brfa;
+       unsigned int sbr, uartclk, baud_raw;
+       cr = readb(sport->port.membase + UARTCR2);
+@@ -2600,7 +2598,7 @@ static void __init
+ lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
+                          int *parity, int *bits)
+ {
+-      unsigned long cr, bd;
++      u32 cr, bd;
+       unsigned int sbr, uartclk, baud_raw;
+       cr = lpuart32_read(&sport->port, UARTCTRL);
+@@ -2806,7 +2804,7 @@ static int lpuart_global_reset(struct lpuart_port *sport)
+ {
+       struct uart_port *port = &sport->port;
+       void __iomem *global_addr;
+-      unsigned long ctrl, bd;
++      u32 ctrl, bd;
+       unsigned int val = 0;
+       int ret;
+@@ -3012,7 +3010,7 @@ static int lpuart_runtime_resume(struct device *dev)
+ static void serial_lpuart_enable_wakeup(struct lpuart_port *sport, bool on)
+ {
+-      unsigned int val, baud;
++      u32 val, baud;
+       if (lpuart_is_32(sport)) {
+               val = lpuart32_read(&sport->port, UARTCTRL);
+@@ -3077,7 +3075,7 @@ static int lpuart_suspend_noirq(struct device *dev)
+ static int lpuart_resume_noirq(struct device *dev)
+ {
+       struct lpuart_port *sport = dev_get_drvdata(dev);
+-      unsigned int val;
++      u32 val;
+       pinctrl_pm_select_default_state(dev);
+@@ -3097,7 +3095,8 @@ static int lpuart_resume_noirq(struct device *dev)
+ static int lpuart_suspend(struct device *dev)
+ {
+       struct lpuart_port *sport = dev_get_drvdata(dev);
+-      unsigned long temp, flags;
++      u32 temp;
++      unsigned long flags;
+       uart_suspend_port(&lpuart_reg, &sport->port);
+-- 
+2.39.5
+
diff --git a/queue-6.12/tty-serial-lpuart-only-disable-cts-instead-of-overwr.patch b/queue-6.12/tty-serial-lpuart-only-disable-cts-instead-of-overwr.patch
new file mode 100644 (file)
index 0000000..3fa85cb
--- /dev/null
@@ -0,0 +1,65 @@
+From 2ae3bf84c036c1480900f85c931409511ce282ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 14:54:46 +0800
+Subject: tty: serial: lpuart: only disable CTS instead of overwriting the
+ whole UARTMODIR register
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit e98ab45ec5182605d2e00114cba3bbf46b0ea27f ]
+
+No need to overwrite the whole UARTMODIR register before waiting the
+transmit engine complete, actually our target here is only to disable
+CTS flow control to avoid the dirty data in TX FIFO may block the
+transmit engine complete.
+Also delete the following duplicate CTS disable configuration.
+
+Fixes: d5a2e0834364 ("tty: serial: lpuart: disable flow control while waiting for the transmit engine to complete")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20250307065446.1122482-1-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index c2b522843b72c..951c3cdac3b94 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -2330,15 +2330,19 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+       /* update the per-port timeout */
+       uart_update_timeout(port, termios->c_cflag, baud);
++      /*
++       * disable CTS to ensure the transmit engine is not blocked by the flow
++       * control when there is dirty data in TX FIFO
++       */
++      lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
++
+       /*
+        * LPUART Transmission Complete Flag may never be set while queuing a break
+        * character, so skip waiting for transmission complete when UARTCTRL_SBK is
+        * asserted.
+        */
+-      if (!(old_ctrl & UARTCTRL_SBK)) {
+-              lpuart32_write(port, 0, UARTMODIR);
++      if (!(old_ctrl & UARTCTRL_SBK))
+               lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC);
+-      }
+       /* disable transmit and receive */
+       lpuart32_write(port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
+@@ -2346,8 +2350,6 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
+       lpuart32_write(port, bd, UARTBAUD);
+       lpuart32_serial_setbrg(sport, baud);
+-      /* disable CTS before enabling UARTCTRL_TE to avoid pending idle preamble */
+-      lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
+       /* restore control register */
+       lpuart32_write(port, ctrl, UARTCTRL);
+       /* re-enable the CTS if needed */
+-- 
+2.39.5
+