--- /dev/null
+From d717dbdb94145bee1e9cf9eca387d973564203c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 May 2024 20:27:36 +0200
+Subject: ALSA: timer: Set lower bound of start tick time
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 4a63bd179fa8d3fcc44a0d9d71d941ddd62f0c4e ]
+
+Currently ALSA timer doesn't have the lower limit of the start tick
+time, and it allows a very small size, e.g. 1 tick with 1ns resolution
+for hrtimer. Such a situation may lead to an unexpected RCU stall,
+where the callback repeatedly queuing the expire update, as reported
+by fuzzer.
+
+This patch introduces a sanity check of the timer start tick time, so
+that the system returns an error when a too small start size is set.
+As of this patch, the lower limit is hard-coded to 100us, which is
+small enough but can still work somehow.
+
+Reported-by: syzbot+43120c2af6ca2938cc38@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/r/000000000000fa00a1061740ab6d@google.com
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20240514182745.4015-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/timer.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index e6e551d4a29e0..42c4c2b029526 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -553,6 +553,14 @@ static int snd_timer_start1(struct snd_timer_instance *timeri,
+ goto unlock;
+ }
+
++ /* check the actual time for the start tick;
++ * bail out as error if it's way too low (< 100us)
++ */
++ if (start) {
++ if ((u64)snd_timer_hw_resolution(timer) * ticks < 100000)
++ return -EINVAL;
++ }
++
+ if (start)
+ timeri->ticks = timeri->cticks = ticks;
+ else if (!timeri->cticks)
+--
+2.43.0
+
--- /dev/null
+From 4ac7dd4e3627a77735efbbf5f69b16637d644ed5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 16:42:30 +0800
+Subject: arm64: dts: meson: fix S4 power-controller node
+
+From: Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+[ Upstream commit 72907de9051dc2aa7b55c2a020e2872184ac17cd ]
+
+The power-controller module works well by adding its parent
+node secure-monitor.
+
+Fixes: 085f7a298a14 ("arm64: dts: add support for S4 power domain controller")
+Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20240412-fix-secpwr-s4-v2-1-3802fd936d77@amlogic.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+index ce90b35686a21..10896f9df682d 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+@@ -65,10 +65,15 @@ xtal: xtal-clk {
+ #clock-cells = <0>;
+ };
+
+- pwrc: power-controller {
+- compatible = "amlogic,meson-s4-pwrc";
+- #power-domain-cells = <1>;
+- status = "okay";
++ firmware {
++ sm: secure-monitor {
++ compatible = "amlogic,meson-gxbb-sm";
++
++ pwrc: power-controller {
++ compatible = "amlogic,meson-s4-pwrc";
++ #power-domain-cells = <1>;
++ };
++ };
+ };
+
+ soc {
+--
+2.43.0
+
--- /dev/null
+From 5062e16102214201d2d3c497889bccda82481fe0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 15:26:59 +0100
+Subject: coresight: etm4x: Do not hardcode IOMEM access for register restore
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit 1e7ba33fa591de1cf60afffcabb45600b3607025 ]
+
+When we restore the register state for ETM4x, while coming back
+from CPU idle, we hardcode IOMEM access. This is wrong and could
+blow up for an ETM with system instructions access (and for ETE).
+
+Fixes: f5bd523690d2 ("coresight: etm4x: Convert all register accesses")
+Reported-by: Yabin Cui <yabinc@google.com>
+Reviewed-by: Mike Leach <mike.leach@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Tested-by: Yabin Cui <yabinc@google.com>
+Link: https://lore.kernel.org/r/20240412142702.2882478-2-suzuki.poulose@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-etm4x-core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index f37f792d352eb..e267113698616 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -1847,8 +1847,10 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
+ {
+ int i;
+ struct etmv4_save_state *state = drvdata->save_state;
+- struct csdev_access tmp_csa = CSDEV_ACCESS_IOMEM(drvdata->base);
+- struct csdev_access *csa = &tmp_csa;
++ struct csdev_access *csa = &drvdata->csdev->access;
++
++ if (WARN_ON(!drvdata->csdev))
++ return;
+
+ etm4_cs_unlock(drvdata, csa);
+ etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
+--
+2.43.0
+
--- /dev/null
+From 3685aa7f962c0a4deb9db14f64053a8dc8992575 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 15:27:00 +0100
+Subject: coresight: etm4x: Do not save/restore Data trace control registers
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit 5eb3a0c2c52368cb9902e9a6ea04888e093c487d ]
+
+ETM4x doesn't support Data trace on A class CPUs. As such do not access the
+Data trace control registers during CPU idle. This could cause problems for
+ETE. While at it, remove all references to the Data trace control registers.
+
+Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU low power states")
+Reported-by: Yabin Cui <yabinc@google.com>
+Reviewed-by: Mike Leach <mike.leach@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Tested-by: Yabin Cui <yabinc@google.com>
+Link: https://lore.kernel.org/r/20240412142702.2882478-3-suzuki.poulose@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../coresight/coresight-etm4x-core.c | 6 ----
+ drivers/hwtracing/coresight/coresight-etm4x.h | 28 -------------------
+ 2 files changed, 34 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index e267113698616..85381f7831268 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -1743,9 +1743,6 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
+ state->trcvissctlr = etm4x_read32(csa, TRCVISSCTLR);
+ if (drvdata->nr_pe_cmp)
+ state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR);
+- state->trcvdctlr = etm4x_read32(csa, TRCVDCTLR);
+- state->trcvdsacctlr = etm4x_read32(csa, TRCVDSACCTLR);
+- state->trcvdarcctlr = etm4x_read32(csa, TRCVDARCCTLR);
+
+ for (i = 0; i < drvdata->nrseqstate - 1; i++)
+ state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i));
+@@ -1876,9 +1873,6 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
+ etm4x_relaxed_write32(csa, state->trcvissctlr, TRCVISSCTLR);
+ if (drvdata->nr_pe_cmp)
+ etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR);
+- etm4x_relaxed_write32(csa, state->trcvdctlr, TRCVDCTLR);
+- etm4x_relaxed_write32(csa, state->trcvdsacctlr, TRCVDSACCTLR);
+- etm4x_relaxed_write32(csa, state->trcvdarcctlr, TRCVDARCCTLR);
+
+ for (i = 0; i < drvdata->nrseqstate - 1; i++)
+ etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i));
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
+index da17b6c49b0f1..574dbaef50836 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x.h
++++ b/drivers/hwtracing/coresight/coresight-etm4x.h
+@@ -43,9 +43,6 @@
+ #define TRCVIIECTLR 0x084
+ #define TRCVISSCTLR 0x088
+ #define TRCVIPCSSCTLR 0x08C
+-#define TRCVDCTLR 0x0A0
+-#define TRCVDSACCTLR 0x0A4
+-#define TRCVDARCCTLR 0x0A8
+ /* Derived resources registers */
+ #define TRCSEQEVRn(n) (0x100 + (n * 4)) /* n = 0-2 */
+ #define TRCSEQRSTEVR 0x118
+@@ -90,9 +87,6 @@
+ /* Address Comparator registers n = 0-15 */
+ #define TRCACVRn(n) (0x400 + (n * 8))
+ #define TRCACATRn(n) (0x480 + (n * 8))
+-/* Data Value Comparator Value registers, n = 0-7 */
+-#define TRCDVCVRn(n) (0x500 + (n * 16))
+-#define TRCDVCMRn(n) (0x580 + (n * 16))
+ /* ContextID/Virtual ContextID comparators, n = 0-7 */
+ #define TRCCIDCVRn(n) (0x600 + (n * 8))
+ #define TRCVMIDCVRn(n) (0x640 + (n * 8))
+@@ -272,9 +266,6 @@
+ /* List of registers accessible via System instructions */
+ #define ETM4x_ONLY_SYSREG_LIST(op, val) \
+ CASE_##op((val), TRCPROCSELR) \
+- CASE_##op((val), TRCVDCTLR) \
+- CASE_##op((val), TRCVDSACCTLR) \
+- CASE_##op((val), TRCVDARCCTLR) \
+ CASE_##op((val), TRCOSLAR)
+
+ #define ETM_COMMON_SYSREG_LIST(op, val) \
+@@ -422,22 +413,6 @@
+ CASE_##op((val), TRCACATRn(13)) \
+ CASE_##op((val), TRCACATRn(14)) \
+ CASE_##op((val), TRCACATRn(15)) \
+- CASE_##op((val), TRCDVCVRn(0)) \
+- CASE_##op((val), TRCDVCVRn(1)) \
+- CASE_##op((val), TRCDVCVRn(2)) \
+- CASE_##op((val), TRCDVCVRn(3)) \
+- CASE_##op((val), TRCDVCVRn(4)) \
+- CASE_##op((val), TRCDVCVRn(5)) \
+- CASE_##op((val), TRCDVCVRn(6)) \
+- CASE_##op((val), TRCDVCVRn(7)) \
+- CASE_##op((val), TRCDVCMRn(0)) \
+- CASE_##op((val), TRCDVCMRn(1)) \
+- CASE_##op((val), TRCDVCMRn(2)) \
+- CASE_##op((val), TRCDVCMRn(3)) \
+- CASE_##op((val), TRCDVCMRn(4)) \
+- CASE_##op((val), TRCDVCMRn(5)) \
+- CASE_##op((val), TRCDVCMRn(6)) \
+- CASE_##op((val), TRCDVCMRn(7)) \
+ CASE_##op((val), TRCCIDCVRn(0)) \
+ CASE_##op((val), TRCCIDCVRn(1)) \
+ CASE_##op((val), TRCCIDCVRn(2)) \
+@@ -907,9 +882,6 @@ struct etmv4_save_state {
+ u32 trcviiectlr;
+ u32 trcvissctlr;
+ u32 trcvipcssctlr;
+- u32 trcvdctlr;
+- u32 trcvdsacctlr;
+- u32 trcvdarcctlr;
+
+ u32 trcseqevr[ETM_MAX_SEQ_STATES];
+ u32 trcseqrstevr;
+--
+2.43.0
+
--- /dev/null
+From c6f3bf16a68edfb7f77f3c98c20d39caa80fd5b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 15:27:02 +0100
+Subject: coresight: etm4x: Fix access to resource selector registers
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit d6fc00d0f640d6010b51054aa8b0fd191177dbc9 ]
+
+Resource selector pair 0 is always implemented and reserved. We must not
+touch it, even during save/restore for CPU Idle. Rest of the driver is
+well behaved. Fix the offending ones.
+
+Reported-by: Yabin Cui <yabinc@google.com>
+Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU low power states")
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Tested-by: Yabin Cui <yabinc@google.com>
+Reviewed-by: Mike Leach <mike.leach@linaro.org>
+Link: https://lore.kernel.org/r/20240412142702.2882478-5-suzuki.poulose@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-etm4x-core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index 4988503f68558..30e8a235242d5 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -1762,7 +1762,8 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
+ state->trccntvr[i] = etm4x_read32(csa, TRCCNTVRn(i));
+ }
+
+- for (i = 0; i < drvdata->nr_resource * 2; i++)
++ /* Resource selector pair 0 is reserved */
++ for (i = 2; i < drvdata->nr_resource * 2; i++)
+ state->trcrsctlr[i] = etm4x_read32(csa, TRCRSCTLRn(i));
+
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+@@ -1893,7 +1894,8 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
+ etm4x_relaxed_write32(csa, state->trccntvr[i], TRCCNTVRn(i));
+ }
+
+- for (i = 0; i < drvdata->nr_resource * 2; i++)
++ /* Resource selector pair 0 is reserved */
++ for (i = 2; i < drvdata->nr_resource * 2; i++)
+ etm4x_relaxed_write32(csa, state->trcrsctlr[i], TRCRSCTLRn(i));
+
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+--
+2.43.0
+
--- /dev/null
+From a82576951c5963eef8c37a2d4e804de44e323035 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 11:28:33 +0530
+Subject: coresight: etm4x: Fix unbalanced pm_runtime_enable()
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit caa41c47dab7e1054f587e592ab21296e3a6781c ]
+
+There is an unbalanced pm_runtime_enable() in etm4_probe_platform_dev()
+when etm4_probe() fails. This problem can be observed via the coresight
+etm4 module's (load -> unload -> load) sequence when etm4_probe() fails
+in etm4_probe_platform_dev().
+
+[ 63.379943] coresight-etm4x 7040000.etm: Unbalanced pm_runtime_enable!
+[ 63.393630] coresight-etm4x 7140000.etm: Unbalanced pm_runtime_enable!
+[ 63.407455] coresight-etm4x 7240000.etm: Unbalanced pm_runtime_enable!
+[ 63.420983] coresight-etm4x 7340000.etm: Unbalanced pm_runtime_enable!
+[ 63.420999] coresight-etm4x 7440000.etm: Unbalanced pm_runtime_enable!
+[ 63.441209] coresight-etm4x 7540000.etm: Unbalanced pm_runtime_enable!
+[ 63.454689] coresight-etm4x 7640000.etm: Unbalanced pm_runtime_enable!
+[ 63.474982] coresight-etm4x 7740000.etm: Unbalanced pm_runtime_enable!
+
+This fixes the above problem - with an explicit pm_runtime_disable() call
+when etm4_probe() fails during etm4_probe_platform_dev().
+
+Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Len Brown <lenb@kernel.org>
+Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: James Clark <james.clark@arm.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: linux-acpi@vger.kernel.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Cc: coresight@lists.linaro.org
+Fixes: 5214b563588e ("coresight: etm4x: Add support for sysreg only devices")
+Reviewed-by: James Clark <james.clark@arm.com>
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20240314055843.2625883-2-anshuman.khandual@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-etm4x-core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index 2e2cabc5f50ab..f37f792d352eb 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -2217,6 +2217,9 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
+ ret = etm4_probe(&pdev->dev);
+
+ pm_runtime_put(&pdev->dev);
++ if (ret)
++ pm_runtime_disable(&pdev->dev);
++
+ return ret;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 4384f8a572258d3e79fea07cc51af1db69f78015 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 15:27:01 +0100
+Subject: coresight: etm4x: Safe access for TRCQCLTR
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit 46bf8d7cd8530eca607379033b9bc4ac5590a0cd ]
+
+ETM4x implements TRCQCLTR only when the Q elements are supported
+and the Q element filtering is supported (TRCIDR0.QFILT). Access
+to the register otherwise could be fatal. Fix this by tracking the
+availability, like the others.
+
+Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU low power states")
+Reported-by: Yabin Cui <yabinc@google.com>
+Reviewed-by: Mike Leach <mike.leach@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Tested-by: Yabin Cui <yabinc@google.com>
+Link: https://lore.kernel.org/r/20240412142702.2882478-4-suzuki.poulose@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-etm4x-core.c | 8 ++++++--
+ drivers/hwtracing/coresight/coresight-etm4x.h | 3 +++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index 85381f7831268..4988503f68558 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -1244,6 +1244,8 @@ static void etm4_init_arch_data(void *info)
+ drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
+ /* QSUPP, bits[16:15] Q element support field */
+ drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
++ if (drvdata->q_support)
++ drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT);
+ /* TSSIZE, bits[28:24] Global timestamp size field */
+ drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
+
+@@ -1736,7 +1738,8 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
+ state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
+ state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
+ state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
+- state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
++ if (drvdata->q_filt)
++ state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
+
+ state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
+ state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR);
+@@ -1866,7 +1869,8 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
+ etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
+ etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
+ etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
+- etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
++ if (drvdata->q_filt)
++ etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
+
+ etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
+ etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR);
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
+index 574dbaef50836..6b6760e49ed35 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x.h
++++ b/drivers/hwtracing/coresight/coresight-etm4x.h
+@@ -135,6 +135,7 @@
+ #define TRCIDR0_TRCCCI BIT(7)
+ #define TRCIDR0_RETSTACK BIT(9)
+ #define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10)
++#define TRCIDR0_QFILT BIT(14)
+ #define TRCIDR0_QSUPP_MASK GENMASK(16, 15)
+ #define TRCIDR0_TSSIZE_MASK GENMASK(28, 24)
+
+@@ -954,6 +955,7 @@ struct etmv4_save_state {
+ * @os_unlock: True if access to management registers is allowed.
+ * @instrp0: Tracing of load and store instructions
+ * as P0 elements is supported.
++ * @q_filt: Q element filtering support, if Q elements are supported.
+ * @trcbb: Indicates if the trace unit supports branch broadcast tracing.
+ * @trccond: If the trace unit supports conditional
+ * instruction tracing.
+@@ -1017,6 +1019,7 @@ struct etmv4_drvdata {
+ bool boot_enable;
+ bool os_unlock;
+ bool instrp0;
++ bool q_filt;
+ bool trcbb;
+ bool trccond;
+ bool retstack;
+--
+2.43.0
+
--- /dev/null
+From ffa3ac5c1d5caf5e3d9c3e2d2d612802a1fc1d4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 21:05:11 -0800
+Subject: counter: linux/counter.h: fix Excess kernel-doc description warning
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 416bdb89605d960405178b9bf04df512d1ace1a3 ]
+
+Remove the @priv: line to prevent the kernel-doc warning:
+
+include/linux/counter.h:400: warning: Excess struct member 'priv' description in 'counter_device'
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Fixes: f2ee4759fb70 ("counter: remove old and now unused registration API")
+Link: https://lore.kernel.org/r/20231223050511.13849-1-rdunlap@infradead.org
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/counter.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/include/linux/counter.h b/include/linux/counter.h
+index 702e9108bbb44..b767b5c821f58 100644
+--- a/include/linux/counter.h
++++ b/include/linux/counter.h
+@@ -359,7 +359,6 @@ struct counter_ops {
+ * @num_counts: number of Counts specified in @counts
+ * @ext: optional array of Counter device extensions
+ * @num_ext: number of Counter device extensions specified in @ext
+- * @priv: optional private data supplied by driver
+ * @dev: internal device structure
+ * @chrdev: internal character device structure
+ * @events_list: list of current watching Counter events
+--
+2.43.0
+
--- /dev/null
+From b3445b27a10096082ebc0755616a11169aed5c90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 02:49:32 +0000
+Subject: dmaengine: idma64: Add check for dma_set_max_seg_size
+
+From: Chen Ni <nichen@iscas.ac.cn>
+
+[ Upstream commit 2b1c1cf08a0addb6df42f16b37133dc7a351de29 ]
+
+As the possible failure of the dma_set_max_seg_size(), it should be
+better to check the return value of the dma_set_max_seg_size().
+
+Fixes: e3fdb1894cfa ("dmaengine: idma64: set maximum allowed segment size for DMA")
+Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
+Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20240403024932.3342606-1-nichen@iscas.ac.cn
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idma64.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
+index 1398814d8fbb6..e3505e56784b1 100644
+--- a/drivers/dma/idma64.c
++++ b/drivers/dma/idma64.c
+@@ -598,7 +598,9 @@ static int idma64_probe(struct idma64_chip *chip)
+
+ idma64->dma.dev = chip->sysdev;
+
+- dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK);
++ ret = dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK);
++ if (ret)
++ return ret;
+
+ ret = dma_async_device_register(&idma64->dma);
+ if (ret)
+--
+2.43.0
+
--- /dev/null
+From 5acfd95f07a2dbe501f05a87e92853865d2f4366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jan 2024 17:39:54 -0800
+Subject: dmaengine: idxd: Avoid unnecessary destruction of file_ida
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 76e43fa6a456787bad31b8d0daeabda27351a480 ]
+
+file_ida is allocated during cdev open and is freed accordingly
+during cdev release. This sequence is guaranteed by driver file
+operations. Therefore, there is no need to destroy an already empty
+file_ida when the WQ cdev is removed.
+
+Worse, ida_free() in cdev release may happen after destruction of
+file_ida per WQ cdev. This can lead to accessing an id in file_ida
+after it has been destroyed, resulting in a kernel panic.
+
+Remove ida_destroy(&file_ida) to address these issues.
+
+Fixes: e6fd6d7e5f0f ("dmaengine: idxd: add a device to represent the file opened")
+Signed-off-by: Lijun Pan <lijun.pan@intel.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20240130013954.2024231-1-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/cdev.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
+index dcefb838b8c0f..73407e5775276 100644
+--- a/drivers/dma/idxd/cdev.c
++++ b/drivers/dma/idxd/cdev.c
+@@ -577,7 +577,6 @@ void idxd_wq_del_cdev(struct idxd_wq *wq)
+ struct idxd_cdev *idxd_cdev;
+
+ idxd_cdev = wq->idxd_cdev;
+- ida_destroy(&file_ida);
+ wq->idxd_cdev = NULL;
+ cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev));
+ put_device(cdev_dev(idxd_cdev));
+--
+2.43.0
+
--- /dev/null
+From e0b87046f752f632ec5d632be53fc87d4d7fb038 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 12:55:12 -0700
+Subject: drm/xe/guc: Check error code when initializing the CT mutex
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+[ Upstream commit b4abeb5545bb3ddcdda3c19067680ad0b2259be4 ]
+
+The initialization via drmm_mutex_init can fail, so we need to check the
+return code and escalate the failure.
+
+The mutex initialization has been moved after all the other init steps
+that can't fail, so we're always guaranteed to have those done and don't
+have to check in the cleanup code.
+
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Reviewed-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240321195512.274210-1-daniele.ceraolospurio@intel.com
+Stable-dep-of: c002bfe644a2 ("drm/xe: Use ordered WQ for G2H handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_ct.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c
+index 24a33fa36496a..006c6830b55a7 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ct.c
++++ b/drivers/gpu/drm/xe/xe_guc_ct.c
+@@ -138,13 +138,16 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
+
+ xe_assert(xe, !(guc_ct_size() % PAGE_SIZE));
+
+- drmm_mutex_init(&xe->drm, &ct->lock);
+ spin_lock_init(&ct->fast_lock);
+ xa_init(&ct->fence_lookup);
+ INIT_WORK(&ct->g2h_worker, g2h_worker_func);
+ init_waitqueue_head(&ct->wq);
+ init_waitqueue_head(&ct->g2h_fence_wq);
+
++ err = drmm_mutex_init(&xe->drm, &ct->lock);
++ if (err)
++ return err;
++
+ primelockdep(ct);
+
+ bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
+--
+2.43.0
+
--- /dev/null
+From d430e04a614582ebc96d24ddbb01f0624b3fbb30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jan 2024 12:35:38 -0800
+Subject: drm/xe/guc: Only take actions in CT irq handler if CTs are enabled
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 5030e16140b655ba00217d47680e697480ac3587 ]
+
+Protect entire IRQ handler by CT being enabled rather than just G2H
+handler.
+
+v2: Return on not enabled in CT irq handler (Michal)
+
+Suggested-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Stable-dep-of: c002bfe644a2 ("drm/xe: Use ordered WQ for G2H handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_ct.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_ct.h b/drivers/gpu/drm/xe/xe_guc_ct.h
+index f15f8a4857e07..9ecb67db8ec40 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ct.h
++++ b/drivers/gpu/drm/xe/xe_guc_ct.h
+@@ -24,9 +24,11 @@ void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p, bool atomic);
+
+ static inline void xe_guc_ct_irq_handler(struct xe_guc_ct *ct)
+ {
++ if (!ct->enabled)
++ return;
++
+ wake_up_all(&ct->wq);
+- if (ct->enabled)
+- queue_work(system_unbound_wq, &ct->g2h_worker);
++ queue_work(system_unbound_wq, &ct->g2h_worker);
+ xe_guc_ct_fast_path(ct);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 95ad221bf81e254480d050b9df5fda71170189cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 May 2024 20:47:58 -0700
+Subject: drm/xe: Use ordered WQ for G2H handler
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit c002bfe644a29ba600c571f2abba13a155a12dcd ]
+
+System work queues are shared, use a dedicated work queue for G2H
+processing to avoid G2H processing getting block behind system tasks.
+
+Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Francois Dugast <francois.dugast@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240506034758.3697397-1-matthew.brost@intel.com
+(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_ct.c | 5 +++++
+ drivers/gpu/drm/xe/xe_guc_ct.h | 2 +-
+ drivers/gpu/drm/xe/xe_guc_ct_types.h | 2 ++
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c
+index 006c6830b55a7..917082af197cd 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ct.c
++++ b/drivers/gpu/drm/xe/xe_guc_ct.c
+@@ -113,6 +113,7 @@ static void guc_ct_fini(struct drm_device *drm, void *arg)
+ {
+ struct xe_guc_ct *ct = arg;
+
++ destroy_workqueue(ct->g2h_wq);
+ xa_destroy(&ct->fence_lookup);
+ }
+
+@@ -138,6 +139,10 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
+
+ xe_assert(xe, !(guc_ct_size() % PAGE_SIZE));
+
++ ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
++ if (!ct->g2h_wq)
++ return -ENOMEM;
++
+ spin_lock_init(&ct->fast_lock);
+ xa_init(&ct->fence_lookup);
+ INIT_WORK(&ct->g2h_worker, g2h_worker_func);
+diff --git a/drivers/gpu/drm/xe/xe_guc_ct.h b/drivers/gpu/drm/xe/xe_guc_ct.h
+index 9ecb67db8ec40..86b67b775eaba 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ct.h
++++ b/drivers/gpu/drm/xe/xe_guc_ct.h
+@@ -28,7 +28,7 @@ static inline void xe_guc_ct_irq_handler(struct xe_guc_ct *ct)
+ return;
+
+ wake_up_all(&ct->wq);
+- queue_work(system_unbound_wq, &ct->g2h_worker);
++ queue_work(ct->g2h_wq, &ct->g2h_worker);
+ xe_guc_ct_fast_path(ct);
+ }
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_ct_types.h b/drivers/gpu/drm/xe/xe_guc_ct_types.h
+index d814d4ee3fc65..bd945ed3ee41e 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ct_types.h
++++ b/drivers/gpu/drm/xe/xe_guc_ct_types.h
+@@ -106,6 +106,8 @@ struct xe_guc_ct {
+ wait_queue_head_t wq;
+ /** @g2h_fence_wq: wait queue used for G2H fencing */
+ wait_queue_head_t g2h_fence_wq;
++ /** @g2h_wq: used to process G2H */
++ struct workqueue_struct *g2h_wq;
+ /** @msg: Message buffer */
+ u32 msg[GUC_CTB_MSG_MAX_LEN];
+ /** @fast_msg: Message buffer */
+--
+2.43.0
+
--- /dev/null
+From a1aa10c97eb060fbfd714305d16216dfeb29244f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Apr 2024 17:42:12 +0200
+Subject: dt-bindings: adc: axi-adc: add clocks property
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit 19fb11d7220b8abc016aa254dc7e6d9f2d49b178 ]
+
+Add a required clock property as we can't access the device registers if
+the AXI bus clock is not properly enabled.
+
+Note this clock is a very fundamental one that is typically enabled
+pretty early during boot. Independently of that, we should really rely on
+it to be enabled.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Fixes: 96553a44e96d ("dt-bindings: iio: adc: add bindings doc for AXI ADC driver")
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20240426-ad9467-new-features-v2-3-6361fc3ba1cc@analog.com
+Cc: <Stable@ver.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
+index 3d49d21ad33df..e1f450b80db27 100644
+--- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
++++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
+@@ -28,6 +28,9 @@ properties:
+ reg:
+ maxItems: 1
+
++ clocks:
++ maxItems: 1
++
+ dmas:
+ maxItems: 1
+
+@@ -48,6 +51,7 @@ required:
+ - compatible
+ - dmas
+ - reg
++ - clocks
+
+ additionalProperties: false
+
+@@ -58,6 +62,7 @@ examples:
+ reg = <0x44a00000 0x10000>;
+ dmas = <&rx_dma 0>;
+ dma-names = "rx";
++ clocks = <&axi_clk>;
+ #io-backend-cells = <0>;
+ };
+ ...
+--
+2.43.0
+
--- /dev/null
+From ecc0c506e87fbaccf3796fd478246a5476173beb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 21:57:14 +0100
+Subject: dt-bindings: adc: axi-adc: update bindings for backend framework
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit a032b921bdeba2274866daafc8e791edd609eb13 ]
+
+'adi,adc-dev' is now deprecated and must not be used anymore. Hence,
+also remove it from being required.
+
+The reason why it's being deprecated is because the axi-adc CORE is now
+an IIO service provider hardware (IIO backends) for consumers to make use
+of. Before, the logic with 'adi,adc-dev' was the opposite (it was kind
+of consumer referencing other nodes/devices) and that proved to be wrong
+and to not scale.
+
+Now, IIO consumers of this hardware are expected to reference it using the
+io-backends property. Hence, the new '#io-backend-cells' is being added
+so the device is easily identified as a provider.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20240210-iio-backend-v11-2-f5242a5fb42a@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 19fb11d7220b ("dt-bindings: adc: axi-adc: add clocks property")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/iio/adc/adi,axi-adc.yaml | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
+index 9996dd93f84b2..3d49d21ad33df 100644
+--- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
++++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
+@@ -39,12 +39,15 @@ properties:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ A reference to a the actual ADC to which this FPGA ADC interfaces to.
++ deprecated: true
++
++ '#io-backend-cells':
++ const: 0
+
+ required:
+ - compatible
+ - dmas
+ - reg
+- - adi,adc-dev
+
+ additionalProperties: false
+
+@@ -55,7 +58,6 @@ examples:
+ reg = <0x44a00000 0x10000>;
+ dmas = <&rx_dma 0>;
+ dma-names = "rx";
+-
+- adi,adc-dev = <&spi_adc>;
++ #io-backend-cells = <0>;
+ };
+ ...
+--
+2.43.0
+
--- /dev/null
+From 55e686e04cc48a334b94d6e63de47f46eb5e7b28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 16:52:01 +0100
+Subject: dt-bindings: PCI: rcar-pci-host: Add missing IOMMU properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 78d212851f0e56b7d7083c4d5014aa7fa8b77e20 ]
+
+make dtbs_check:
+
+ arch/arm64/boot/dts/renesas/r8a77951-salvator-xs.dtb: pcie@fe000000: Unevaluated properties are not allowed ('iommu-map', 'iommu-map-mask' were unexpected)
+ from schema $id: http://devicetree.org/schemas/pci/rcar-pci-host.yaml#
+
+Fix this by adding the missing IOMMU-related properties.
+
+[kwilczynski: added missing Fixes: tag]
+Fixes: 0d69ce3c2c63 ("dt-bindings: PCI: rcar-pci-host: Convert bindings to json-schema")
+Link: https://lore.kernel.org/linux-pci/babc878a93cb6461a5d39331f8ecfa654dfda921.1706802597.git.geert+renesas@glider.be
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/pci/rcar-pci-host.yaml | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml b/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml
+index b6a7cb32f61e5..835b6db00c279 100644
+--- a/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml
++++ b/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml
+@@ -77,6 +77,9 @@ properties:
+ vpcie12v-supply:
+ description: The 12v regulator to use for PCIe.
+
++ iommu-map: true
++ iommu-map-mask: true
++
+ required:
+ - compatible
+ - reg
+--
+2.43.0
+
--- /dev/null
+From 6754a4579d3af6993353daeb4f9bb9e12d6e9bb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Apr 2024 12:00:58 +0200
+Subject: dt-bindings: PCI: rockchip,rk3399-pcie: Add missing maxItems to
+ ep-gpios
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 52d06636a4ae4db24ebfe23fae7a525f7e983604 ]
+
+Properties with GPIOs should define number of actual GPIOs, so add
+missing maxItems to ep-gpios. Otherwise multiple GPIOs could be
+provided which is not a true hardware description.
+
+Fixes: aa222f9311e1 ("dt-bindings: PCI: Convert Rockchip RK3399 PCIe to DT schema")
+Link: https://lore.kernel.org/linux-pci/20240401100058.15749-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml
+index 531008f0b6ac3..002b728cbc718 100644
+--- a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml
++++ b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml
+@@ -37,6 +37,7 @@ properties:
+ description: This property is needed if using 24MHz OSC for RC's PHY.
+
+ ep-gpios:
++ maxItems: 1
+ description: pre-reset GPIO
+
+ vpcie12v-supply:
+--
+2.43.0
+
--- /dev/null
+From 1603af7b588df0be2edd0285d3e14065bea35921 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 May 2024 19:19:28 +0300
+Subject: dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68]
+ power-domains
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 59e377a124dc9039d9554d823b1cb4942bcee9a0 ]
+
+The Qualcomm MSM8996 and MSM8998 platforms don't have separate power
+domain for the UFS PHY. Replace required:power-domains with the
+conditional schema.
+
+Fixes: dc5cb63592bd ("dt-bindings: phy: migrate QMP UFS PHY bindings to qcom,sc8280xp-qmp-ufs-phy.yaml")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240501-qcom-phy-fixes-v1-2-f1fd15c33fb3@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+index 8474eef8d0ff5..b2bae42134a29 100644
+--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
++++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+@@ -73,7 +73,6 @@ required:
+ - reg
+ - clocks
+ - clock-names
+- - power-domains
+ - resets
+ - reset-names
+ - vdda-phy-supply
+@@ -134,6 +133,21 @@ allOf:
+ clock-names:
+ maxItems: 1
+
++ - if:
++ properties:
++ compatible:
++ contains:
++ enum:
++ - qcom,msm8996-qmp-ufs-phy
++ - qcom,msm8998-qmp-ufs-phy
++ then:
++ properties:
++ power-domains:
++ false
++ else:
++ required:
++ - power-domains
++
+ additionalProperties: false
+
+ examples:
+--
+2.43.0
+
--- /dev/null
+From 14f10f92a7924eac85292a42ac82e8d7e9c1e7f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 May 2024 19:19:29 +0300
+Subject: dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for
+ sc8180x
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 960b3f023d3bda0efd6e573a0647227d1115d266 ]
+
+The qcom,sc8180x-usb-hs-phy device uses qcom,usb-snps-hs-7nm-phy
+fallback. Correct the schema for this platform.
+
+Fixes: 9160fb7c39a1 ("dt-bindings: phy: qcom,usb-snps-femto-v2: use fallback compatibles")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240501-qcom-phy-fixes-v1-3-f1fd15c33fb3@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
+index 0f200e3f97a9a..fce7f8a19e9c0 100644
+--- a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
++++ b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
+@@ -15,9 +15,6 @@ description: |
+ properties:
+ compatible:
+ oneOf:
+- - enum:
+- - qcom,sc8180x-usb-hs-phy
+- - qcom,usb-snps-femto-v2-phy
+ - items:
+ - enum:
+ - qcom,sa8775p-usb-hs-phy
+@@ -26,6 +23,7 @@ properties:
+ - items:
+ - enum:
+ - qcom,sc7280-usb-hs-phy
++ - qcom,sc8180x-usb-hs-phy
+ - qcom,sdx55-usb-hs-phy
+ - qcom,sdx65-usb-hs-phy
+ - qcom,sm6375-usb-hs-phy
+--
+2.43.0
+
--- /dev/null
+From a1f0655ae2fcc7b3fe89260aaf7c1afc9211951a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 06:55:01 +0200
+Subject: dt-bindings: pinctrl: mediatek: mt7622: fix array properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 61fcbbf3ca038c048c942ce31bb3d3c846c87581 ]
+
+Some properties (function groups & pins) are meant to be arrays and
+should allow multiple entries out of enum sets. Use "items" for those.
+
+Mistake was noticed during validation of in-kernel DTS files.
+
+Fixes: b9ffc18c6388 ("dt-bindings: mediatek: convert pinctrl to yaml")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Rob Herring <robh@kernel.org>
+Message-ID: <20240423045502.7778-1-zajec5@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pinctrl/mediatek,mt7622-pinctrl.yaml | 92 ++++++++++---------
+ 1 file changed, 49 insertions(+), 43 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
+index bd72a326e6e06..60f30a59f3853 100644
+--- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
+@@ -97,7 +97,8 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [emmc, emmc_rst]
++ items:
++ enum: [emmc, emmc_rst]
+ - if:
+ properties:
+ function:
+@@ -105,8 +106,9 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
+- rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
++ items:
++ enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
++ rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
+ - if:
+ properties:
+ function:
+@@ -123,10 +125,11 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
+- i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
+- i2s1_out_data, i2s2_out_data, i2s3_out_data,
+- i2s4_out_data]
++ items:
++ enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
++ i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
++ i2s1_out_data, i2s2_out_data, i2s3_out_data,
++ i2s4_out_data]
+ - if:
+ properties:
+ function:
+@@ -159,10 +162,11 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
+- pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
+- pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
+- pcie_wake, pcie_clkreq]
++ items:
++ enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
++ pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
++ pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
++ pcie_wake, pcie_clkreq]
+ - if:
+ properties:
+ function:
+@@ -178,11 +182,12 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
+- pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
+- pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
+- pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
+- pwm_ch7_0, pwm_0, pwm_1]
++ items:
++ enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
++ pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
++ pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
++ pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
++ pwm_ch7_0, pwm_0, pwm_1]
+ - if:
+ properties:
+ function:
+@@ -260,33 +265,34 @@ patternProperties:
+ pins:
+ description:
+ An array of strings. Each string contains the name of a pin.
+- enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
+- RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
+- I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
+- I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
+- G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
+- G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
+- NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
+- MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
+- MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
+- MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
+- MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
+- PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
+- GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
+- PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
+- AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
+- PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
+- WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
+- WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
+- EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
+- EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
+- WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
+- UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
+- UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
+- PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
+- GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
+- TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
+- WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
++ items:
++ enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
++ RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
++ I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
++ I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
++ G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
++ G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
++ NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
++ MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
++ MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
++ MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
++ MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
++ PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
++ GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
++ PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
++ AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
++ PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
++ WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
++ WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
++ EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
++ EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
++ WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
++ UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
++ UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
++ PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
++ GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
++ TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
++ WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
+
+ bias-disable: true
+
+--
+2.43.0
+
--- /dev/null
+From 8d9ca9ac62b93af0a43e15fd70041ed3cad8d45e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 10:58:07 +0800
+Subject: dt-bindings: pinctrl: qcom: update functions to match with driver
+
+From: Tengfei Fan <quic_tengfan@quicinc.com>
+
+[ Upstream commit 842ecb5fcf8de17dfde11d4ec5f41930f0076887 ]
+
+Some functions were consolidated in the SM4450 pinctrl driver, but they
+had not been updated in the binding file before the previous SM4450
+pinctrl patch series was merged.
+Update functions in this binding file to match with SM4450 pinctrl
+driver. Some functions need to be consolidated and some functions need
+to be removed.
+The following functions are removed:
+ - atest_char0, atest_char1, atest_char2, atest_char3
+ - atest_usb00, atest_usb01, atest_usb02, atest_usb03
+ - audio_ref
+ - cci_async
+ - cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4
+ - cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3
+ - coex_uart1
+ - cri_trng0, cri_trng1
+ - dbg_out
+ - ddr_pxi0, ddr_pxi1
+ - dp0_hot
+ - gcc_gp1, gcc_gp2, gcc_gp3
+ - ibi_i3c
+ - jitter_bist
+ - mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3
+ - mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws, mi2s2_data0,
+ mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0, mi2s_mclk1
+ - nav_gpio0, nav_gpio1, nav_gpio2
+ - phase_flag0, phase_flag1, phase_flag10, phase_flag11, phase_flag12,
+ phase_flag13, phase_flag14, phase_flag15, phase_flag16,
+ phase_flag17, phase_flag18, phase_flag19, phase_flag2, phase_flag20,
+ phase_flag21, phase_flag22, phase_flag23, phase_flag24,
+ phase_flag25, phase_flag26, phase_flag27, phase_flag28,
+ phase_flag29, phase_flag3, phase_flag30, phase_flag31, phase_flag4,
+ phase_flag5, phase_flag6, phase_flag7, phase_flag8, phase_flag9
+ - pll_bist, pll_clk
+ - prng_rosc0, prng_rosc1, prng_rosc2, prng_rosc3
+ - qdss_gpio0, qdss_gpio1, qdss_gpio10, qdss_gpio11, qdss_gpio12,
+ qdss_gpio13, qdss_gpio14, qdss_gpio15, qdss_gpio2, qdss_gpio3,
+ qdss_gpio4, qdss_gpio5, qdss_gpio6, qdss_gpio7, qdss_gpio8,
+ qdss_gpio9
+ - qlink0_wmss
+ - qup0_se5, qup0_se6, qup0_se7, qup1_se5, qup1_se6
+ - sd_write
+ - tb_trig
+ - tgu_ch0, tgu_ch1, tgu_ch2, tgu_ch3
+ - tmess_prng0, tmess_prng1, tmess_prng2, tmess_prng3
+ - tsense_pwm1, tsense_pwm2
+ - uim0_clk, uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
+ uim1_present, uim1_reset
+ - usb0_hs, usb0_phy
+ - vsense_trigger
+
+The following functions are added:
+ - atest_char
+ - atest_usb0
+ - audio_ref_clk
+ - cci
+ - cci_async_in0
+ - cmu_rng
+ - coex_uart1_rx, coex_uart1_tx
+ - dbg_out_clk
+ - ddr_pxi0_test, ddr_pxi1_test
+ - gcc_gp1_clk, gcc_gp2_clk, gcc_gp3_clk
+ - ibi_i3c_qup0, ibi_i3c_qup1
+ - jitter_bist_ref
+ - mdp_vsync
+ - nav
+ - phase_flag
+ - pll_bist_sync, pll_clk_aux
+ - prng_rosc
+ - qlink0_wmss_reset
+ - sd_write_protect
+ - tb_trig_sdc1, tb_trig_sdc2
+ - tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout, tgu_ch3_trigout
+ - tmess_prng
+ - tsense_pwm1_out, tsense_pwm2_out
+ - uim0, uim1
+ - usb0_hs_ac, usb0_phy_ps
+ - vsense_trigger_mirnat
+ - wlan1_adc_dtest0, wlan1_adc_dtest1
+
+Fixes: 7bf8b78f86db ("dt-bindings: pinctrl: qcom: Add SM4450 pinctrl")
+Signed-off-by: Tengfei Fan <quic_tengfan@quicinc.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Message-ID: <20240312025807.26075-3-quic_tengfan@quicinc.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bindings/pinctrl/qcom,sm4450-tlmm.yaml | 52 +++++++------------
+ 1 file changed, 18 insertions(+), 34 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml
+index bb08ca5a1509e..53d59b641bf78 100644
+--- a/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml
+@@ -72,40 +72,24 @@ $defs:
+ description:
+ Specify the alternative function to be configured for the specified
+ pins.
+- enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2,
+- atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02,
+- atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c,
+- cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4,
+- cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng,
+- cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
+- dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c,
+- jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2,
+- mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws,
+- mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0,
+- mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk,
+- phase_flag0, phase_flag1, phase_flag10, phase_flag11,
+- phase_flag12, phase_flag13, phase_flag14, phase_flag15,
+- phase_flag16, phase_flag17, phase_flag18, phase_flag19,
+- phase_flag2, phase_flag20, phase_flag21, phase_flag22,
+- phase_flag23, phase_flag24, phase_flag25, phase_flag26,
+- phase_flag27, phase_flag28, phase_flag29, phase_flag3,
+- phase_flag30, phase_flag31, phase_flag4, phase_flag5,
+- phase_flag6, phase_flag7, phase_flag8, phase_flag9,
+- pll_bist, pll_clk, prng_rosc0, prng_rosc1, prng_rosc2,
+- prng_rosc3, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1,
+- qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
+- qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5,
+- qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable,
+- qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request,
+- qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss,
+- qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
+- qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3,
+- qup1_se4, qup1_se5, qup1_se6, sd_write, tb_trig, tgu_ch0,
+- tgu_ch1, tgu_ch2, tgu_ch3, tmess_prng0, tmess_prng1,
+- tmess_prng2, tmess_prng3, tsense_pwm1, tsense_pwm2, uim0_clk,
+- uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
+- uim1_present, uim1_reset, usb0_hs, usb0_phy, vfr_0, vfr_1,
+- vsense_trigger ]
++ enum: [ gpio, atest_char, atest_usb0, audio_ref_clk, cam_mclk,
++ cci_async_in0, cci_i2c, cci, cmu_rng, coex_uart1_rx,
++ coex_uart1_tx, cri_trng, dbg_out_clk, ddr_bist,
++ ddr_pxi0_test, ddr_pxi1_test, gcc_gp1_clk, gcc_gp2_clk,
++ gcc_gp3_clk, host2wlan_sol, ibi_i3c_qup0, ibi_i3c_qup1,
++ jitter_bist_ref, mdp_vsync0_out, mdp_vsync1_out,
++ mdp_vsync2_out, mdp_vsync3_out, mdp_vsync, nav,
++ pcie0_clk_req, phase_flag, pll_bist_sync, pll_clk_aux,
++ prng_rosc, qdss_cti_trig0, qdss_cti_trig1, qdss_gpio,
++ qlink0_enable, qlink0_request, qlink0_wmss_reset,
++ qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4,
++ qup1_se0, qup1_se1, qup1_se2, qup1_se2_l2, qup1_se3,
++ qup1_se4, sd_write_protect, tb_trig_sdc1, tb_trig_sdc2,
++ tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout,
++ tgu_ch3_trigout, tmess_prng, tsense_pwm1_out,
++ tsense_pwm2_out, uim0, uim1, usb0_hs_ac, usb0_phy_ps,
++ vfr_0_mira, vfr_0_mirb, vfr_1, vsense_trigger_mirnat,
++ wlan1_adc_dtest0, wlan1_adc_dtest1 ]
+
+ required:
+ - pins
+--
+2.43.0
+
--- /dev/null
+From 3377da3377094a688bd40389a8cdb0432eb8ee5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 10:34:52 -0500
+Subject: eventfs: Create eventfs_root_inode to store dentry
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit c3137ab6318d56370dd5541ebf027ddfc0c8557c ]
+
+Only the root "events" directory stores a dentry. There's no reason to
+hold a dentry pointer for every eventfs_inode as it is never set except
+for the root "events" eventfs_inode.
+
+Create a eventfs_root_inode structure that holds the events_dir dentry.
+The "events" eventfs_inode *is* special, let it have its own descriptor.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240201161617.658992558@goodmis.org
+
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Al Viro <viro@ZenIV.linux.org.uk>
+Cc: Ajay Kaher <ajay.kaher@broadcom.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: b63db58e2fa5 ("eventfs/tracing: Add callback for release of an eventfs_inode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/tracefs/event_inode.c | 65 +++++++++++++++++++++++++++++++++-------
+ fs/tracefs/internal.h | 2 --
+ 2 files changed, 55 insertions(+), 12 deletions(-)
+
+diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
+index 56d1741fe0413..59099b36e9a91 100644
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -35,6 +35,17 @@ static DEFINE_MUTEX(eventfs_mutex);
+ /* Choose something "unique" ;-) */
+ #define EVENTFS_FILE_INODE_INO 0x12c4e37
+
++struct eventfs_root_inode {
++ struct eventfs_inode ei;
++ struct dentry *events_dir;
++};
++
++static struct eventfs_root_inode *get_root_inode(struct eventfs_inode *ei)
++{
++ WARN_ON_ONCE(!ei->is_events);
++ return container_of(ei, struct eventfs_root_inode, ei);
++}
++
+ /* Just try to make something consistent and unique */
+ static int eventfs_dir_ino(struct eventfs_inode *ei)
+ {
+@@ -73,12 +84,18 @@ enum {
+ static void release_ei(struct kref *ref)
+ {
+ struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
++ struct eventfs_root_inode *rei;
+
+ WARN_ON_ONCE(!ei->is_freed);
+
+ kfree(ei->entry_attrs);
+ kfree_const(ei->name);
+- kfree_rcu(ei, rcu);
++ if (ei->is_events) {
++ rei = get_root_inode(ei);
++ kfree_rcu(rei, ei.rcu);
++ } else {
++ kfree_rcu(ei, rcu);
++ }
+ }
+
+ static inline void put_ei(struct eventfs_inode *ei)
+@@ -423,19 +440,43 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry,
+ return NULL;
+ }
+
++static inline struct eventfs_inode *init_ei(struct eventfs_inode *ei, const char *name)
++{
++ ei->name = kstrdup_const(name, GFP_KERNEL);
++ if (!ei->name)
++ return NULL;
++ kref_init(&ei->kref);
++ return ei;
++}
++
+ static inline struct eventfs_inode *alloc_ei(const char *name)
+ {
+ struct eventfs_inode *ei = kzalloc(sizeof(*ei), GFP_KERNEL);
++ struct eventfs_inode *result;
+
+ if (!ei)
+ return NULL;
+
+- ei->name = kstrdup_const(name, GFP_KERNEL);
+- if (!ei->name) {
++ result = init_ei(ei, name);
++ if (!result)
+ kfree(ei);
++
++ return result;
++}
++
++static inline struct eventfs_inode *alloc_root_ei(const char *name)
++{
++ struct eventfs_root_inode *rei = kzalloc(sizeof(*rei), GFP_KERNEL);
++ struct eventfs_inode *ei;
++
++ if (!rei)
+ return NULL;
+- }
+- kref_init(&ei->kref);
++
++ rei->ei.is_events = 1;
++ ei = init_ei(&rei->ei, name);
++ if (!ei)
++ kfree(rei);
++
+ return ei;
+ }
+
+@@ -724,6 +765,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ int size, void *data)
+ {
+ struct dentry *dentry = tracefs_start_creating(name, parent);
++ struct eventfs_root_inode *rei;
+ struct eventfs_inode *ei;
+ struct tracefs_inode *ti;
+ struct inode *inode;
+@@ -736,7 +778,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ if (IS_ERR(dentry))
+ return ERR_CAST(dentry);
+
+- ei = alloc_ei(name);
++ ei = alloc_root_ei(name);
+ if (!ei)
+ goto fail;
+
+@@ -745,10 +787,11 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ goto fail;
+
+ // Note: we have a ref to the dentry from tracefs_start_creating()
+- ei->events_dir = dentry;
++ rei = get_root_inode(ei);
++ rei->events_dir = dentry;
++
+ ei->entries = entries;
+ ei->nr_entries = size;
+- ei->is_events = 1;
+ ei->data = data;
+
+ /* Save the ownership of this directory */
+@@ -859,13 +902,15 @@ void eventfs_remove_dir(struct eventfs_inode *ei)
+ */
+ void eventfs_remove_events_dir(struct eventfs_inode *ei)
+ {
++ struct eventfs_root_inode *rei;
+ struct dentry *dentry;
+
+- dentry = ei->events_dir;
++ rei = get_root_inode(ei);
++ dentry = rei->events_dir;
+ if (!dentry)
+ return;
+
+- ei->events_dir = NULL;
++ rei->events_dir = NULL;
+ eventfs_remove_dir(ei);
+
+ /*
+diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
+index 824cbe83679cc..29f0c999975b6 100644
+--- a/fs/tracefs/internal.h
++++ b/fs/tracefs/internal.h
+@@ -40,7 +40,6 @@ struct eventfs_attr {
+ * @children: link list into the child eventfs_inode
+ * @entries: the array of entries representing the files in the directory
+ * @name: the name of the directory to create
+- * @events_dir: the dentry of the events directory
+ * @entry_attrs: Saved mode and ownership of the @d_children
+ * @data: The private data to pass to the callbacks
+ * @attr: Saved mode and ownership of eventfs_inode itself
+@@ -58,7 +57,6 @@ struct eventfs_inode {
+ struct list_head children;
+ const struct eventfs_entry *entries;
+ const char *name;
+- struct dentry *events_dir;
+ struct eventfs_attr *entry_attrs;
+ void *data;
+ struct eventfs_attr attr;
+--
+2.43.0
+
--- /dev/null
+From eb94f917ba14165b86b4e3dc7ad94cbf0867ec17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 16:08:25 -0400
+Subject: eventfs: Do not differentiate the toplevel events directory
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit d53891d348ac3eceaf48f4732a1f4f5c0e0a55ce ]
+
+The toplevel events directory is really no different than the events
+directory of instances. Having the two be different caused
+inconsistencies and made it harder to fix the permissions bugs.
+
+Make all events directories act the same.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240502200905.846448710@goodmis.org
+
+Cc: stable@vger.kernel.org
+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>
+Fixes: 8186fff7ab649 ("tracefs/eventfs: Use root and instance inodes as default ownership")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/tracefs/event_inode.c | 29 ++++++++---------------------
+ fs/tracefs/internal.h | 7 +++----
+ 2 files changed, 11 insertions(+), 25 deletions(-)
+
+diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
+index db869e52aa5cc..fd111e10f04e4 100644
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -68,7 +68,6 @@ enum {
+ EVENTFS_SAVE_MODE = BIT(16),
+ EVENTFS_SAVE_UID = BIT(17),
+ EVENTFS_SAVE_GID = BIT(18),
+- EVENTFS_TOPLEVEL = BIT(19),
+ };
+
+ #define EVENTFS_MODE_MASK (EVENTFS_SAVE_MODE - 1)
+@@ -225,14 +224,10 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
+ return ret;
+ }
+
+-static void update_top_events_attr(struct eventfs_inode *ei, struct super_block *sb)
++static void update_events_attr(struct eventfs_inode *ei, struct super_block *sb)
+ {
+ struct inode *root;
+
+- /* Only update if the "events" was on the top level */
+- if (!ei || !(ei->attr.mode & EVENTFS_TOPLEVEL))
+- return;
+-
+ /* Get the tracefs root inode. */
+ root = d_inode(sb->s_root);
+ ei->attr.uid = root->i_uid;
+@@ -245,10 +240,10 @@ static void set_top_events_ownership(struct inode *inode)
+ struct eventfs_inode *ei = ti->private;
+
+ /* The top events directory doesn't get automatically updated */
+- if (!ei || !ei->is_events || !(ei->attr.mode & EVENTFS_TOPLEVEL))
++ if (!ei || !ei->is_events)
+ return;
+
+- update_top_events_attr(ei, inode->i_sb);
++ update_events_attr(ei, inode->i_sb);
+
+ if (!(ei->attr.mode & EVENTFS_SAVE_UID))
+ inode->i_uid = ei->attr.uid;
+@@ -277,7 +272,7 @@ static int eventfs_permission(struct mnt_idmap *idmap,
+ return generic_permission(idmap, inode, mask);
+ }
+
+-static const struct inode_operations eventfs_root_dir_inode_operations = {
++static const struct inode_operations eventfs_dir_inode_operations = {
+ .lookup = eventfs_root_lookup,
+ .setattr = eventfs_set_attr,
+ .getattr = eventfs_get_attr,
+@@ -345,7 +340,7 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry)
+ // Walk upwards until you find the events inode
+ } while (!ei->is_events);
+
+- update_top_events_attr(ei, dentry->d_sb);
++ update_events_attr(ei, dentry->d_sb);
+
+ return ei;
+ }
+@@ -449,7 +444,7 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry,
+ update_inode_attr(dentry, inode, &ei->attr,
+ S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+
+- inode->i_op = &eventfs_root_dir_inode_operations;
++ inode->i_op = &eventfs_dir_inode_operations;
+ inode->i_fop = &eventfs_file_operations;
+
+ /* All directories will have the same inode number */
+@@ -824,14 +819,6 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ uid = d_inode(dentry->d_parent)->i_uid;
+ gid = d_inode(dentry->d_parent)->i_gid;
+
+- /*
+- * If the events directory is of the top instance, then parent
+- * is NULL. Set the attr.mode to reflect this and its permissions will
+- * default to the tracefs root dentry.
+- */
+- if (!parent)
+- ei->attr.mode = EVENTFS_TOPLEVEL;
+-
+ /* This is used as the default ownership of the files and directories */
+ ei->attr.uid = uid;
+ ei->attr.gid = gid;
+@@ -840,13 +827,13 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ INIT_LIST_HEAD(&ei->list);
+
+ ti = get_tracefs(inode);
+- ti->flags |= TRACEFS_EVENT_INODE | TRACEFS_EVENT_TOP_INODE;
++ ti->flags |= TRACEFS_EVENT_INODE;
+ ti->private = ei;
+
+ inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ inode->i_uid = uid;
+ inode->i_gid = gid;
+- inode->i_op = &eventfs_root_dir_inode_operations;
++ inode->i_op = &eventfs_dir_inode_operations;
+ inode->i_fop = &eventfs_file_operations;
+
+ dentry->d_fsdata = get_ei(ei);
+diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
+index 29f0c999975b6..f704d8348357e 100644
+--- a/fs/tracefs/internal.h
++++ b/fs/tracefs/internal.h
+@@ -4,10 +4,9 @@
+
+ enum {
+ TRACEFS_EVENT_INODE = BIT(1),
+- TRACEFS_EVENT_TOP_INODE = BIT(2),
+- TRACEFS_GID_PERM_SET = BIT(3),
+- TRACEFS_UID_PERM_SET = BIT(4),
+- TRACEFS_INSTANCE_INODE = BIT(5),
++ TRACEFS_GID_PERM_SET = BIT(2),
++ TRACEFS_UID_PERM_SET = BIT(3),
++ TRACEFS_INSTANCE_INODE = BIT(4),
+ };
+
+ struct tracefs_inode {
+--
+2.43.0
+
--- /dev/null
+From 02d6f1e22584272a0a121587a1ad7caae347b786 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 16:08:22 -0400
+Subject: eventfs: Free all of the eventfs_inode after RCU
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit ee4e0379475e4fe723986ae96293e465014fa8d9 ]
+
+The freeing of eventfs_inode via a kfree_rcu() callback. But the content
+of the eventfs_inode was being freed after the last kref. This is
+dangerous, as changes are being made that can access the content of an
+eventfs_inode from an RCU loop.
+
+Instead of using kfree_rcu() use call_rcu() that calls a function to do
+all the freeing of the eventfs_inode after a RCU grace period has expired.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240502200905.370261163@goodmis.org
+
+Cc: stable@vger.kernel.org
+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>
+Fixes: 43aa6f97c2d03 ("eventfs: Get rid of dentry pointers without refcounts")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/tracefs/event_inode.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
+index 57830b2bedb6d..db869e52aa5cc 100644
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -73,6 +73,21 @@ enum {
+
+ #define EVENTFS_MODE_MASK (EVENTFS_SAVE_MODE - 1)
+
++static void free_ei_rcu(struct rcu_head *rcu)
++{
++ struct eventfs_inode *ei = container_of(rcu, struct eventfs_inode, rcu);
++ struct eventfs_root_inode *rei;
++
++ kfree(ei->entry_attrs);
++ kfree_const(ei->name);
++ if (ei->is_events) {
++ rei = get_root_inode(ei);
++ kfree(rei);
++ } else {
++ kfree(ei);
++ }
++}
++
+ /*
+ * eventfs_inode reference count management.
+ *
+@@ -85,7 +100,6 @@ static void release_ei(struct kref *ref)
+ {
+ struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
+ const struct eventfs_entry *entry;
+- struct eventfs_root_inode *rei;
+
+ WARN_ON_ONCE(!ei->is_freed);
+
+@@ -95,14 +109,7 @@ static void release_ei(struct kref *ref)
+ entry->release(entry->name, ei->data);
+ }
+
+- kfree(ei->entry_attrs);
+- kfree_const(ei->name);
+- if (ei->is_events) {
+- rei = get_root_inode(ei);
+- kfree_rcu(rei, ei.rcu);
+- } else {
+- kfree_rcu(ei, rcu);
+- }
++ call_rcu(&ei->rcu, free_ei_rcu);
+ }
+
+ static inline void put_ei(struct eventfs_inode *ei)
+--
+2.43.0
+
--- /dev/null
+From 2918c1b1bee28ae2c0c10cc10b47b5046aeba2be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 16:08:27 -0400
+Subject: eventfs: Have "events" directory get permissions from its parent
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit d57cf30c4c07837799edec949102b0adf58bae79 ]
+
+The events directory gets its permissions from the root inode. But this
+can cause an inconsistency if the instances directory changes its
+permissions, as the permissions of the created directories under it should
+inherit the permissions of the instances directory when directories under
+it are created.
+
+Currently the behavior is:
+
+ # cd /sys/kernel/tracing
+ # chgrp 1002 instances
+ # mkdir instances/foo
+ # ls -l instances/foo
+[..]
+ -r--r----- 1 root lkp 0 May 1 18:55 buffer_total_size_kb
+ -rw-r----- 1 root lkp 0 May 1 18:55 current_tracer
+ -rw-r----- 1 root lkp 0 May 1 18:55 error_log
+ drwxr-xr-x 1 root root 0 May 1 18:55 events
+ --w------- 1 root lkp 0 May 1 18:55 free_buffer
+ drwxr-x--- 2 root lkp 0 May 1 18:55 options
+ drwxr-x--- 10 root lkp 0 May 1 18:55 per_cpu
+ -rw-r----- 1 root lkp 0 May 1 18:55 set_event
+
+All the files and directories under "foo" has the "lkp" group except the
+"events" directory. That's because its getting its default value from the
+mount point instead of its parent.
+
+Have the "events" directory make its default value based on its parent's
+permissions. That now gives:
+
+ # ls -l instances/foo
+[..]
+ -rw-r----- 1 root lkp 0 May 1 21:16 buffer_subbuf_size_kb
+ -r--r----- 1 root lkp 0 May 1 21:16 buffer_total_size_kb
+ -rw-r----- 1 root lkp 0 May 1 21:16 current_tracer
+ -rw-r----- 1 root lkp 0 May 1 21:16 error_log
+ drwxr-xr-x 1 root lkp 0 May 1 21:16 events
+ --w------- 1 root lkp 0 May 1 21:16 free_buffer
+ drwxr-x--- 2 root lkp 0 May 1 21:16 options
+ drwxr-x--- 10 root lkp 0 May 1 21:16 per_cpu
+ -rw-r----- 1 root lkp 0 May 1 21:16 set_event
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240502200906.161887248@goodmis.org
+
+Cc: stable@vger.kernel.org
+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>
+Fixes: 8186fff7ab649 ("tracefs/eventfs: Use root and instance inodes as default ownership")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/tracefs/event_inode.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
+index fd111e10f04e4..3b785f4ca95e4 100644
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -37,6 +37,7 @@ static DEFINE_MUTEX(eventfs_mutex);
+
+ struct eventfs_root_inode {
+ struct eventfs_inode ei;
++ struct inode *parent_inode;
+ struct dentry *events_dir;
+ };
+
+@@ -226,12 +227,23 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
+
+ static void update_events_attr(struct eventfs_inode *ei, struct super_block *sb)
+ {
+- struct inode *root;
++ struct eventfs_root_inode *rei;
++ struct inode *parent;
++
++ rei = get_root_inode(ei);
++
++ /* Use the parent inode permissions unless root set its permissions */
++ parent = rei->parent_inode;
+
+- /* Get the tracefs root inode. */
+- root = d_inode(sb->s_root);
+- ei->attr.uid = root->i_uid;
+- ei->attr.gid = root->i_gid;
++ if (rei->ei.attr.mode & EVENTFS_SAVE_UID)
++ ei->attr.uid = rei->ei.attr.uid;
++ else
++ ei->attr.uid = parent->i_uid;
++
++ if (rei->ei.attr.mode & EVENTFS_SAVE_GID)
++ ei->attr.gid = rei->ei.attr.gid;
++ else
++ ei->attr.gid = parent->i_gid;
+ }
+
+ static void set_top_events_ownership(struct inode *inode)
+@@ -810,6 +822,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ // Note: we have a ref to the dentry from tracefs_start_creating()
+ rei = get_root_inode(ei);
+ rei->events_dir = dentry;
++ rei->parent_inode = d_inode(dentry->d_sb->s_root);
+
+ ei->entries = entries;
+ ei->nr_entries = size;
+@@ -819,10 +832,15 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ uid = d_inode(dentry->d_parent)->i_uid;
+ gid = d_inode(dentry->d_parent)->i_gid;
+
+- /* This is used as the default ownership of the files and directories */
+ ei->attr.uid = uid;
+ ei->attr.gid = gid;
+
++ /*
++ * When the "events" directory is created, it takes on the
++ * permissions of its parent. But can be reset on remount.
++ */
++ ei->attr.mode |= EVENTFS_SAVE_UID | EVENTFS_SAVE_GID;
++
+ INIT_LIST_HEAD(&ei->children);
+ INIT_LIST_HEAD(&ei->list);
+
+--
+2.43.0
+
--- /dev/null
+From 7972838b569eb8074ec84a90edd2d48a884072e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 09:03:15 -0400
+Subject: eventfs/tracing: Add callback for release of an eventfs_inode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit b63db58e2fa5d6963db9c45df88e60060f0ff35f ]
+
+Synthetic events create and destroy tracefs files when they are created
+and removed. The tracing subsystem has its own file descriptor
+representing the state of the events attached to the tracefs files.
+There's a race between the eventfs files and this file descriptor of the
+tracing system where the following can cause an issue:
+
+With two scripts 'A' and 'B' doing:
+
+ Script 'A':
+ echo "hello int aaa" > /sys/kernel/tracing/synthetic_events
+ while :
+ do
+ echo 0 > /sys/kernel/tracing/events/synthetic/hello/enable
+ done
+
+ Script 'B':
+ echo > /sys/kernel/tracing/synthetic_events
+
+Script 'A' creates a synthetic event "hello" and then just writes zero
+into its enable file.
+
+Script 'B' removes all synthetic events (including the newly created
+"hello" event).
+
+What happens is that the opening of the "enable" file has:
+
+ {
+ struct trace_event_file *file = inode->i_private;
+ int ret;
+
+ ret = tracing_check_open_get_tr(file->tr);
+ [..]
+
+But deleting the events frees the "file" descriptor, and a "use after
+free" happens with the dereference at "file->tr".
+
+The file descriptor does have a reference counter, but there needs to be a
+way to decrement it from the eventfs when the eventfs_inode is removed
+that represents this file descriptor.
+
+Add an optional "release" callback to the eventfs_entry array structure,
+that gets called when the eventfs file is about to be removed. This allows
+for the creating on the eventfs file to increment the tracing file
+descriptor ref counter. When the eventfs file is deleted, it can call the
+release function that will call the put function for the tracing file
+descriptor.
+
+This will protect the tracing file from being freed while a eventfs file
+that references it is being opened.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240426073410.17154-1-Tze-nan.Wu@mediatek.com/
+Link: https://lore.kernel.org/linux-trace-kernel/20240502090315.448cba46@gandalf.local.home
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Fixes: 5790b1fb3d672 ("eventfs: Remove eventfs_file and just use eventfs_inode")
+Reported-by: Tze-nan wu <Tze-nan.Wu@mediatek.com>
+Tested-by: Tze-nan Wu (吳澤南) <Tze-nan.Wu@mediatek.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/tracefs/event_inode.c | 23 +++++++++++++++++++++--
+ include/linux/tracefs.h | 3 +++
+ kernel/trace/trace_events.c | 12 ++++++++++++
+ 3 files changed, 36 insertions(+), 2 deletions(-)
+
+diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
+index 59099b36e9a91..57830b2bedb6d 100644
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -84,10 +84,17 @@ enum {
+ static void release_ei(struct kref *ref)
+ {
+ struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
++ const struct eventfs_entry *entry;
+ struct eventfs_root_inode *rei;
+
+ WARN_ON_ONCE(!ei->is_freed);
+
++ for (int i = 0; i < ei->nr_entries; i++) {
++ entry = &ei->entries[i];
++ if (entry->release)
++ entry->release(entry->name, ei->data);
++ }
++
+ kfree(ei->entry_attrs);
+ kfree_const(ei->name);
+ if (ei->is_events) {
+@@ -112,6 +119,18 @@ static inline void free_ei(struct eventfs_inode *ei)
+ }
+ }
+
++/*
++ * Called when creation of an ei fails, do not call release() functions.
++ */
++static inline void cleanup_ei(struct eventfs_inode *ei)
++{
++ if (ei) {
++ /* Set nr_entries to 0 to prevent release() function being called */
++ ei->nr_entries = 0;
++ free_ei(ei);
++ }
++}
++
+ static inline struct eventfs_inode *get_ei(struct eventfs_inode *ei)
+ {
+ if (ei)
+@@ -742,7 +761,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode
+
+ /* Was the parent freed? */
+ if (list_empty(&ei->list)) {
+- free_ei(ei);
++ cleanup_ei(ei);
+ ei = NULL;
+ }
+ return ei;
+@@ -843,7 +862,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
+ return ei;
+
+ fail:
+- free_ei(ei);
++ cleanup_ei(ei);
+ tracefs_failed_creating(dentry);
+ return ERR_PTR(-ENOMEM);
+ }
+diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
+index 7a5fe17b6bf9c..d03f746587167 100644
+--- a/include/linux/tracefs.h
++++ b/include/linux/tracefs.h
+@@ -62,6 +62,8 @@ struct eventfs_file;
+ typedef int (*eventfs_callback)(const char *name, umode_t *mode, void **data,
+ const struct file_operations **fops);
+
++typedef void (*eventfs_release)(const char *name, void *data);
++
+ /**
+ * struct eventfs_entry - dynamically created eventfs file call back handler
+ * @name: Then name of the dynamic file in an eventfs directory
+@@ -72,6 +74,7 @@ typedef int (*eventfs_callback)(const char *name, umode_t *mode, void **data,
+ struct eventfs_entry {
+ const char *name;
+ eventfs_callback callback;
++ eventfs_release release;
+ };
+
+ struct eventfs_inode;
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index 52f75c36bbca4..6ef29eba90ceb 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -2552,6 +2552,14 @@ static int event_callback(const char *name, umode_t *mode, void **data,
+ return 0;
+ }
+
++/* The file is incremented on creation and freeing the enable file decrements it */
++static void event_release(const char *name, void *data)
++{
++ struct trace_event_file *file = data;
++
++ event_file_put(file);
++}
++
+ static int
+ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
+ {
+@@ -2566,6 +2574,7 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
+ {
+ .name = "enable",
+ .callback = event_callback,
++ .release = event_release,
+ },
+ {
+ .name = "filter",
+@@ -2634,6 +2643,9 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
+ return ret;
+ }
+
++ /* Gets decremented on freeing of the "enable" file */
++ event_file_get(file);
++
+ return 0;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 7d2ddaeb1fb8647b006bba509213d42b45b811d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 22:00:28 -0800
+Subject: extcon: max8997: select IRQ_DOMAIN instead of depending on it
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit b1781d0a1458070d40134e4f3412ec9d70099bec ]
+
+IRQ_DOMAIN is a hidden (not user visible) symbol. Users cannot set
+it directly thru "make *config", so drivers should select it instead
+of depending on it if they need it.
+Relying on it being set for a dependency is risky.
+
+Consistently using "select" or "depends on" can also help reduce
+Kconfig circular dependency issues.
+
+Therefore, change EXTCON_MAX8997's use of "depends on" for
+IRQ_DOMAIN to "select".
+
+Link: https://lore.kernel.org/lkml/20240213060028.9744-1-rdunlap@infradead.org/
+Fixes: dca1a71e4108 ("extcon: Add support irq domain for MAX8997 muic")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
+index 5f869eacd19ab..3da94b3822923 100644
+--- a/drivers/extcon/Kconfig
++++ b/drivers/extcon/Kconfig
+@@ -116,7 +116,8 @@ config EXTCON_MAX77843
+
+ config EXTCON_MAX8997
+ tristate "Maxim MAX8997 EXTCON Support"
+- depends on MFD_MAX8997 && IRQ_DOMAIN
++ depends on MFD_MAX8997
++ select IRQ_DOMAIN
+ help
+ If you say yes here you get support for the MUIC device of
+ Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory
+--
+2.43.0
+
--- /dev/null
+From 0b1ca78528f08924120089818ea783e7abbd0fc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 May 2024 11:33:39 +0800
+Subject: f2fs: compress: don't allow unaligned truncation on released compress
+ inode
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 29ed2b5dd521ce7c5d8466cd70bf0cc9d07afeee ]
+
+f2fs image may be corrupted after below testcase:
+- mkfs.f2fs -O extra_attr,compression -f /dev/vdb
+- mount /dev/vdb /mnt/f2fs
+- touch /mnt/f2fs/file
+- f2fs_io setflags compression /mnt/f2fs/file
+- dd if=/dev/zero of=/mnt/f2fs/file bs=4k count=4
+- f2fs_io release_cblocks /mnt/f2fs/file
+- truncate -s 8192 /mnt/f2fs/file
+- umount /mnt/f2fs
+- fsck.f2fs /dev/vdb
+
+[ASSERT] (fsck_chk_inode_blk:1256) --> ino: 0x5 has i_blocks: 0x00000002, but has 0x3 blocks
+[FSCK] valid_block_count matching with CP [Fail] [0x4, 0x5]
+[FSCK] other corrupted bugs [Fail]
+
+The reason is: partial truncation assume compressed inode has reserved
+blocks, after partial truncation, valid block count may change w/o
+.i_blocks and .total_valid_block_count update, result in corruption.
+
+This patch only allow cluster size aligned truncation on released
+compress inode for fixing.
+
+Fixes: c61404153eb6 ("f2fs: introduce FI_COMPRESS_RELEASED instead of using IMMUTABLE bit")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 0971dc22810f7..8d3a854f8b0e7 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -935,9 +935,14 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+ ATTR_GID | ATTR_TIMES_SET))))
+ return -EPERM;
+
+- if ((attr->ia_valid & ATTR_SIZE) &&
+- !f2fs_is_compress_backend_ready(inode))
+- return -EOPNOTSUPP;
++ if ((attr->ia_valid & ATTR_SIZE)) {
++ if (!f2fs_is_compress_backend_ready(inode))
++ return -EOPNOTSUPP;
++ if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED) &&
++ !IS_ALIGNED(attr->ia_size,
++ F2FS_BLK_TO_BYTES(F2FS_I(inode)->i_cluster_size)))
++ return -EINVAL;
++ }
+
+ err = setattr_prepare(idmap, dentry, attr);
+ if (err)
+--
+2.43.0
+
--- /dev/null
+From 0b21bc65262d353ae4ba5d10c8b77c364bd0332c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 May 2024 18:41:37 +0800
+Subject: f2fs: compress: fix error path of inc_valid_block_count()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 043c832371cd9023fbd725138ddc6c7f288dc469 ]
+
+If inc_valid_block_count() can not allocate all requested blocks,
+it needs to release block count in .total_valid_block_count and
+resevation blocks in inode.
+
+Fixes: 54607494875e ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index f561f75ef98e9..252e373c1938f 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2276,7 +2276,7 @@ static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
+ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+ struct inode *inode, blkcnt_t *count, bool partial)
+ {
+- blkcnt_t diff = 0, release = 0;
++ long long diff = 0, release = 0;
+ block_t avail_user_block_count;
+ int ret;
+
+@@ -2296,26 +2296,27 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+ percpu_counter_add(&sbi->alloc_valid_block_count, (*count));
+
+ spin_lock(&sbi->stat_lock);
+- sbi->total_valid_block_count += (block_t)(*count);
+- avail_user_block_count = get_available_block_count(sbi, inode, true);
+
+- if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
++ avail_user_block_count = get_available_block_count(sbi, inode, true);
++ diff = (long long)sbi->total_valid_block_count + *count -
++ avail_user_block_count;
++ if (unlikely(diff > 0)) {
+ if (!partial) {
+ spin_unlock(&sbi->stat_lock);
++ release = *count;
+ goto enospc;
+ }
+-
+- diff = sbi->total_valid_block_count - avail_user_block_count;
+ if (diff > *count)
+ diff = *count;
+ *count -= diff;
+ release = diff;
+- sbi->total_valid_block_count -= diff;
+ if (!*count) {
+ spin_unlock(&sbi->stat_lock);
+ goto enospc;
+ }
+ }
++ sbi->total_valid_block_count += (block_t)(*count);
++
+ spin_unlock(&sbi->stat_lock);
+
+ if (unlikely(release)) {
+--
+2.43.0
+
--- /dev/null
+From 7a840a550df639790829529e8aa389b72bced122 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 May 2024 18:41:39 +0800
+Subject: f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/
+ cp_rwsem lock
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 0a4ed2d97cb6d044196cc3e726b6699222b41019 ]
+
+It needs to cover {reserve,release}_compress_blocks() w/ cp_rwsem lock
+to avoid racing with checkpoint, otherwise, filesystem metadata including
+blkaddr in dnode, inode fields and .total_valid_block_count may be
+corrupted after SPO case.
+
+Fixes: ef8d563f184e ("f2fs: introduce F2FS_IOC_RELEASE_COMPRESS_BLOCKS")
+Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 91a5f1a41f26e..0971dc22810f7 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3541,9 +3541,12 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+ struct dnode_of_data dn;
+ pgoff_t end_offset, count;
+
++ f2fs_lock_op(sbi);
++
+ set_new_dnode(&dn, inode, NULL, NULL, 0);
+ ret = f2fs_get_dnode_of_data(&dn, page_idx, LOOKUP_NODE);
+ if (ret) {
++ f2fs_unlock_op(sbi);
+ if (ret == -ENOENT) {
+ page_idx = f2fs_get_next_page_offset(&dn,
+ page_idx);
+@@ -3561,6 +3564,8 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+
+ f2fs_put_dnode(&dn);
+
++ f2fs_unlock_op(sbi);
++
+ if (ret < 0)
+ break;
+
+@@ -3713,9 +3718,12 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ struct dnode_of_data dn;
+ pgoff_t end_offset, count;
+
++ f2fs_lock_op(sbi);
++
+ set_new_dnode(&dn, inode, NULL, NULL, 0);
+ ret = f2fs_get_dnode_of_data(&dn, page_idx, LOOKUP_NODE);
+ if (ret) {
++ f2fs_unlock_op(sbi);
+ if (ret == -ENOENT) {
+ page_idx = f2fs_get_next_page_offset(&dn,
+ page_idx);
+@@ -3733,6 +3741,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+
+ f2fs_put_dnode(&dn);
+
++ f2fs_unlock_op(sbi);
++
+ if (ret < 0)
+ break;
+
+--
+2.43.0
+
--- /dev/null
+From 15d067ff5030afa9a449b6a18cee0ec43a50b161 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Apr 2024 15:26:03 +0800
+Subject: f2fs: compress: fix to relocate check condition in
+ f2fs_{release,reserve}_compress_blocks()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 7c5dffb3d90c5921b91981cc663e02757d90526e ]
+
+Compress flag should be checked after inode lock held to avoid
+racing w/ f2fs_setflags_common(), fix it.
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Reported-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Closes: https://lore.kernel.org/linux-f2fs-devel/CAHJ8P3LdZXLc2rqeYjvymgYHr2+YLuJ0sLG9DdsJZmwO7deuhw@mail.gmail.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 66bd3559d86ee..246ae3639bc0a 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3494,9 +3494,6 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+ if (!f2fs_sb_has_compression(sbi))
+ return -EOPNOTSUPP;
+
+- if (!f2fs_compressed_file(inode))
+- return -EINVAL;
+-
+ if (f2fs_readonly(sbi->sb))
+ return -EROFS;
+
+@@ -3515,7 +3512,8 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+ goto out;
+ }
+
+- if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++ if (!f2fs_compressed_file(inode) ||
++ is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -3678,9 +3676,6 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ if (!f2fs_sb_has_compression(sbi))
+ return -EOPNOTSUPP;
+
+- if (!f2fs_compressed_file(inode))
+- return -EINVAL;
+-
+ if (f2fs_readonly(sbi->sb))
+ return -EROFS;
+
+@@ -3692,7 +3687,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+
+ inode_lock(inode);
+
+- if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++ if (!f2fs_compressed_file(inode) ||
++ !is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
+ ret = -EINVAL;
+ goto unlock_inode;
+ }
+--
+2.43.0
+
--- /dev/null
+From ce5584447b17f2ff4ee4cceb37f84403f715b867 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Apr 2024 15:26:04 +0800
+Subject: f2fs: compress: fix to relocate check condition in
+ f2fs_ioc_{,de}compress_file()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit bd9ae4ae9e585061acfd4a169f2321706f900246 ]
+
+Compress flag should be checked after inode lock held to avoid
+racing w/ f2fs_setflags_common() , fix it.
+
+Fixes: 5fdb322ff2c2 ("f2fs: add F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE")
+Reported-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Closes: https://lore.kernel.org/linux-f2fs-devel/CAHJ8P3LdZXLc2rqeYjvymgYHr2+YLuJ0sLG9DdsJZmwO7deuhw@mail.gmail.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 246ae3639bc0a..4f223395c9a90 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -4092,9 +4092,6 @@ static int f2fs_ioc_decompress_file(struct file *filp)
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EBADF;
+
+- if (!f2fs_compressed_file(inode))
+- return -EINVAL;
+-
+ f2fs_balance_fs(sbi, true);
+
+ file_start_write(filp);
+@@ -4105,7 +4102,8 @@ static int f2fs_ioc_decompress_file(struct file *filp)
+ goto out;
+ }
+
+- if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++ if (!f2fs_compressed_file(inode) ||
++ is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -4171,9 +4169,6 @@ static int f2fs_ioc_compress_file(struct file *filp)
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EBADF;
+
+- if (!f2fs_compressed_file(inode))
+- return -EINVAL;
+-
+ f2fs_balance_fs(sbi, true);
+
+ file_start_write(filp);
+@@ -4184,7 +4179,8 @@ static int f2fs_ioc_compress_file(struct file *filp)
+ goto out;
+ }
+
+- if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++ if (!f2fs_compressed_file(inode) ||
++ is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
+ ret = -EINVAL;
+ goto out;
+ }
+--
+2.43.0
+
--- /dev/null
+From c6c883d48c7e9a2990ef67edf30fa1cc41643c1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 May 2024 18:41:36 +0800
+Subject: f2fs: compress: fix to update i_compr_blocks correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 186e7d71534df4589405925caca5597af7626c12 ]
+
+Previously, we account reserved blocks and compressed blocks into
+@compr_blocks, then, f2fs_i_compr_blocks_update(,compr_blocks) will
+update i_compr_blocks incorrectly, fix it.
+
+Meanwhile, for the case all blocks in cluster were reserved, fix to
+update dn->ofs_in_node correctly.
+
+Fixes: eb8fbaa53374 ("f2fs: compress: fix to check unreleased compressed cluster")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 449e6f1625033..124fd8f2fd1ac 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3616,7 +3616,8 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
+
+ while (count) {
+ int compr_blocks = 0;
+- blkcnt_t reserved;
++ blkcnt_t reserved = 0;
++ blkcnt_t to_reserved;
+ int ret;
+
+ for (i = 0; i < cluster_size; i++) {
+@@ -3636,20 +3637,26 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
+ * fails in release_compress_blocks(), so NEW_ADDR
+ * is a possible case.
+ */
+- if (blkaddr == NEW_ADDR ||
+- __is_valid_data_blkaddr(blkaddr)) {
++ if (blkaddr == NEW_ADDR) {
++ reserved++;
++ continue;
++ }
++ if (__is_valid_data_blkaddr(blkaddr)) {
+ compr_blocks++;
+ continue;
+ }
+ }
+
+- reserved = cluster_size - compr_blocks;
++ to_reserved = cluster_size - compr_blocks - reserved;
+
+ /* for the case all blocks in cluster were reserved */
+- if (reserved == 1)
++ if (to_reserved == 1) {
++ dn->ofs_in_node += cluster_size;
+ goto next;
++ }
+
+- ret = inc_valid_block_count(sbi, dn->inode, &reserved, false);
++ ret = inc_valid_block_count(sbi, dn->inode,
++ &to_reserved, false);
+ if (unlikely(ret))
+ return ret;
+
+@@ -3660,7 +3667,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
+
+ f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true);
+
+- *reserved_blocks += reserved;
++ *reserved_blocks += to_reserved;
+ next:
+ count -= cluster_size;
+ }
+--
+2.43.0
+
--- /dev/null
+From dbcd721e8c3ab1225124ee06365dc19024e54772 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 11:21:00 -0800
+Subject: f2fs: deprecate io_bits
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+[ Upstream commit 87161a2b0aed9e9b614bbf6fe8697ad560ceb0cb ]
+
+Let's deprecate an unused io_bits feature to save CPU cycles and memory.
+
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 043c832371cd ("f2fs: compress: fix error path of inc_valid_block_count()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/filesystems/f2fs.rst | 2 -
+ fs/f2fs/data.c | 73 +------------------------
+ fs/f2fs/f2fs.h | 25 ++-------
+ fs/f2fs/file.c | 2 -
+ fs/f2fs/gc.c | 10 +---
+ fs/f2fs/segment.c | 9 +--
+ fs/f2fs/super.c | 88 +-----------------------------
+ include/linux/f2fs_fs.h | 6 --
+ 8 files changed, 10 insertions(+), 205 deletions(-)
+
+diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
+index d32c6209685d6..f66bf6bea02be 100644
+--- a/Documentation/filesystems/f2fs.rst
++++ b/Documentation/filesystems/f2fs.rst
+@@ -228,8 +228,6 @@ mode=%s Control block allocation mode which supports "adaptive"
+ option for more randomness.
+ Please, use these options for your experiments and we strongly
+ recommend to re-format the filesystem after using these options.
+-io_bits=%u Set the bit size of write IO requests. It should be set
+- with "mode=lfs".
+ usrquota Enable plain user disk quota accounting.
+ grpquota Enable plain group disk quota accounting.
+ prjquota Enable plain project quota accounting.
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index a871ba9fa3aab..a585a8d5eab0c 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -338,17 +338,6 @@ static void f2fs_write_end_io(struct bio *bio)
+ struct page *page = bvec->bv_page;
+ enum count_type type = WB_DATA_TYPE(page, false);
+
+- if (page_private_dummy(page)) {
+- clear_page_private_dummy(page);
+- unlock_page(page);
+- mempool_free(page, sbi->write_io_dummy);
+-
+- if (unlikely(bio->bi_status))
+- f2fs_stop_checkpoint(sbi, true,
+- STOP_CP_REASON_WRITE_FAIL);
+- continue;
+- }
+-
+ fscrypt_finalize_bounce_page(&page);
+
+ #ifdef CONFIG_F2FS_FS_COMPRESSION
+@@ -522,50 +511,13 @@ void f2fs_submit_read_bio(struct f2fs_sb_info *sbi, struct bio *bio,
+ submit_bio(bio);
+ }
+
+-static void f2fs_align_write_bio(struct f2fs_sb_info *sbi, struct bio *bio)
+-{
+- unsigned int start =
+- (bio->bi_iter.bi_size >> F2FS_BLKSIZE_BITS) % F2FS_IO_SIZE(sbi);
+-
+- if (start == 0)
+- return;
+-
+- /* fill dummy pages */
+- for (; start < F2FS_IO_SIZE(sbi); start++) {
+- struct page *page =
+- mempool_alloc(sbi->write_io_dummy,
+- GFP_NOIO | __GFP_NOFAIL);
+- f2fs_bug_on(sbi, !page);
+-
+- lock_page(page);
+-
+- zero_user_segment(page, 0, PAGE_SIZE);
+- set_page_private_dummy(page);
+-
+- if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE)
+- f2fs_bug_on(sbi, 1);
+- }
+-}
+-
+ static void f2fs_submit_write_bio(struct f2fs_sb_info *sbi, struct bio *bio,
+ enum page_type type)
+ {
+ WARN_ON_ONCE(is_read_io(bio_op(bio)));
+
+- if (type == DATA || type == NODE) {
+- if (f2fs_lfs_mode(sbi) && current->plug)
+- blk_finish_plug(current->plug);
+-
+- if (F2FS_IO_ALIGNED(sbi)) {
+- f2fs_align_write_bio(sbi, bio);
+- /*
+- * In the NODE case, we lose next block address chain.
+- * So, we need to do checkpoint in f2fs_sync_file.
+- */
+- if (type == NODE)
+- set_sbi_flag(sbi, SBI_NEED_CP);
+- }
+- }
++ if (f2fs_lfs_mode(sbi) && current->plug && PAGE_TYPE_ON_MAIN(type))
++ blk_finish_plug(current->plug);
+
+ trace_f2fs_submit_write_bio(sbi->sb, type, bio);
+ iostat_update_submit_ctx(bio, type);
+@@ -794,16 +746,6 @@ static bool io_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
+ block_t last_blkaddr,
+ block_t cur_blkaddr)
+ {
+- if (F2FS_IO_ALIGNED(sbi) && (fio->type == DATA || fio->type == NODE)) {
+- unsigned int filled_blocks =
+- F2FS_BYTES_TO_BLK(bio->bi_iter.bi_size);
+- unsigned int io_size = F2FS_IO_SIZE(sbi);
+- unsigned int left_vecs = bio->bi_max_vecs - bio->bi_vcnt;
+-
+- /* IOs in bio is aligned and left space of vectors is not enough */
+- if (!(filled_blocks % io_size) && left_vecs < io_size)
+- return false;
+- }
+ if (!page_is_mergeable(sbi, bio, last_blkaddr, cur_blkaddr))
+ return false;
+ return io_type_is_mergeable(io, fio);
+@@ -1055,14 +997,6 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ __submit_merged_bio(io);
+ alloc_new:
+ if (io->bio == NULL) {
+- if (F2FS_IO_ALIGNED(sbi) &&
+- (fio->type == DATA || fio->type == NODE) &&
+- fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
+- dec_page_count(sbi, WB_DATA_TYPE(bio_page,
+- fio->compressed_page));
+- fio->retry = 1;
+- goto skip;
+- }
+ io->bio = __bio_alloc(fio, BIO_MAX_VECS);
+ f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host,
+ bio_page->index, fio, GFP_NOIO);
+@@ -1092,7 +1026,6 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ __submit_merged_bio(io);
+ }
+ #endif
+-skip:
+ if (fio->in_list)
+ goto next;
+ out:
+@@ -2669,8 +2602,6 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
+ if (fio) {
+ if (page_private_gcing(fio->page))
+ return true;
+- if (page_private_dummy(fio->page))
+- return true;
+ if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
+ f2fs_is_checkpointed_data(sbi, fio->old_blkaddr)))
+ return true;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 6610ff6d7e6cc..e3c231352f6db 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -147,7 +147,6 @@ struct f2fs_rwsem {
+
+ struct f2fs_mount_info {
+ unsigned int opt;
+- int write_io_size_bits; /* Write IO size bits */
+ block_t root_reserved_blocks; /* root reserved blocks */
+ kuid_t s_resuid; /* reserved blocks for uid */
+ kgid_t s_resgid; /* reserved blocks for gid */
+@@ -1116,6 +1115,7 @@ enum count_type {
+ * ... Only can be used with META.
+ */
+ #define PAGE_TYPE_OF_BIO(type) ((type) > META ? META : (type))
++#define PAGE_TYPE_ON_MAIN(type) ((type) == DATA || (type) == NODE)
+ enum page_type {
+ DATA = 0,
+ NODE = 1, /* should not change this */
+@@ -1210,7 +1210,6 @@ struct f2fs_io_info {
+ unsigned int submitted:1; /* indicate IO submission */
+ unsigned int in_list:1; /* indicate fio is in io_list */
+ unsigned int is_por:1; /* indicate IO is from recovery or not */
+- unsigned int retry:1; /* need to reallocate block address */
+ unsigned int encrypted:1; /* indicate file is encrypted */
+ unsigned int post_read:1; /* require post read */
+ enum iostat_type io_type; /* io type */
+@@ -1412,18 +1411,16 @@ static inline void f2fs_clear_bit(unsigned int nr, char *addr);
+ * Layout A: lowest bit should be 1
+ * | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... |
+ * bit 0 PAGE_PRIVATE_NOT_POINTER
+- * bit 1 PAGE_PRIVATE_DUMMY_WRITE
+- * bit 2 PAGE_PRIVATE_ONGOING_MIGRATION
+- * bit 3 PAGE_PRIVATE_INLINE_INODE
+- * bit 4 PAGE_PRIVATE_REF_RESOURCE
+- * bit 5- f2fs private data
++ * bit 1 PAGE_PRIVATE_ONGOING_MIGRATION
++ * bit 2 PAGE_PRIVATE_INLINE_INODE
++ * bit 3 PAGE_PRIVATE_REF_RESOURCE
++ * bit 4- f2fs private data
+ *
+ * Layout B: lowest bit should be 0
+ * page.private is a wrapped pointer.
+ */
+ enum {
+ PAGE_PRIVATE_NOT_POINTER, /* private contains non-pointer data */
+- PAGE_PRIVATE_DUMMY_WRITE, /* data page for padding aligned IO */
+ PAGE_PRIVATE_ONGOING_MIGRATION, /* data page which is on-going migrating */
+ PAGE_PRIVATE_INLINE_INODE, /* inode page contains inline data */
+ PAGE_PRIVATE_REF_RESOURCE, /* dirty page has referenced resources */
+@@ -1570,7 +1567,6 @@ struct f2fs_sb_info {
+ struct f2fs_bio_info *write_io[NR_PAGE_TYPE]; /* for write bios */
+ /* keep migration IO order for LFS mode */
+ struct f2fs_rwsem io_order_lock;
+- mempool_t *write_io_dummy; /* Dummy pages */
+ pgoff_t page_eio_ofs[NR_PAGE_TYPE]; /* EIO page offset */
+ int page_eio_cnt[NR_PAGE_TYPE]; /* EIO count */
+
+@@ -2286,10 +2282,6 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+ if (!__allow_reserved_blocks(sbi, inode, true))
+ avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
+
+- if (F2FS_IO_ALIGNED(sbi))
+- avail_user_block_count -= sbi->blocks_per_seg *
+- SM_I(sbi)->additional_reserved_segments;
+-
+ if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+ if (avail_user_block_count > sbi->unusable_block_count)
+ avail_user_block_count -= sbi->unusable_block_count;
+@@ -2371,17 +2363,14 @@ static inline void clear_page_private_##name(struct page *page) \
+ PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
+ PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
+ PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
+-PAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE);
+
+ PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
+ PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
+ PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
+-PAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE);
+
+ PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
+ PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
+ PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
+-PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
+
+ static inline unsigned long get_page_private_data(struct page *page)
+ {
+@@ -2637,10 +2626,6 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
+ if (!__allow_reserved_blocks(sbi, inode, false))
+ valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks;
+
+- if (F2FS_IO_ALIGNED(sbi))
+- valid_block_count += sbi->blocks_per_seg *
+- SM_I(sbi)->additional_reserved_segments;
+-
+ user_block_count = sbi->user_block_count;
+ if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
+ user_block_count -= sbi->unusable_block_count;
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 124fd8f2fd1ac..91a5f1a41f26e 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -819,8 +819,6 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw)
+ */
+ if (f2fs_sb_has_blkzoned(sbi) && (rw == WRITE))
+ return true;
+- if (f2fs_lfs_mode(sbi) && rw == WRITE && F2FS_IO_ALIGNED(sbi))
+- return true;
+ if (is_sbi_flag_set(sbi, SBI_CP_DISABLED))
+ return true;
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index a079eebfb080b..6899f434ad688 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1184,7 +1184,6 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
+ .op_flags = 0,
+ .encrypted_page = NULL,
+ .in_list = 0,
+- .retry = 0,
+ };
+ int err;
+
+@@ -1273,7 +1272,6 @@ static int move_data_block(struct inode *inode, block_t bidx,
+ .op_flags = 0,
+ .encrypted_page = NULL,
+ .in_list = 0,
+- .retry = 0,
+ };
+ struct dnode_of_data dn;
+ struct f2fs_summary sum;
+@@ -1393,18 +1391,12 @@ static int move_data_block(struct inode *inode, block_t bidx,
+ fio.op_flags = REQ_SYNC;
+ fio.new_blkaddr = newaddr;
+ f2fs_submit_page_write(&fio);
+- if (fio.retry) {
+- err = -EAGAIN;
+- if (PageWriteback(fio.encrypted_page))
+- end_page_writeback(fio.encrypted_page);
+- goto put_page_out;
+- }
+
+ f2fs_update_iostat(fio.sbi, NULL, FS_GC_DATA_IO, F2FS_BLKSIZE);
+
+ f2fs_update_data_blkaddr(&dn, newaddr);
+ set_inode_flag(inode, FI_APPEND_WRITE);
+-put_page_out:
++
+ f2fs_put_page(fio.encrypted_page, 1);
+ recover_block:
+ if (err)
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 6d5774093452f..dbe3ff73bce72 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3507,9 +3507,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+ if (fio) {
+ struct f2fs_bio_info *io;
+
+- if (F2FS_IO_ALIGNED(sbi))
+- fio->retry = 0;
+-
+ INIT_LIST_HEAD(&fio->list);
+ fio->in_list = 1;
+ io = sbi->write_io[fio->type] + fio->temp;
+@@ -3557,7 +3554,7 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
+
+ if (keep_order)
+ f2fs_down_read(&fio->sbi->io_order_lock);
+-reallocate:
++
+ f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
+ &fio->new_blkaddr, sum, type, fio);
+ if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO)
+@@ -3565,10 +3562,6 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
+
+ /* writeout dirty page into bdev */
+ f2fs_submit_page_write(fio);
+- if (fio->retry) {
+- fio->old_blkaddr = fio->new_blkaddr;
+- goto reallocate;
+- }
+
+ f2fs_update_device_state(fio->sbi, fio->ino, fio->new_blkaddr, 1);
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 4ba613ed3a179..96e0ff4edf024 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -137,7 +137,6 @@ enum {
+ Opt_resgid,
+ Opt_resuid,
+ Opt_mode,
+- Opt_io_size_bits,
+ Opt_fault_injection,
+ Opt_fault_type,
+ Opt_lazytime,
+@@ -216,7 +215,6 @@ static match_table_t f2fs_tokens = {
+ {Opt_resgid, "resgid=%u"},
+ {Opt_resuid, "resuid=%u"},
+ {Opt_mode, "mode=%s"},
+- {Opt_io_size_bits, "io_bits=%u"},
+ {Opt_fault_injection, "fault_injection=%u"},
+ {Opt_fault_type, "fault_type=%u"},
+ {Opt_lazytime, "lazytime"},
+@@ -343,46 +341,6 @@ static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
+ F2FS_OPTION(sbi).s_resgid));
+ }
+
+-static inline int adjust_reserved_segment(struct f2fs_sb_info *sbi)
+-{
+- unsigned int sec_blks = sbi->blocks_per_seg * sbi->segs_per_sec;
+- unsigned int avg_vblocks;
+- unsigned int wanted_reserved_segments;
+- block_t avail_user_block_count;
+-
+- if (!F2FS_IO_ALIGNED(sbi))
+- return 0;
+-
+- /* average valid block count in section in worst case */
+- avg_vblocks = sec_blks / F2FS_IO_SIZE(sbi);
+-
+- /*
+- * we need enough free space when migrating one section in worst case
+- */
+- wanted_reserved_segments = (F2FS_IO_SIZE(sbi) / avg_vblocks) *
+- reserved_segments(sbi);
+- wanted_reserved_segments -= reserved_segments(sbi);
+-
+- avail_user_block_count = sbi->user_block_count -
+- sbi->current_reserved_blocks -
+- F2FS_OPTION(sbi).root_reserved_blocks;
+-
+- if (wanted_reserved_segments * sbi->blocks_per_seg >
+- avail_user_block_count) {
+- f2fs_err(sbi, "IO align feature can't grab additional reserved segment: %u, available segments: %u",
+- wanted_reserved_segments,
+- avail_user_block_count >> sbi->log_blocks_per_seg);
+- return -ENOSPC;
+- }
+-
+- SM_I(sbi)->additional_reserved_segments = wanted_reserved_segments;
+-
+- f2fs_info(sbi, "IO align feature needs additional reserved segment: %u",
+- wanted_reserved_segments);
+-
+- return 0;
+-}
+-
+ static inline void adjust_unusable_cap_perc(struct f2fs_sb_info *sbi)
+ {
+ if (!F2FS_OPTION(sbi).unusable_cap_perc)
+@@ -919,16 +877,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+ }
+ kfree(name);
+ break;
+- case Opt_io_size_bits:
+- if (args->from && match_int(args, &arg))
+- return -EINVAL;
+- if (arg <= 0 || arg > __ilog2_u32(BIO_MAX_VECS)) {
+- f2fs_warn(sbi, "Not support %ld, larger than %d",
+- BIT(arg), BIO_MAX_VECS);
+- return -EINVAL;
+- }
+- F2FS_OPTION(sbi).write_io_size_bits = arg;
+- break;
+ #ifdef CONFIG_F2FS_FAULT_INJECTION
+ case Opt_fault_injection:
+ if (args->from && match_int(args, &arg))
+@@ -1398,12 +1346,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+ }
+ #endif
+
+- if (F2FS_IO_SIZE_BITS(sbi) && !f2fs_lfs_mode(sbi)) {
+- f2fs_err(sbi, "Should set mode=lfs with %luKB-sized IO",
+- F2FS_IO_SIZE_KB(sbi));
+- return -EINVAL;
+- }
+-
+ if (test_opt(sbi, INLINE_XATTR_SIZE)) {
+ int min_size, max_size;
+
+@@ -1724,7 +1666,6 @@ static void f2fs_put_super(struct super_block *sb)
+
+ f2fs_destroy_page_array_cache(sbi);
+ f2fs_destroy_xattr_caches(sbi);
+- mempool_destroy(sbi->write_io_dummy);
+ #ifdef CONFIG_QUOTA
+ for (i = 0; i < MAXQUOTAS; i++)
+ kfree(F2FS_OPTION(sbi).s_qf_names[i]);
+@@ -2084,9 +2025,6 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
+ F2FS_OPTION(sbi).s_resuid),
+ from_kgid_munged(&init_user_ns,
+ F2FS_OPTION(sbi).s_resgid));
+- if (F2FS_IO_SIZE_BITS(sbi))
+- seq_printf(seq, ",io_bits=%u",
+- F2FS_OPTION(sbi).write_io_size_bits);
+ #ifdef CONFIG_F2FS_FAULT_INJECTION
+ if (test_opt(sbi, FAULT_INJECTION)) {
+ seq_printf(seq, ",fault_injection=%u",
+@@ -2338,7 +2276,6 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ bool no_read_extent_cache = !test_opt(sbi, READ_EXTENT_CACHE);
+ bool no_age_extent_cache = !test_opt(sbi, AGE_EXTENT_CACHE);
+ bool enable_checkpoint = !test_opt(sbi, DISABLE_CHECKPOINT);
+- bool no_io_align = !F2FS_IO_ALIGNED(sbi);
+ bool no_atgc = !test_opt(sbi, ATGC);
+ bool no_discard = !test_opt(sbi, DISCARD);
+ bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE);
+@@ -2446,12 +2383,6 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ goto restore_opts;
+ }
+
+- if (no_io_align == !!F2FS_IO_ALIGNED(sbi)) {
+- err = -EINVAL;
+- f2fs_warn(sbi, "switch io_bits option is not allowed");
+- goto restore_opts;
+- }
+-
+ if (no_compress_cache == !!test_opt(sbi, COMPRESS_CACHE)) {
+ err = -EINVAL;
+ f2fs_warn(sbi, "switch compress_cache option is not allowed");
+@@ -4306,8 +4237,6 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
+ FDEV(i).total_segments,
+ FDEV(i).start_blk, FDEV(i).end_blk);
+ }
+- f2fs_info(sbi,
+- "IO Block Size: %8ld KB", F2FS_IO_SIZE_KB(sbi));
+ return 0;
+ }
+
+@@ -4520,19 +4449,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+ if (err)
+ goto free_iostat;
+
+- if (F2FS_IO_ALIGNED(sbi)) {
+- sbi->write_io_dummy =
+- mempool_create_page_pool(2 * (F2FS_IO_SIZE(sbi) - 1), 0);
+- if (!sbi->write_io_dummy) {
+- err = -ENOMEM;
+- goto free_percpu;
+- }
+- }
+-
+ /* init per sbi slab cache */
+ err = f2fs_init_xattr_caches(sbi);
+ if (err)
+- goto free_io_dummy;
++ goto free_percpu;
+ err = f2fs_init_page_array_cache(sbi);
+ if (err)
+ goto free_xattr_cache;
+@@ -4620,10 +4540,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+ goto free_nm;
+ }
+
+- err = adjust_reserved_segment(sbi);
+- if (err)
+- goto free_nm;
+-
+ /* For write statistics */
+ sbi->sectors_written_start = f2fs_get_sectors_written(sbi);
+
+@@ -4854,8 +4770,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+ f2fs_destroy_page_array_cache(sbi);
+ free_xattr_cache:
+ f2fs_destroy_xattr_caches(sbi);
+-free_io_dummy:
+- mempool_destroy(sbi->write_io_dummy);
+ free_percpu:
+ destroy_percpu_info(sbi);
+ free_iostat:
+diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
+index 3f016d3c1ec4f..a8c0c081ec4df 100644
+--- a/include/linux/f2fs_fs.h
++++ b/include/linux/f2fs_fs.h
+@@ -41,12 +41,6 @@
+
+ #define F2FS_ENC_UTF8_12_1 1
+
+-#define F2FS_IO_SIZE(sbi) BIT(F2FS_OPTION(sbi).write_io_size_bits) /* Blocks */
+-#define F2FS_IO_SIZE_KB(sbi) BIT(F2FS_OPTION(sbi).write_io_size_bits + 2) /* KB */
+-#define F2FS_IO_SIZE_BITS(sbi) (F2FS_OPTION(sbi).write_io_size_bits) /* power of 2 */
+-#define F2FS_IO_SIZE_MASK(sbi) (F2FS_IO_SIZE(sbi) - 1)
+-#define F2FS_IO_ALIGNED(sbi) (F2FS_IO_SIZE(sbi) > 1)
+-
+ /* This flag is used by node and meta inodes, and by recovery */
+ #define GFP_F2FS_ZERO (GFP_NOFS | __GFP_ZERO)
+
+--
+2.43.0
+
--- /dev/null
+From 94f68f54f6b71883c517a01a4ee449c15a933e3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Apr 2024 21:51:42 -0600
+Subject: f2fs: fix block migration when section is not aligned to pow2
+
+From: Wu Bo <bo.wu@vivo.com>
+
+[ Upstream commit aa4074e8fec4d2e686daee627fcafb3503efe365 ]
+
+As for zoned-UFS, f2fs section size is forced to zone size. And zone
+size may not aligned to pow2.
+
+Fixes: 859fca6b706e ("f2fs: swap: support migrating swapfile in aligned write mode")
+Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com>
+Signed-off-by: Wu Bo <bo.wu@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 8e9aaa9e41cce..a871ba9fa3aab 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -3968,15 +3968,14 @@ static int check_swap_activate(struct swap_info_struct *sis,
+ struct address_space *mapping = swap_file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+- sector_t cur_lblock;
+- sector_t last_lblock;
+- sector_t pblock;
+- sector_t lowest_pblock = -1;
+- sector_t highest_pblock = 0;
++ block_t cur_lblock;
++ block_t last_lblock;
++ block_t pblock;
++ block_t lowest_pblock = -1;
++ block_t highest_pblock = 0;
+ int nr_extents = 0;
+- unsigned long nr_pblocks;
++ unsigned int nr_pblocks;
+ unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
+- unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
+ unsigned int not_aligned = 0;
+ int ret = 0;
+
+@@ -4014,8 +4013,8 @@ static int check_swap_activate(struct swap_info_struct *sis,
+ pblock = map.m_pblk;
+ nr_pblocks = map.m_len;
+
+- if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
+- nr_pblocks & sec_blks_mask) {
++ if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
++ nr_pblocks % blks_per_sec) {
+ not_aligned++;
+
+ nr_pblocks = roundup(nr_pblocks, blks_per_sec);
+--
+2.43.0
+
--- /dev/null
+From 1134aa47c0d9ebf3e89da3d242b38ede8c9d962c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 May 2024 11:43:33 +0800
+Subject: f2fs: fix to add missing iput() in gc_data_segment()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit a798ff17cd2dabe47d5d4ed3d509631793c36e19 ]
+
+During gc_data_segment(), if inode state is abnormal, it missed to call
+iput(), fix it.
+
+Fixes: b73e52824c89 ("f2fs: reposition unlock_new_inode to prevent accessing invalid inode")
+Fixes: 9056d6489f5a ("f2fs: fix to do sanity check on inode type during garbage collection")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 6899f434ad688..61f142f2cce23 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1552,10 +1552,15 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ int err;
+
+ inode = f2fs_iget(sb, dni.ino);
+- if (IS_ERR(inode) || is_bad_inode(inode) ||
+- special_file(inode->i_mode))
++ if (IS_ERR(inode))
+ continue;
+
++ if (is_bad_inode(inode) ||
++ special_file(inode->i_mode)) {
++ iput(inode);
++ continue;
++ }
++
+ err = f2fs_gc_pinned_control(inode, gc_type, segno);
+ if (err == -EAGAIN) {
+ iput(inode);
+--
+2.43.0
+
--- /dev/null
+From 911dc36a67123e9996fc7391a424177e697b1f5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 22:24:20 +0800
+Subject: f2fs: fix to check pinfile flag in f2fs_move_file_range()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit e07230da0500e0919a765037c5e81583b519be2c ]
+
+ioctl(F2FS_IOC_MOVE_RANGE) can truncate or punch hole on pinned file,
+fix to disallow it.
+
+Fixes: 5fed0be8583f ("f2fs: do not allow partial truncation on pinned file")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index fb6c3777ef1a8..449e6f1625033 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -2819,7 +2819,8 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
+ goto out;
+ }
+
+- if (f2fs_compressed_file(src) || f2fs_compressed_file(dst)) {
++ if (f2fs_compressed_file(src) || f2fs_compressed_file(dst) ||
++ f2fs_is_pinned_file(src) || f2fs_is_pinned_file(dst)) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+--
+2.43.0
+
--- /dev/null
+From 124f352837899e408b0b193efb7c803cfda70789 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 11:31:00 +0800
+Subject: f2fs: fix to release node block count in error path of
+ f2fs_new_node_page()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 0fa4e57c1db263effd72d2149d4e21da0055c316 ]
+
+It missed to call dec_valid_node_count() to release node block count
+in error path, fix it.
+
+Fixes: 141170b759e0 ("f2fs: fix to avoid use f2fs_bug_on() in f2fs_new_node_page()")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/node.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 2ea9c99e7dcb7..ad3ebe489f66a 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1319,6 +1319,7 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
+ }
+ if (unlikely(new_ni.blk_addr != NULL_ADDR)) {
+ err = -EFSCORRUPTED;
++ dec_valid_node_count(sbi, dn->inode, !ofs);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+ goto fail;
+@@ -1345,7 +1346,6 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
+ if (ofs == 0)
+ inc_valid_inode_count(sbi);
+ return page;
+-
+ fail:
+ clear_node_page_dirty(page);
+ f2fs_put_page(page, 1);
+--
+2.43.0
+
--- /dev/null
+From 36ea46dc70f0a5f63343c6b68628c9b216bd865a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 22:24:19 +0800
+Subject: f2fs: fix to relocate check condition in f2fs_fallocate()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 278a6253a673611dbc8ab72a3b34b151a8e75822 ]
+
+compress and pinfile flag should be checked after inode lock held to
+avoid race condition, fix it.
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Fixes: 5fed0be8583f ("f2fs: do not allow partial truncation on pinned file")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 4f223395c9a90..fb6c3777ef1a8 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1803,15 +1803,6 @@ static long f2fs_fallocate(struct file *file, int mode,
+ (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
+ return -EOPNOTSUPP;
+
+- /*
+- * Pinned file should not support partial truncation since the block
+- * can be used by applications.
+- */
+- if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
+- (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
+- FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE)))
+- return -EOPNOTSUPP;
+-
+ if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+ FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE |
+ FALLOC_FL_INSERT_RANGE))
+@@ -1819,6 +1810,17 @@ static long f2fs_fallocate(struct file *file, int mode,
+
+ inode_lock(inode);
+
++ /*
++ * Pinned file should not support partial truncation since the block
++ * can be used by applications.
++ */
++ if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
++ (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
++ FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE))) {
++ ret = -EOPNOTSUPP;
++ goto out;
++ }
++
+ ret = file_modified(file);
+ if (ret)
+ goto out;
+--
+2.43.0
+
--- /dev/null
+From 97f29b28d9698e81292bd37e5b11038fc0c9a6d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 19:28:45 +0800
+Subject: f2fs: fix to wait on page writeback in __clone_blkaddrs()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit d3876e34e7e789e2cbdd782360fef2a777391082 ]
+
+In below race condition, dst page may become writeback status
+in __clone_blkaddrs(), it needs to wait writeback before update,
+fix it.
+
+Thread A GC Thread
+- f2fs_move_file_range
+ - filemap_write_and_wait_range(dst)
+ - gc_data_segment
+ - f2fs_down_write(dst)
+ - move_data_page
+ - set_page_writeback(dst_page)
+ - f2fs_submit_page_write
+ - f2fs_up_write(dst)
+ - f2fs_down_write(dst)
+ - __exchange_data_block
+ - __clone_blkaddrs
+ - f2fs_get_new_data_page
+ - memcpy_page
+
+Fixes: 0a2aa8fbb969 ("f2fs: refactor __exchange_data_block for speed up")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 51970b345eeee..66bd3559d86ee 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1311,6 +1311,9 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
+ f2fs_put_page(psrc, 1);
+ return PTR_ERR(pdst);
+ }
++
++ f2fs_wait_on_page_writeback(pdst, DATA, true, true);
++
+ memcpy_page(pdst, 0, psrc, 0, PAGE_SIZE);
+ set_page_dirty(pdst);
+ set_page_private_gcing(pdst);
+--
+2.43.0
+
--- /dev/null
+From f1f1d7449113b65219164357826b422363fbb1a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 11:15:15 +0800
+Subject: f2fs: introduce get_available_block_count() for cleanup
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 0f1c6ede6da9f7c5dd7380b74a64850298279168 ]
+
+There are very similar codes in inc_valid_block_count() and
+inc_valid_node_count() which is used for available user block
+count calculation.
+
+This patch introduces a new helper get_available_block_count()
+to include those common codes, and used it to clean up codes.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 043c832371cd ("f2fs: compress: fix error path of inc_valid_block_count()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 49 +++++++++++++++++++++++++++----------------------
+ 1 file changed, 27 insertions(+), 22 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index e3c231352f6db..f561f75ef98e9 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2251,6 +2251,27 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
+ return false;
+ }
+
++static inline unsigned int get_available_block_count(struct f2fs_sb_info *sbi,
++ struct inode *inode, bool cap)
++{
++ block_t avail_user_block_count;
++
++ avail_user_block_count = sbi->user_block_count -
++ sbi->current_reserved_blocks;
++
++ if (!__allow_reserved_blocks(sbi, inode, cap))
++ avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
++
++ if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
++ if (avail_user_block_count > sbi->unusable_block_count)
++ avail_user_block_count -= sbi->unusable_block_count;
++ else
++ avail_user_block_count = 0;
++ }
++
++ return avail_user_block_count;
++}
++
+ static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
+ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+ struct inode *inode, blkcnt_t *count, bool partial)
+@@ -2276,18 +2297,8 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+
+ spin_lock(&sbi->stat_lock);
+ sbi->total_valid_block_count += (block_t)(*count);
+- avail_user_block_count = sbi->user_block_count -
+- sbi->current_reserved_blocks;
++ avail_user_block_count = get_available_block_count(sbi, inode, true);
+
+- if (!__allow_reserved_blocks(sbi, inode, true))
+- avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
+-
+- if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+- if (avail_user_block_count > sbi->unusable_block_count)
+- avail_user_block_count -= sbi->unusable_block_count;
+- else
+- avail_user_block_count = 0;
+- }
+ if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
+ if (!partial) {
+ spin_unlock(&sbi->stat_lock);
+@@ -2600,7 +2611,8 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
+ struct inode *inode, bool is_inode)
+ {
+ block_t valid_block_count;
+- unsigned int valid_node_count, user_block_count;
++ unsigned int valid_node_count;
++ unsigned int avail_user_block_count;
+ int err;
+
+ if (is_inode) {
+@@ -2620,17 +2632,10 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
+
+ spin_lock(&sbi->stat_lock);
+
+- valid_block_count = sbi->total_valid_block_count +
+- sbi->current_reserved_blocks + 1;
+-
+- if (!__allow_reserved_blocks(sbi, inode, false))
+- valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks;
+-
+- user_block_count = sbi->user_block_count;
+- if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
+- user_block_count -= sbi->unusable_block_count;
++ valid_block_count = sbi->total_valid_block_count + 1;
++ avail_user_block_count = get_available_block_count(sbi, inode, false);
+
+- if (unlikely(valid_block_count > user_block_count)) {
++ if (unlikely(valid_block_count > avail_user_block_count)) {
+ spin_unlock(&sbi->stat_lock);
+ goto enospc;
+ }
+--
+2.43.0
+
--- /dev/null
+From 1e3ca2e2c01eb83b2a1e48a0e92a589e18b35e0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 15:42:23 +0800
+Subject: f2fs: multidev: fix to recognize valid zero block address
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 33e62cd7b4c281cd737c62e5d8c4f0e602a8c5c5 ]
+
+As reported by Yi Zhang in mailing list [1], kernel warning was catched
+during zbd/010 test as below:
+
+./check zbd/010
+zbd/010 (test gap zone support with F2FS) [failed]
+ runtime ... 3.752s
+ something found in dmesg:
+ [ 4378.146781] run blktests zbd/010 at 2024-02-18 11:31:13
+ [ 4378.192349] null_blk: module loaded
+ [ 4378.209860] null_blk: disk nullb0 created
+ [ 4378.413285] scsi_debug:sdebug_driver_probe: scsi_debug: trim
+poll_queues to 0. poll_q/nr_hw = (0/1)
+ [ 4378.422334] scsi host15: scsi_debug: version 0191 [20210520]
+ dev_size_mb=1024, opts=0x0, submit_queues=1, statistics=0
+ [ 4378.434922] scsi 15:0:0:0: Direct-Access-ZBC Linux
+scsi_debug 0191 PQ: 0 ANSI: 7
+ [ 4378.443343] scsi 15:0:0:0: Power-on or device reset occurred
+ [ 4378.449371] sd 15:0:0:0: Attached scsi generic sg5 type 20
+ [ 4378.449418] sd 15:0:0:0: [sdf] Host-managed zoned block device
+ ...
+ (See '/mnt/tests/gitlab.com/api/v4/projects/19168116/repository/archive.zip/storage/blktests/blk/blktests/results/nodev/zbd/010.dmesg'
+
+WARNING: CPU: 22 PID: 44011 at fs/iomap/iter.c:51
+CPU: 22 PID: 44011 Comm: fio Not tainted 6.8.0-rc3+ #1
+RIP: 0010:iomap_iter+0x32b/0x350
+Call Trace:
+ <TASK>
+ __iomap_dio_rw+0x1df/0x830
+ f2fs_file_read_iter+0x156/0x3d0 [f2fs]
+ aio_read+0x138/0x210
+ io_submit_one+0x188/0x8c0
+ __x64_sys_io_submit+0x8c/0x1a0
+ do_syscall_64+0x86/0x170
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+
+Shinichiro Kawasaki helps to analyse this issue and proposes a potential
+fixing patch in [2].
+
+Quoted from reply of Shinichiro Kawasaki:
+
+"I confirmed that the trigger commit is dbf8e63f48af as Yi reported. I took a
+look in the commit, but it looks fine to me. So I thought the cause is not
+in the commit diff.
+
+I found the WARN is printed when the f2fs is set up with multiple devices,
+and read requests are mapped to the very first block of the second device in the
+direct read path. In this case, f2fs_map_blocks() and f2fs_map_blocks_cached()
+modify map->m_pblk as the physical block address from each block device. It
+becomes zero when it is mapped to the first block of the device. However,
+f2fs_iomap_begin() assumes that map->m_pblk is the physical block address of the
+whole f2fs, across the all block devices. It compares map->m_pblk against
+NULL_ADDR == 0, then go into the unexpected branch and sets the invalid
+iomap->length. The WARN catches the invalid iomap->length.
+
+This WARN is printed even for non-zoned block devices, by following steps.
+
+ - Create two (non-zoned) null_blk devices memory backed with 128MB size each:
+ nullb0 and nullb1.
+ # mkfs.f2fs /dev/nullb0 -c /dev/nullb1
+ # mount -t f2fs /dev/nullb0 "${mount_dir}"
+ # dd if=/dev/zero of="${mount_dir}/test.dat" bs=1M count=192
+ # dd if="${mount_dir}/test.dat" of=/dev/null bs=1M count=192 iflag=direct
+
+..."
+
+So, the root cause of this issue is: when multi-devices feature is on,
+f2fs_map_blocks() may return zero blkaddr in non-primary device, which is
+a verified valid block address, however, f2fs_iomap_begin() treats it as
+an invalid block address, and then it triggers the warning in iomap
+framework code.
+
+Finally, as discussed, we decide to use a more simple and direct way that
+checking (map.m_flags & F2FS_MAP_MAPPED) condition instead of
+(map.m_pblk != NULL_ADDR) to fix this issue.
+
+Thanks a lot for the effort of Yi Zhang and Shinichiro Kawasaki on this
+issue.
+
+[1] https://lore.kernel.org/linux-f2fs-devel/CAHj4cs-kfojYC9i0G73PRkYzcxCTex=-vugRFeP40g_URGvnfQ@mail.gmail.com/
+[2] https://lore.kernel.org/linux-f2fs-devel/gngdj77k4picagsfdtiaa7gpgnup6fsgwzsltx6milmhegmjff@iax2n4wvrqye/
+
+Reported-by: Yi Zhang <yi.zhang@redhat.com>
+Closes: https://lore.kernel.org/linux-f2fs-devel/CAHj4cs-kfojYC9i0G73PRkYzcxCTex=-vugRFeP40g_URGvnfQ@mail.gmail.com/
+Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Fixes: 1517c1a7a445 ("f2fs: implement iomap operations")
+Fixes: 8d3c1fa3fa5e ("f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 05158f89ef32d..8e9aaa9e41cce 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -4246,7 +4246,7 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
+ if (WARN_ON_ONCE(map.m_pblk == COMPRESS_ADDR))
+ return -EINVAL;
+
+- if (map.m_pblk != NULL_ADDR) {
++ if (map.m_flags & F2FS_MAP_MAPPED) {
+ iomap->length = blks_to_bytes(inode, map.m_len);
+ iomap->type = IOMAP_MAPPED;
+ iomap->flags |= IOMAP_F_MERGED;
+--
+2.43.0
+
--- /dev/null
+From 4a497caca7acd5bec2c230383b788f06860069af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Apr 2024 09:34:24 +0200
+Subject: firmware: dmi-id: add a release callback function
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit cf770af5645a41a753c55a053fa1237105b0964a ]
+
+dmi_class uses kfree() as the .release function, but that now causes
+a warning with clang-16 as it violates control flow integrity (KCFI)
+rules:
+
+drivers/firmware/dmi-id.c:174:17: error: cast from 'void (*)(const void *)' to 'void (*)(struct device *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 174 | .dev_release = (void(*)(struct device *)) kfree,
+
+Add an explicit function to call kfree() instead.
+
+Fixes: 4f5c791a850e ("DMI-based module autoloading")
+Link: https://lore.kernel.org/lkml/20240213100238.456912-1-arnd@kernel.org/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/dmi-id.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
+index 5f3a3e913d28f..d19c78a78ae3a 100644
+--- a/drivers/firmware/dmi-id.c
++++ b/drivers/firmware/dmi-id.c
+@@ -169,9 +169,14 @@ static int dmi_dev_uevent(const struct device *dev, struct kobj_uevent_env *env)
+ return 0;
+ }
+
++static void dmi_dev_release(struct device *dev)
++{
++ kfree(dev);
++}
++
+ static struct class dmi_class = {
+ .name = "dmi",
+- .dev_release = (void(*)(struct device *)) kfree,
++ .dev_release = dmi_dev_release,
+ .dev_uevent = dmi_dev_uevent,
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 4848bfd76aa2adc3776e49c561586553736260b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Mar 2024 18:18:37 +0100
+Subject: fpga: bridge: add owner module and take its refcount
+
+From: Marco Pagani <marpagan@redhat.com>
+
+[ Upstream commit 1da11f822042eb6ef4b6064dc048f157a7852529 ]
+
+The current implementation of the fpga bridge assumes that the low-level
+module registers a driver for the parent device and uses its owner pointer
+to take the module's refcount. This approach is problematic since it can
+lead to a null pointer dereference while attempting to get the bridge if
+the parent device does not have a driver.
+
+To address this problem, add a module owner pointer to the fpga_bridge
+struct and use it to take the module's refcount. Modify the function for
+registering a bridge to take an additional owner module parameter and
+rename it to avoid conflicts. Use the old function name for a helper macro
+that automatically sets the module that registers the bridge as the owner.
+This ensures compatibility with existing low-level control modules and
+reduces the chances of registering a bridge without setting the owner.
+
+Also, update the documentation to keep it consistent with the new interface
+for registering an fpga bridge.
+
+Other changes: opportunistically move put_device() from __fpga_bridge_get()
+to fpga_bridge_get() and of_fpga_bridge_get() to improve code clarity since
+the bridge device is taken in these functions.
+
+Fixes: 21aeda950c5f ("fpga: add fpga bridge framework")
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Suggested-by: Xu Yilun <yilun.xu@intel.com>
+Reviewed-by: Russ Weight <russ.weight@linux.dev>
+Signed-off-by: Marco Pagani <marpagan@redhat.com>
+Acked-by: Xu Yilun <yilun.xu@intel.com>
+Link: https://lore.kernel.org/r/20240322171839.233864-1-marpagan@redhat.com
+Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/driver-api/fpga/fpga-bridge.rst | 7 ++-
+ drivers/fpga/fpga-bridge.c | 57 ++++++++++---------
+ include/linux/fpga/fpga-bridge.h | 10 +++-
+ 3 files changed, 43 insertions(+), 31 deletions(-)
+
+diff --git a/Documentation/driver-api/fpga/fpga-bridge.rst b/Documentation/driver-api/fpga/fpga-bridge.rst
+index 6042085340953..833f68fb07008 100644
+--- a/Documentation/driver-api/fpga/fpga-bridge.rst
++++ b/Documentation/driver-api/fpga/fpga-bridge.rst
+@@ -6,9 +6,12 @@ API to implement a new FPGA bridge
+
+ * struct fpga_bridge - The FPGA Bridge structure
+ * struct fpga_bridge_ops - Low level Bridge driver ops
+-* fpga_bridge_register() - Create and register a bridge
++* __fpga_bridge_register() - Create and register a bridge
+ * fpga_bridge_unregister() - Unregister a bridge
+
++The helper macro ``fpga_bridge_register()`` automatically sets
++the module that registers the FPGA bridge as the owner.
++
+ .. kernel-doc:: include/linux/fpga/fpga-bridge.h
+ :functions: fpga_bridge
+
+@@ -16,7 +19,7 @@ API to implement a new FPGA bridge
+ :functions: fpga_bridge_ops
+
+ .. kernel-doc:: drivers/fpga/fpga-bridge.c
+- :functions: fpga_bridge_register
++ :functions: __fpga_bridge_register
+
+ .. kernel-doc:: drivers/fpga/fpga-bridge.c
+ :functions: fpga_bridge_unregister
+diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
+index a024be2b84e29..83d35fbb82450 100644
+--- a/drivers/fpga/fpga-bridge.c
++++ b/drivers/fpga/fpga-bridge.c
+@@ -55,33 +55,26 @@ int fpga_bridge_disable(struct fpga_bridge *bridge)
+ }
+ EXPORT_SYMBOL_GPL(fpga_bridge_disable);
+
+-static struct fpga_bridge *__fpga_bridge_get(struct device *dev,
++static struct fpga_bridge *__fpga_bridge_get(struct device *bridge_dev,
+ struct fpga_image_info *info)
+ {
+ struct fpga_bridge *bridge;
+- int ret = -ENODEV;
+
+- bridge = to_fpga_bridge(dev);
++ bridge = to_fpga_bridge(bridge_dev);
+
+ bridge->info = info;
+
+- if (!mutex_trylock(&bridge->mutex)) {
+- ret = -EBUSY;
+- goto err_dev;
+- }
++ if (!mutex_trylock(&bridge->mutex))
++ return ERR_PTR(-EBUSY);
+
+- if (!try_module_get(dev->parent->driver->owner))
+- goto err_ll_mod;
++ if (!try_module_get(bridge->br_ops_owner)) {
++ mutex_unlock(&bridge->mutex);
++ return ERR_PTR(-ENODEV);
++ }
+
+ dev_dbg(&bridge->dev, "get\n");
+
+ return bridge;
+-
+-err_ll_mod:
+- mutex_unlock(&bridge->mutex);
+-err_dev:
+- put_device(dev);
+- return ERR_PTR(ret);
+ }
+
+ /**
+@@ -98,13 +91,18 @@ static struct fpga_bridge *__fpga_bridge_get(struct device *dev,
+ struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
+ struct fpga_image_info *info)
+ {
+- struct device *dev;
++ struct fpga_bridge *bridge;
++ struct device *bridge_dev;
+
+- dev = class_find_device_by_of_node(&fpga_bridge_class, np);
+- if (!dev)
++ bridge_dev = class_find_device_by_of_node(&fpga_bridge_class, np);
++ if (!bridge_dev)
+ return ERR_PTR(-ENODEV);
+
+- return __fpga_bridge_get(dev, info);
++ bridge = __fpga_bridge_get(bridge_dev, info);
++ if (IS_ERR(bridge))
++ put_device(bridge_dev);
++
++ return bridge;
+ }
+ EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
+
+@@ -125,6 +123,7 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data)
+ struct fpga_bridge *fpga_bridge_get(struct device *dev,
+ struct fpga_image_info *info)
+ {
++ struct fpga_bridge *bridge;
+ struct device *bridge_dev;
+
+ bridge_dev = class_find_device(&fpga_bridge_class, NULL, dev,
+@@ -132,7 +131,11 @@ struct fpga_bridge *fpga_bridge_get(struct device *dev,
+ if (!bridge_dev)
+ return ERR_PTR(-ENODEV);
+
+- return __fpga_bridge_get(bridge_dev, info);
++ bridge = __fpga_bridge_get(bridge_dev, info);
++ if (IS_ERR(bridge))
++ put_device(bridge_dev);
++
++ return bridge;
+ }
+ EXPORT_SYMBOL_GPL(fpga_bridge_get);
+
+@@ -146,7 +149,7 @@ void fpga_bridge_put(struct fpga_bridge *bridge)
+ dev_dbg(&bridge->dev, "put\n");
+
+ bridge->info = NULL;
+- module_put(bridge->dev.parent->driver->owner);
++ module_put(bridge->br_ops_owner);
+ mutex_unlock(&bridge->mutex);
+ put_device(&bridge->dev);
+ }
+@@ -316,18 +319,19 @@ static struct attribute *fpga_bridge_attrs[] = {
+ ATTRIBUTE_GROUPS(fpga_bridge);
+
+ /**
+- * fpga_bridge_register - create and register an FPGA Bridge device
++ * __fpga_bridge_register - create and register an FPGA Bridge device
+ * @parent: FPGA bridge device from pdev
+ * @name: FPGA bridge name
+ * @br_ops: pointer to structure of fpga bridge ops
+ * @priv: FPGA bridge private data
++ * @owner: owner module containing the br_ops
+ *
+ * Return: struct fpga_bridge pointer or ERR_PTR()
+ */
+ struct fpga_bridge *
+-fpga_bridge_register(struct device *parent, const char *name,
+- const struct fpga_bridge_ops *br_ops,
+- void *priv)
++__fpga_bridge_register(struct device *parent, const char *name,
++ const struct fpga_bridge_ops *br_ops,
++ void *priv, struct module *owner)
+ {
+ struct fpga_bridge *bridge;
+ int id, ret;
+@@ -357,6 +361,7 @@ fpga_bridge_register(struct device *parent, const char *name,
+
+ bridge->name = name;
+ bridge->br_ops = br_ops;
++ bridge->br_ops_owner = owner;
+ bridge->priv = priv;
+
+ bridge->dev.groups = br_ops->groups;
+@@ -386,7 +391,7 @@ fpga_bridge_register(struct device *parent, const char *name,
+
+ return ERR_PTR(ret);
+ }
+-EXPORT_SYMBOL_GPL(fpga_bridge_register);
++EXPORT_SYMBOL_GPL(__fpga_bridge_register);
+
+ /**
+ * fpga_bridge_unregister - unregister an FPGA bridge
+diff --git a/include/linux/fpga/fpga-bridge.h b/include/linux/fpga/fpga-bridge.h
+index 223da48a6d18b..94c4edd047e54 100644
+--- a/include/linux/fpga/fpga-bridge.h
++++ b/include/linux/fpga/fpga-bridge.h
+@@ -45,6 +45,7 @@ struct fpga_bridge_info {
+ * @dev: FPGA bridge device
+ * @mutex: enforces exclusive reference to bridge
+ * @br_ops: pointer to struct of FPGA bridge ops
++ * @br_ops_owner: module containing the br_ops
+ * @info: fpga image specific information
+ * @node: FPGA bridge list node
+ * @priv: low level driver private date
+@@ -54,6 +55,7 @@ struct fpga_bridge {
+ struct device dev;
+ struct mutex mutex; /* for exclusive reference to bridge */
+ const struct fpga_bridge_ops *br_ops;
++ struct module *br_ops_owner;
+ struct fpga_image_info *info;
+ struct list_head node;
+ void *priv;
+@@ -79,10 +81,12 @@ int of_fpga_bridge_get_to_list(struct device_node *np,
+ struct fpga_image_info *info,
+ struct list_head *bridge_list);
+
++#define fpga_bridge_register(parent, name, br_ops, priv) \
++ __fpga_bridge_register(parent, name, br_ops, priv, THIS_MODULE)
+ struct fpga_bridge *
+-fpga_bridge_register(struct device *parent, const char *name,
+- const struct fpga_bridge_ops *br_ops,
+- void *priv);
++__fpga_bridge_register(struct device *parent, const char *name,
++ const struct fpga_bridge_ops *br_ops, void *priv,
++ struct module *owner);
+ void fpga_bridge_unregister(struct fpga_bridge *br);
+
+ #endif /* _LINUX_FPGA_BRIDGE_H */
+--
+2.43.0
+
--- /dev/null
+From b31579350087e10b608e88b1935ba25e3fc450a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 20:29:26 +0100
+Subject: fpga: manager: add owner module and take its refcount
+
+From: Marco Pagani <marpagan@redhat.com>
+
+[ Upstream commit 4d4d2d4346857bf778fafaa97d6f76bb1663e3c9 ]
+
+The current implementation of the fpga manager assumes that the low-level
+module registers a driver for the parent device and uses its owner pointer
+to take the module's refcount. This approach is problematic since it can
+lead to a null pointer dereference while attempting to get the manager if
+the parent device does not have a driver.
+
+To address this problem, add a module owner pointer to the fpga_manager
+struct and use it to take the module's refcount. Modify the functions for
+registering the manager to take an additional owner module parameter and
+rename them to avoid conflicts. Use the old function names for helper
+macros that automatically set the module that registers the manager as the
+owner. This ensures compatibility with existing low-level control modules
+and reduces the chances of registering a manager without setting the owner.
+
+Also, update the documentation to keep it consistent with the new interface
+for registering an fpga manager.
+
+Other changes: opportunistically move put_device() from __fpga_mgr_get() to
+fpga_mgr_get() and of_fpga_mgr_get() to improve code clarity since the
+manager device is taken in these functions.
+
+Fixes: 654ba4cc0f3e ("fpga manager: ensure lifetime with of_fpga_mgr_get")
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Suggested-by: Xu Yilun <yilun.xu@intel.com>
+Signed-off-by: Marco Pagani <marpagan@redhat.com>
+Acked-by: Xu Yilun <yilun.xu@intel.com>
+Link: https://lore.kernel.org/r/20240305192926.84886-1-marpagan@redhat.com
+Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/driver-api/fpga/fpga-mgr.rst | 34 +++++----
+ drivers/fpga/fpga-mgr.c | 82 +++++++++++++---------
+ include/linux/fpga/fpga-mgr.h | 26 +++++--
+ 3 files changed, 89 insertions(+), 53 deletions(-)
+
+diff --git a/Documentation/driver-api/fpga/fpga-mgr.rst b/Documentation/driver-api/fpga/fpga-mgr.rst
+index 49c0a95126532..8d2b79f696c1f 100644
+--- a/Documentation/driver-api/fpga/fpga-mgr.rst
++++ b/Documentation/driver-api/fpga/fpga-mgr.rst
+@@ -24,7 +24,8 @@ How to support a new FPGA device
+ --------------------------------
+
+ To add another FPGA manager, write a driver that implements a set of ops. The
+-probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as::
++probe function calls ``fpga_mgr_register()`` or ``fpga_mgr_register_full()``,
++such as::
+
+ static const struct fpga_manager_ops socfpga_fpga_ops = {
+ .write_init = socfpga_fpga_ops_configure_init,
+@@ -69,10 +70,11 @@ probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as::
+ }
+
+ Alternatively, the probe function could call one of the resource managed
+-register functions, devm_fpga_mgr_register() or devm_fpga_mgr_register_full().
+-When these functions are used, the parameter syntax is the same, but the call
+-to fpga_mgr_unregister() should be removed. In the above example, the
+-socfpga_fpga_remove() function would not be required.
++register functions, ``devm_fpga_mgr_register()`` or
++``devm_fpga_mgr_register_full()``. When these functions are used, the
++parameter syntax is the same, but the call to ``fpga_mgr_unregister()`` should be
++removed. In the above example, the ``socfpga_fpga_remove()`` function would not be
++required.
+
+ The ops will implement whatever device specific register writes are needed to
+ do the programming sequence for this particular FPGA. These ops return 0 for
+@@ -125,15 +127,19 @@ API for implementing a new FPGA Manager driver
+ * struct fpga_manager - the FPGA manager struct
+ * struct fpga_manager_ops - Low level FPGA manager driver ops
+ * struct fpga_manager_info - Parameter structure for fpga_mgr_register_full()
+-* fpga_mgr_register_full() - Create and register an FPGA manager using the
++* __fpga_mgr_register_full() - Create and register an FPGA manager using the
+ fpga_mgr_info structure to provide the full flexibility of options
+-* fpga_mgr_register() - Create and register an FPGA manager using standard
++* __fpga_mgr_register() - Create and register an FPGA manager using standard
+ arguments
+-* devm_fpga_mgr_register_full() - Resource managed version of
+- fpga_mgr_register_full()
+-* devm_fpga_mgr_register() - Resource managed version of fpga_mgr_register()
++* __devm_fpga_mgr_register_full() - Resource managed version of
++ __fpga_mgr_register_full()
++* __devm_fpga_mgr_register() - Resource managed version of __fpga_mgr_register()
+ * fpga_mgr_unregister() - Unregister an FPGA manager
+
++Helper macros ``fpga_mgr_register_full()``, ``fpga_mgr_register()``,
++``devm_fpga_mgr_register_full()``, and ``devm_fpga_mgr_register()`` are available
++to ease the registration.
++
+ .. kernel-doc:: include/linux/fpga/fpga-mgr.h
+ :functions: fpga_mgr_states
+
+@@ -147,16 +153,16 @@ API for implementing a new FPGA Manager driver
+ :functions: fpga_manager_info
+
+ .. kernel-doc:: drivers/fpga/fpga-mgr.c
+- :functions: fpga_mgr_register_full
++ :functions: __fpga_mgr_register_full
+
+ .. kernel-doc:: drivers/fpga/fpga-mgr.c
+- :functions: fpga_mgr_register
++ :functions: __fpga_mgr_register
+
+ .. kernel-doc:: drivers/fpga/fpga-mgr.c
+- :functions: devm_fpga_mgr_register_full
++ :functions: __devm_fpga_mgr_register_full
+
+ .. kernel-doc:: drivers/fpga/fpga-mgr.c
+- :functions: devm_fpga_mgr_register
++ :functions: __devm_fpga_mgr_register
+
+ .. kernel-doc:: drivers/fpga/fpga-mgr.c
+ :functions: fpga_mgr_unregister
+diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
+index 06651389c5926..0f4035b089a2e 100644
+--- a/drivers/fpga/fpga-mgr.c
++++ b/drivers/fpga/fpga-mgr.c
+@@ -664,20 +664,16 @@ static struct attribute *fpga_mgr_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(fpga_mgr);
+
+-static struct fpga_manager *__fpga_mgr_get(struct device *dev)
++static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev)
+ {
+ struct fpga_manager *mgr;
+
+- mgr = to_fpga_manager(dev);
++ mgr = to_fpga_manager(mgr_dev);
+
+- if (!try_module_get(dev->parent->driver->owner))
+- goto err_dev;
++ if (!try_module_get(mgr->mops_owner))
++ mgr = ERR_PTR(-ENODEV);
+
+ return mgr;
+-
+-err_dev:
+- put_device(dev);
+- return ERR_PTR(-ENODEV);
+ }
+
+ static int fpga_mgr_dev_match(struct device *dev, const void *data)
+@@ -693,12 +689,18 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data)
+ */
+ struct fpga_manager *fpga_mgr_get(struct device *dev)
+ {
+- struct device *mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev,
+- fpga_mgr_dev_match);
++ struct fpga_manager *mgr;
++ struct device *mgr_dev;
++
++ mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, fpga_mgr_dev_match);
+ if (!mgr_dev)
+ return ERR_PTR(-ENODEV);
+
+- return __fpga_mgr_get(mgr_dev);
++ mgr = __fpga_mgr_get(mgr_dev);
++ if (IS_ERR(mgr))
++ put_device(mgr_dev);
++
++ return mgr;
+ }
+ EXPORT_SYMBOL_GPL(fpga_mgr_get);
+
+@@ -711,13 +713,18 @@ EXPORT_SYMBOL_GPL(fpga_mgr_get);
+ */
+ struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
+ {
+- struct device *dev;
++ struct fpga_manager *mgr;
++ struct device *mgr_dev;
+
+- dev = class_find_device_by_of_node(&fpga_mgr_class, node);
+- if (!dev)
++ mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node);
++ if (!mgr_dev)
+ return ERR_PTR(-ENODEV);
+
+- return __fpga_mgr_get(dev);
++ mgr = __fpga_mgr_get(mgr_dev);
++ if (IS_ERR(mgr))
++ put_device(mgr_dev);
++
++ return mgr;
+ }
+ EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
+
+@@ -727,7 +734,7 @@ EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
+ */
+ void fpga_mgr_put(struct fpga_manager *mgr)
+ {
+- module_put(mgr->dev.parent->driver->owner);
++ module_put(mgr->mops_owner);
+ put_device(&mgr->dev);
+ }
+ EXPORT_SYMBOL_GPL(fpga_mgr_put);
+@@ -766,9 +773,10 @@ void fpga_mgr_unlock(struct fpga_manager *mgr)
+ EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
+
+ /**
+- * fpga_mgr_register_full - create and register an FPGA Manager device
++ * __fpga_mgr_register_full - create and register an FPGA Manager device
+ * @parent: fpga manager device from pdev
+ * @info: parameters for fpga manager
++ * @owner: owner module containing the ops
+ *
+ * The caller of this function is responsible for calling fpga_mgr_unregister().
+ * Using devm_fpga_mgr_register_full() instead is recommended.
+@@ -776,7 +784,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
+ * Return: pointer to struct fpga_manager pointer or ERR_PTR()
+ */
+ struct fpga_manager *
+-fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info)
++__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
++ struct module *owner)
+ {
+ const struct fpga_manager_ops *mops = info->mops;
+ struct fpga_manager *mgr;
+@@ -804,6 +813,8 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in
+
+ mutex_init(&mgr->ref_mutex);
+
++ mgr->mops_owner = owner;
++
+ mgr->name = info->name;
+ mgr->mops = info->mops;
+ mgr->priv = info->priv;
+@@ -841,14 +852,15 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in
+
+ return ERR_PTR(ret);
+ }
+-EXPORT_SYMBOL_GPL(fpga_mgr_register_full);
++EXPORT_SYMBOL_GPL(__fpga_mgr_register_full);
+
+ /**
+- * fpga_mgr_register - create and register an FPGA Manager device
++ * __fpga_mgr_register - create and register an FPGA Manager device
+ * @parent: fpga manager device from pdev
+ * @name: fpga manager name
+ * @mops: pointer to structure of fpga manager ops
+ * @priv: fpga manager private data
++ * @owner: owner module containing the ops
+ *
+ * The caller of this function is responsible for calling fpga_mgr_unregister().
+ * Using devm_fpga_mgr_register() instead is recommended. This simple
+@@ -859,8 +871,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_register_full);
+ * Return: pointer to struct fpga_manager pointer or ERR_PTR()
+ */
+ struct fpga_manager *
+-fpga_mgr_register(struct device *parent, const char *name,
+- const struct fpga_manager_ops *mops, void *priv)
++__fpga_mgr_register(struct device *parent, const char *name,
++ const struct fpga_manager_ops *mops, void *priv, struct module *owner)
+ {
+ struct fpga_manager_info info = { 0 };
+
+@@ -868,9 +880,9 @@ fpga_mgr_register(struct device *parent, const char *name,
+ info.mops = mops;
+ info.priv = priv;
+
+- return fpga_mgr_register_full(parent, &info);
++ return __fpga_mgr_register_full(parent, &info, owner);
+ }
+-EXPORT_SYMBOL_GPL(fpga_mgr_register);
++EXPORT_SYMBOL_GPL(__fpga_mgr_register);
+
+ /**
+ * fpga_mgr_unregister - unregister an FPGA manager
+@@ -900,9 +912,10 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res)
+ }
+
+ /**
+- * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()
++ * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()
+ * @parent: fpga manager device from pdev
+ * @info: parameters for fpga manager
++ * @owner: owner module containing the ops
+ *
+ * Return: fpga manager pointer on success, negative error code otherwise.
+ *
+@@ -910,7 +923,8 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res)
+ * function will be called automatically when the managing device is detached.
+ */
+ struct fpga_manager *
+-devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info)
++__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
++ struct module *owner)
+ {
+ struct fpga_mgr_devres *dr;
+ struct fpga_manager *mgr;
+@@ -919,7 +933,7 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf
+ if (!dr)
+ return ERR_PTR(-ENOMEM);
+
+- mgr = fpga_mgr_register_full(parent, info);
++ mgr = __fpga_mgr_register_full(parent, info, owner);
+ if (IS_ERR(mgr)) {
+ devres_free(dr);
+ return mgr;
+@@ -930,14 +944,15 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf
+
+ return mgr;
+ }
+-EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full);
++EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full);
+
+ /**
+- * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
++ * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
+ * @parent: fpga manager device from pdev
+ * @name: fpga manager name
+ * @mops: pointer to structure of fpga manager ops
+ * @priv: fpga manager private data
++ * @owner: owner module containing the ops
+ *
+ * Return: fpga manager pointer on success, negative error code otherwise.
+ *
+@@ -946,8 +961,9 @@ EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full);
+ * device is detached.
+ */
+ struct fpga_manager *
+-devm_fpga_mgr_register(struct device *parent, const char *name,
+- const struct fpga_manager_ops *mops, void *priv)
++__devm_fpga_mgr_register(struct device *parent, const char *name,
++ const struct fpga_manager_ops *mops, void *priv,
++ struct module *owner)
+ {
+ struct fpga_manager_info info = { 0 };
+
+@@ -955,9 +971,9 @@ devm_fpga_mgr_register(struct device *parent, const char *name,
+ info.mops = mops;
+ info.priv = priv;
+
+- return devm_fpga_mgr_register_full(parent, &info);
++ return __devm_fpga_mgr_register_full(parent, &info, owner);
+ }
+-EXPORT_SYMBOL_GPL(devm_fpga_mgr_register);
++EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register);
+
+ static void fpga_mgr_dev_release(struct device *dev)
+ {
+diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
+index 54f63459efd6e..0d4fe068f3d8a 100644
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -201,6 +201,7 @@ struct fpga_manager_ops {
+ * @state: state of fpga manager
+ * @compat_id: FPGA manager id for compatibility check.
+ * @mops: pointer to struct of fpga manager ops
++ * @mops_owner: module containing the mops
+ * @priv: low level driver private date
+ */
+ struct fpga_manager {
+@@ -210,6 +211,7 @@ struct fpga_manager {
+ enum fpga_mgr_states state;
+ struct fpga_compat_id *compat_id;
+ const struct fpga_manager_ops *mops;
++ struct module *mops_owner;
+ void *priv;
+ };
+
+@@ -230,18 +232,30 @@ struct fpga_manager *fpga_mgr_get(struct device *dev);
+
+ void fpga_mgr_put(struct fpga_manager *mgr);
+
++#define fpga_mgr_register_full(parent, info) \
++ __fpga_mgr_register_full(parent, info, THIS_MODULE)
+ struct fpga_manager *
+-fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info);
++__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
++ struct module *owner);
+
++#define fpga_mgr_register(parent, name, mops, priv) \
++ __fpga_mgr_register(parent, name, mops, priv, THIS_MODULE)
+ struct fpga_manager *
+-fpga_mgr_register(struct device *parent, const char *name,
+- const struct fpga_manager_ops *mops, void *priv);
++__fpga_mgr_register(struct device *parent, const char *name,
++ const struct fpga_manager_ops *mops, void *priv, struct module *owner);
++
+ void fpga_mgr_unregister(struct fpga_manager *mgr);
+
++#define devm_fpga_mgr_register_full(parent, info) \
++ __devm_fpga_mgr_register_full(parent, info, THIS_MODULE)
+ struct fpga_manager *
+-devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info);
++__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
++ struct module *owner);
++#define devm_fpga_mgr_register(parent, name, mops, priv) \
++ __devm_fpga_mgr_register(parent, name, mops, priv, THIS_MODULE)
+ struct fpga_manager *
+-devm_fpga_mgr_register(struct device *parent, const char *name,
+- const struct fpga_manager_ops *mops, void *priv);
++__devm_fpga_mgr_register(struct device *parent, const char *name,
++ const struct fpga_manager_ops *mops, void *priv,
++ struct module *owner);
+
+ #endif /*_LINUX_FPGA_MGR_H */
+--
+2.43.0
+
--- /dev/null
+From fea28798459b011fd39139f7e040ea12832632d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Apr 2024 10:35:59 +0200
+Subject: fpga: region: add owner module and take its refcount
+
+From: Marco Pagani <marpagan@redhat.com>
+
+[ Upstream commit b7c0e1ecee403a43abc89eb3e75672b01ff2ece9 ]
+
+The current implementation of the fpga region assumes that the low-level
+module registers a driver for the parent device and uses its owner pointer
+to take the module's refcount. This approach is problematic since it can
+lead to a null pointer dereference while attempting to get the region
+during programming if the parent device does not have a driver.
+
+To address this problem, add a module owner pointer to the fpga_region
+struct and use it to take the module's refcount. Modify the functions for
+registering a region to take an additional owner module parameter and
+rename them to avoid conflicts. Use the old function names for helper
+macros that automatically set the module that registers the region as the
+owner. This ensures compatibility with existing low-level control modules
+and reduces the chances of registering a region without setting the owner.
+
+Also, update the documentation to keep it consistent with the new interface
+for registering an fpga region.
+
+Fixes: 0fa20cdfcc1f ("fpga: fpga-region: device tree control for FPGA")
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Suggested-by: Xu Yilun <yilun.xu@intel.com>
+Reviewed-by: Russ Weight <russ.weight@linux.dev>
+Signed-off-by: Marco Pagani <marpagan@redhat.com>
+Acked-by: Xu Yilun <yilun.xu@intel.com>
+Link: https://lore.kernel.org/r/20240419083601.77403-1-marpagan@redhat.com
+Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/driver-api/fpga/fpga-region.rst | 13 ++++++----
+ drivers/fpga/fpga-region.c | 24 +++++++++++--------
+ include/linux/fpga/fpga-region.h | 13 +++++++---
+ 3 files changed, 32 insertions(+), 18 deletions(-)
+
+diff --git a/Documentation/driver-api/fpga/fpga-region.rst b/Documentation/driver-api/fpga/fpga-region.rst
+index dc55d60a0b4a5..2d03b5fb76575 100644
+--- a/Documentation/driver-api/fpga/fpga-region.rst
++++ b/Documentation/driver-api/fpga/fpga-region.rst
+@@ -46,13 +46,16 @@ API to add a new FPGA region
+ ----------------------------
+
+ * struct fpga_region - The FPGA region struct
+-* struct fpga_region_info - Parameter structure for fpga_region_register_full()
+-* fpga_region_register_full() - Create and register an FPGA region using the
++* struct fpga_region_info - Parameter structure for __fpga_region_register_full()
++* __fpga_region_register_full() - Create and register an FPGA region using the
+ fpga_region_info structure to provide the full flexibility of options
+-* fpga_region_register() - Create and register an FPGA region using standard
++* __fpga_region_register() - Create and register an FPGA region using standard
+ arguments
+ * fpga_region_unregister() - Unregister an FPGA region
+
++Helper macros ``fpga_region_register()`` and ``fpga_region_register_full()``
++automatically set the module that registers the FPGA region as the owner.
++
+ The FPGA region's probe function will need to get a reference to the FPGA
+ Manager it will be using to do the programming. This usually would happen
+ during the region's probe function.
+@@ -82,10 +85,10 @@ following APIs to handle building or tearing down that list.
+ :functions: fpga_region_info
+
+ .. kernel-doc:: drivers/fpga/fpga-region.c
+- :functions: fpga_region_register_full
++ :functions: __fpga_region_register_full
+
+ .. kernel-doc:: drivers/fpga/fpga-region.c
+- :functions: fpga_region_register
++ :functions: __fpga_region_register
+
+ .. kernel-doc:: drivers/fpga/fpga-region.c
+ :functions: fpga_region_unregister
+diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
+index b364a929425ce..753cd142503e0 100644
+--- a/drivers/fpga/fpga-region.c
++++ b/drivers/fpga/fpga-region.c
+@@ -53,7 +53,7 @@ static struct fpga_region *fpga_region_get(struct fpga_region *region)
+ }
+
+ get_device(dev);
+- if (!try_module_get(dev->parent->driver->owner)) {
++ if (!try_module_get(region->ops_owner)) {
+ put_device(dev);
+ mutex_unlock(®ion->mutex);
+ return ERR_PTR(-ENODEV);
+@@ -75,7 +75,7 @@ static void fpga_region_put(struct fpga_region *region)
+
+ dev_dbg(dev, "put\n");
+
+- module_put(dev->parent->driver->owner);
++ module_put(region->ops_owner);
+ put_device(dev);
+ mutex_unlock(®ion->mutex);
+ }
+@@ -181,14 +181,16 @@ static struct attribute *fpga_region_attrs[] = {
+ ATTRIBUTE_GROUPS(fpga_region);
+
+ /**
+- * fpga_region_register_full - create and register an FPGA Region device
++ * __fpga_region_register_full - create and register an FPGA Region device
+ * @parent: device parent
+ * @info: parameters for FPGA Region
++ * @owner: module containing the get_bridges function
+ *
+ * Return: struct fpga_region or ERR_PTR()
+ */
+ struct fpga_region *
+-fpga_region_register_full(struct device *parent, const struct fpga_region_info *info)
++__fpga_region_register_full(struct device *parent, const struct fpga_region_info *info,
++ struct module *owner)
+ {
+ struct fpga_region *region;
+ int id, ret = 0;
+@@ -213,6 +215,7 @@ fpga_region_register_full(struct device *parent, const struct fpga_region_info *
+ region->compat_id = info->compat_id;
+ region->priv = info->priv;
+ region->get_bridges = info->get_bridges;
++ region->ops_owner = owner;
+
+ mutex_init(®ion->mutex);
+ INIT_LIST_HEAD(®ion->bridge_list);
+@@ -241,13 +244,14 @@ fpga_region_register_full(struct device *parent, const struct fpga_region_info *
+
+ return ERR_PTR(ret);
+ }
+-EXPORT_SYMBOL_GPL(fpga_region_register_full);
++EXPORT_SYMBOL_GPL(__fpga_region_register_full);
+
+ /**
+- * fpga_region_register - create and register an FPGA Region device
++ * __fpga_region_register - create and register an FPGA Region device
+ * @parent: device parent
+ * @mgr: manager that programs this region
+ * @get_bridges: optional function to get bridges to a list
++ * @owner: module containing the get_bridges function
+ *
+ * This simple version of the register function should be sufficient for most users.
+ * The fpga_region_register_full() function is available for users that need to
+@@ -256,17 +260,17 @@ EXPORT_SYMBOL_GPL(fpga_region_register_full);
+ * Return: struct fpga_region or ERR_PTR()
+ */
+ struct fpga_region *
+-fpga_region_register(struct device *parent, struct fpga_manager *mgr,
+- int (*get_bridges)(struct fpga_region *))
++__fpga_region_register(struct device *parent, struct fpga_manager *mgr,
++ int (*get_bridges)(struct fpga_region *), struct module *owner)
+ {
+ struct fpga_region_info info = { 0 };
+
+ info.mgr = mgr;
+ info.get_bridges = get_bridges;
+
+- return fpga_region_register_full(parent, &info);
++ return __fpga_region_register_full(parent, &info, owner);
+ }
+-EXPORT_SYMBOL_GPL(fpga_region_register);
++EXPORT_SYMBOL_GPL(__fpga_region_register);
+
+ /**
+ * fpga_region_unregister - unregister an FPGA region
+diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
+index 9d4d32909340a..5fbc05fe70a6b 100644
+--- a/include/linux/fpga/fpga-region.h
++++ b/include/linux/fpga/fpga-region.h
+@@ -36,6 +36,7 @@ struct fpga_region_info {
+ * @mgr: FPGA manager
+ * @info: FPGA image info
+ * @compat_id: FPGA region id for compatibility check.
++ * @ops_owner: module containing the get_bridges function
+ * @priv: private data
+ * @get_bridges: optional function to get bridges to a list
+ */
+@@ -46,6 +47,7 @@ struct fpga_region {
+ struct fpga_manager *mgr;
+ struct fpga_image_info *info;
+ struct fpga_compat_id *compat_id;
++ struct module *ops_owner;
+ void *priv;
+ int (*get_bridges)(struct fpga_region *region);
+ };
+@@ -58,12 +60,17 @@ fpga_region_class_find(struct device *start, const void *data,
+
+ int fpga_region_program_fpga(struct fpga_region *region);
+
++#define fpga_region_register_full(parent, info) \
++ __fpga_region_register_full(parent, info, THIS_MODULE)
+ struct fpga_region *
+-fpga_region_register_full(struct device *parent, const struct fpga_region_info *info);
++__fpga_region_register_full(struct device *parent, const struct fpga_region_info *info,
++ struct module *owner);
+
++#define fpga_region_register(parent, mgr, get_bridges) \
++ __fpga_region_register(parent, mgr, get_bridges, THIS_MODULE)
+ struct fpga_region *
+-fpga_region_register(struct device *parent, struct fpga_manager *mgr,
+- int (*get_bridges)(struct fpga_region *));
++__fpga_region_register(struct device *parent, struct fpga_manager *mgr,
++ int (*get_bridges)(struct fpga_region *), struct module *owner);
+ void fpga_region_unregister(struct fpga_region *region);
+
+ #endif /* _FPGA_REGION_H */
+--
+2.43.0
+
--- /dev/null
+From 201d6e16ca1902df45f21bb3669ec40dcbd5aa39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 May 2024 15:59:01 +0800
+Subject: gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent
+ node match
+
+From: Devyn Liu <liudingyuan@huawei.com>
+
+[ Upstream commit adbc49a5a8c6fcf7be154c2e30213bbf472940da ]
+
+Previous patch modified the standard used by acpi_gpiochip_find()
+to match device nodes. Using the device node set in gc->gpiodev->d-
+ev instead of gc->parent.
+
+However, there is a situation in gpio-dwapb where the GPIO device
+driver will set gc->fwnode for each port corresponding to a child
+node under a GPIO device, so gc->gpiodev->dev will be assigned the
+value of each child node in gpiochip_add_data().
+
+gpio-dwapb.c:
+128,31 static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
+ struct dwapb_port_property *pp,
+ unsigned int offs);
+port->gc.fwnode = pp->fwnode;
+
+693,39 static int dwapb_gpio_probe;
+err = dwapb_gpio_add_port(gpio, &pdata->properties[i], i);
+
+When other drivers request GPIO pin resources through the GPIO device
+node provided by ACPI (corresponding to the parent node), the change
+of the matching object to gc->gpiodev->dev in acpi_gpiochip_find()
+only allows finding the value of each port (child node), resulting
+in a failed request.
+
+Reapply the condition of using gc->parent for match in acpi_gpio-
+chip_find() in the code can compatible with the problem of gpio-dwapb,
+and will not affect the two cases mentioned in the patch:
+1. There is no setting for gc->fwnode.
+2. The case that depends on using gc->fwnode for match.
+
+Fixes: 5062e4c14b75 ("gpiolib: acpi: use the fwnode in acpi_gpiochip_find()")
+Fixes: 067dbc1ea5ce ("gpiolib: acpi: Don't use GPIO chip fwnode in acpi_gpiochip_find()")
+Signed-off-by: Devyn Liu <liudingyuan@huawei.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Tested-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-acpi.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
+index cd3e9657cc36d..551b604903e14 100644
+--- a/drivers/gpio/gpiolib-acpi.c
++++ b/drivers/gpio/gpiolib-acpi.c
+@@ -128,7 +128,24 @@ static bool acpi_gpio_deferred_req_irqs_done;
+
+ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
+ {
+- return device_match_acpi_handle(&gc->gpiodev->dev, data);
++ /* First check the actual GPIO device */
++ if (device_match_acpi_handle(&gc->gpiodev->dev, data))
++ return true;
++
++ /*
++ * When the ACPI device is artificially split to the banks of GPIOs,
++ * where each of them is represented by a separate GPIO device,
++ * the firmware node of the physical device may not be shared among
++ * the banks as they may require different values for the same property,
++ * e.g., number of GPIOs in a certain bank. In such case the ACPI handle
++ * of a GPIO device is NULL and can not be used. Hence we have to check
++ * the parent device to be sure that there is no match before bailing
++ * out.
++ */
++ if (gc->parent)
++ return device_match_acpi_handle(gc->parent, data);
++
++ return false;
+ }
+
+ /**
+--
+2.43.0
+
--- /dev/null
+From 842e5c47e09a65f3044958a75d9ce9c0bc79274a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 10:06:35 +0200
+Subject: greybus: arche-ctrl: move device table to its right location
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 6a0b8c0da8d8d418cde6894a104cf74e6098ddfa ]
+
+The arche-ctrl has two platform drivers and three of_device_id tables,
+but one table is only used for the the module loader, while the other
+two seem to be associated with their drivers.
+
+This leads to a W=1 warning when the driver is built-in:
+
+drivers/staging/greybus/arche-platform.c:623:34: error: 'arche_combined_id' defined but not used [-Werror=unused-const-variable=]
+ 623 | static const struct of_device_id arche_combined_id[] = {
+
+Drop the extra table and register both tables that are actually
+used as the ones for the module loader instead.
+
+Fixes: 7b62b61c752a ("greybus: arche-ctrl: Don't expose driver internals to arche-platform driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240403080702.3509288-18-arnd@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/greybus/arche-apb-ctrl.c | 1 +
+ drivers/staging/greybus/arche-platform.c | 9 +--------
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c
+index 8541995008da8..aa6f266b62a14 100644
+--- a/drivers/staging/greybus/arche-apb-ctrl.c
++++ b/drivers/staging/greybus/arche-apb-ctrl.c
+@@ -466,6 +466,7 @@ static const struct of_device_id arche_apb_ctrl_of_match[] = {
+ { .compatible = "usbffff,2", },
+ { },
+ };
++MODULE_DEVICE_TABLE(of, arche_apb_ctrl_of_match);
+
+ static struct platform_driver arche_apb_ctrl_device_driver = {
+ .probe = arche_apb_ctrl_probe,
+diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c
+index 891b75327d7f7..b33977ccd5271 100644
+--- a/drivers/staging/greybus/arche-platform.c
++++ b/drivers/staging/greybus/arche-platform.c
+@@ -619,14 +619,7 @@ static const struct of_device_id arche_platform_of_match[] = {
+ { .compatible = "google,arche-platform", },
+ { },
+ };
+-
+-static const struct of_device_id arche_combined_id[] = {
+- /* Use PID/VID of SVC device */
+- { .compatible = "google,arche-platform", },
+- { .compatible = "usbffff,2", },
+- { },
+-};
+-MODULE_DEVICE_TABLE(of, arche_combined_id);
++MODULE_DEVICE_TABLE(of, arche_platform_of_match);
+
+ static struct platform_driver arche_platform_device_driver = {
+ .probe = arche_platform_probe,
+--
+2.43.0
+
--- /dev/null
+From 27cde0cdadc5b0cb91660fb5b2506bd4c539aaab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 22:09:55 +0000
+Subject: greybus: lights: check return of get_channel_from_mode
+
+From: Rui Miguel Silva <rmfrfs@gmail.com>
+
+[ Upstream commit a1ba19a1ae7cd1e324685ded4ab563e78fe68648 ]
+
+If channel for the given node is not found we return null from
+get_channel_from_mode. Make sure we validate the return pointer
+before using it in two of the missing places.
+
+This was originally reported in [0]:
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+[0] https://lore.kernel.org/all/20240301190425.120605-1-m.lobanov@rosalinux.ru
+
+Fixes: 2870b52bae4c ("greybus: lights: add lights implementation")
+Reported-by: Mikhail Lobanov <m.lobanov@rosalinux.ru>
+Suggested-by: Mikhail Lobanov <m.lobanov@rosalinux.ru>
+Suggested-by: Alex Elder <elder@ieee.org>
+Signed-off-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Link: https://lore.kernel.org/r/20240325221549.2185265-1-rmfrfs@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/greybus/light.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c
+index c6bd86a5335ab..9999f84016992 100644
+--- a/drivers/staging/greybus/light.c
++++ b/drivers/staging/greybus/light.c
+@@ -147,6 +147,9 @@ static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
+ channel = get_channel_from_mode(channel->light,
+ GB_CHANNEL_MODE_TORCH);
+
++ if (!channel)
++ return -EINVAL;
++
+ /* For not flash we need to convert brightness to intensity */
+ intensity = channel->intensity_uA.min +
+ (channel->intensity_uA.step * channel->led->brightness);
+@@ -549,7 +552,10 @@ static int gb_lights_light_v4l2_register(struct gb_light *light)
+ }
+
+ channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH);
+- WARN_ON(!channel_flash);
++ if (!channel_flash) {
++ dev_err(dev, "failed to get flash channel from mode\n");
++ return -EINVAL;
++ }
+
+ fled = &channel_flash->fled;
+
+--
+2.43.0
+
--- /dev/null
+From abbfa6ff114dcafc4f73e3c4872b3761080e6496 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 May 2024 15:12:08 +0530
+Subject: i2c: cadence: Avoid fifo clear after start
+
+From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
+
+[ Upstream commit c2e55b449de7298a751ed0256251019d302af453 ]
+
+The Driver unintentionally programs ctrl reg to clear the fifo, which
+happens after the start of transaction. Previously, this was not an issue
+as it involved read-modified-write. However, this issue breaks i2c reads
+on QEMU, as i2c-read is executed before guest starts programming control
+register.
+
+Fixes: ff0cf7bca630 ("i2c: cadence: Remove unnecessary register reads")
+Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-cadence.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index de3f58b60dce5..6f7d753a8197c 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -633,6 +633,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
+
+ if (hold_clear) {
+ ctrl_reg &= ~CDNS_I2C_CR_HOLD;
++ ctrl_reg &= ~CDNS_I2C_CR_CLR_FIFO;
+ /*
+ * In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size
+ * register reaches '0'. This is an IP bug which causes transfer size
+--
+2.43.0
+
--- /dev/null
+From 0cc02bc8e603bfd57c1d9fd2074e3f66a7c8e4ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jan 2024 13:48:24 +0100
+Subject: i2c: synquacer: Fix an error handling path in synquacer_i2c_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 55750148e5595bb85605e8fbb40b2759c2c4c2d7 ]
+
+If an error occurs after the clk_prepare_enable() call, it should be undone
+by a corresponding clk_disable_unprepare() call, as already done in the
+remove() function.
+
+As devm_clk_get() is used, we can switch to devm_clk_get_enabled() to
+handle it automatically and fix the probe.
+
+Update the remove() function accordingly and remove the now useless
+clk_disable_unprepare() call.
+
+Fixes: 0d676a6c4390 ("i2c: add support for Socionext SynQuacer I2C controller")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-synquacer.c | 20 +++++++-------------
+ 1 file changed, 7 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c
+index bbea521b05dda..a73f5bb9a1645 100644
+--- a/drivers/i2c/busses/i2c-synquacer.c
++++ b/drivers/i2c/busses/i2c-synquacer.c
+@@ -550,17 +550,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
+ device_property_read_u32(&pdev->dev, "socionext,pclk-rate",
+ &i2c->pclkrate);
+
+- i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
+- if (PTR_ERR(i2c->pclk) == -EPROBE_DEFER)
+- return -EPROBE_DEFER;
+- if (!IS_ERR_OR_NULL(i2c->pclk)) {
+- dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
+-
+- ret = clk_prepare_enable(i2c->pclk);
+- if (ret)
+- return dev_err_probe(&pdev->dev, ret, "failed to enable clock\n");
+- i2c->pclkrate = clk_get_rate(i2c->pclk);
+- }
++ i2c->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
++ if (IS_ERR(i2c->pclk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(i2c->pclk),
++ "failed to get and enable clock\n");
++
++ dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
++ i2c->pclkrate = clk_get_rate(i2c->pclk);
+
+ if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE ||
+ i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE)
+@@ -615,8 +611,6 @@ static void synquacer_i2c_remove(struct platform_device *pdev)
+ struct synquacer_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adapter);
+- if (!IS_ERR(i2c->pclk))
+- clk_disable_unprepare(i2c->pclk);
+ };
+
+ static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = {
+--
+2.43.0
+
--- /dev/null
+From ceaee2be56b77c3c2515cf26bff6ceaa10c09a85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Mar 2024 18:53:00 +0000
+Subject: iio: adc: stm32: Fixing err code to not indicate success
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 3735ca0b072656c3aa2cedc617a5e639b583a472 ]
+
+This path would result in returning 0 / success on an error path.
+
+Cc: Olivier Moysan <olivier.moysan@foss.st.com>
+Fixes: 95bc818404b2 ("iio: adc: stm32-adc: add support of generic channels binding")
+Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Link: https://lore.kernel.org/r/20240330185305.1319844-4-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/stm32-adc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
+index b5d3c9cea5c4e..283c207571064 100644
+--- a/drivers/iio/adc/stm32-adc.c
++++ b/drivers/iio/adc/stm32-adc.c
+@@ -2234,6 +2234,7 @@ static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev,
+ if (vin[0] != val || vin[1] >= adc_info->max_channels) {
+ dev_err(&indio_dev->dev, "Invalid channel in%d-in%d\n",
+ vin[0], vin[1]);
++ ret = -EINVAL;
+ goto err;
+ }
+ } else if (ret != -EINVAL) {
+--
+2.43.0
+
--- /dev/null
+From 53d08e24206248c2744b3bffb4a359ce95ed3169 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Mar 2024 16:04:32 +0200
+Subject: iio: core: Leave private pointer NULL when no private data supplied
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit f0245ab389330cbc1d187e358a5b890d9f5383db ]
+
+In iio_device_alloc() when size of the private data is 0,
+the private pointer is calculated to point behind the valid data.
+Leave it NULL when no private data supplied.
+
+Fixes: 6d4ebd565d15 ("iio: core: wrap IIO device into an iio_dev_opaque object")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://lore.kernel.org/r/20240304140650.977784-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/industrialio-core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
+index 173dc00762a15..cc9f0d41f59b2 100644
+--- a/drivers/iio/industrialio-core.c
++++ b/drivers/iio/industrialio-core.c
+@@ -1656,8 +1656,10 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
+ return NULL;
+
+ indio_dev = &iio_dev_opaque->indio_dev;
+- indio_dev->priv = (char *)iio_dev_opaque +
+- ALIGN(sizeof(struct iio_dev_opaque), IIO_DMA_MINALIGN);
++
++ if (sizeof_priv)
++ indio_dev->priv = (char *)iio_dev_opaque +
++ ALIGN(sizeof(*iio_dev_opaque), IIO_DMA_MINALIGN);
+
+ indio_dev->dev.parent = parent;
+ indio_dev->dev.type = &iio_device_type;
+--
+2.43.0
+
--- /dev/null
+From 7611299115f7300404c947b5559578749703fed6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 12:50:27 +0200
+Subject: iio: pressure: dps310: support negative temperature values
+
+From: Thomas Haemmerle <thomas.haemmerle@leica-geosystems.com>
+
+[ Upstream commit 9dd6b32e76ff714308964cd9ec91466a343dcb8b ]
+
+The current implementation interprets negative values returned from
+`dps310_calculate_temp` as error codes.
+This has a side effect that when negative temperature values are
+calculated, they are interpreted as error.
+
+Fix this by using the return value only for error handling and passing a
+pointer for the value.
+
+Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310")
+Signed-off-by: Thomas Haemmerle <thomas.haemmerle@leica-geosystems.com>
+Link: https://lore.kernel.org/r/20240415105030.1161770-2-thomas.haemmerle@leica-geosystems.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/pressure/dps310.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
+index 1ff091b2f764d..d0a516d56da47 100644
+--- a/drivers/iio/pressure/dps310.c
++++ b/drivers/iio/pressure/dps310.c
+@@ -730,7 +730,7 @@ static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2,
+ }
+ }
+
+-static int dps310_calculate_temp(struct dps310_data *data)
++static int dps310_calculate_temp(struct dps310_data *data, int *val)
+ {
+ s64 c0;
+ s64 t;
+@@ -746,7 +746,9 @@ static int dps310_calculate_temp(struct dps310_data *data)
+ t = c0 + ((s64)data->temp_raw * (s64)data->c1);
+
+ /* Convert to milliCelsius and scale the temperature */
+- return (int)div_s64(t * 1000LL, kt);
++ *val = (int)div_s64(t * 1000LL, kt);
++
++ return 0;
+ }
+
+ static int dps310_read_temp(struct dps310_data *data, int *val, int *val2,
+@@ -768,11 +770,10 @@ static int dps310_read_temp(struct dps310_data *data, int *val, int *val2,
+ if (rc)
+ return rc;
+
+- rc = dps310_calculate_temp(data);
+- if (rc < 0)
++ rc = dps310_calculate_temp(data, val);
++ if (rc)
+ return rc;
+
+- *val = rc;
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+--
+2.43.0
+
--- /dev/null
+From 595e3741a1867e1affe6172a9bbfe271843a6240 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 20:42:33 +0100
+Subject: interconnect: qcom: qcm2290: Fix mas_snoc_bimc QoS port assignment
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 230d05b1179f6ce6f8dc8a2b99eba92799ac22d7 ]
+
+The value was wrong, resulting in misprogramming of the hardware.
+Fix it.
+
+Fixes: 1a14b1ac3935 ("interconnect: qcom: Add QCM2290 driver support")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240326-topic-rpm_icc_qos_cleanup-v1-2-357e736792be@linaro.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/qcom/qcm2290.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c
+index 96735800b13c0..ba4cc08684d63 100644
+--- a/drivers/interconnect/qcom/qcm2290.c
++++ b/drivers/interconnect/qcom/qcm2290.c
+@@ -164,7 +164,7 @@ static struct qcom_icc_node mas_snoc_bimc = {
+ .name = "mas_snoc_bimc",
+ .buswidth = 16,
+ .qos.ap_owned = true,
+- .qos.qos_port = 2,
++ .qos.qos_port = 6,
+ .qos.qos_mode = NOC_QOS_MODE_BYPASS,
+ .mas_rpm_id = 164,
+ .slv_rpm_id = -1,
+--
+2.43.0
+
--- /dev/null
+From 13cc0cfe260d689a6b0e3e74b8bc2fffabbc9f79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 10:07:50 +0900
+Subject: ksmbd: use rwsem instead of rwlock for lease break
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit d1c189c6cb8b0fb7b5ee549237d27889c40c2f8b ]
+
+lease break wait for lease break acknowledgment.
+rwsem is more suitable than unlock while traversing the list for parent
+lease break in ->m_op_list.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/oplock.c | 30 +++++++++++-------------------
+ fs/smb/server/smb2pdu.c | 4 ++--
+ fs/smb/server/smb_common.c | 4 ++--
+ fs/smb/server/vfs_cache.c | 20 ++++++++++----------
+ fs/smb/server/vfs_cache.h | 2 +-
+ 5 files changed, 26 insertions(+), 34 deletions(-)
+
+diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
+index 2292ca6ff00b6..3b8f80639ae84 100644
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -206,9 +206,9 @@ static void opinfo_add(struct oplock_info *opinfo)
+ {
+ struct ksmbd_inode *ci = opinfo->o_fp->f_ci;
+
+- write_lock(&ci->m_lock);
++ down_write(&ci->m_lock);
+ list_add_rcu(&opinfo->op_entry, &ci->m_op_list);
+- write_unlock(&ci->m_lock);
++ up_write(&ci->m_lock);
+ }
+
+ static void opinfo_del(struct oplock_info *opinfo)
+@@ -220,9 +220,9 @@ static void opinfo_del(struct oplock_info *opinfo)
+ lease_del_list(opinfo);
+ write_unlock(&lease_list_lock);
+ }
+- write_lock(&ci->m_lock);
++ down_write(&ci->m_lock);
+ list_del_rcu(&opinfo->op_entry);
+- write_unlock(&ci->m_lock);
++ up_write(&ci->m_lock);
+ }
+
+ static unsigned long opinfo_count(struct ksmbd_file *fp)
+@@ -525,21 +525,18 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
+ * Compare lease key and client_guid to know request from same owner
+ * of same client
+ */
+- read_lock(&ci->m_lock);
++ down_read(&ci->m_lock);
+ list_for_each_entry(opinfo, &ci->m_op_list, op_entry) {
+ if (!opinfo->is_lease)
+ continue;
+- read_unlock(&ci->m_lock);
+ lease = opinfo->o_lease;
+
+ ret = compare_guid_key(opinfo, client_guid, lctx->lease_key);
+ if (ret) {
+ m_opinfo = opinfo;
+ /* skip upgrading lease about breaking lease */
+- if (atomic_read(&opinfo->breaking_cnt)) {
+- read_lock(&ci->m_lock);
++ if (atomic_read(&opinfo->breaking_cnt))
+ continue;
+- }
+
+ /* upgrading lease */
+ if ((atomic_read(&ci->op_count) +
+@@ -569,9 +566,8 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
+ lease_none_upgrade(opinfo, lctx->req_state);
+ }
+ }
+- read_lock(&ci->m_lock);
+ }
+- read_unlock(&ci->m_lock);
++ up_read(&ci->m_lock);
+
+ return m_opinfo;
+ }
+@@ -1118,7 +1114,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
+ if (!p_ci)
+ return;
+
+- read_lock(&p_ci->m_lock);
++ down_read(&p_ci->m_lock);
+ list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
+ if (!opinfo->is_lease)
+ continue;
+@@ -1136,13 +1132,11 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
+ continue;
+ }
+
+- read_unlock(&p_ci->m_lock);
+ oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
+ opinfo_conn_put(opinfo);
+- read_lock(&p_ci->m_lock);
+ }
+ }
+- read_unlock(&p_ci->m_lock);
++ up_read(&p_ci->m_lock);
+
+ ksmbd_inode_put(p_ci);
+ }
+@@ -1163,7 +1157,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
+ if (!p_ci)
+ return;
+
+- read_lock(&p_ci->m_lock);
++ down_read(&p_ci->m_lock);
+ list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
+ if (!opinfo->is_lease)
+ continue;
+@@ -1177,13 +1171,11 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
+ atomic_dec(&opinfo->conn->r_count);
+ continue;
+ }
+- read_unlock(&p_ci->m_lock);
+ oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
+ opinfo_conn_put(opinfo);
+- read_lock(&p_ci->m_lock);
+ }
+ }
+- read_unlock(&p_ci->m_lock);
++ up_read(&p_ci->m_lock);
+
+ ksmbd_inode_put(p_ci);
+ }
+diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
+index 8ae0c4d5ab96c..82ed14ce1a656 100644
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -3192,9 +3192,9 @@ int smb2_open(struct ksmbd_work *work)
+ * after daccess, saccess, attrib_only, and stream are
+ * initialized.
+ */
+- write_lock(&fp->f_ci->m_lock);
++ down_write(&fp->f_ci->m_lock);
+ list_add(&fp->node, &fp->f_ci->m_fp_list);
+- write_unlock(&fp->f_ci->m_lock);
++ up_write(&fp->f_ci->m_lock);
+
+ /* Check delete pending among previous fp before oplock break */
+ if (ksmbd_inode_pending_delete(fp)) {
+diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c
+index fcaf373cc0080..474dadf6b7b8b 100644
+--- a/fs/smb/server/smb_common.c
++++ b/fs/smb/server/smb_common.c
+@@ -646,7 +646,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
+ * Lookup fp in master fp list, and check desired access and
+ * shared mode between previous open and current open.
+ */
+- read_lock(&curr_fp->f_ci->m_lock);
++ down_read(&curr_fp->f_ci->m_lock);
+ list_for_each_entry(prev_fp, &curr_fp->f_ci->m_fp_list, node) {
+ if (file_inode(filp) != file_inode(prev_fp->filp))
+ continue;
+@@ -722,7 +722,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
+ break;
+ }
+ }
+- read_unlock(&curr_fp->f_ci->m_lock);
++ up_read(&curr_fp->f_ci->m_lock);
+
+ return rc;
+ }
+diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
+index 4e82ff627d122..1abd9b85302e8 100644
+--- a/fs/smb/server/vfs_cache.c
++++ b/fs/smb/server/vfs_cache.c
+@@ -165,7 +165,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
+ ci->m_fattr = 0;
+ INIT_LIST_HEAD(&ci->m_fp_list);
+ INIT_LIST_HEAD(&ci->m_op_list);
+- rwlock_init(&ci->m_lock);
++ init_rwsem(&ci->m_lock);
+ ci->m_de = fp->filp->f_path.dentry;
+ return 0;
+ }
+@@ -261,14 +261,14 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
+ }
+
+ if (atomic_dec_and_test(&ci->m_count)) {
+- write_lock(&ci->m_lock);
++ down_write(&ci->m_lock);
+ if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
+ ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
+- write_unlock(&ci->m_lock);
++ up_write(&ci->m_lock);
+ ksmbd_vfs_unlink(filp);
+- write_lock(&ci->m_lock);
++ down_write(&ci->m_lock);
+ }
+- write_unlock(&ci->m_lock);
++ up_write(&ci->m_lock);
+
+ ksmbd_inode_free(ci);
+ }
+@@ -289,9 +289,9 @@ static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp
+ if (!has_file_id(fp->volatile_id))
+ return;
+
+- write_lock(&fp->f_ci->m_lock);
++ down_write(&fp->f_ci->m_lock);
+ list_del_init(&fp->node);
+- write_unlock(&fp->f_ci->m_lock);
++ up_write(&fp->f_ci->m_lock);
+
+ write_lock(&ft->lock);
+ idr_remove(ft->idr, fp->volatile_id);
+@@ -501,17 +501,17 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry)
+ if (!ci)
+ return NULL;
+
+- read_lock(&ci->m_lock);
++ down_read(&ci->m_lock);
+ list_for_each_entry(lfp, &ci->m_fp_list, node) {
+ if (inode == file_inode(lfp->filp)) {
+ atomic_dec(&ci->m_count);
+ lfp = ksmbd_fp_get(lfp);
+- read_unlock(&ci->m_lock);
++ up_read(&ci->m_lock);
+ return lfp;
+ }
+ }
+ atomic_dec(&ci->m_count);
+- read_unlock(&ci->m_lock);
++ up_read(&ci->m_lock);
+ return NULL;
+ }
+
+diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
+index a528f0cc775ae..b8a623932f568 100644
+--- a/fs/smb/server/vfs_cache.h
++++ b/fs/smb/server/vfs_cache.h
+@@ -46,7 +46,7 @@ struct stream {
+ };
+
+ struct ksmbd_inode {
+- rwlock_t m_lock;
++ struct rw_semaphore m_lock;
+ atomic_t m_count;
+ atomic_t op_count;
+ /* opinfo count for streams */
+--
+2.43.0
+
--- /dev/null
+From f2919b75e5e8f13aa0d80e8dcd33dc45111bf069 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Apr 2024 17:38:47 +0200
+Subject: leds: pwm: Disable PWM when going to suspend
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 974afccd37947a6951a052ef8118c961e57eaf7b ]
+
+On stm32mp1xx based machines (and others) a PWM consumer has to disable
+the PWM because an enabled PWM refuses to suspend. So check the
+LED_SUSPENDED flag and depending on that set the .enabled property.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218559
+Fixes: 76fe464c8e64 ("leds: pwm: Don't disable the PWM when the LED should be off")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20240417153846.271751-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-pwm.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index 4e3936a39d0ed..e1b414b403534 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -53,7 +53,13 @@ static int led_pwm_set(struct led_classdev *led_cdev,
+ duty = led_dat->pwmstate.period - duty;
+
+ led_dat->pwmstate.duty_cycle = duty;
+- led_dat->pwmstate.enabled = true;
++ /*
++ * Disabling a PWM doesn't guarantee that it emits the inactive level.
++ * So keep it on. Only for suspending the PWM should be disabled because
++ * otherwise it refuses to suspend. The possible downside is that the
++ * LED might stay (or even go) on.
++ */
++ led_dat->pwmstate.enabled = !(led_cdev->flags & LED_SUSPENDED);
+ return pwm_apply_might_sleep(led_dat->pwm, &led_dat->pwmstate);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From ebe360a276f5cdd2c9bbfb0a4cc37a70111a7afa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 May 2024 22:20:15 -0700
+Subject: libsubcmd: Fix parse-options memory leak
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 230a7a71f92212e723fa435d4ca5922de33ec88a ]
+
+If a usage string is built in parse_options_subcommand, also free it.
+
+Fixes: 901421a5bdf605d2 ("perf tools: Remove subcmd dependencies on strbuf")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Josh Poimboeuf <jpoimboe@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240509052015.1914670-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/subcmd/parse-options.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c
+index 9fa75943f2ed1..d943d78b787ed 100644
+--- a/tools/lib/subcmd/parse-options.c
++++ b/tools/lib/subcmd/parse-options.c
+@@ -633,11 +633,10 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
+ const char *const subcommands[], const char *usagestr[], int flags)
+ {
+ struct parse_opt_ctx_t ctx;
++ char *buf = NULL;
+
+ /* build usage string if it's not provided */
+ if (subcommands && !usagestr[0]) {
+- char *buf = NULL;
+-
+ astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
+
+ for (int i = 0; subcommands[i]; i++) {
+@@ -679,7 +678,10 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
+ astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
+ usage_with_options(usagestr, options);
+ }
+-
++ if (buf) {
++ usagestr[0] = NULL;
++ free(buf);
++ }
+ return parse_options_end(&ctx);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From d3652d4d32b62bf2121a1341fa78c47fd444e81e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 May 2024 12:24:18 +0800
+Subject: LoongArch: Fix callchain parse error with kernel tracepoint events
+ again
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+[ Upstream commit d6af2c76399f98444a5b4de96baf4b362d9f102b ]
+
+With commit d3119bc985fb645 ("LoongArch: Fix callchain parse error with
+kernel tracepoint events"), perf can parse kernel callchain, but not
+complete and sometimes maybe error. The reason is LoongArch's unwinders
+(guess, prologue and orc) don't really need fp (i.e., regs[22]), and
+they use sp (i.e., regs[3]) as the frame address rather than the current
+stack pointer.
+
+Fix that by removing the assignment of regs[22], and instead assign the
+__builtin_frame_address(0) to regs[3].
+
+Without fix:
+
+ Children Self Command Shared Object Symbol
+ ........ ........ ............. ................. ................
+ 33.91% 33.91% swapper [kernel.vmlinux] [k] __schedule
+ |
+ |--33.04%--__schedule
+ |
+ --0.87%--__arch_cpu_idle
+ __schedule
+
+With this fix:
+
+ Children Self Command Shared Object Symbol
+ ........ ........ ............. ................. ................
+ 31.16% 31.16% swapper [kernel.vmlinux] [k] __schedule
+ |
+ |--20.63%--smpboot_entry
+ | cpu_startup_entry
+ | schedule_idle
+ | __schedule
+ |
+ --10.53%--start_kernel
+ cpu_startup_entry
+ schedule_idle
+ __schedule
+
+Fixes: d3119bc985fb645 ("LoongArch: Fix callchain parse error with kernel tracepoint events")
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/include/asm/perf_event.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/loongarch/include/asm/perf_event.h b/arch/loongarch/include/asm/perf_event.h
+index 52b638059e40b..f948a0676daf8 100644
+--- a/arch/loongarch/include/asm/perf_event.h
++++ b/arch/loongarch/include/asm/perf_event.h
+@@ -13,8 +13,7 @@
+
+ #define perf_arch_fetch_caller_regs(regs, __ip) { \
+ (regs)->csr_era = (__ip); \
+- (regs)->regs[3] = current_stack_pointer; \
+- (regs)->regs[22] = (unsigned long) __builtin_frame_address(0); \
++ (regs)->regs[3] = (unsigned long) __builtin_frame_address(0); \
+ }
+
+ #endif /* __LOONGARCH_PERF_EVENT_H__ */
+--
+2.43.0
+
--- /dev/null
+From 6dd31c0015c838f1eb5385854b18161490565b3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Apr 2024 10:01:21 +0800
+Subject: mailbox: mtk-cmdq: Fix pm_runtime_get_sync() warning in mbox shutdown
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 747a69a119c469121385543f21c2d08562968ccc ]
+
+The return value of pm_runtime_get_sync() in cmdq_mbox_shutdown()
+will return 1 when pm runtime state is active, and we don't want to
+get the warning message in this case.
+
+So we change the return value < 0 for WARN_ON().
+
+Fixes: 8afe816b0c99 ("mailbox: mtk-cmdq-mailbox: Implement Runtime PM with autosuspend")
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mtk-cmdq-mailbox.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
+index ead2200f39ba0..033aff11f87cf 100644
+--- a/drivers/mailbox/mtk-cmdq-mailbox.c
++++ b/drivers/mailbox/mtk-cmdq-mailbox.c
+@@ -465,7 +465,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
+ struct cmdq_task *task, *tmp;
+ unsigned long flags;
+
+- WARN_ON(pm_runtime_get_sync(cmdq->mbox.dev));
++ WARN_ON(pm_runtime_get_sync(cmdq->mbox.dev) < 0);
+
+ spin_lock_irqsave(&thread->chan->lock, flags);
+ if (list_empty(&thread->task_busy_list))
+--
+2.43.0
+
--- /dev/null
+From 566c71884d8ec02e5e6f1f24702d26a9b56418b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 10:27:21 +0200
+Subject: microblaze: Remove early printk call from cpuinfo-static.c
+
+From: Michal Simek <michal.simek@amd.com>
+
+[ Upstream commit 58d647506c92ccd3cfa0c453c68ddd14f40bf06f ]
+
+Early printk has been removed already that's why also remove calling it.
+Similar change has been done in cpuinfo-pvr-full.c by commit cfbd8d1979af
+("microblaze: Remove early printk setup").
+
+Fixes: 96f0e6fcc9ad ("microblaze: remove redundant early_printk support")
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Link: https://lore.kernel.org/r/2f10db506be8188fa07b6ec331caca01af1b10f8.1712824039.git.michal.simek@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/microblaze/kernel/cpu/cpuinfo-static.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
+index 85dbda4a08a81..03da36dc6d9c9 100644
+--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
++++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
+@@ -18,7 +18,7 @@ static const char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
+ static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
+
+ #define err_printk(x) \
+- early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n");
++ pr_err("ERROR: Microblaze " x "-different for kernel and DTS\n");
+
+ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
+ {
+--
+2.43.0
+
--- /dev/null
+From 589d2ed19b113a999afcf701253472bce9cc0707 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 10:21:44 +0200
+Subject: microblaze: Remove gcc flag for non existing early_printk.c file
+
+From: Michal Simek <michal.simek@amd.com>
+
+[ Upstream commit edc66cf0c4164aa3daf6cc55e970bb94383a6a57 ]
+
+early_printk support for removed long time ago but compilation flag for
+ftrace still points to already removed file that's why remove that line
+too.
+
+Fixes: 96f0e6fcc9ad ("microblaze: remove redundant early_printk support")
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Link: https://lore.kernel.org/r/5493467419cd2510a32854e2807bcd263de981a0.1712823702.git.michal.simek@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/microblaze/kernel/Makefile | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
+index 4393bee64eaf8..85c4d29ef43e9 100644
+--- a/arch/microblaze/kernel/Makefile
++++ b/arch/microblaze/kernel/Makefile
+@@ -7,7 +7,6 @@ ifdef CONFIG_FUNCTION_TRACER
+ # Do not trace early boot code and low level code
+ CFLAGS_REMOVE_timer.o = -pg
+ CFLAGS_REMOVE_intc.o = -pg
+-CFLAGS_REMOVE_early_printk.o = -pg
+ CFLAGS_REMOVE_ftrace.o = -pg
+ CFLAGS_REMOVE_process.o = -pg
+ endif
+--
+2.43.0
+
--- /dev/null
+From bdcb25947abaaa28095a1b1b4b540d4e7a301ee8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Apr 2024 10:05:58 +0200
+Subject: module: don't ignore sysfs_create_link() failures
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 85d2b0aa170351380be39fe4ff7973df1427fe76 ]
+
+The sysfs_create_link() return code is marked as __must_check, but the
+module_add_driver() function tries hard to not care, by assigning the
+return code to a variable. When building with 'make W=1', gcc still
+warns because this variable is only assigned but not used:
+
+drivers/base/module.c: In function 'module_add_driver':
+drivers/base/module.c:36:6: warning: variable 'no_warn' set but not used [-Wunused-but-set-variable]
+
+Rework the code to properly unwind and return the error code to the
+caller. My reading of the original code was that it tries to
+not fail when the links already exist, so keep ignoring -EEXIST
+errors.
+
+Fixes: e17e0f51aeea ("Driver core: show drivers in /sys/module/")
+See-also: 4a7fb6363f2d ("add __must_check to device management code")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
+Link: https://lore.kernel.org/r/20240408080616.3911573-1-arnd@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/base.h | 9 ++++++---
+ drivers/base/bus.c | 9 ++++++++-
+ drivers/base/module.c | 42 +++++++++++++++++++++++++++++++-----------
+ 3 files changed, 45 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/base/base.h b/drivers/base/base.h
+index eb4c0ace92420..a8e3d8165232f 100644
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -192,11 +192,14 @@ extern struct kset *devices_kset;
+ void devices_kset_move_last(struct device *dev);
+
+ #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
+-void module_add_driver(struct module *mod, struct device_driver *drv);
++int module_add_driver(struct module *mod, struct device_driver *drv);
+ void module_remove_driver(struct device_driver *drv);
+ #else
+-static inline void module_add_driver(struct module *mod,
+- struct device_driver *drv) { }
++static inline int module_add_driver(struct module *mod,
++ struct device_driver *drv)
++{
++ return 0;
++}
+ static inline void module_remove_driver(struct device_driver *drv) { }
+ #endif
+
+diff --git a/drivers/base/bus.c b/drivers/base/bus.c
+index daee55c9b2d9e..ffea0728b8b2f 100644
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -674,7 +674,12 @@ int bus_add_driver(struct device_driver *drv)
+ if (error)
+ goto out_del_list;
+ }
+- module_add_driver(drv->owner, drv);
++ error = module_add_driver(drv->owner, drv);
++ if (error) {
++ printk(KERN_ERR "%s: failed to create module links for %s\n",
++ __func__, drv->name);
++ goto out_detach;
++ }
+
+ error = driver_create_file(drv, &driver_attr_uevent);
+ if (error) {
+@@ -699,6 +704,8 @@ int bus_add_driver(struct device_driver *drv)
+
+ return 0;
+
++out_detach:
++ driver_detach(drv);
+ out_del_list:
+ klist_del(&priv->knode_bus);
+ out_unregister:
+diff --git a/drivers/base/module.c b/drivers/base/module.c
+index 46ad4d636731d..a1b55da07127d 100644
+--- a/drivers/base/module.c
++++ b/drivers/base/module.c
+@@ -30,14 +30,14 @@ static void module_create_drivers_dir(struct module_kobject *mk)
+ mutex_unlock(&drivers_dir_mutex);
+ }
+
+-void module_add_driver(struct module *mod, struct device_driver *drv)
++int module_add_driver(struct module *mod, struct device_driver *drv)
+ {
+ char *driver_name;
+- int no_warn;
+ struct module_kobject *mk = NULL;
++ int ret;
+
+ if (!drv)
+- return;
++ return 0;
+
+ if (mod)
+ mk = &mod->mkobj;
+@@ -56,17 +56,37 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
+ }
+
+ if (!mk)
+- return;
++ return 0;
++
++ ret = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
++ if (ret)
++ return ret;
+
+- /* Don't check return codes; these calls are idempotent */
+- no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
+ driver_name = make_driver_name(drv);
+- if (driver_name) {
+- module_create_drivers_dir(mk);
+- no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
+- driver_name);
+- kfree(driver_name);
++ if (!driver_name) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ module_create_drivers_dir(mk);
++ if (!mk->drivers_dir) {
++ ret = -EINVAL;
++ goto out;
+ }
++
++ ret = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, driver_name);
++ if (ret)
++ goto out;
++
++ kfree(driver_name);
++
++ return 0;
++out:
++ sysfs_remove_link(&drv->p->kobj, "module");
++ sysfs_remove_link(mk->drivers_dir, driver_name);
++ kfree(driver_name);
++
++ return ret;
+ }
+
+ void module_remove_driver(struct device_driver *drv)
+--
+2.43.0
+
--- /dev/null
+From f2c45ef6fc02ff1a29e22e9b516429f42b6d912d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 20:35:57 +0200
+Subject: ovl: remove upper umask handling from ovl_create_upper()
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit 096802748ea1dea8b476938e0a8dc16f4bd2f1ad ]
+
+This is already done by vfs_prepare_mode() when creating the upper object
+by vfs_create(), vfs_mkdir() and vfs_mknod().
+
+No regressions have been observed in xfstests run with posix acls turned
+off for the upper filesystem.
+
+Fixes: 1639a49ccdce ("fs: move S_ISGID stripping into the vfs_*() helpers")
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/dir.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 0f8b4a719237c..02d89a285d0dc 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -327,9 +327,6 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
+ struct dentry *newdentry;
+ int err;
+
+- if (!attr->hardlink && !IS_POSIXACL(udir))
+- attr->mode &= ~current_umask();
+-
+ inode_lock_nested(udir, I_MUTEX_PARENT);
+ newdentry = ovl_create_real(ofs, udir,
+ ovl_lookup_upper(ofs, dentry->d_name.name,
+--
+2.43.0
+
--- /dev/null
+From 44a4af5695db7fba68f7abae5696b40633831a69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 14:43:30 +0530
+Subject: PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk
+ from host
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 869bc52534065990cb57013b2bb354c0c1e66c5c ]
+
+The DWC glue drivers requiring an active reference clock from the PCIe host
+for initializing their PCIe EP core, set a flag called 'core_init_notifier'
+to let DWC driver know that these drivers need a special attention during
+initialization. In these drivers, access to the hw registers (like DBI)
+before receiving the active refclk from host will result in access failure
+and also could cause a whole system hang.
+
+But the current DWC EP driver doesn't honor the requirements of the drivers
+setting 'core_init_notifier' flag and tries to access the DBI registers
+during dw_pcie_ep_init(). This causes the system hang for glue drivers such
+as Tegra194 and Qcom EP as they depend on refclk from host and have set the
+above mentioned flag.
+
+To workaround this issue, users of the affected platforms have to maintain
+the dependency with the PCIe host by booting the PCIe EP after host boot.
+But this won't provide a good user experience, since PCIe EP is _one_ of
+the features of those platforms and it doesn't make sense to delay the
+whole platform booting due to PCIe requiring active refclk.
+
+So to fix this issue, let's move all the DBI access from
+dw_pcie_ep_init() in the DWC EP driver to the dw_pcie_ep_init_complete()
+API. This API will only be called by the drivers setting
+'core_init_notifier' flag once refclk is received from host. For the rest
+of the drivers that gets the refclk locally, this API will be called
+within dw_pcie_ep_init().
+
+Link: https://lore.kernel.org/linux-pci/20240327-pci-dbi-rework-v12-1-082625472414@linaro.org
+Fixes: e966f7390da9 ("PCI: dwc: Refactor core initialization code for EP mode")
+Co-developed-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pci/controller/dwc/pcie-designware-ep.c | 120 +++++++++++-------
+ 1 file changed, 71 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 746a11dcb67f1..c43a1479de2ce 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -604,11 +604,16 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
+ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
+ {
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
++ struct dw_pcie_ep_func *ep_func;
++ struct device *dev = pci->dev;
++ struct pci_epc *epc = ep->epc;
+ unsigned int offset, ptm_cap_base;
+ unsigned int nbars;
+ u8 hdr_type;
++ u8 func_no;
++ int i, ret;
++ void *addr;
+ u32 reg;
+- int i;
+
+ hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
+ PCI_HEADER_TYPE_MASK;
+@@ -619,6 +624,58 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
+ return -EIO;
+ }
+
++ dw_pcie_version_detect(pci);
++
++ dw_pcie_iatu_detect(pci);
++
++ ret = dw_pcie_edma_detect(pci);
++ if (ret)
++ return ret;
++
++ if (!ep->ib_window_map) {
++ ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
++ GFP_KERNEL);
++ if (!ep->ib_window_map)
++ goto err_remove_edma;
++ }
++
++ if (!ep->ob_window_map) {
++ ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
++ GFP_KERNEL);
++ if (!ep->ob_window_map)
++ goto err_remove_edma;
++ }
++
++ if (!ep->outbound_addr) {
++ addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),
++ GFP_KERNEL);
++ if (!addr)
++ goto err_remove_edma;
++ ep->outbound_addr = addr;
++ }
++
++ for (func_no = 0; func_no < epc->max_functions; func_no++) {
++
++ ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
++ if (ep_func)
++ continue;
++
++ ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
++ if (!ep_func)
++ goto err_remove_edma;
++
++ ep_func->func_no = func_no;
++ ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
++ PCI_CAP_ID_MSI);
++ ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
++ PCI_CAP_ID_MSIX);
++
++ list_add_tail(&ep_func->list, &ep->func_list);
++ }
++
++ if (ep->ops->init)
++ ep->ops->init(ep);
++
+ offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
+ ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
+
+@@ -658,14 +715,17 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
+ dw_pcie_dbi_ro_wr_dis(pci);
+
+ return 0;
++
++err_remove_edma:
++ dw_pcie_edma_remove(pci);
++
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
+
+ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ {
+ int ret;
+- void *addr;
+- u8 func_no;
+ struct resource *res;
+ struct pci_epc *epc;
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+@@ -673,7 +733,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ struct platform_device *pdev = to_platform_device(dev);
+ struct device_node *np = dev->of_node;
+ const struct pci_epc_features *epc_features;
+- struct dw_pcie_ep_func *ep_func;
+
+ INIT_LIST_HEAD(&ep->func_list);
+
+@@ -691,26 +750,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ if (ep->ops->pre_init)
+ ep->ops->pre_init(ep);
+
+- dw_pcie_version_detect(pci);
+-
+- dw_pcie_iatu_detect(pci);
+-
+- ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
+- GFP_KERNEL);
+- if (!ep->ib_window_map)
+- return -ENOMEM;
+-
+- ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
+- GFP_KERNEL);
+- if (!ep->ob_window_map)
+- return -ENOMEM;
+-
+- addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),
+- GFP_KERNEL);
+- if (!addr)
+- return -ENOMEM;
+- ep->outbound_addr = addr;
+-
+ epc = devm_pci_epc_create(dev, &epc_ops);
+ if (IS_ERR(epc)) {
+ dev_err(dev, "Failed to create epc device\n");
+@@ -724,23 +763,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ if (ret < 0)
+ epc->max_functions = 1;
+
+- for (func_no = 0; func_no < epc->max_functions; func_no++) {
+- ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
+- if (!ep_func)
+- return -ENOMEM;
+-
+- ep_func->func_no = func_no;
+- ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
+- PCI_CAP_ID_MSI);
+- ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
+- PCI_CAP_ID_MSIX);
+-
+- list_add_tail(&ep_func->list, &ep->func_list);
+- }
+-
+- if (ep->ops->init)
+- ep->ops->init(ep);
+-
+ ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
+ ep->page_size);
+ if (ret < 0) {
+@@ -756,25 +778,25 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ goto err_exit_epc_mem;
+ }
+
+- ret = dw_pcie_edma_detect(pci);
+- if (ret)
+- goto err_free_epc_mem;
+-
+ if (ep->ops->get_features) {
+ epc_features = ep->ops->get_features(ep);
+ if (epc_features->core_init_notifier)
+ return 0;
+ }
+
++ /*
++ * NOTE:- Avoid accessing the hardware (Ex:- DBI space) before this
++ * step as platforms that implement 'core_init_notifier' feature may
++ * not have the hardware ready (i.e. core initialized) for access
++ * (Ex: tegra194). Any hardware access on such platforms result
++ * in system hang.
++ */
+ ret = dw_pcie_ep_init_complete(ep);
+ if (ret)
+- goto err_remove_edma;
++ goto err_free_epc_mem;
+
+ return 0;
+
+-err_remove_edma:
+- dw_pcie_edma_remove(pci);
+-
+ err_free_epc_mem:
+ pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
+ epc->mem->window.page_size);
+--
+2.43.0
+
--- /dev/null
+From 3bc5142d992b95d86a9a42bfdea0b52f3ca7a873 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 May 2024 02:25:43 +0000
+Subject: PCI/EDR: Align EDR_PORT_DPC_ENABLE_DSM with PCI Firmware r3.3
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit f24ba846133d0edec785ac6430d4daf6e9c93a09 ]
+
+The "Downstream Port Containment related Enhancements" ECN of Jan 28, 2019
+(document 12888 below), defined the EDR_PORT_DPC_ENABLE_DSM function with
+Revision ID 5 with Arg3 being an integer. But when the ECN was integrated
+into PCI Firmware r3.3, sec 4.6.12, it was defined as Revision ID 6 with
+Arg3 being a package containing an integer.
+
+The implementation in acpi_enable_dpc() supplies a package as Arg3 (arg4 in
+the code), but it previously specified Revision ID 5. Align this with PCI
+Firmware r3.3 by using Revision ID 6.
+
+If firmware implemented per the ECN, its Revision 5 function would receive
+a package as Arg3 when it expects an integer, so acpi_enable_dpc() would
+likely fail. If such firmware exists and lacks a Revision 6 function that
+expects a package, we may have to add support for Revision 5.
+
+Link: https://lore.kernel.org/r/20240501022543.1626025-1-sathyanarayanan.kuppuswamy@linux.intel.com
+Link: https://members.pcisig.com/wg/PCI-SIG/document/12888
+Fixes: ac1c8e35a326 ("PCI/DPC: Add Error Disconnect Recover (EDR) support")
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+[bhelgaas: split into two patches, update commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Satish Thatchanamurthy <Satish.Thatchanamurt@Dell.com> # one platform
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/edr.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/pcie/edr.c b/drivers/pci/pcie/edr.c
+index 5f4914d313a17..fa085677c91de 100644
+--- a/drivers/pci/pcie/edr.c
++++ b/drivers/pci/pcie/edr.c
+@@ -32,10 +32,10 @@ static int acpi_enable_dpc(struct pci_dev *pdev)
+ int status = 0;
+
+ /*
+- * Behavior when calling unsupported _DSM functions is undefined,
+- * so check whether EDR_PORT_DPC_ENABLE_DSM is supported.
++ * Per PCI Firmware r3.3, sec 4.6.12, EDR_PORT_DPC_ENABLE_DSM is
++ * optional. Return success if it's not implemented.
+ */
+- if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 5,
++ if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 6,
+ 1ULL << EDR_PORT_DPC_ENABLE_DSM))
+ return 0;
+
+@@ -46,12 +46,7 @@ static int acpi_enable_dpc(struct pci_dev *pdev)
+ argv4.package.count = 1;
+ argv4.package.elements = &req;
+
+- /*
+- * Per Downstream Port Containment Related Enhancements ECN to PCI
+- * Firmware Specification r3.2, sec 4.6.12, EDR_PORT_DPC_ENABLE_DSM is
+- * optional. Return success if it's not implemented.
+- */
+- obj = acpi_evaluate_dsm(adev->handle, &pci_acpi_dsm_guid, 5,
++ obj = acpi_evaluate_dsm(adev->handle, &pci_acpi_dsm_guid, 6,
+ EDR_PORT_DPC_ENABLE_DSM, &argv4);
+ if (!obj)
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 083fa6ca6946f107b0f13ba3a5ac2a3833249e11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 May 2024 14:31:38 -0500
+Subject: PCI/EDR: Align EDR_PORT_LOCATE_DSM with PCI Firmware r3.3
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit e2e78a294a8a863898b781dbcf90e087eda3155d ]
+
+The "Downstream Port Containment related Enhancements" ECN of Jan 28, 2019
+(document 12888 below), defined the EDR_PORT_LOCATE_DSM function with
+Revision ID 5 with a return value encoding (Bits 2:0 = Function, Bits 7:3 =
+Device, Bits 15:8 = Bus). When the ECN was integrated into PCI Firmware
+r3.3, sec 4.6.13, Bit 31 was added to indicate success or failure.
+
+Check Bit 31 for failure in acpi_dpc_port_get().
+
+Link: https://lore.kernel.org/r/20240501022543.1626025-1-sathyanarayanan.kuppuswamy@linux.intel.com
+Link: https://members.pcisig.com/wg/PCI-SIG/document/12888
+Fixes: ac1c8e35a326 ("PCI/DPC: Add Error Disconnect Recover (EDR) support")
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+[bhelgaas: split into two patches, update commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Satish Thatchanamurthy <Satish.Thatchanamurt@Dell.com> # one platform
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/edr.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/pcie/edr.c b/drivers/pci/pcie/edr.c
+index fa085677c91de..e86298dbbcff6 100644
+--- a/drivers/pci/pcie/edr.c
++++ b/drivers/pci/pcie/edr.c
+@@ -80,8 +80,9 @@ static struct pci_dev *acpi_dpc_port_get(struct pci_dev *pdev)
+ u16 port;
+
+ /*
+- * Behavior when calling unsupported _DSM functions is undefined,
+- * so check whether EDR_PORT_DPC_ENABLE_DSM is supported.
++ * If EDR_PORT_LOCATE_DSM is not implemented under the target of
++ * EDR, the target is the port that experienced the containment
++ * event (PCI Firmware r3.3, sec 4.6.13).
+ */
+ if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 5,
+ 1ULL << EDR_PORT_LOCATE_DSM))
+@@ -98,6 +99,16 @@ static struct pci_dev *acpi_dpc_port_get(struct pci_dev *pdev)
+ return NULL;
+ }
+
++ /*
++ * Bit 31 represents the success/failure of the operation. If bit
++ * 31 is set, the operation failed.
++ */
++ if (obj->integer.value & BIT(31)) {
++ ACPI_FREE(obj);
++ pci_err(pdev, "Locate Port _DSM failed\n");
++ return NULL;
++ }
++
+ /*
+ * Firmware returns DPC port BDF details in following format:
+ * 15:8 = bus
+--
+2.43.0
+
--- /dev/null
+From 6143810f5df627b5ca920daa6fbb8ec16f313da0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Mar 2024 18:57:29 +0800
+Subject: PCI: of_property: Return error for int_map allocation failure
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit e6f7d27df5d208b50cae817a91d128fb434bb12c ]
+
+Return -ENOMEM from of_pci_prop_intr_map() if kcalloc() fails to prevent a
+NULL pointer dereference in this case.
+
+Fixes: 407d1a51921e ("PCI: Create device tree node for bridge")
+Link: https://lore.kernel.org/r/20240303105729.78624-1-duoming@zju.edu.cn
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/of_property.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
+index c2c7334152bc0..03539e5053720 100644
+--- a/drivers/pci/of_property.c
++++ b/drivers/pci/of_property.c
+@@ -238,6 +238,8 @@ static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs,
+ return 0;
+
+ int_map = kcalloc(map_sz, sizeof(u32), GFP_KERNEL);
++ if (!int_map)
++ return -ENOMEM;
+ mapp = int_map;
+
+ list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
+--
+2.43.0
+
--- /dev/null
+From 46d7b00e302489f8c7369ad768e81b709db14e27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Apr 2024 15:00:53 +0530
+Subject: PCI: tegra194: Fix probe path for Endpoint mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vidya Sagar <vidyas@nvidia.com>
+
+[ Upstream commit 19326006a21da26532d982254677c892dae8f29b ]
+
+Tegra194 PCIe probe path is taking failure path in success case for
+Endpoint mode. Return success from the switch case instead of going
+into the failure path.
+
+Fixes: c57247f940e8 ("PCI: tegra: Add support for PCIe endpoint mode in Tegra194")
+Link: https://lore.kernel.org/linux-pci/20240408093053.3948634-1-vidyas@nvidia.com
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 7afa9e9aabe21..2349e284f6e8f 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -2269,11 +2269,14 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
+ ret = tegra_pcie_config_ep(pcie, pdev);
+ if (ret < 0)
+ goto fail;
++ else
++ return 0;
+ break;
+
+ default:
+ dev_err(dev, "Invalid PCIe device type %d\n",
+ pcie->of_data->mode);
++ ret = -EINVAL;
+ }
+
+ fail:
+--
+2.43.0
+
--- /dev/null
+From 5ac606f92c1a62ae506cf075f8799712bc46cc19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 16:08:19 +0300
+Subject: PCI: Wait for Link Training==0 before starting Link retrain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 73cb3a35f94db723c0211ad099bce55b2155e3f0 ]
+
+Two changes were made in link retraining logic independent of each other.
+
+The commit e7e39756363a ("PCI/ASPM: Avoid link retraining race") added a
+check to pcie_retrain_link() to ensure no Link Training is currently active
+to address the Implementation Note in PCIe r6.1 sec 7.5.3.7. At that time
+pcie_wait_for_retrain() only checked for the Link Training (LT) bit being
+cleared.
+
+The commit 680e9c47a229 ("PCI: Add support for polling DLLLA to
+pcie_retrain_link()") generalized pcie_wait_for_retrain() into
+pcie_wait_for_link_status() which can wait either for LT or the Data Link
+Layer Link Active (DLLLA) bit with 'use_lt' argument and supporting waiting
+for either cleared or set using 'active' argument.
+
+In the merge commit 1abb47390350 ("Merge branch 'pci/enumeration'"), those
+two divergent branches converged. The merge changed LT bit checking added
+in the commit e7e39756363a ("PCI/ASPM: Avoid link retraining race") to now
+wait for completion of any ongoing Link Training using DLLLA bit being set
+if 'use_lt' is false.
+
+When 'use_lt' is false, the pseudo-code steps of what occurs in
+pcie_retrain_link():
+
+ 1. Wait for DLLLA==1
+ 2. Trigger link to retrain
+ 3. Wait for DLLLA==1
+
+Step 3 waits for the link to come up from the retraining triggered by Step
+2. As Step 1 is supposed to wait for any ongoing retraining to end, using
+DLLLA also for it does not make sense because link training being active is
+still indicated using LT bit, not with DLLLA.
+
+Correct the pcie_wait_for_link_status() parameters in Step 1 to only wait
+for LT==0 to ensure there is no ongoing Link Training.
+
+This only impacts the Target Speed quirk, which is the only case where
+waiting for DLLLA bit is used. It currently works in the problematic case
+by means of link training getting initiated by hardware repeatedly and
+respecting the new link parameters set by the caller, which then make
+training succeed and bring the link up, setting DLLLA and causing
+pcie_wait_for_link_status() to return success. We are not supposed to rely
+on luck and need to make sure that LT transitioned through the inactive
+state though before we initiate link training by hand via RL (Retrain Link)
+bit.
+
+Fixes: 1abb47390350 ("Merge branch 'pci/enumeration'")
+Link: https://lore.kernel.org/r/20240423130820.43824-1-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index c3585229c12a2..12dc5bfb87088 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -5049,7 +5049,7 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt)
+ * avoid LTSSM race as recommended in Implementation Note at the
+ * end of PCIe r6.0.1 sec 7.5.3.7.
+ */
+- rc = pcie_wait_for_link_status(pdev, use_lt, !use_lt);
++ rc = pcie_wait_for_link_status(pdev, true, false);
+ if (rc)
+ return rc;
+
+--
+2.43.0
+
--- /dev/null
+From 4507259ef27dbfe058f6f82e8ded9b119fb5f127 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 10:57:08 -0700
+Subject: perf annotate: Fix annotation_calc_lines() to pass correct address to
+ get_srcline()
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit aaf494cf483a1a835c44e942861429b30a00cab0 ]
+
+It should pass a proper address (i.e. suitable for objdump or addr2line)
+to get_srcline() in order to work correctly. It used to pass an address
+with map__rip_2objdump() as the second argument but later it's changed
+to use notes->start. It's ok in normal cases but it can be changed when
+annotate_opts.full_addr is set. So let's convert the address directly
+instead of using the notes->start.
+
+Also the last argument is an IP to print symbol offset if requested. So
+it should pass symbol-relative address.
+
+Fixes: 7d18a824b5e57ddd ("perf annotate: Toggle full address <-> offset display")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240404175716.1225482-2-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/annotate.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
+index 86a996290e9ab..78088dd73248b 100644
+--- a/tools/perf/util/annotate.c
++++ b/tools/perf/util/annotate.c
+@@ -2988,7 +2988,7 @@ void annotation__toggle_full_addr(struct annotation *notes, struct map_symbol *m
+ annotation__update_column_widths(notes);
+ }
+
+-static void annotation__calc_lines(struct annotation *notes, struct map *map,
++static void annotation__calc_lines(struct annotation *notes, struct map_symbol *ms,
+ struct rb_root *root)
+ {
+ struct annotation_line *al;
+@@ -2996,6 +2996,7 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map,
+
+ list_for_each_entry(al, ¬es->src->source, node) {
+ double percent_max = 0.0;
++ u64 addr;
+ int i;
+
+ for (i = 0; i < al->data_nr; i++) {
+@@ -3011,8 +3012,9 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map,
+ if (percent_max <= 0.5)
+ continue;
+
+- al->path = get_srcline(map__dso(map), notes->start + al->offset, NULL,
+- false, true, notes->start + al->offset);
++ addr = map__rip_2objdump(ms->map, ms->sym->start);
++ al->path = get_srcline(map__dso(ms->map), addr + al->offset, NULL,
++ false, true, ms->sym->start + al->offset);
+ insert_source_line(&tmp_root, al);
+ }
+
+@@ -3023,7 +3025,7 @@ static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root)
+ {
+ struct annotation *notes = symbol__annotation(ms->sym);
+
+- annotation__calc_lines(notes, ms->map, root);
++ annotation__calc_lines(notes, ms, root);
+ }
+
+ int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel)
+--
+2.43.0
+
--- /dev/null
+From c9fbf1c682c98ac4c863a951f2a5d962b004e9bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Mar 2024 15:43:12 -0700
+Subject: perf annotate: Get rid of duplicate --group option item
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 374af9f1f06b5e991c810d2e4983d6f58df32136 ]
+
+The options array in cmd_annotate() has duplicate --group options. It
+only needs one and let's get rid of the other.
+
+ $ perf annotate -h 2>&1 | grep group
+ --group Show event group information together
+ --group Show event group information together
+
+Fixes: 7ebaf4890f63eb90 ("perf annotate: Support '--group' option")
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240322224313.423181-1-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-annotate.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
+index 6c1cc797692d9..9cd97fd76bb5e 100644
+--- a/tools/perf/builtin-annotate.c
++++ b/tools/perf/builtin-annotate.c
+@@ -809,8 +809,6 @@ int cmd_annotate(int argc, const char **argv)
+ "Enable symbol demangling"),
+ OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
+ "Enable kernel symbol demangling"),
+- OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
+- "Show event group information together"),
+ OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
+ "Show a column with the sum of periods"),
+ OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
+--
+2.43.0
+
--- /dev/null
+From 46d015dc8f60e7570e7b1cb7cdce886a562d486a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 14:50:26 +0800
+Subject: perf bench internals inject-build-id: Fix trap divide when collecting
+ just one DSO
+
+From: He Zhe <zhe.he@windriver.com>
+
+[ Upstream commit d9180e23fbfa3875424d3a6b28b71b072862a52a ]
+
+'perf bench internals inject-build-id' suffers from the following error when
+only one DSO is collected.
+
+ # perf bench internals inject-build-id -v
+ Collected 1 DSOs
+ traps: internals-injec[2305] trap divide error
+ ip:557566ba6394 sp:7ffd4de97fe0 error:0 in perf[557566b2a000+23d000]
+ Build-id injection benchmark
+ Iteration #1
+ Floating point exception
+
+This patch removes the unnecessary minus one from the divisor which also
+corrects the randomization range.
+
+Signed-off-by: He Zhe <zhe.he@windriver.com>
+Fixes: 0bf02a0d80427f26 ("perf bench: Add build-id injection benchmark")
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20240507065026.2652929-1-zhe.he@windriver.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/bench/inject-buildid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c
+index 49331743c7439..a759eb2328bea 100644
+--- a/tools/perf/bench/inject-buildid.c
++++ b/tools/perf/bench/inject-buildid.c
+@@ -362,7 +362,7 @@ static int inject_build_id(struct bench_data *data, u64 *max_rss)
+ return -1;
+
+ for (i = 0; i < nr_mmaps; i++) {
+- int idx = rand() % (nr_dsos - 1);
++ int idx = rand() % nr_dsos;
+ struct bench_dso *dso = &dsos[idx];
+ u64 timestamp = rand() % 1000000;
+
+--
+2.43.0
+
--- /dev/null
+From 7e08e660b27de4525bdf4c532932a85050f1090a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Apr 2024 21:09:10 -0700
+Subject: perf bench uprobe: Remove lib64 from libc.so.6 binary path
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 459fee7b508231cd4622b3bd94aaa85e8e16b888 ]
+
+bpf_program__attach_uprobe_opts will search LD_LIBRARY_PATH and so
+specifying `/lib64` is unnecessary and causes failures for libc.so.6
+paths like `/lib/x86_64-linux-gnu/libc.so.6`.
+
+Fixes: 7b47623b8cae8149 ("perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrei Vagin <avagin@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kees Kook <keescook@chromium.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240406040911.1603801-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/bench/uprobe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
+index 5c71fdc419dd7..b722ff88fe7de 100644
+--- a/tools/perf/bench/uprobe.c
++++ b/tools/perf/bench/uprobe.c
+@@ -47,7 +47,7 @@ static const char * const bench_uprobe_usage[] = {
+ #define bench_uprobe__attach_uprobe(prog) \
+ skel->links.prog = bpf_program__attach_uprobe_opts(/*prog=*/skel->progs.prog, \
+ /*pid=*/-1, \
+- /*binary_path=*/"/lib64/libc.so.6", \
++ /*binary_path=*/"libc.so.6", \
+ /*func_offset=*/0, \
+ /*opts=*/&uprobe_opts); \
+ if (!skel->links.prog) { \
+--
+2.43.0
+
--- /dev/null
+From 34bac9df074bc994b0a890e228bb1586390e90b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 15:20:12 -0700
+Subject: perf build: Fix out of tree build related to installation of
+ sysreg-defs
+
+From: Ethan Adams <j.ethan.adams@gmail.com>
+
+[ Upstream commit efae55bb78cf8722c7df01cd974197dfd13ece39 ]
+
+It seems that a previous modification to sysreg-defs, which corrected
+emitting the header to the specified output directory, exposed missing
+subdir, prefix variables.
+
+This breaks out of tree builds of perf as the file is now built into the
+output directory, but still tries to descend into output directory as a
+subdir.
+
+Fixes: a29ee6aea7030786 ("perf build: Ensure sysreg-defs Makefile respects output dir")
+Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
+Reviewed-by: Tycho Andersen <tycho@tycho.pizza>
+Signed-off-by: Ethan Adams <j.ethan.adams@gmail.com>
+Tested-by: Tycho Andersen <tycho@tycho.pizza>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240314222012.47193-1-j.ethan.adams@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Makefile.perf | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
+index 116db7874412d..27705df2e2ba8 100644
+--- a/tools/perf/Makefile.perf
++++ b/tools/perf/Makefile.perf
+@@ -455,18 +455,19 @@ SHELL = $(SHELL_PATH)
+
+ arm64_gen_sysreg_dir := $(srctree)/tools/arch/arm64/tools
+ ifneq ($(OUTPUT),)
+- arm64_gen_sysreg_outdir := $(OUTPUT)
++ arm64_gen_sysreg_outdir := $(abspath $(OUTPUT))
+ else
+ arm64_gen_sysreg_outdir := $(CURDIR)
+ endif
+
+ arm64-sysreg-defs: FORCE
+- $(Q)$(MAKE) -C $(arm64_gen_sysreg_dir) O=$(arm64_gen_sysreg_outdir)
++ $(Q)$(MAKE) -C $(arm64_gen_sysreg_dir) O=$(arm64_gen_sysreg_outdir) \
++ prefix= subdir=
+
+ arm64-sysreg-defs-clean:
+ $(call QUIET_CLEAN,arm64-sysreg-defs)
+ $(Q)$(MAKE) -C $(arm64_gen_sysreg_dir) O=$(arm64_gen_sysreg_outdir) \
+- clean > /dev/null
++ prefix= subdir= clean > /dev/null
+
+ beauty_linux_dir := $(srctree)/tools/perf/trace/beauty/include/linux/
+ linux_uapi_dir := $(srctree)/tools/include/uapi/linux
+--
+2.43.0
+
--- /dev/null
+From e0db6a482dc458229402c5190bd308bbde25f794 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 17:34:24 -0700
+Subject: perf daemon: Fix file leak in daemon_session__control
+
+From: Samasth Norway Ananda <samasth.norway.ananda@oracle.com>
+
+[ Upstream commit 09541603462c399c7408d50295db99b4b8042eaa ]
+
+The open() function returns -1 on error.
+
+The 'control' and 'ack' file descriptors are both initialized with
+open() and further validated with 'if' statement.
+
+'if (!control)' would evaluate to 'true' if returned value on error were
+'0' but it is actually '-1'.
+
+Fixes: edcaa47958c7438b ("perf daemon: Add 'ping' command")
+Signed-off-by: Samasth Norway Ananda <samasth.norway.ananda@oracle.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240510003424.2016914-1-samasth.norway.ananda@oracle.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-daemon.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c
+index 83954af36753a..de76bbc50bfbc 100644
+--- a/tools/perf/builtin-daemon.c
++++ b/tools/perf/builtin-daemon.c
+@@ -523,7 +523,7 @@ static int daemon_session__control(struct daemon_session *session,
+ session->base, SESSION_CONTROL);
+
+ control = open(control_path, O_WRONLY|O_NONBLOCK);
+- if (!control)
++ if (control < 0)
+ return -1;
+
+ if (do_ack) {
+@@ -532,7 +532,7 @@ static int daemon_session__control(struct daemon_session *session,
+ session->base, SESSION_ACK);
+
+ ack = open(ack_path, O_RDONLY, O_NONBLOCK);
+- if (!ack) {
++ if (ack < 0) {
+ close(control);
+ return -1;
+ }
+--
+2.43.0
+
--- /dev/null
+From 11ed4a56e59d70a1b6de2664a3198343db15d0aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 10:00:13 -0700
+Subject: perf docs: Document bpf event modifier
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit eb4d27cf9aef3e6c9bcaf8fa1a1cadc2433d847b ]
+
+Document that 'b' is used as a modifier to make an event use a BPF
+counter.
+
+Fixes: 01bd8efcec444468 ("perf stat: Introduce ':b' modifier")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240416170014.985191-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Documentation/perf-list.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
+index 3b12595193c9f..6bf2468f59d31 100644
+--- a/tools/perf/Documentation/perf-list.txt
++++ b/tools/perf/Documentation/perf-list.txt
+@@ -71,6 +71,7 @@ counted. The following modifiers exist:
+ D - pin the event to the PMU
+ W - group is weak and will fallback to non-group if not schedulable,
+ e - group or event are exclusive and do not share the PMU
++ b - use BPF aggregration (see perf stat --bpf-counters)
+
+ The 'p' modifier can be used for specifying how precise the instruction
+ address should be. The 'p' modifier can be specified multiple times:
+--
+2.43.0
+
--- /dev/null
+From f8bfcbfd9cf07f35dca7016c5256d17913d06dc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 10:32:23 +0200
+Subject: perf intel-pt: Fix unassigned instruction op (discovered by
+ MemorySanitizer)
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit e101a05f79fd4ee3e89d2f3fb716493c33a33708 ]
+
+MemorySanitizer discovered instances where the instruction op value was
+not assigned.:
+
+ WARNING: MemorySanitizer: use-of-uninitialized-value
+ #0 0x5581c00a76b3 in intel_pt_sample_flags tools/perf/util/intel-pt.c:1527:17
+ Uninitialized value was stored to memory at
+ #0 0x5581c005ddf8 in intel_pt_walk_insn tools/perf/util/intel-pt-decoder/intel-pt-decoder.c:1256:25
+
+The op value is used to set branch flags for branch instructions
+encountered when walking the code, so fix by setting op to
+INTEL_PT_OP_OTHER in other cases.
+
+Fixes: 4c761d805bb2d2ea ("perf intel-pt: Fix intel_pt_fup_event() assumptions about setting state type")
+Reported-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Tested-by: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Closes: https://lore.kernel.org/linux-perf-users/20240320162619.1272015-1-irogers@google.com/
+Link: https://lore.kernel.org/r/20240326083223.10883-1-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 2 ++
+ tools/perf/util/intel-pt.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+index b450178e3420b..e733f6b1f7ac5 100644
+--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+@@ -1319,6 +1319,8 @@ static bool intel_pt_fup_event(struct intel_pt_decoder *decoder, bool no_tip)
+ bool ret = false;
+
+ decoder->state.type &= ~INTEL_PT_BRANCH;
++ decoder->state.insn_op = INTEL_PT_OP_OTHER;
++ decoder->state.insn_len = 0;
+
+ if (decoder->set_fup_cfe_ip || decoder->set_fup_cfe) {
+ bool ip = decoder->set_fup_cfe_ip;
+diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
+index f38893e0b0369..4db9a098f5926 100644
+--- a/tools/perf/util/intel-pt.c
++++ b/tools/perf/util/intel-pt.c
+@@ -764,6 +764,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
+
+ addr_location__init(&al);
+ intel_pt_insn->length = 0;
++ intel_pt_insn->op = INTEL_PT_OP_OTHER;
+
+ if (to_ip && *ip == to_ip)
+ goto out_no_cache;
+@@ -898,6 +899,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
+
+ if (to_ip && *ip == to_ip) {
+ intel_pt_insn->length = 0;
++ intel_pt_insn->op = INTEL_PT_OP_OTHER;
+ goto out_no_cache;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 010c28150994d8bf1c8409f0f11d1b5457cbf99c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 14:35:07 -0700
+Subject: perf pmu: Assume sysfs events are always the same case
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 7b6dd7a923281a7ccb980a0f768d6926721eb3cc ]
+
+Perf event names aren't case sensitive. For sysfs events the entire
+directory of events is read then iterated comparing names in a case
+insensitive way, most often to see if an event is present.
+
+Consider:
+
+ $ perf stat -e inst_retired.any true
+
+The event inst_retired.any may be present in any PMU, so every PMU's
+sysfs events are loaded and then searched with strcasecmp to see if
+any match. This event is only present on the cpu PMU as a JSON event
+so a lot of events were loaded from sysfs unnecessarily just to prove
+an event didn't exist there.
+
+This change avoids loading all the events by assuming sysfs event
+names are always either lower or uppercase. It uses file exists and
+only loads the events when the desired event is present.
+
+For the example above, the number of openat calls measured by 'perf
+trace' on a tigerlake laptop goes from 325 down to 255. The reduction
+will be larger for machines with many PMUs, particularly replicated
+uncore PMUs.
+
+Ensure pmu_aliases_parse() is called before all uses of the aliases
+list, but remove some "pmu->sysfs_aliases_loaded" tests as they are now
+part of the function.
+
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240502213507.2339733-7-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: d9c5f5f94c2d ("perf pmu: Count sys and cpuid JSON events separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmu.c | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index a0ec0103e0a62..bd4270c3beb54 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -425,9 +425,30 @@ static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,
+ {
+ struct perf_pmu_alias *alias;
+
+- if (load && !pmu->sysfs_aliases_loaded)
+- pmu_aliases_parse(pmu);
++ if (load && !pmu->sysfs_aliases_loaded) {
++ bool has_sysfs_event;
++ char event_file_name[FILENAME_MAX + 8];
+
++ /*
++ * Test if alias/event 'name' exists in the PMU's sysfs/events
++ * directory. If not skip parsing the sysfs aliases. Sysfs event
++ * name must be all lower or all upper case.
++ */
++ scnprintf(event_file_name, sizeof(event_file_name), "events/%s", name);
++ for (size_t i = 7, n = 7 + strlen(name); i < n; i++)
++ event_file_name[i] = tolower(event_file_name[i]);
++
++ has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);
++ if (!has_sysfs_event) {
++ for (size_t i = 7, n = 7 + strlen(name); i < n; i++)
++ event_file_name[i] = toupper(event_file_name[i]);
++
++ has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);
++ }
++ if (has_sysfs_event)
++ pmu_aliases_parse(pmu);
++
++ }
+ list_for_each_entry(alias, &pmu->aliases, list) {
+ if (!strcasecmp(alias->name, name))
+ return alias;
+@@ -1629,9 +1650,7 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
+ {
+ size_t nr;
+
+- if (!pmu->sysfs_aliases_loaded)
+- pmu_aliases_parse(pmu);
+-
++ pmu_aliases_parse(pmu);
+ nr = pmu->sysfs_aliases;
+
+ if (pmu->cpu_aliases_added)
+@@ -1690,6 +1709,7 @@ int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus,
+ struct strbuf sb;
+
+ strbuf_init(&sb, /*hint=*/ 0);
++ pmu_aliases_parse(pmu);
+ pmu_add_cpu_aliases(pmu);
+ list_for_each_entry(event, &pmu->aliases, list) {
+ size_t buf_used;
+@@ -2090,6 +2110,7 @@ const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)
+ if (!pmu)
+ return NULL;
+
++ pmu_aliases_parse(pmu);
+ pmu_add_cpu_aliases(pmu);
+ list_for_each_entry(event, &pmu->aliases, list) {
+ struct perf_event_attr attr = {.config = 0,};
+--
+2.43.0
+
--- /dev/null
+From 367b5eddccf58f10c598ebc249d549d174d00609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 May 2024 17:36:01 -0700
+Subject: perf pmu: Count sys and cpuid JSON events separately
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit d9c5f5f94c2d356fdf3503f7fcaf254512bc032d ]
+
+Sys events are eagerly loaded as each event has a compat option that may
+mean the event is or isn't associated with the PMU.
+
+These shouldn't be counted as loaded_json_events as that is used for
+JSON events matching the CPUID that may or may not have been loaded. The
+mismatch causes issues on ARM64 that uses sys events.
+
+Fixes: e6ff1eed3584362d ("perf pmu: Lazily add JSON events")
+Closes: https://lore.kernel.org/lkml/20240510024729.1075732-1-justin.he@arm.com/
+Reported-by: Jia He <justin.he@arm.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240511003601.2666907-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmu.c | 70 ++++++++++++++++++++++++++++++-------------
+ tools/perf/util/pmu.h | 6 ++--
+ 2 files changed, 53 insertions(+), 23 deletions(-)
+
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index bd4270c3beb54..f1b58784bdffe 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -36,6 +36,18 @@ struct perf_pmu perf_pmu__fake = {
+
+ #define UNIT_MAX_LEN 31 /* max length for event unit name */
+
++enum event_source {
++ /* An event loaded from /sys/devices/<pmu>/events. */
++ EVENT_SRC_SYSFS,
++ /* An event loaded from a CPUID matched json file. */
++ EVENT_SRC_CPU_JSON,
++ /*
++ * An event loaded from a /sys/devices/<pmu>/identifier matched json
++ * file.
++ */
++ EVENT_SRC_SYS_JSON,
++};
++
+ /**
+ * struct perf_pmu_alias - An event either read from sysfs or builtin in
+ * pmu-events.c, created by parsing the pmu-events json files.
+@@ -521,7 +533,7 @@ static int update_alias(const struct pmu_event *pe,
+
+ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
+ const char *desc, const char *val, FILE *val_fd,
+- const struct pmu_event *pe)
++ const struct pmu_event *pe, enum event_source src)
+ {
+ struct perf_pmu_alias *alias;
+ int ret;
+@@ -573,25 +585,30 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
+ }
+ snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
+ }
+- if (!pe) {
+- /* Update an event from sysfs with json data. */
+- struct update_alias_data data = {
+- .pmu = pmu,
+- .alias = alias,
+- };
+-
++ switch (src) {
++ default:
++ case EVENT_SRC_SYSFS:
+ alias->from_sysfs = true;
+ if (pmu->events_table) {
++ /* Update an event from sysfs with json data. */
++ struct update_alias_data data = {
++ .pmu = pmu,
++ .alias = alias,
++ };
+ if (pmu_events_table__find_event(pmu->events_table, pmu, name,
+ update_alias, &data) == 0)
+- pmu->loaded_json_aliases++;
++ pmu->cpu_json_aliases++;
+ }
+- }
+-
+- if (!pe)
+ pmu->sysfs_aliases++;
+- else
+- pmu->loaded_json_aliases++;
++ break;
++ case EVENT_SRC_CPU_JSON:
++ pmu->cpu_json_aliases++;
++ break;
++ case EVENT_SRC_SYS_JSON:
++ pmu->sys_json_aliases++;
++ break;
++
++ }
+ list_add_tail(&alias->list, &pmu->aliases);
+ return 0;
+ }
+@@ -667,7 +684,8 @@ static int pmu_aliases_parse(struct perf_pmu *pmu)
+ }
+
+ if (perf_pmu__new_alias(pmu, name, /*desc=*/ NULL,
+- /*val=*/ NULL, file, /*pe=*/ NULL) < 0)
++ /*val=*/ NULL, file, /*pe=*/ NULL,
++ EVENT_SRC_SYSFS) < 0)
+ pr_debug("Cannot set up %s\n", name);
+ fclose(file);
+ }
+@@ -920,7 +938,8 @@ static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe,
+ {
+ struct perf_pmu *pmu = vdata;
+
+- perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=*/ NULL, pe);
++ perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=*/ NULL,
++ pe, EVENT_SRC_CPU_JSON);
+ return 0;
+ }
+
+@@ -955,13 +974,14 @@ static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe,
+ return 0;
+
+ if (pmu_uncore_alias_match(pe->pmu, pmu->name) &&
+- pmu_uncore_identifier_match(pe->compat, pmu->id)) {
++ pmu_uncore_identifier_match(pe->compat, pmu->id)) {
+ perf_pmu__new_alias(pmu,
+ pe->name,
+ pe->desc,
+ pe->event,
+ /*val_fd=*/ NULL,
+- pe);
++ pe,
++ EVENT_SRC_SYS_JSON);
+ }
+
+ return 0;
+@@ -1053,6 +1073,12 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char
+ pmu->max_precise = pmu_max_precise(dirfd, pmu);
+ pmu->alias_name = pmu_find_alias_name(pmu, dirfd);
+ pmu->events_table = perf_pmu__find_events_table(pmu);
++ /*
++ * Load the sys json events/aliases when loading the PMU as each event
++ * may have a different compat regular expression. We therefore can't
++ * know the number of sys json events/aliases without computing the
++ * regular expressions for them all.
++ */
+ pmu_add_sys_aliases(pmu);
+ list_add_tail(&pmu->list, pmus);
+
+@@ -1651,12 +1677,14 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
+ size_t nr;
+
+ pmu_aliases_parse(pmu);
+- nr = pmu->sysfs_aliases;
++ nr = pmu->sysfs_aliases + pmu->sys_json_aliases;;
+
+ if (pmu->cpu_aliases_added)
+- nr += pmu->loaded_json_aliases;
++ nr += pmu->cpu_json_aliases;
+ else if (pmu->events_table)
+- nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->loaded_json_aliases;
++ nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->cpu_json_aliases;
++ else
++ assert(pmu->cpu_json_aliases == 0);
+
+ return pmu->selectable ? nr + 1 : nr;
+ }
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index 109f3704a6461..25803ea92ed34 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -121,8 +121,10 @@ struct perf_pmu {
+ const struct pmu_events_table *events_table;
+ /** @sysfs_aliases: Number of sysfs aliases loaded. */
+ uint32_t sysfs_aliases;
+- /** @sysfs_aliases: Number of json event aliases loaded. */
+- uint32_t loaded_json_aliases;
++ /** @cpu_json_aliases: Number of json event aliases loaded specific to the CPUID. */
++ uint32_t cpu_json_aliases;
++ /** @sys_json_aliases: Number of json event aliases loaded matching the PMU's identifier. */
++ uint32_t sys_json_aliases;
+ /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */
+ bool sysfs_aliases_loaded;
+ /**
+--
+2.43.0
+
--- /dev/null
+From 4e8241d81864768f7c3b73970233cd5baa602f4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 11:13:30 -0300
+Subject: perf probe: Add missing libgen.h header needed for using basename()
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 581037151910126a7934e369e4b6ac70eda9a703 ]
+
+This prototype is obtained indirectly, by luck, from some other header
+in probe-event.c in most systems, but recently exploded on alpine:edge:
+
+ 8 13.39 alpine:edge : FAIL gcc version 13.2.1 20240309 (Alpine 13.2.1_git20240309)
+ util/probe-event.c: In function 'convert_exec_to_group':
+ util/probe-event.c:225:16: error: implicit declaration of function 'basename' [-Werror=implicit-function-declaration]
+ 225 | ptr1 = basename(exec_copy);
+ | ^~~~~~~~
+ util/probe-event.c:225:14: error: assignment to 'char *' from 'int' makes pointer from integer without a cast [-Werror=int-conversion]
+ 225 | ptr1 = basename(exec_copy);
+ | ^
+ cc1: all warnings being treated as errors
+ make[3]: *** [/git/perf-6.8.0/tools/build/Makefile.build:158: util] Error 2
+
+Fix it by adding the libgen.h header where basename() is prototyped.
+
+Fixes: fb7345bbf7fad9bf ("perf probe: Support basic dwarf-based operations on uprobe events")
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/lkml/
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/probe-event.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
+index a1a796043691f..d8e70a54d9e5e 100644
+--- a/tools/perf/util/probe-event.c
++++ b/tools/perf/util/probe-event.c
+@@ -11,6 +11,7 @@
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
++#include <libgen.h>
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+--
+2.43.0
+
--- /dev/null
+From 8ad568ae4c051214bc96879bfd22afefbccb501e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 23:46:36 -0800
+Subject: perf record: Delete session after stopping sideband thread
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 88ce0106a1f603bf360cb397e8fe293f8298fabb ]
+
+The session has a header in it which contains a perf env with
+bpf_progs. The bpf_progs are accessed by the sideband thread and so
+the sideband thread must be stopped before the session is deleted, to
+avoid a use after free. This error was detected by AddressSanitizer
+in the following:
+
+ ==2054673==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d000161e00 at pc 0x55769289de54 bp 0x7f9df36d4ab0 sp 0x7f9df36d4aa8
+ READ of size 8 at 0x61d000161e00 thread T1
+ #0 0x55769289de53 in __perf_env__insert_bpf_prog_info util/env.c:42
+ #1 0x55769289dbb1 in perf_env__insert_bpf_prog_info util/env.c:29
+ #2 0x557692bbae29 in perf_env__add_bpf_info util/bpf-event.c:483
+ #3 0x557692bbb01a in bpf_event__sb_cb util/bpf-event.c:512
+ #4 0x5576928b75f4 in perf_evlist__poll_thread util/sideband_evlist.c:68
+ #5 0x7f9df96a63eb in start_thread nptl/pthread_create.c:444
+ #6 0x7f9df9726a4b in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
+
+ 0x61d000161e00 is located 384 bytes inside of 2136-byte region [0x61d000161c80,0x61d0001624d8)
+ freed by thread T0 here:
+ #0 0x7f9dfa6d7288 in __interceptor_free libsanitizer/asan/asan_malloc_linux.cpp:52
+ #1 0x557692978d50 in perf_session__delete util/session.c:319
+ #2 0x557692673959 in __cmd_record tools/perf/builtin-record.c:2884
+ #3 0x55769267a9f0 in cmd_record tools/perf/builtin-record.c:4259
+ #4 0x55769286710c in run_builtin tools/perf/perf.c:349
+ #5 0x557692867678 in handle_internal_command tools/perf/perf.c:402
+ #6 0x557692867a40 in run_argv tools/perf/perf.c:446
+ #7 0x557692867fae in main tools/perf/perf.c:562
+ #8 0x7f9df96456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
+
+Fixes: 657ee5531903339b ("perf evlist: Introduce side band thread")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Disha Goel <disgoel@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Link: https://lore.kernel.org/r/20240301074639.2260708-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-record.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index 3ddd4381aebd2..7f583fd0750cb 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -2877,10 +2877,10 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
+ }
+ #endif
+ zstd_fini(&session->zstd_data);
+- perf_session__delete(session);
+-
+ if (!opts->no_bpf_event)
+ evlist__stop_sb_thread(rec->sb_evlist);
++
++ perf_session__delete(session);
+ return status;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 0e65278b1218bb063cc2dbefe084623376788d92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 10:54:47 +0300
+Subject: perf record: Fix debug message placement for test consumption
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 792bc998baf9ae17297b1f93b1edc3ca34a0b7e2 ]
+
+evlist__config() might mess up the debug output consumed by test
+"Test per-thread recording" in "Miscellaneous Intel PT testing".
+
+Move it out from between the debug prints:
+
+ "perf record opening and mmapping events" and
+ "perf record done opening and mmapping events"
+
+Fixes: da4062021e0e6da5 ("perf tools: Add debug messages and comments for testing")
+Closes: https://lore.kernel.org/linux-perf-users/ZhVfc5jYLarnGzKa@x1/
+Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20240411075447.17306-1-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-record.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index 7f583fd0750cb..a5051a571d5af 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -1355,8 +1355,6 @@ static int record__open(struct record *rec)
+ struct record_opts *opts = &rec->opts;
+ int rc = 0;
+
+- evlist__config(evlist, opts, &callchain_param);
+-
+ evlist__for_each_entry(evlist, pos) {
+ try_again:
+ if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) {
+@@ -2479,6 +2477,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
+
+ evlist__uniquify_name(rec->evlist);
+
++ evlist__config(rec->evlist, opts, &callchain_param);
++
+ /* Debug message used by test scripts */
+ pr_debug3("perf record opening and mmapping events\n");
+ if (record__open(rec) != 0) {
+--
+2.43.0
+
--- /dev/null
+From d0e68bb3e0a86cb980e726c0f82e8730a32c71e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 20:53:00 -0700
+Subject: perf report: Avoid SEGV in report__setup_sample_type()
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 45b4f402a6b782352c4bafcff682bfb01da9ca05 ]
+
+In some cases evsel->name is lazily initialized in evsel__name(). If not
+initialized passing NULL to strstr() leads to a SEGV.
+
+Fixes: ccb17caecfbd542f ("perf report: Set PERF_SAMPLE_DATA_SRC bit for Arm SPE event")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linux.dev>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240508035301.1554434-4-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-report.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index f2ed2b7e80a32..ea8636abbb8db 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -427,7 +427,7 @@ static int report__setup_sample_type(struct report *rep)
+ * compatibility, set the bit if it's an old perf data file.
+ */
+ evlist__for_each_entry(session->evlist, evsel) {
+- if (strstr(evsel->name, "arm_spe") &&
++ if (strstr(evsel__name(evsel), "arm_spe") &&
+ !(sample_type & PERF_SAMPLE_DATA_SRC)) {
+ evsel->core.attr.sample_type |= PERF_SAMPLE_DATA_SRC;
+ sample_type |= PERF_SAMPLE_DATA_SRC;
+--
+2.43.0
+
--- /dev/null
+From fc451fe67f1201f7d7661c7cc2233ddcc8bb4e34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 08:48:05 +0200
+Subject: perf report: Fix PAI counter names for s390 virtual machines
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit b74bc5a633a7d72f89141d481d835e73bda3c3ae ]
+
+s390 introduced the Processor Activity Instrumentation (PAI) counter
+facility on LPAR and virtual machines z/VM for models 3931 and 3932.
+
+These counters are stored as raw data in the perf.data file and are
+displayed with:
+
+ # perf report -i /tmp//perfout-635468 -D | grep Counter
+ Counter:007 <unknown> Value:0x00000000000186a0
+ Counter:032 <unknown> Value:0x0000000000000001
+ Counter:032 <unknown> Value:0x0000000000000001
+ Counter:032 <unknown> Value:0x0000000000000001
+ #
+
+However on z/VM virtual machines, the counter names are not retrieved
+from the PMU and are shown as '<unknown>'. This is caused by the CPU
+string saved in the mapfile.csv for this machine:
+
+ ^IBM.393[12].*3\.7.[[:xdigit:]]+$,3,cf_z16,core
+
+This string contains the CPU Measurement facility first and second
+version number and authorization level (3\.7.[[:xdigit:]]+). These
+numbers do not apply to the PAI counter facility. In fact they can be
+omitted.
+
+Shorten the CPU identification string for this machine to manufacturer
+and model. This is sufficient for all PMU devices.
+
+Output after:
+
+ # perf report -i /tmp//perfout-635468 -D | grep Counter
+ Counter:007 km_aes_128 Value:0x00000000000186a0
+ Counter:032 kma_gcm_aes_256 Value:0x0000000000000001
+ Counter:032 kma_gcm_aes_256 Value:0x0000000000000001
+ Counter:032 kma_gcm_aes_256 Value:0x0000000000000001
+ #
+
+Fixes: b539deafbadb2fc6 ("perf report: Add s390 raw data interpretation for PAI counters")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Sven Schnelle <svens@linux.ibm.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240404064806.1362876-1-tmricht@linux.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/pmu-events/arch/s390/mapfile.csv | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/pmu-events/arch/s390/mapfile.csv b/tools/perf/pmu-events/arch/s390/mapfile.csv
+index a918e1af77a57..b22648d127517 100644
+--- a/tools/perf/pmu-events/arch/s390/mapfile.csv
++++ b/tools/perf/pmu-events/arch/s390/mapfile.csv
+@@ -5,4 +5,4 @@ Family-model,Version,Filename,EventType
+ ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core
+ ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core
+ ^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_z15,core
+-^IBM.393[12].*3\.7.[[:xdigit:]]+$,3,cf_z16,core
++^IBM.393[12].*$,3,cf_z16,core
+--
+2.43.0
+
--- /dev/null
+From bb6421731c41d7dac2b45ed03d4d7c041c0b5556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Apr 2024 14:27:23 +0800
+Subject: perf sched timehist: Fix -g/--call-graph option failure
+
+From: Yang Jihong <yangjihong@bytedance.com>
+
+[ Upstream commit 6e4b398770d5023eb6383da9360a23bd537c155b ]
+
+When 'perf sched' enables the call-graph recording, sample_type of dummy
+event does not have PERF_SAMPLE_CALLCHAIN, timehist_check_attr() checks
+that the evsel does not have a callchain, and set show_callchain to 0.
+
+Currently 'perf sched timehist' only saves callchain when processing the
+'sched:sched_switch event', timehist_check_attr() only needs to determine
+whether the event has PERF_SAMPLE_CALLCHAIN.
+
+Before:
+
+ # perf sched record -g true
+ [ perf record: Woken up 0 times to write data ]
+ [ perf record: Captured and wrote 4.153 MB perf.data (7536 samples) ]
+ # perf sched timehist
+ Samples do not have callchains.
+ time cpu task name wait time sch delay run time
+ [tid/pid] (msec) (msec) (msec)
+ --------------- ------ ------------------------------ --------- --------- ---------
+ 147851.826019 [0000] perf[285035] 0.000 0.000 0.000
+ 147851.826029 [0000] migration/0[15] 0.000 0.003 0.009
+ 147851.826063 [0001] perf[285035] 0.000 0.000 0.000
+ 147851.826069 [0001] migration/1[21] 0.000 0.003 0.006
+ <SNIP>
+
+After:
+
+ # perf sched record -g true
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 2.572 MB perf.data (822 samples) ]
+ # perf sched timehist
+ time cpu task name waittime sch delay runtime
+ [tid/pid] (msec) (msec) (msec)
+ ----------- --- --------------- -------- -------- -----
+ 4193.035164 [0] perf[277062] 0.000 0.000 0.000 __traceiter_sched_switch <- __traceiter_sched_switch <- __sched_text_start <- preempt_schedule_common <- __cond_resched <- __wait_for_common <- wait_for_completion
+ 4193.035174 [0] migration/0[15] 0.000 0.003 0.009 __traceiter_sched_switch <- __traceiter_sched_switch <- __sched_text_start <- smpboot_thread_fn <- kthread <- ret_from_fork
+ 4193.035207 [1] perf[277062] 0.000 0.000 0.000 __traceiter_sched_switch <- __traceiter_sched_switch <- __sched_text_start <- preempt_schedule_common <- __cond_resched <- __wait_for_common <- wait_for_completion
+ 4193.035214 [1] migration/1[21] 0.000 0.003 0.007 __traceiter_sched_switch <- __traceiter_sched_switch <- __sched_text_start <- smpboot_thread_fn <- kthread <- ret_from_fork
+ <SNIP>
+
+Fixes: 9c95e4ef06572349 ("perf evlist: Add evlist__findnew_tracking_event() helper")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Yang Jihong <yangjihong@bytedance.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Yang Jihong <yangjihong1@huawei.com>
+Link: https://lore.kernel.org/r/20240401062724.1006010-2-yangjihong@bytedance.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-sched.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
+index dd6065afbbaf6..5c1badc4d8f2c 100644
+--- a/tools/perf/builtin-sched.c
++++ b/tools/perf/builtin-sched.c
+@@ -3000,8 +3000,11 @@ static int timehist_check_attr(struct perf_sched *sched,
+ return -1;
+ }
+
+- if (sched->show_callchain && !evsel__has_callchain(evsel)) {
+- pr_info("Samples do not have callchains.\n");
++ /* only need to save callchain related to sched_switch event */
++ if (sched->show_callchain &&
++ evsel__name_is(evsel, "sched:sched_switch") &&
++ !evsel__has_callchain(evsel)) {
++ pr_info("Samples of sched_switch event do not have callchains.\n");
+ sched->show_callchain = 0;
+ symbol_conf.use_callchain = 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From b2f6dcd3d4e2ec49e26a558ec4496e849be4c95a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 08:48:06 +0200
+Subject: perf stat: Do not fail on metrics on s390 z/VM systems
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit c2f3d7dfc7373d53286f2a5c882d3397a5070adc ]
+
+On s390 z/VM virtual machines command 'perf list' also displays metrics:
+
+ # perf list | grep -A 20 'Metric Groups:'
+ Metric Groups:
+
+ No_group:
+ cpi
+ [Cycles per Instruction]
+ est_cpi
+ [Estimated Instruction Complexity CPI infinite Level 1]
+ finite_cpi
+ [Cycles per Instructions from Finite cache/memory]
+ l1mp
+ [Level One Miss per 100 Instructions]
+ l2p
+ [Percentage sourced from Level 2 cache]
+ l3p
+ [Percentage sourced from Level 3 on same chip cache]
+ l4lp
+ [Percentage sourced from Level 4 Local cache on same book]
+ l4rp
+ [Percentage sourced from Level 4 Remote cache on different book]
+ memp
+ [Percentage sourced from memory]
+ ....
+ #
+
+The command
+
+ # perf stat -M cpi -- true
+ event syntax error: '{CPU_CYCLES/metric-id=CPU_CYCLES/.....'
+ \___ Bad event or PMU
+
+ Unable to find PMU or event on a PMU of 'CPU_CYCLES'
+
+ event syntax error: '{CPU_CYCLES/metric-id=CPU_CYCLES/...'
+ \___ Cannot find PMU `CPU_CYCLES'.
+ Missing kernel support?
+ #
+
+fails. 'perf stat' should not fail on metrics when the referenced CPU
+Counter Measurement PMU is not available.
+
+Output after:
+
+ # perf stat -M est_cpi -- sleep 1
+
+ Performance counter stats for 'sleep 1':
+
+ 1,000,887,494 ns duration_time # 0.00 est_cpi
+
+ 1.000887494 seconds time elapsed
+
+ 0.000143000 seconds user
+ 0.000662000 seconds sys
+
+ #
+
+Fixes: 7f76b31130680fb3 ("perf list: Add IBM z16 event description for s390")
+Suggested-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Sven Schnelle <svens@linux.ibm.com>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240404064806.1362876-2-tmricht@linux.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arch/s390/cf_z16/transaction.json | 28 +++++++++----------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json
+index ec2ff78e2b5f2..3ab1d3a6638c4 100644
+--- a/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json
++++ b/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json
+@@ -2,71 +2,71 @@
+ {
+ "BriefDescription": "Transaction count",
+ "MetricName": "transaction",
+- "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
++ "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL if has_event(TX_C_TEND) else 0"
+ },
+ {
+ "BriefDescription": "Cycles per Instruction",
+ "MetricName": "cpi",
+- "MetricExpr": "CPU_CYCLES / INSTRUCTIONS"
++ "MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(INSTRUCTIONS) else 0"
+ },
+ {
+ "BriefDescription": "Problem State Instruction Ratio",
+ "MetricName": "prbstate",
+- "MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100"
++ "MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0"
+ },
+ {
+ "BriefDescription": "Level One Miss per 100 Instructions",
+ "MetricName": "l1mp",
+- "MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100"
++ "MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0"
+ },
+ {
+ "BriefDescription": "Percentage sourced from Level 2 cache",
+ "MetricName": "l2p",
+- "MetricExpr": "((DCW_REQ + DCW_REQ_IV + ICW_REQ + ICW_REQ_IV) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100"
++ "MetricExpr": "((DCW_REQ + DCW_REQ_IV + ICW_REQ + ICW_REQ_IV) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100 if has_event(DCW_REQ) else 0"
+ },
+ {
+ "BriefDescription": "Percentage sourced from Level 3 on same chip cache",
+ "MetricName": "l3p",
+- "MetricExpr": "((DCW_REQ_CHIP_HIT + DCW_ON_CHIP + DCW_ON_CHIP_IV + DCW_ON_CHIP_CHIP_HIT + ICW_REQ_CHIP_HIT + ICW_ON_CHIP + ICW_ON_CHIP_IV + ICW_ON_CHIP_CHIP_HIT) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100"
++ "MetricExpr": "((DCW_REQ_CHIP_HIT + DCW_ON_CHIP + DCW_ON_CHIP_IV + DCW_ON_CHIP_CHIP_HIT + ICW_REQ_CHIP_HIT + ICW_ON_CHIP + ICW_ON_CHIP_IV + ICW_ON_CHIP_CHIP_HIT) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100 if has_event(DCW_REQ_CHIP_HIT) else 0"
+ },
+ {
+ "BriefDescription": "Percentage sourced from Level 4 Local cache on same book",
+ "MetricName": "l4lp",
+- "MetricExpr": "((DCW_REQ_DRAWER_HIT + DCW_ON_CHIP_DRAWER_HIT + DCW_ON_MODULE + DCW_ON_DRAWER + IDCW_ON_MODULE_IV + IDCW_ON_MODULE_CHIP_HIT + IDCW_ON_MODULE_DRAWER_HIT + IDCW_ON_DRAWER_IV + IDCW_ON_DRAWER_CHIP_HIT + IDCW_ON_DRAWER_DRAWER_HIT + ICW_REQ_DRAWER_HIT + ICW_ON_CHIP_DRAWER_HIT + ICW_ON_MODULE + ICW_ON_DRAWER) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100"
++ "MetricExpr": "((DCW_REQ_DRAWER_HIT + DCW_ON_CHIP_DRAWER_HIT + DCW_ON_MODULE + DCW_ON_DRAWER + IDCW_ON_MODULE_IV + IDCW_ON_MODULE_CHIP_HIT + IDCW_ON_MODULE_DRAWER_HIT + IDCW_ON_DRAWER_IV + IDCW_ON_DRAWER_CHIP_HIT + IDCW_ON_DRAWER_DRAWER_HIT + ICW_REQ_DRAWER_HIT + ICW_ON_CHIP_DRAWER_HIT + ICW_ON_MODULE + ICW_ON_DRAWER) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100 if has_event(DCW_REQ_DRAWER_HIT) else 0"
+ },
+ {
+ "BriefDescription": "Percentage sourced from Level 4 Remote cache on different book",
+ "MetricName": "l4rp",
+- "MetricExpr": "((DCW_OFF_DRAWER + IDCW_OFF_DRAWER_IV + IDCW_OFF_DRAWER_CHIP_HIT + IDCW_OFF_DRAWER_DRAWER_HIT + ICW_OFF_DRAWER) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100"
++ "MetricExpr": "((DCW_OFF_DRAWER + IDCW_OFF_DRAWER_IV + IDCW_OFF_DRAWER_CHIP_HIT + IDCW_OFF_DRAWER_DRAWER_HIT + ICW_OFF_DRAWER) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100 if has_event(DCW_OFF_DRAWER) else 0"
+ },
+ {
+ "BriefDescription": "Percentage sourced from memory",
+ "MetricName": "memp",
+- "MetricExpr": "((DCW_ON_CHIP_MEMORY + DCW_ON_MODULE_MEMORY + DCW_ON_DRAWER_MEMORY + DCW_OFF_DRAWER_MEMORY + ICW_ON_CHIP_MEMORY + ICW_ON_MODULE_MEMORY + ICW_ON_DRAWER_MEMORY + ICW_OFF_DRAWER_MEMORY) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100"
++ "MetricExpr": "((DCW_ON_CHIP_MEMORY + DCW_ON_MODULE_MEMORY + DCW_ON_DRAWER_MEMORY + DCW_OFF_DRAWER_MEMORY + ICW_ON_CHIP_MEMORY + ICW_ON_MODULE_MEMORY + ICW_ON_DRAWER_MEMORY + ICW_OFF_DRAWER_MEMORY) / (L1I_DIR_WRITES + L1D_DIR_WRITES)) * 100 if has_event(DCW_ON_CHIP_MEMORY) else 0"
+ },
+ {
+ "BriefDescription": "Cycles per Instructions from Finite cache/memory",
+ "MetricName": "finite_cpi",
+- "MetricExpr": "L1C_TLB2_MISSES / INSTRUCTIONS"
++ "MetricExpr": "L1C_TLB2_MISSES / INSTRUCTIONS if has_event(L1C_TLB2_MISSES) else 0"
+ },
+ {
+ "BriefDescription": "Estimated Instruction Complexity CPI infinite Level 1",
+ "MetricName": "est_cpi",
+- "MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS)"
++ "MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(INSTRUCTIONS) else 0"
+ },
+ {
+ "BriefDescription": "Estimated Sourcing Cycles per Level 1 Miss",
+ "MetricName": "scpl1m",
+- "MetricExpr": "L1C_TLB2_MISSES / (L1I_DIR_WRITES + L1D_DIR_WRITES)"
++ "MetricExpr": "L1C_TLB2_MISSES / (L1I_DIR_WRITES + L1D_DIR_WRITES) if has_event(L1C_TLB2_MISSES) else 0"
+ },
+ {
+ "BriefDescription": "Estimated TLB CPU percentage of Total CPU",
+ "MetricName": "tlb_percent",
+- "MetricExpr": "((DTLB2_MISSES + ITLB2_MISSES) / CPU_CYCLES) * (L1C_TLB2_MISSES / (L1I_PENALTY_CYCLES + L1D_PENALTY_CYCLES)) * 100"
++ "MetricExpr": "((DTLB2_MISSES + ITLB2_MISSES) / CPU_CYCLES) * (L1C_TLB2_MISSES / (L1I_PENALTY_CYCLES + L1D_PENALTY_CYCLES)) * 100 if has_event(CPU_CYCLES) else 0"
+ },
+ {
+ "BriefDescription": "Estimated Cycles per TLB Miss",
+ "MetricName": "tlb_miss",
+- "MetricExpr": "((DTLB2_MISSES + ITLB2_MISSES) / (DTLB2_WRITES + ITLB2_WRITES)) * (L1C_TLB2_MISSES / (L1I_PENALTY_CYCLES + L1D_PENALTY_CYCLES))"
++ "MetricExpr": "((DTLB2_MISSES + ITLB2_MISSES) / (DTLB2_WRITES + ITLB2_WRITES)) * (L1C_TLB2_MISSES / (L1I_PENALTY_CYCLES + L1D_PENALTY_CYCLES)) if has_event(DTLB2_MISSES) else 0"
+ }
+ ]
+--
+2.43.0
+
--- /dev/null
+From 0b77e9713f858dea849450535152e2d10a0e94da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 22:13:09 -0700
+Subject: perf stat: Don't display metric header for non-leader uncore events
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 193a9e30207f54777ff42d0d8be8389edc522277 ]
+
+On an Intel tigerlake laptop a metric like:
+
+ {
+ "BriefDescription": "Test",
+ "MetricExpr": "imc_free_running@data_read@ + imc_free_running@data_write@",
+ "MetricGroup": "Test",
+ "MetricName": "Test",
+ "ScaleUnit": "6.103515625e-5MiB"
+ },
+
+Will have 4 events:
+
+ uncore_imc_free_running_0/data_read/
+ uncore_imc_free_running_0/data_write/
+ uncore_imc_free_running_1/data_read/
+ uncore_imc_free_running_1/data_write/
+
+If aggregration is disabled with metric-only 2 column headers are
+needed:
+
+ $ perf stat -M test --metric-only -A -a sleep 1
+
+ Performance counter stats for 'system wide':
+
+ MiB Test MiB Test
+ CPU0 1821.0 1820.5
+
+But when not, the counts aggregated in the metric leader and only 1
+column should be shown:
+
+ $ perf stat -M test --metric-only -a sleep 1
+ Performance counter stats for 'system wide':
+
+ MiB Test
+ 5909.4
+
+ 1.001258915 seconds time elapsed
+
+Achieve this by skipping events that aren't metric leaders when
+printing column headers and aggregation isn't disabled.
+
+The bug is long standing, the fixes tag is set to a refactor as that
+is as far back as is reasonable to backport.
+
+Fixes: 088519f318be3a41 ("perf stat: Move the display functions to stat-display.c")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kaige Ye <ye@kaige.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Link: https://lore.kernel.org/r/20240510051309.2452468-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/stat-display.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
+index b7d00a538d703..5f2e20448a074 100644
+--- a/tools/perf/util/stat-display.c
++++ b/tools/perf/util/stat-display.c
+@@ -1207,6 +1207,9 @@ static void print_metric_headers(struct perf_stat_config *config,
+
+ /* Print metrics headers only */
+ evlist__for_each_entry(evlist, counter) {
++ if (config->aggr_mode != AGGR_NONE && counter->metric_leader != counter)
++ continue;
++
+ os.evsel = counter;
+
+ perf_stat__print_shadow_stats(config, counter, 0,
+--
+2.43.0
+
--- /dev/null
+From 338e6891c7bf6133941d9d8703521b4b5764da2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 15:12:08 +0100
+Subject: perf symbols: Fix ownership of string in dso__load_vmlinux()
+
+From: James Clark <james.clark@arm.com>
+
+[ Upstream commit 25626e19ae6df34f336f235b6b3dbd1b566d2738 ]
+
+The linked commit updated dso__load_vmlinux() to call
+dso__set_long_name() before loading the symbols. Loading the symbols may
+not succeed but dso__set_long_name() takes ownership of the string. The
+two callers of this function free the string themselves on failure
+cases, resulting in the following error:
+
+ $ perf record -- ls
+ $ perf report
+
+ free(): double free detected in tcache 2
+
+Fix it by always taking ownership of the string, even on failure. This
+means the string is either freed at the very first early exit condition,
+or later when the dso is deleted or the long name is replaced. Now no
+special return value is needed to signify that the caller needs to
+free the string.
+
+Fixes: e59fea47f83e8a9a ("perf symbols: Fix DSO kernel load and symbol process to correctly map DSO to its long_name, type and adjust_symbols")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: James Clark <james.clark@arm.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240507141210.195939-5-james.clark@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/symbol.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
+index be212ba157dc3..a5a56ed45ebc3 100644
+--- a/tools/perf/util/symbol.c
++++ b/tools/perf/util/symbol.c
+@@ -1937,6 +1937,10 @@ int dso__load(struct dso *dso, struct map *map)
+ return ret;
+ }
+
++/*
++ * Always takes ownership of vmlinux when vmlinux_allocated == true, even if
++ * it returns an error.
++ */
+ int dso__load_vmlinux(struct dso *dso, struct map *map,
+ const char *vmlinux, bool vmlinux_allocated)
+ {
+@@ -1955,8 +1959,11 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
+ else
+ symtab_type = DSO_BINARY_TYPE__VMLINUX;
+
+- if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
++ if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type)) {
++ if (vmlinux_allocated)
++ free((char *) vmlinux);
+ return -1;
++ }
+
+ /*
+ * dso__load_sym() may copy 'dso' which will result in the copies having
+@@ -1999,7 +2006,6 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map)
+ err = dso__load_vmlinux(dso, map, filename, true);
+ if (err > 0)
+ goto out;
+- free(filename);
+ }
+ out:
+ return err;
+@@ -2151,7 +2157,6 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map)
+ err = dso__load_vmlinux(dso, map, filename, true);
+ if (err > 0)
+ return err;
+- free(filename);
+ }
+
+ if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
+--
+2.43.0
+
--- /dev/null
+From 00135977a7c68175b21b25385a08daca7987474b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 11:37:49 +0000
+Subject: perf test shell arm_coresight: Increase buffer size for Coresight
+ basic tests
+
+From: James Clark <james.clark@arm.com>
+
+[ Upstream commit 10b6ee3b597b1b1b4dc390aaf9d589664af31df9 ]
+
+These tests record in a mode that includes kernel trace but look for
+samples of a userspace process. This makes them sensitive to any kernel
+compilation options that increase the amount of time spent in the
+kernel. If the trace buffer is completely filled before userspace is
+reached then the test will fail. Double the buffer size to fix this.
+
+The other tests in the same file aren't sensitive to this for various
+reasons, for example the iterate devices test filters by userspace trace
+only. But in order to keep coverage of all the modes, increase the
+buffer size rather than filtering by userspace for the basic tests.
+
+Fixes: d1efa4a0a696e487 ("perf cs-etm: Add separate decode paths for timeless and per-thread modes")
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Signed-off-by: James Clark <james.clark@arm.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20240326113749.257250-1-james.clark@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/test_arm_coresight.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh
+index 65dd852071250..3302ea0b96723 100755
+--- a/tools/perf/tests/shell/test_arm_coresight.sh
++++ b/tools/perf/tests/shell/test_arm_coresight.sh
+@@ -188,7 +188,7 @@ arm_cs_etm_snapshot_test() {
+
+ arm_cs_etm_basic_test() {
+ echo "Recording trace with '$*'"
+- perf record -o ${perfdata} "$@" -- ls > /dev/null 2>&1
++ perf record -o ${perfdata} "$@" -m,8M -- ls > /dev/null 2>&1
+
+ perf_script_branch_samples ls &&
+ perf_report_branch_samples ls &&
+--
+2.43.0
+
--- /dev/null
+From 23b3648c2aa2c1084242ce36ed91eb828a4f5155 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 11:34:53 +0100
+Subject: perf tests: Apply attributes to all events in object code reading
+ test
+
+From: James Clark <james.clark@arm.com>
+
+[ Upstream commit 2dade41a533f337447b945239b87ff31a8857890 ]
+
+PERF_PMU_CAP_EXTENDED_HW_TYPE results in multiple events being opened on
+heterogeneous systems. Currently this test only sets its required
+attributes on the first event. Not disabling enable_on_exec on the other
+events causes the test to fail because the forked objdump processes are
+sampled. No tracking event is opened so Perf only knows about its own
+mappings causing the objdump samples to give the following error:
+
+ $ perf test -vvv "object code reading"
+
+ Reading object code for memory address: 0xffff9aaa55ec
+ thread__find_map failed
+ ---- end(-1) ----
+ 24: Object code reading : FAILED!
+
+Fixes: 251aa040244a3b17 ("perf parse-events: Wildcard most "numeric" events")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: James Clark <james.clark@arm.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linux.dev>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Spoorthy S <spoorts2@in.ibm.com>
+Link: https://lore.kernel.org/r/20240410103458.813656-3-james.clark@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/code-reading.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
+index 7a3a7bbbec714..29d2f3ee4e10f 100644
+--- a/tools/perf/tests/code-reading.c
++++ b/tools/perf/tests/code-reading.c
+@@ -637,11 +637,11 @@ static int do_test_code_reading(bool try_kcore)
+
+ evlist__config(evlist, &opts, NULL);
+
+- evsel = evlist__first(evlist);
+-
+- evsel->core.attr.comm = 1;
+- evsel->core.attr.disabled = 1;
+- evsel->core.attr.enable_on_exec = 0;
++ evlist__for_each_entry(evlist, evsel) {
++ evsel->core.attr.comm = 1;
++ evsel->core.attr.disabled = 1;
++ evsel->core.attr.enable_on_exec = 0;
++ }
+
+ ret = evlist__open(evlist);
+ if (ret < 0) {
+--
+2.43.0
+
--- /dev/null
+From 5b222890b3ad9500f5ab5ea3e4148513862b8368 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 11:34:52 +0100
+Subject: perf tests: Make "test data symbol" more robust on Neoverse N1
+
+From: James Clark <james.clark@arm.com>
+
+[ Upstream commit 256ef072b3842273ce703db18b603b051aca95fe ]
+
+To prevent anyone from seeing a test failure appear as a regression and
+thinking that it was caused by their code change, insert some noise into
+the loop which makes it immune to sampling bias issues (errata 1694299).
+
+The "test data symbol" test can fail with any unrelated change that
+shifts the loop into an unfortunate position in the Perf binary which is
+almost impossible to debug as the root cause of the test failure.
+Ultimately it's caused by the referenced errata.
+
+Fixes: 60abedb8aa902b06 ("perf test: Introduce script for data symbol testing")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: James Clark <james.clark@arm.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linux.dev>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Spoorthy S <spoorts2@in.ibm.com>
+Link: https://lore.kernel.org/r/20240410103458.813656-2-james.clark@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/workloads/datasym.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/tools/perf/tests/workloads/datasym.c b/tools/perf/tests/workloads/datasym.c
+index ddd40bc63448a..8e08fc75a973e 100644
+--- a/tools/perf/tests/workloads/datasym.c
++++ b/tools/perf/tests/workloads/datasym.c
+@@ -16,6 +16,22 @@ static int datasym(int argc __maybe_unused, const char **argv __maybe_unused)
+ {
+ for (;;) {
+ buf1.data1++;
++ if (buf1.data1 == 123) {
++ /*
++ * Add some 'noise' in the loop to work around errata
++ * 1694299 on Arm N1.
++ *
++ * Bias exists in SPE sampling which can cause the load
++ * and store instructions to be skipped entirely. This
++ * comes and goes randomly depending on the offset the
++ * linker places the datasym loop at in the Perf binary.
++ * With an extra branch in the middle of the loop that
++ * isn't always taken, the instruction stream is no
++ * longer a continuous repeating pattern that interacts
++ * badly with the bias.
++ */
++ buf1.data1++;
++ }
+ buf1.data2 += buf1.data1;
+ }
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 0c9a66599e32b406406de069928a17c5b9a80f5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 20:53:01 -0700
+Subject: perf thread: Fixes to thread__new() related to initializing comm
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 3536c2575e88a890cf696b4ccd3da36bc937853b ]
+
+Freeing the thread on failure won't work with reference count checking,
+use thread__delete().
+
+Don't allocate the comm_str, use a stack allocation instead.
+
+Fixes: f6005cafebab72f8 ("perf thread: Add reference count checking")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linux.dev>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240508035301.1554434-5-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/thread.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
+index 89c47a5098e28..0170e4b5340df 100644
+--- a/tools/perf/util/thread.c
++++ b/tools/perf/util/thread.c
+@@ -39,12 +39,13 @@ int thread__init_maps(struct thread *thread, struct machine *machine)
+
+ struct thread *thread__new(pid_t pid, pid_t tid)
+ {
+- char *comm_str;
+- struct comm *comm;
+ RC_STRUCT(thread) *_thread = zalloc(sizeof(*_thread));
+ struct thread *thread;
+
+ if (ADD_RC_CHK(thread, _thread) != NULL) {
++ struct comm *comm;
++ char comm_str[32];
++
+ thread__set_pid(thread, pid);
+ thread__set_tid(thread, tid);
+ thread__set_ppid(thread, -1);
+@@ -56,13 +57,8 @@ struct thread *thread__new(pid_t pid, pid_t tid)
+ init_rwsem(thread__namespaces_lock(thread));
+ init_rwsem(thread__comm_lock(thread));
+
+- comm_str = malloc(32);
+- if (!comm_str)
+- goto err_thread;
+-
+- snprintf(comm_str, 32, ":%d", tid);
++ snprintf(comm_str, sizeof(comm_str), ":%d", tid);
+ comm = comm__new(comm_str, 0, false);
+- free(comm_str);
+ if (!comm)
+ goto err_thread;
+
+@@ -76,7 +72,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
+ return thread;
+
+ err_thread:
+- free(thread);
++ thread__delete(thread);
+ return NULL;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 887012f45b49171169c2d96a0757a43d5d3d9274 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 16:19:15 -0800
+Subject: perf tools: Add/use PMU reverse lookup from config to name
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 67ee8e71daabb8632931b7559e5c8a4b69a427f8 ]
+
+Add perf_pmu__name_from_config that does a reverse lookup from a
+config number to an alias name. The lookup is expensive as the config
+is computed for every alias by filling in a perf_event_attr, but this
+is only done when verbose output is enabled. The lookup also only
+considers config, and not config1, config2 or config3.
+
+An example of the output:
+
+ $ perf stat -vv -e data_read true
+ ...
+ perf_event_attr:
+ type 24 (uncore_imc_free_running_0)
+ size 136
+ config 0x20ff (data_read)
+ sample_type IDENTIFIER
+ read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+ disabled 1
+ inherit 1
+ exclude_guest 1
+ ...
+
+Committer notes:
+
+Fix the python binding build by adding dummies for not strictly
+needed perf_pmu__name_from_config() and perf_pmus__find_by_type().
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Tested-by: Kan Liang <kan.liang@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Yang Jihong <yangjihong1@huawei.com>
+Link: https://lore.kernel.org/r/20240308001915.4060155-7-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: d9c5f5f94c2d ("perf pmu: Count sys and cpuid JSON events separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/perf_event_attr_fprintf.c | 10 ++++++++--
+ tools/perf/util/pmu.c | 18 ++++++++++++++++++
+ tools/perf/util/pmu.h | 1 +
+ tools/perf/util/python.c | 10 ++++++++++
+ 4 files changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c
+index 29e66835da3a7..59fbbba796974 100644
+--- a/tools/perf/util/perf_event_attr_fprintf.c
++++ b/tools/perf/util/perf_event_attr_fprintf.c
+@@ -222,8 +222,14 @@ static void __p_config_tracepoint_id(char *buf, size_t size, u64 value)
+ }
+ #endif
+
+-static void __p_config_id(char *buf, size_t size, u32 type, u64 value)
++static void __p_config_id(struct perf_pmu *pmu, char *buf, size_t size, u32 type, u64 value)
+ {
++ const char *name = perf_pmu__name_from_config(pmu, value);
++
++ if (name) {
++ print_id_hex(name);
++ return;
++ }
+ switch (type) {
+ case PERF_TYPE_HARDWARE:
+ return __p_config_hw_id(buf, size, value);
+@@ -252,7 +258,7 @@ static void __p_config_id(char *buf, size_t size, u32 type, u64 value)
+ #define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val)
+ #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
+ #define p_type_id(val) __p_type_id(pmu, buf, BUF_SIZE, val)
+-#define p_config_id(val) __p_config_id(buf, BUF_SIZE, attr->type, val)
++#define p_config_id(val) __p_config_id(pmu, buf, BUF_SIZE, attr->type, val)
+
+ #define PRINT_ATTRn(_n, _f, _p, _a) \
+ do { \
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index 6b82f4759ce69..a0ec0103e0a62 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -2082,3 +2082,21 @@ void perf_pmu__delete(struct perf_pmu *pmu)
+ zfree(&pmu->id);
+ free(pmu);
+ }
++
++const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)
++{
++ struct perf_pmu_alias *event;
++
++ if (!pmu)
++ return NULL;
++
++ pmu_add_cpu_aliases(pmu);
++ list_for_each_entry(event, &pmu->aliases, list) {
++ struct perf_event_attr attr = {.config = 0,};
++ int ret = perf_pmu__config(pmu, &attr, &event->terms, NULL);
++
++ if (ret == 0 && config == attr.config)
++ return event->name;
++ }
++ return NULL;
++}
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index 424c3fee09496..109f3704a6461 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -266,5 +266,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char
+ struct perf_pmu *perf_pmu__create_placeholder_core_pmu(struct list_head *core_pmus);
+ void perf_pmu__delete(struct perf_pmu *pmu);
+ struct perf_pmu *perf_pmus__find_core_pmu(void);
++const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config);
+
+ #endif /* __PMU_H */
+diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
+index 8761f51b5c7c8..ae4b2cd2e1e95 100644
+--- a/tools/perf/util/python.c
++++ b/tools/perf/util/python.c
+@@ -103,6 +103,16 @@ int perf_pmu__scan_file(const struct perf_pmu *pmu, const char *name, const char
+ return EOF;
+ }
+
++const char *perf_pmu__name_from_config(struct perf_pmu *pmu __maybe_unused, u64 config __maybe_unused)
++{
++ return NULL;
++}
++
++struct perf_pmu *perf_pmus__find_by_type(unsigned int type __maybe_unused)
++{
++ return NULL;
++}
++
+ int perf_pmus__num_core_pmus(void)
+ {
+ return 1;
+--
+2.43.0
+
--- /dev/null
+From 985e9f404a44637d63d1aede899d5fea45dc1efe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 16:19:14 -0800
+Subject: perf tools: Use pmus to describe type from attribute
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 7093882067e2e2f88d3449c35c5f0f3f566c8a26 ]
+
+When dumping a perf_event_attr, use pmus to find the PMU and its name
+by the type number. This allows dynamically added PMUs to be described.
+
+Before:
+
+ $ perf stat -vv -e data_read true
+ ...
+ perf_event_attr:
+ type 24
+ size 136
+ config 0x20ff
+ sample_type IDENTIFIER
+ read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+ disabled 1
+ inherit 1
+ exclude_guest 1
+ ...
+
+After:
+
+ $ perf stat -vv -e data_read true
+ ...
+ perf_event_attr:
+ type 24 (uncore_imc_free_running_0)
+ size 136
+ config 0x20ff
+ sample_type IDENTIFIER
+ read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+ disabled 1
+ inherit 1
+ exclude_guest 1
+ ...
+
+However, it also means that when we have a PMU name we prefer it to a
+hard coded name:
+
+Before:
+
+ $ perf stat -vv -e faults true
+ ...
+ perf_event_attr:
+ type 1 (PERF_TYPE_SOFTWARE)
+ size 136
+ config 0x2 (PERF_COUNT_SW_PAGE_FAULTS)
+ sample_type IDENTIFIER
+ read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+ disabled 1
+ inherit 1
+ enable_on_exec 1
+ exclude_guest 1
+ ...
+
+After:
+
+ $ perf stat -vv -e faults true
+ ...
+ perf_event_attr:
+ type 1 (software)
+ size 136
+ config 0x2 (PERF_COUNT_SW_PAGE_FAULTS)
+ sample_type IDENTIFIER
+ read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+ disabled 1
+ inherit 1
+ enable_on_exec 1
+ exclude_guest 1
+ ...
+
+It feels more consistent to do this, rather than only prefer a PMU
+name when a hard coded name isn't available.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Tested-by: Kan Liang <kan.liang@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Yang Jihong <yangjihong1@huawei.com>
+Link: https://lore.kernel.org/r/20240308001915.4060155-6-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: d9c5f5f94c2d ("perf pmu: Count sys and cpuid JSON events separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/perf_event_attr_fprintf.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c
+index 8f04d3b7f3ec7..29e66835da3a7 100644
+--- a/tools/perf/util/perf_event_attr_fprintf.c
++++ b/tools/perf/util/perf_event_attr_fprintf.c
+@@ -7,6 +7,8 @@
+ #include <linux/types.h>
+ #include <linux/perf_event.h>
+ #include "util/evsel_fprintf.h"
++#include "util/pmu.h"
++#include "util/pmus.h"
+ #include "trace-event.h"
+
+ struct bit_names {
+@@ -75,9 +77,12 @@ static void __p_read_format(char *buf, size_t size, u64 value)
+ }
+
+ #define ENUM_ID_TO_STR_CASE(x) case x: return (#x);
+-static const char *stringify_perf_type_id(u64 value)
++static const char *stringify_perf_type_id(struct perf_pmu *pmu, u32 type)
+ {
+- switch (value) {
++ if (pmu)
++ return pmu->name;
++
++ switch (type) {
+ ENUM_ID_TO_STR_CASE(PERF_TYPE_HARDWARE)
+ ENUM_ID_TO_STR_CASE(PERF_TYPE_SOFTWARE)
+ ENUM_ID_TO_STR_CASE(PERF_TYPE_TRACEPOINT)
+@@ -175,9 +180,9 @@ do { \
+ #define print_id_unsigned(_s) PRINT_ID(_s, "%"PRIu64)
+ #define print_id_hex(_s) PRINT_ID(_s, "%#"PRIx64)
+
+-static void __p_type_id(char *buf, size_t size, u64 value)
++static void __p_type_id(struct perf_pmu *pmu, char *buf, size_t size, u64 value)
+ {
+- print_id_unsigned(stringify_perf_type_id(value));
++ print_id_unsigned(stringify_perf_type_id(pmu, value));
+ }
+
+ static void __p_config_hw_id(char *buf, size_t size, u64 value)
+@@ -246,7 +251,7 @@ static void __p_config_id(char *buf, size_t size, u32 type, u64 value)
+ #define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val)
+ #define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val)
+ #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
+-#define p_type_id(val) __p_type_id(buf, BUF_SIZE, val)
++#define p_type_id(val) __p_type_id(pmu, buf, BUF_SIZE, val)
+ #define p_config_id(val) __p_config_id(buf, BUF_SIZE, attr->type, val)
+
+ #define PRINT_ATTRn(_n, _f, _p, _a) \
+@@ -262,6 +267,7 @@ do { \
+ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
+ attr__fprintf_f attr__fprintf, void *priv)
+ {
++ struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type);
+ char buf[BUF_SIZE];
+ int ret = 0;
+
+--
+2.43.0
+
--- /dev/null
+From 685434350fb95dd1b2614f65fabfab4d10a64c80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 20:52:58 -0700
+Subject: perf ui browser: Avoid SEGV on title
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 90f01afb0dfafbc9b094bb61e61a4ac297d9d0d2 ]
+
+If the title is NULL then it can lead to a SEGV.
+
+Fixes: 769e6a1e15bdbbaf ("perf ui browser: Don't save pointer to stack memory")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linux.dev>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240508035301.1554434-2-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/ui/browser.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
+index c4cdf2ea69b72..19503e8387385 100644
+--- a/tools/perf/ui/browser.c
++++ b/tools/perf/ui/browser.c
+@@ -203,7 +203,7 @@ void ui_browser__refresh_dimensions(struct ui_browser *browser)
+ void ui_browser__handle_resize(struct ui_browser *browser)
+ {
+ ui__refresh_dimensions(false);
+- ui_browser__show(browser, browser->title, ui_helpline__current);
++ ui_browser__show(browser, browser->title ?: "", ui_helpline__current);
+ ui_browser__refresh(browser);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 471eb64019f6d54783e338891d028c6f98ff0e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 11:35:38 -0700
+Subject: perf ui browser: Don't save pointer to stack memory
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 769e6a1e15bdbbaf2b0d2f37c24f2c53268bd21f ]
+
+ui_browser__show() is capturing the input title that is stack allocated
+memory in hist_browser__run().
+
+Avoid a use after return by strdup-ing the string.
+
+Committer notes:
+
+Further explanation from Ian Rogers:
+
+My command line using tui is:
+$ sudo bash -c 'rm /tmp/asan.log*; export
+ASAN_OPTIONS="log_path=/tmp/asan.log"; /tmp/perf/perf mem record -a
+sleep 1; /tmp/perf/perf mem report'
+I then go to the perf annotate view and quit. This triggers the asan
+error (from the log file):
+```
+==1254591==ERROR: AddressSanitizer: stack-use-after-return on address
+0x7f2813331920 at pc 0x7f28180
+65991 bp 0x7fff0a21c750 sp 0x7fff0a21bf10
+READ of size 80 at 0x7f2813331920 thread T0
+ #0 0x7f2818065990 in __interceptor_strlen
+../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:461
+ #1 0x7f2817698251 in SLsmg_write_wrapped_string
+(/lib/x86_64-linux-gnu/libslang.so.2+0x98251)
+ #2 0x7f28176984b9 in SLsmg_write_nstring
+(/lib/x86_64-linux-gnu/libslang.so.2+0x984b9)
+ #3 0x55c94045b365 in ui_browser__write_nstring ui/browser.c:60
+ #4 0x55c94045c558 in __ui_browser__show_title ui/browser.c:266
+ #5 0x55c94045c776 in ui_browser__show ui/browser.c:288
+ #6 0x55c94045c06d in ui_browser__handle_resize ui/browser.c:206
+ #7 0x55c94047979b in do_annotate ui/browsers/hists.c:2458
+ #8 0x55c94047fb17 in evsel__hists_browse ui/browsers/hists.c:3412
+ #9 0x55c940480a0c in perf_evsel_menu__run ui/browsers/hists.c:3527
+ #10 0x55c940481108 in __evlist__tui_browse_hists ui/browsers/hists.c:3613
+ #11 0x55c9404813f7 in evlist__tui_browse_hists ui/browsers/hists.c:3661
+ #12 0x55c93ffa253f in report__browse_hists tools/perf/builtin-report.c:671
+ #13 0x55c93ffa58ca in __cmd_report tools/perf/builtin-report.c:1141
+ #14 0x55c93ffaf159 in cmd_report tools/perf/builtin-report.c:1805
+ #15 0x55c94000c05c in report_events tools/perf/builtin-mem.c:374
+ #16 0x55c94000d96d in cmd_mem tools/perf/builtin-mem.c:516
+ #17 0x55c9400e44ee in run_builtin tools/perf/perf.c:350
+ #18 0x55c9400e4a5a in handle_internal_command tools/perf/perf.c:403
+ #19 0x55c9400e4e22 in run_argv tools/perf/perf.c:447
+ #20 0x55c9400e53ad in main tools/perf/perf.c:561
+ #21 0x7f28170456c9 in __libc_start_call_main
+../sysdeps/nptl/libc_start_call_main.h:58
+ #22 0x7f2817045784 in __libc_start_main_impl ../csu/libc-start.c:360
+ #23 0x55c93ff544c0 in _start (/tmp/perf/perf+0x19a4c0) (BuildId:
+84899b0e8c7d3a3eaa67b2eb35e3d8b2f8cd4c93)
+
+Address 0x7f2813331920 is located in stack of thread T0 at offset 32 in frame
+ #0 0x55c94046e85e in hist_browser__run ui/browsers/hists.c:746
+
+ This frame has 1 object(s):
+ [32, 192) 'title' (line 747) <== Memory access at offset 32 is
+inside this variable
+HINT: this may be a false positive if your program uses some custom
+stack unwind mechanism, swapcontext or vfork
+```
+hist_browser__run isn't on the stack so the asan error looks legit.
+There's no clean init/exit on struct ui_browser so I may be trading a
+use-after-return for a memory leak, but that seems look a good trade
+anyway.
+
+Fixes: 05e8b0804ec4 ("perf ui browser: Stop using 'self'")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ben Gainey <ben.gainey@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Li Dong <lidong@vivo.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Oliver Upton <oliver.upton@linux.dev>
+Cc: Paran Lee <p4ranlee@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Sun Haiyong <sunhaiyong@loongson.cn>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Yanteng Si <siyanteng@loongson.cn>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Link: https://lore.kernel.org/r/20240507183545.1236093-2-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/ui/browser.c | 4 +++-
+ tools/perf/ui/browser.h | 2 +-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
+index 603d11283cbdc..c4cdf2ea69b72 100644
+--- a/tools/perf/ui/browser.c
++++ b/tools/perf/ui/browser.c
+@@ -287,7 +287,8 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
+ mutex_lock(&ui__lock);
+ __ui_browser__show_title(browser, title);
+
+- browser->title = title;
++ free(browser->title);
++ browser->title = strdup(title);
+ zfree(&browser->helpline);
+
+ va_start(ap, helpline);
+@@ -304,6 +305,7 @@ void ui_browser__hide(struct ui_browser *browser)
+ mutex_lock(&ui__lock);
+ ui_helpline__pop();
+ zfree(&browser->helpline);
++ zfree(&browser->title);
+ mutex_unlock(&ui__lock);
+ }
+
+diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
+index 510ce45540501..6e98d5f8f71cc 100644
+--- a/tools/perf/ui/browser.h
++++ b/tools/perf/ui/browser.h
+@@ -21,7 +21,7 @@ struct ui_browser {
+ u8 extra_title_lines;
+ int current_color;
+ void *priv;
+- const char *title;
++ char *title;
+ char *helpline;
+ const char *no_samples_msg;
+ void (*refresh_dimensions)(struct ui_browser *browser);
+--
+2.43.0
+
--- /dev/null
+From c0734231ffeb16556f8470ccb8b359658598221b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 23:32:45 +0300
+Subject: pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs
+
+From: Danila Tikhonov <danila@jiaxyga.com>
+
+[ Upstream commit 5ed79863fae5c06eb33f5cd6b6bdf22dd7089392 ]
+
+SDC1 and UFS_RESET special pins are located in the west memory bank.
+
+SDC1 have address 0x359a000:
+0x3500000 (TLMM BASE) + 0x0 (WEST) + 0x9a000 (SDC1_OFFSET) = 0x359a000
+
+UFS_RESET have address 0x359f000:
+0x3500000 (TLMM BASE) + 0x0 (WEST) + 0x9f000 (UFS_OFFSET) = 0x359a000
+
+Fixes: b915395c9e04 ("pinctrl: qcom: Add SM7150 pinctrl driver")
+Signed-off-by: Danila Tikhonov <danila@jiaxyga.com>
+Message-ID: <20240423203245.188480-1-danila@jiaxyga.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/pinctrl-sm7150.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-sm7150.c b/drivers/pinctrl/qcom/pinctrl-sm7150.c
+index c25357ca1963e..b9f067de8ef0e 100644
+--- a/drivers/pinctrl/qcom/pinctrl-sm7150.c
++++ b/drivers/pinctrl/qcom/pinctrl-sm7150.c
+@@ -65,7 +65,7 @@ enum {
+ .intr_detection_width = 2, \
+ }
+
+-#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
++#define SDC_QDSD_PINGROUP(pg_name, _tile, ctl, pull, drv) \
+ { \
+ .grp = PINCTRL_PINGROUP(#pg_name, \
+ pg_name##_pins, \
+@@ -75,7 +75,7 @@ enum {
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+- .tile = SOUTH, \
++ .tile = _tile, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+@@ -101,7 +101,7 @@ enum {
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+- .tile = SOUTH, \
++ .tile = WEST, \
+ .mux_bit = -1, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+@@ -1199,13 +1199,13 @@ static const struct msm_pingroup sm7150_groups[] = {
+ [117] = PINGROUP(117, NORTH, _, _, _, _, _, _, _, _, _),
+ [118] = PINGROUP(118, NORTH, _, _, _, _, _, _, _, _, _),
+ [119] = UFS_RESET(ufs_reset, 0x9f000),
+- [120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x9a000, 15, 0),
+- [121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x9a000, 13, 6),
+- [122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x9a000, 11, 3),
+- [123] = SDC_QDSD_PINGROUP(sdc1_data, 0x9a000, 9, 0),
+- [124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x98000, 14, 6),
+- [125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x98000, 11, 3),
+- [126] = SDC_QDSD_PINGROUP(sdc2_data, 0x98000, 9, 0),
++ [120] = SDC_QDSD_PINGROUP(sdc1_rclk, WEST, 0x9a000, 15, 0),
++ [121] = SDC_QDSD_PINGROUP(sdc1_clk, WEST, 0x9a000, 13, 6),
++ [122] = SDC_QDSD_PINGROUP(sdc1_cmd, WEST, 0x9a000, 11, 3),
++ [123] = SDC_QDSD_PINGROUP(sdc1_data, WEST, 0x9a000, 9, 0),
++ [124] = SDC_QDSD_PINGROUP(sdc2_clk, SOUTH, 0x98000, 14, 6),
++ [125] = SDC_QDSD_PINGROUP(sdc2_cmd, SOUTH, 0x98000, 11, 3),
++ [126] = SDC_QDSD_PINGROUP(sdc2_data, SOUTH, 0x98000, 9, 0),
+ };
+
+ static const struct msm_gpio_wakeirq_map sm7150_pdc_map[] = {
+--
+2.43.0
+
--- /dev/null
+From 0979a34517ffa129690ab9800374bed40cba2e26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Apr 2024 12:41:31 +0100
+Subject: pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet
+ interfaces
+
+From: Paul Barker <paul.barker.ct@bp.renesas.com>
+
+[ Upstream commit cd27553b0dee6fdc4a2535ab9fc3c8fbdd811d13 ]
+
+The RZ/G3S SoC supports configurable supply voltages for several of its
+I/O interfaces. All of these interfaces support both 1.8V and 3.3V
+supplies, but only the Ethernet and XSPI interfaces support a 2.5V
+supply.
+
+Voltage selection for the XSPI interface is not yet supported, so this
+leaves only the Ethernet interfaces currently supporting selection of a
+2.5V supply. So we need to return an error if there is an attempt to
+select a 2.5V supply for any non-Ethernet interface.
+
+Fixes: 51996952b8b5 ("pinctrl: renesas: rzg2l: Add support to select power source for Ethernet pins")
+Signed-off-by: Paul Barker <paul.barker.ct@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20240417114132.6605-1-paul.barker.ct@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+index 01ef6921cb35c..5bbcb38f843a0 100644
+--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+@@ -668,6 +668,8 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
+ val = PVDD_1800;
+ break;
+ case 2500:
++ if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
++ return -EINVAL;
+ val = PVDD_2500;
+ break;
+ case 3300:
+--
+2.43.0
+
--- /dev/null
+From decad3a5c17171049ab7843c54f492e06c28346f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 16:38:40 +0800
+Subject: ppdev: Add an error check in register_device
+
+From: Huai-Yuan Liu <qq810974084@gmail.com>
+
+[ Upstream commit fbf740aeb86a4fe82ad158d26d711f2f3be79b3e ]
+
+In register_device, the return value of ida_simple_get is unchecked,
+in witch ida_simple_get will use an invalid index value.
+
+To address this issue, index should be checked after ida_simple_get. When
+the index value is abnormal, a warning message should be printed, the port
+should be dropped, and the value should be recorded.
+
+Fixes: 9a69645dde11 ("ppdev: fix registering same device name")
+Signed-off-by: Huai-Yuan Liu <qq810974084@gmail.com>
+Link: https://lore.kernel.org/r/20240412083840.234085-1-qq810974084@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/ppdev.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
+index ee951b265213f..58e9dcc2a3087 100644
+--- a/drivers/char/ppdev.c
++++ b/drivers/char/ppdev.c
+@@ -296,28 +296,35 @@ static int register_device(int minor, struct pp_struct *pp)
+ if (!port) {
+ pr_warn("%s: no associated port!\n", name);
+ rc = -ENXIO;
+- goto err;
++ goto err_free_name;
+ }
+
+ index = ida_alloc(&ida_index, GFP_KERNEL);
++ if (index < 0) {
++ pr_warn("%s: failed to get index!\n", name);
++ rc = index;
++ goto err_put_port;
++ }
++
+ memset(&ppdev_cb, 0, sizeof(ppdev_cb));
+ ppdev_cb.irq_func = pp_irq;
+ ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
+ ppdev_cb.private = pp;
+ pdev = parport_register_dev_model(port, name, &ppdev_cb, index);
+- parport_put_port(port);
+
+ if (!pdev) {
+ pr_warn("%s: failed to register device!\n", name);
+ rc = -ENXIO;
+ ida_free(&ida_index, index);
+- goto err;
++ goto err_put_port;
+ }
+
+ pp->pdev = pdev;
+ pp->index = index;
+ dev_dbg(&pdev->dev, "registered pardevice\n");
+-err:
++err_put_port:
++ parport_put_port(port);
++err_free_name:
+ kfree(name);
+ return rc;
+ }
+--
+2.43.0
+
--- /dev/null
+From f791208e7a1360127af4c578bc8b57acb9ae3244 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Aug 2023 17:13:18 +0200
+Subject: remove call_{read,write}_iter() functions
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit 7c98f7cb8fda964fbc60b9307ad35e94735fa35f ]
+
+These have no clear purpose. This is effectively a revert of commit
+bb7462b6fd64 ("vfs: use helpers for calling f_op->{read,write}_iter()").
+
+The patch was created with the help of a coccinelle script.
+
+Fixes: bb7462b6fd64 ("vfs: use helpers for calling f_op->{read,write}_iter()")
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 4 ++--
+ drivers/target/target_core_file.c | 4 ++--
+ fs/aio.c | 4 ++--
+ fs/read_write.c | 12 ++++++------
+ fs/splice.c | 4 ++--
+ include/linux/fs.h | 12 ------------
+ io_uring/rw.c | 4 ++--
+ 7 files changed, 16 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index f8145499da38c..379bc9b9e8f61 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -445,9 +445,9 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
+ cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
+
+ if (rw == ITER_SOURCE)
+- ret = call_write_iter(file, &cmd->iocb, &iter);
++ ret = file->f_op->write_iter(&cmd->iocb, &iter);
+ else
+- ret = call_read_iter(file, &cmd->iocb, &iter);
++ ret = file->f_op->read_iter(&cmd->iocb, &iter);
+
+ lo_rw_aio_do_completion(cmd);
+
+diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
+index 4d447520bab87..94e6cd4e7e43d 100644
+--- a/drivers/target/target_core_file.c
++++ b/drivers/target/target_core_file.c
+@@ -299,9 +299,9 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
+ aio_cmd->iocb.ki_flags |= IOCB_DSYNC;
+
+ if (is_write)
+- ret = call_write_iter(file, &aio_cmd->iocb, &iter);
++ ret = file->f_op->write_iter(&aio_cmd->iocb, &iter);
+ else
+- ret = call_read_iter(file, &aio_cmd->iocb, &iter);
++ ret = file->f_op->read_iter(&aio_cmd->iocb, &iter);
+
+ if (ret != -EIOCBQUEUED)
+ cmd_rw_aio_complete(&aio_cmd->iocb, ret);
+diff --git a/fs/aio.c b/fs/aio.c
+index 0f4f531c97800..744c7d1562dce 100644
+--- a/fs/aio.c
++++ b/fs/aio.c
+@@ -1605,7 +1605,7 @@ static int aio_read(struct kiocb *req, const struct iocb *iocb,
+ return ret;
+ ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter));
+ if (!ret)
+- aio_rw_done(req, call_read_iter(file, req, &iter));
++ aio_rw_done(req, file->f_op->read_iter(req, &iter));
+ kfree(iovec);
+ return ret;
+ }
+@@ -1636,7 +1636,7 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
+ if (S_ISREG(file_inode(file)->i_mode))
+ kiocb_start_write(req);
+ req->ki_flags |= IOCB_WRITE;
+- aio_rw_done(req, call_write_iter(file, req, &iter));
++ aio_rw_done(req, file->f_op->write_iter(req, &iter));
+ }
+ kfree(iovec);
+ return ret;
+diff --git a/fs/read_write.c b/fs/read_write.c
+index d4c036e82b6c3..2de7f6adb33d3 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -392,7 +392,7 @@ static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, lo
+ kiocb.ki_pos = (ppos ? *ppos : 0);
+ iov_iter_ubuf(&iter, ITER_DEST, buf, len);
+
+- ret = call_read_iter(filp, &kiocb, &iter);
++ ret = filp->f_op->read_iter(&kiocb, &iter);
+ BUG_ON(ret == -EIOCBQUEUED);
+ if (ppos)
+ *ppos = kiocb.ki_pos;
+@@ -494,7 +494,7 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t
+ kiocb.ki_pos = (ppos ? *ppos : 0);
+ iov_iter_ubuf(&iter, ITER_SOURCE, (void __user *)buf, len);
+
+- ret = call_write_iter(filp, &kiocb, &iter);
++ ret = filp->f_op->write_iter(&kiocb, &iter);
+ BUG_ON(ret == -EIOCBQUEUED);
+ if (ret > 0 && ppos)
+ *ppos = kiocb.ki_pos;
+@@ -736,9 +736,9 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
+ kiocb.ki_pos = (ppos ? *ppos : 0);
+
+ if (type == READ)
+- ret = call_read_iter(filp, &kiocb, iter);
++ ret = filp->f_op->read_iter(&kiocb, iter);
+ else
+- ret = call_write_iter(filp, &kiocb, iter);
++ ret = filp->f_op->write_iter(&kiocb, iter);
+ BUG_ON(ret == -EIOCBQUEUED);
+ if (ppos)
+ *ppos = kiocb.ki_pos;
+@@ -799,7 +799,7 @@ ssize_t vfs_iocb_iter_read(struct file *file, struct kiocb *iocb,
+ if (ret < 0)
+ return ret;
+
+- ret = call_read_iter(file, iocb, iter);
++ ret = file->f_op->read_iter(iocb, iter);
+ out:
+ if (ret >= 0)
+ fsnotify_access(file);
+@@ -860,7 +860,7 @@ ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb,
+ return ret;
+
+ kiocb_start_write(iocb);
+- ret = call_write_iter(file, iocb, iter);
++ ret = file->f_op->write_iter(iocb, iter);
+ if (ret != -EIOCBQUEUED)
+ kiocb_end_write(iocb);
+ if (ret > 0)
+diff --git a/fs/splice.c b/fs/splice.c
+index 218e24b1ac401..60aed8de21f85 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -362,7 +362,7 @@ ssize_t copy_splice_read(struct file *in, loff_t *ppos,
+ iov_iter_bvec(&to, ITER_DEST, bv, npages, len);
+ init_sync_kiocb(&kiocb, in);
+ kiocb.ki_pos = *ppos;
+- ret = call_read_iter(in, &kiocb, &to);
++ ret = in->f_op->read_iter(&kiocb, &to);
+
+ if (ret > 0) {
+ keep = DIV_ROUND_UP(ret, PAGE_SIZE);
+@@ -740,7 +740,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
+ iov_iter_bvec(&from, ITER_SOURCE, array, n, sd.total_len - left);
+ init_sync_kiocb(&kiocb, out);
+ kiocb.ki_pos = sd.pos;
+- ret = call_write_iter(out, &kiocb, &from);
++ ret = out->f_op->write_iter(&kiocb, &from);
+ sd.pos = kiocb.ki_pos;
+ if (ret <= 0)
+ break;
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 10e32c8ef1e9c..6a305a357199b 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2076,18 +2076,6 @@ struct inode_operations {
+ struct offset_ctx *(*get_offset_ctx)(struct inode *inode);
+ } ____cacheline_aligned;
+
+-static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio,
+- struct iov_iter *iter)
+-{
+- return file->f_op->read_iter(kio, iter);
+-}
+-
+-static inline ssize_t call_write_iter(struct file *file, struct kiocb *kio,
+- struct iov_iter *iter)
+-{
+- return file->f_op->write_iter(kio, iter);
+-}
+-
+ static inline int call_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+ return file->f_op->mmap(file, vma);
+diff --git a/io_uring/rw.c b/io_uring/rw.c
+index c3c154790e452..3181a4086bc5b 100644
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -700,7 +700,7 @@ static inline int io_iter_do_read(struct io_rw *rw, struct iov_iter *iter)
+ struct file *file = rw->kiocb.ki_filp;
+
+ if (likely(file->f_op->read_iter))
+- return call_read_iter(file, &rw->kiocb, iter);
++ return file->f_op->read_iter(&rw->kiocb, iter);
+ else if (file->f_op->read)
+ return loop_rw_iter(READ, rw, iter);
+ else
+@@ -1053,7 +1053,7 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
+ kiocb->ki_flags |= IOCB_WRITE;
+
+ if (likely(req->file->f_op->write_iter))
+- ret2 = call_write_iter(req->file, kiocb, &s->iter);
++ ret2 = req->file->f_op->write_iter(kiocb, &s->iter);
+ else if (req->file->f_op->write)
+ ret2 = loop_rw_iter(WRITE, rw, &s->iter);
+ else
+--
+2.43.0
+
--- /dev/null
+From 20460ecca97dac3dd1fa5ebc72df6c9aab7f017e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 14:50:32 +0200
+Subject: riscv: dts: starfive: visionfive 2: Remove non-existing TDM hardware
+
+From: Hannah Peuckmann <hannah.peuckmann@canonical.com>
+
+[ Upstream commit dcde4e97b122ac318aaa71e8bcd2857dc28a0d12 ]
+
+This partially reverts
+commit e7c304c0346d ("riscv: dts: starfive: jh7110: add the node and pins configuration for tdm")
+
+This added device tree nodes for TDM hardware that is not actually on the
+VisionFive 2 board, but connected on the 40pin header. Many different extension
+boards could be added on those pins, so this should be handled by overlays
+instead.
+This also conflicts with the I2S node which also attempts to grab GPIO 44:
+
+ starfive-jh7110-sys-pinctrl 13040000.pinctrl: pin GPIO44 already requested by 10090000.tdm; cannot claim for 120c0000.i2s
+
+Fixes: e7c304c0346d ("riscv: dts: starfive: jh7110: add the node and pins configuration for tdm")
+Signed-off-by: Hannah Peuckmann <hannah.peuckmann@canonical.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../jh7110-starfive-visionfive-2.dtsi | 40 -------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+index b89e9791efa72..30aa170bb76c7 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -551,40 +551,6 @@ GPOEN_ENABLE,
+ };
+ };
+
+- tdm_pins: tdm-0 {
+- tx-pins {
+- pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
+- GPOEN_ENABLE,
+- GPI_NONE)>;
+- bias-pull-up;
+- drive-strength = <2>;
+- input-disable;
+- input-schmitt-disable;
+- slew-rate = <0>;
+- };
+-
+- rx-pins {
+- pinmux = <GPIOMUX(61, GPOUT_HIGH,
+- GPOEN_DISABLE,
+- GPI_SYS_TDM_RXD)>;
+- input-enable;
+- };
+-
+- sync-pins {
+- pinmux = <GPIOMUX(63, GPOUT_HIGH,
+- GPOEN_DISABLE,
+- GPI_SYS_TDM_SYNC)>;
+- input-enable;
+- };
+-
+- pcmclk-pins {
+- pinmux = <GPIOMUX(38, GPOUT_HIGH,
+- GPOEN_DISABLE,
+- GPI_SYS_TDM_CLK)>;
+- input-enable;
+- };
+- };
+-
+ uart0_pins: uart0-0 {
+ tx-pins {
+ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
+@@ -610,12 +576,6 @@ GPOEN_DISABLE,
+ };
+ };
+
+-&tdm {
+- pinctrl-names = "default";
+- pinctrl-0 = <&tdm_pins>;
+- status = "okay";
+-};
+-
+ &uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+--
+2.43.0
+
--- /dev/null
+From 7baca6dac7245a689429455af2ac392e85f77e1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 14:50:33 +0200
+Subject: riscv: dts: starfive: visionfive 2: Remove non-existing I2S hardware
+
+From: Hannah Peuckmann <hannah.peuckmann@canonical.com>
+
+[ Upstream commit e0503d47e93dead8c0475ea1eb624e03fada21d3 ]
+
+This partially reverts
+commit 92cfc35838b2 ("riscv: dts: starfive: Add the nodes and pins of I2Srx/I2Stx0/I2Stx1")
+
+This added device tree nodes for I2S hardware that is not actually on the
+VisionFive 2 board, but connected on the 40pin header. Many different extension
+boards could be added on those pins, so this should be handled by overlays
+instead.
+This also conflicts with the TDM node which also attempts to grab GPIO 44:
+
+ starfive-jh7110-sys-pinctrl 13040000.pinctrl: pin GPIO44 already requested by 10090000.tdm; cannot claim for 120c0000.i2s
+
+Fixes: 92cfc35838b2 ("riscv: dts: starfive: Add the nodes and pins of I2Srx/I2Stx0/I2Stx1")
+Signed-off-by: Hannah Peuckmann <hannah.peuckmann@canonical.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../jh7110-starfive-visionfive-2.dtsi | 58 -------------------
+ 1 file changed, 58 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+index 30aa170bb76c7..c779cc826e918 100644
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -230,24 +230,6 @@ &i2c6 {
+ status = "okay";
+ };
+
+-&i2srx {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2srx_pins>;
+- status = "okay";
+-};
+-
+-&i2stx0 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&mclk_ext_pins>;
+- status = "okay";
+-};
+-
+-&i2stx1 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2stx1_pins>;
+- status = "okay";
+-};
+-
+ &mmc0 {
+ max-frequency = <100000000>;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
+@@ -392,46 +374,6 @@ GPOEN_SYS_I2C6_DATA,
+ };
+ };
+
+- i2srx_pins: i2srx-0 {
+- clk-sd-pins {
+- pinmux = <GPIOMUX(38, GPOUT_LOW,
+- GPOEN_DISABLE,
+- GPI_SYS_I2SRX_BCLK)>,
+- <GPIOMUX(63, GPOUT_LOW,
+- GPOEN_DISABLE,
+- GPI_SYS_I2SRX_LRCK)>,
+- <GPIOMUX(38, GPOUT_LOW,
+- GPOEN_DISABLE,
+- GPI_SYS_I2STX1_BCLK)>,
+- <GPIOMUX(63, GPOUT_LOW,
+- GPOEN_DISABLE,
+- GPI_SYS_I2STX1_LRCK)>,
+- <GPIOMUX(61, GPOUT_LOW,
+- GPOEN_DISABLE,
+- GPI_SYS_I2SRX_SDIN0)>;
+- input-enable;
+- };
+- };
+-
+- i2stx1_pins: i2stx1-0 {
+- sd-pins {
+- pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
+- GPOEN_ENABLE,
+- GPI_NONE)>;
+- bias-disable;
+- input-disable;
+- };
+- };
+-
+- mclk_ext_pins: mclk-ext-0 {
+- mclk-ext-pins {
+- pinmux = <GPIOMUX(4, GPOUT_LOW,
+- GPOEN_DISABLE,
+- GPI_SYS_MCLK_EXT)>;
+- input-enable;
+- };
+- };
+-
+ mmc0_pins: mmc0-0 {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+--
+2.43.0
+
--- /dev/null
+From a1973fa43d40e50fc0245a8ca7bcd30e7dfddb5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 21:49:42 -0700
+Subject: riscv: Flush the instruction cache during SMP bringup
+
+From: Samuel Holland <samuel.holland@sifive.com>
+
+[ Upstream commit 58661a30f1bcc748475ffd9be6d2fc9e4e6be679 ]
+
+Instruction cache flush IPIs are sent only to CPUs in cpu_online_mask,
+so they will not target a CPU until it calls set_cpu_online() earlier in
+smp_callin(). As a result, if instruction memory is modified between the
+CPU coming out of reset and that point, then its instruction cache may
+contain stale data. Therefore, the instruction cache must be flushed
+after the set_cpu_online() synchronization point.
+
+Fixes: 08f051eda33b ("RISC-V: Flush I$ when making a dirty page executable")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
+Link: https://lore.kernel.org/r/20240327045035.368512-2-samuel.holland@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/smpboot.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index 519b6bd946e5d..bbdb9ec62df0a 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -26,7 +26,7 @@
+ #include <linux/sched/task_stack.h>
+ #include <linux/sched/mm.h>
+
+-#include <asm/cpufeature.h>
++#include <asm/cacheflush.h>
+ #include <asm/cpu_ops.h>
+ #include <asm/cpufeature.h>
+ #include <asm/irq.h>
+@@ -239,9 +239,10 @@ asmlinkage __visible void smp_callin(void)
+ riscv_user_isa_enable();
+
+ /*
+- * Remote TLB flushes are ignored while the CPU is offline, so emit
+- * a local TLB flush right now just in case.
++ * Remote cache and TLB flushes are ignored while the CPU is offline,
++ * so flush them both right now just in case.
+ */
++ local_flush_icache_all();
+ local_flush_tlb_all();
+ complete(&cpu_running);
+ /*
+--
+2.43.0
+
--- /dev/null
+From d747038899b39d0264e67dca47f25f0fceca944a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 May 2024 09:20:27 +0200
+Subject: s390/boot: Remove alt_stfle_fac_list from decompressor
+
+From: Sven Schnelle <svens@linux.ibm.com>
+
+[ Upstream commit e7dec0b7926f3cd493c697c4c389df77e8e8a34c ]
+
+It is nowhere used in the decompressor, therefore remove it.
+
+Fixes: 17e89e1340a3 ("s390/facilities: move stfl information from lowcore to global data")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/boot/startup.c | 1 -
+ arch/s390/kernel/setup.c | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
+index 9cc76e631759b..3c2855c3d6df0 100644
+--- a/arch/s390/boot/startup.c
++++ b/arch/s390/boot/startup.c
+@@ -32,7 +32,6 @@ unsigned long __bootdata_preserved(max_mappable);
+ unsigned long __bootdata(ident_map_size);
+
+ u64 __bootdata_preserved(stfle_fac_list[16]);
+-u64 __bootdata_preserved(alt_stfle_fac_list[16]);
+ struct oldmem_data __bootdata_preserved(oldmem_data);
+
+ struct machine_info machine;
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index d1f3b56e7afc2..9c43f45139fd4 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -155,7 +155,7 @@ unsigned int __bootdata_preserved(zlib_dfltcc_support);
+ EXPORT_SYMBOL(zlib_dfltcc_support);
+ u64 __bootdata_preserved(stfle_fac_list[16]);
+ EXPORT_SYMBOL(stfle_fac_list);
+-u64 __bootdata_preserved(alt_stfle_fac_list[16]);
++u64 alt_stfle_fac_list[16];
+ struct oldmem_data __bootdata_preserved(oldmem_data);
+
+ unsigned long VMALLOC_START;
+--
+2.43.0
+
--- /dev/null
+From 67c408ec35321b2c4775bb29ea803eff694c5ba2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 May 2024 12:41:25 +0200
+Subject: s390/ipl: Fix incorrect initialization of len fields in nvme reipl
+ block
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit 9c922b73acaf39f867668d9cbe5dc69c23511f84 ]
+
+Use correct symbolic constants IPL_BP_NVME_LEN and IPL_BP0_NVME_LEN
+to initialize nvme reipl block when 'scp_data' sysfs attribute is
+being updated. This bug had not been detected before because
+the corresponding fcp and nvme symbolic constants are equal.
+
+Fixes: 23a457b8d57d ("s390: nvme reipl")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/ipl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
+index ba75f6bee7742..47ab49ae542d3 100644
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -962,8 +962,8 @@ static ssize_t reipl_nvme_scpdata_write(struct file *filp, struct kobject *kobj,
+ scpdata_len += padding;
+ }
+
+- reipl_block_nvme->hdr.len = IPL_BP_FCP_LEN + scpdata_len;
+- reipl_block_nvme->nvme.len = IPL_BP0_FCP_LEN + scpdata_len;
++ reipl_block_nvme->hdr.len = IPL_BP_NVME_LEN + scpdata_len;
++ reipl_block_nvme->nvme.len = IPL_BP0_NVME_LEN + scpdata_len;
+ reipl_block_nvme->nvme.scp_data_len = scpdata_len;
+
+ return count;
+--
+2.43.0
+
--- /dev/null
+From 768f8f7984eaaf3d74d1710fbd9c8e695ef5feee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 May 2024 12:41:26 +0200
+Subject: s390/ipl: Fix incorrect initialization of nvme dump block
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit 7faacaeaf6ce12fae78751de5ad869d8f1e1cd7a ]
+
+Initialize the correct fields of the nvme dump block.
+This bug had not been detected before because first, the fcp and nvme fields
+of struct ipl_parameter_block are part of the same union and, therefore,
+overlap in memory and second, they are identical in structure and size.
+
+Fixes: d70e38cb1dee ("s390: nvme dump support")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/ipl.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
+index 47ab49ae542d3..8b95657db0a02 100644
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -1858,9 +1858,9 @@ static int __init dump_nvme_init(void)
+ }
+ dump_block_nvme->hdr.len = IPL_BP_NVME_LEN;
+ dump_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION;
+- dump_block_nvme->fcp.len = IPL_BP0_NVME_LEN;
+- dump_block_nvme->fcp.pbt = IPL_PBT_NVME;
+- dump_block_nvme->fcp.opt = IPL_PB0_NVME_OPT_DUMP;
++ dump_block_nvme->nvme.len = IPL_BP0_NVME_LEN;
++ dump_block_nvme->nvme.pbt = IPL_PBT_NVME;
++ dump_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_DUMP;
+ dump_capabilities |= DUMP_TYPE_NVME;
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 03568e3b94f83e2cbaf5d9fa56d3d2fccd9136df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 17:02:53 +0200
+Subject: s390/vdso: Create .build-id links for unstripped vdso files
+
+From: Jens Remus <jremus@linux.ibm.com>
+
+[ Upstream commit fc2f5f10f9bc5e58d38e9fda7dae107ac04a799f ]
+
+Citing Andy Lutomirski from commit dda1e95cee38 ("x86/vdso: Create
+.build-id links for unstripped vdso files"):
+
+"With this change, doing 'make vdso_install' and telling gdb:
+
+set debug-file-directory /lib/modules/KVER/vdso
+
+will enable vdso debugging with symbols. This is useful for
+testing, but kernel RPM builds will probably want to manually delete
+these symlinks or otherwise do something sensible when they strip
+the vdso/*.so files."
+
+Fixes: 4bff8cb54502 ("s390: convert to GENERIC_VDSO")
+Signed-off-by: Jens Remus <jremus@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/Makefile.vdsoinst | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/Makefile.vdsoinst b/scripts/Makefile.vdsoinst
+index c477d17b0aa5b..a81ca735003e4 100644
+--- a/scripts/Makefile.vdsoinst
++++ b/scripts/Makefile.vdsoinst
+@@ -21,7 +21,7 @@ $$(dest): $$(src) FORCE
+ $$(call cmd,install)
+
+ # Some architectures create .build-id symlinks
+-ifneq ($(filter arm sparc x86, $(SRCARCH)),)
++ifneq ($(filter arm s390 sparc x86, $(SRCARCH)),)
+ link := $(install-dir)/.build-id/$$(shell $(READELF) -n $$(src) | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p').debug
+
+ __default: $$(link)
+--
+2.43.0
+
--- /dev/null
+From 4238c3738db50e6d33583a565b9d527b7137cc61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 17:02:52 +0200
+Subject: s390/vdso: Generate unwind information for C modules
+
+From: Jens Remus <jremus@linux.ibm.com>
+
+[ Upstream commit 10f70525365146046dddcc3d36bfaea2aee0376a ]
+
+GDB fails to unwind vDSO functions with error message "PC not saved",
+for instance when stepping through gettimeofday().
+
+Add -fasynchronous-unwind-tables to CFLAGS to generate .eh_frame
+DWARF unwind information for the vDSO C modules.
+
+Fixes: 4bff8cb54502 ("s390: convert to GENERIC_VDSO")
+Signed-off-by: Jens Remus <jremus@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/vdso32/Makefile | 3 ++-
+ arch/s390/kernel/vdso64/Makefile | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
+index b12a274cbb473..9090c0e5de254 100644
+--- a/arch/s390/kernel/vdso32/Makefile
++++ b/arch/s390/kernel/vdso32/Makefile
+@@ -20,7 +20,8 @@ KBUILD_AFLAGS_32 += -m31 -s
+
+ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_32 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_32))
+-KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin
++KBUILD_CFLAGS_32 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_32))
++KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin -fasynchronous-unwind-tables
+
+ LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \
+ --hash-style=both --build-id=sha1 -melf_s390 -T
+diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
+index ef98327260972..a44f51de1f1ea 100644
+--- a/arch/s390/kernel/vdso64/Makefile
++++ b/arch/s390/kernel/vdso64/Makefile
+@@ -26,7 +26,8 @@ KBUILD_AFLAGS_64 += -m64
+ KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64))
+ KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64))
+-KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin
++KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64))
++KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
+ ldflags-y := -shared -soname=linux-vdso64.so.1 \
+ --hash-style=both --build-id=sha1 -T
+
+--
+2.43.0
+
--- /dev/null
+From 9330e6a2ca8a1a0f527740c969cc3b536fb9958b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 14:28:43 +0200
+Subject: s390/vdso: Use standard stack frame layout
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit 185445c7c137822ad856aae91a41e199370cb534 ]
+
+By default user space is compiled with standard stack frame layout and not
+with the packed stack layout. The vdso code however inherited the
+-mpacked-stack compiler option from the kernel. Remove this option to make
+sure the vdso is compiled with standard stack frame layout.
+
+This makes sure that the stack frame backchain location for vdso generated
+stack frames is the same like for calling code (if compiled with default
+options). This allows to manually walk stack frames without DWARF
+information, like the kernel is doing it e.g. with arch_stack_walk_user().
+
+Fixes: 4bff8cb54502 ("s390: convert to GENERIC_VDSO")
+Reviewed-by: Jens Remus <jremus@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/vdso32/Makefile | 1 +
+ arch/s390/kernel/vdso64/Makefile | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
+index 9090c0e5de254..4800d80decee6 100644
+--- a/arch/s390/kernel/vdso32/Makefile
++++ b/arch/s390/kernel/vdso32/Makefile
+@@ -19,6 +19,7 @@ KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
+ KBUILD_AFLAGS_32 += -m31 -s
+
+ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
++KBUILD_CFLAGS_32 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_32 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_32))
+ KBUILD_CFLAGS_32 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_32))
+ KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin -fasynchronous-unwind-tables
+diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
+index a44f51de1f1ea..2f2e4e997030c 100644
+--- a/arch/s390/kernel/vdso64/Makefile
++++ b/arch/s390/kernel/vdso64/Makefile
+@@ -24,6 +24,7 @@ KBUILD_AFLAGS_64 := $(filter-out -m64,$(KBUILD_AFLAGS))
+ KBUILD_AFLAGS_64 += -m64
+
+ KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
++KBUILD_CFLAGS_64 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_64))
+ KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64))
+ KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64))
+ KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64))
+--
+2.43.0
+
--- /dev/null
+From facdba5927609c954f569c27ace4e2681e25ba63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 14:27:31 +0100
+Subject: s390/vdso64: filter out munaligned-symbols flag for vdso
+
+From: Sumanth Korikkar <sumanthk@linux.ibm.com>
+
+[ Upstream commit 8192a1b3807510d0ed5be1f8988c08f8d41cced9 ]
+
+Gcc recently implemented an optimization [1] for loading symbols without
+explicit alignment, aligning with the IBM Z ELF ABI. This ABI mandates
+symbols to reside on a 2-byte boundary, enabling the use of the larl
+instruction. However, kernel linker scripts may still generate unaligned
+symbols. To address this, a new -munaligned-symbols option has been
+introduced [2] in recent gcc versions.
+
+[1] https://gcc.gnu.org/pipermail/gcc-patches/2023-June/622872.html
+[2] https://gcc.gnu.org/pipermail/gcc-patches/2023-August/625986.html
+
+However, when -munaligned-symbols is used in vdso code, it leads to the
+following compilation error:
+`.data.rel.ro.local' referenced in section `.text' of
+arch/s390/kernel/vdso64/vdso64_generic.o: defined in discarded section
+`.data.rel.ro.local' of arch/s390/kernel/vdso64/vdso64_generic.o
+
+vdso linker script discards .data section to make it lightweight.
+However, -munaligned-symbols in vdso object files references literal
+pool and accesses _vdso_data. Hence, compile vdso code without
+-munaligned-symbols. This means in the future, vdso code should deal
+with alignment of newly introduced unaligned linker symbols.
+
+Acked-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240219132734.22881-2-sumanthk@linux.ibm.com
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Stable-dep-of: 10f705253651 ("s390/vdso: Generate unwind information for C modules")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/vdso64/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
+index caa4ebff8a193..ef98327260972 100644
+--- a/arch/s390/kernel/vdso64/Makefile
++++ b/arch/s390/kernel/vdso64/Makefile
+@@ -25,6 +25,7 @@ KBUILD_AFLAGS_64 += -m64
+
+ KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64))
++KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64))
+ KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin
+ ldflags-y := -shared -soname=linux-vdso64.so.1 \
+ --hash-style=both --build-id=sha1 -T
+--
+2.43.0
+
--- /dev/null
+From e116cef045f6e1e473982262ea6af6eb05bca315 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Apr 2024 22:50:30 +0300
+Subject: serial: max3100: Fix bitwise types
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit e60955dbecb97f080848a57524827e2db29c70fd ]
+
+Sparse is not happy about misuse of bitwise types:
+
+ .../max3100.c:194:13: warning: incorrect type in assignment (different base types)
+ .../max3100.c:194:13: expected unsigned short [addressable] [usertype] etx
+ .../max3100.c:194:13: got restricted __be16 [usertype]
+ .../max3100.c:202:15: warning: cast to restricted __be16
+
+Fix this by choosing proper types for the respective variables.
+
+Fixes: 7831d56b0a35 ("tty: MAX3100")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20240402195306.269276-4-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/max3100.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
+index b3e63b6a402e1..3d2b83d6ab51a 100644
+--- a/drivers/tty/serial/max3100.c
++++ b/drivers/tty/serial/max3100.c
+@@ -45,6 +45,9 @@
+ #include <linux/freezer.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
++#include <linux/types.h>
++
++#include <asm/unaligned.h>
+
+ #include <linux/serial_max3100.h>
+
+@@ -191,7 +194,7 @@ static void max3100_timeout(struct timer_list *t)
+ static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx)
+ {
+ struct spi_message message;
+- u16 etx, erx;
++ __be16 etx, erx;
+ int status;
+ struct spi_transfer tran = {
+ .tx_buf = &etx,
+--
+2.43.0
+
--- /dev/null
+From cf7dc87ef0593c0b4fc63036675516b1d97096fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Apr 2024 22:50:28 +0300
+Subject: serial: max3100: Lock port->lock when calling
+ uart_handle_cts_change()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 77ab53371a2066fdf9b895246505f5ef5a4b5d47 ]
+
+uart_handle_cts_change() has to be called with port lock taken,
+Since we run it in a separate work, the lock may not be taken at
+the time of running. Make sure that it's taken by explicitly doing
+that. Without it we got a splat:
+
+ WARNING: CPU: 0 PID: 10 at drivers/tty/serial/serial_core.c:3491 uart_handle_cts_change+0xa6/0xb0
+ ...
+ Workqueue: max3100-0 max3100_work [max3100]
+ RIP: 0010:uart_handle_cts_change+0xa6/0xb0
+ ...
+ max3100_handlerx+0xc5/0x110 [max3100]
+ max3100_work+0x12a/0x340 [max3100]
+
+Fixes: 7831d56b0a35 ("tty: MAX3100")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20240402195306.269276-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/max3100.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
+index 5efb2b593be33..45022f2909f0a 100644
+--- a/drivers/tty/serial/max3100.c
++++ b/drivers/tty/serial/max3100.c
+@@ -213,7 +213,7 @@ static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx)
+ return 0;
+ }
+
+-static int max3100_handlerx(struct max3100_port *s, u16 rx)
++static int max3100_handlerx_unlocked(struct max3100_port *s, u16 rx)
+ {
+ unsigned int status = 0;
+ int ret = 0, cts;
+@@ -254,6 +254,17 @@ static int max3100_handlerx(struct max3100_port *s, u16 rx)
+ return ret;
+ }
+
++static int max3100_handlerx(struct max3100_port *s, u16 rx)
++{
++ unsigned long flags;
++ int ret;
++
++ uart_port_lock_irqsave(&s->port, &flags);
++ ret = max3100_handlerx_unlocked(s, rx);
++ uart_port_unlock_irqrestore(&s->port, flags);
++ return ret;
++}
++
+ static void max3100_work(struct work_struct *w)
+ {
+ struct max3100_port *s = container_of(w, struct max3100_port, work);
+--
+2.43.0
+
--- /dev/null
+From 04837655aa647f165370b768af8847af66035c9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Apr 2024 22:50:29 +0300
+Subject: serial: max3100: Update uart_driver_registered on driver removal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 712a1fcb38dc7cac6da63ee79a88708fbf9c45ec ]
+
+The removal of the last MAX3100 device triggers the removal of
+the driver. However, code doesn't update the respective global
+variable and after insmod — rmmod — insmod cycle the kernel
+oopses:
+
+ max3100 spi-PRP0001:01: max3100_probe: adding port 0
+ BUG: kernel NULL pointer dereference, address: 0000000000000408
+ ...
+ RIP: 0010:serial_core_register_port+0xa0/0x840
+ ...
+ max3100_probe+0x1b6/0x280 [max3100]
+ spi_probe+0x8d/0xb0
+
+Update the actual state so next time UART driver will be registered
+again.
+
+Hugo also noticed, that the error path in the probe also affected
+by having the variable set, and not cleared. Instead of clearing it
+move the assignment after the successfull uart_register_driver() call.
+
+Fixes: 7831d56b0a35 ("tty: MAX3100")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20240402195306.269276-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/max3100.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
+index 45022f2909f0a..b3e63b6a402e1 100644
+--- a/drivers/tty/serial/max3100.c
++++ b/drivers/tty/serial/max3100.c
+@@ -749,13 +749,14 @@ static int max3100_probe(struct spi_device *spi)
+ mutex_lock(&max3100s_lock);
+
+ if (!uart_driver_registered) {
+- uart_driver_registered = 1;
+ retval = uart_register_driver(&max3100_uart_driver);
+ if (retval) {
+ printk(KERN_ERR "Couldn't register max3100 uart driver\n");
+ mutex_unlock(&max3100s_lock);
+ return retval;
+ }
++
++ uart_driver_registered = 1;
+ }
+
+ for (i = 0; i < MAX_MAX3100; i++)
+@@ -841,6 +842,7 @@ static void max3100_remove(struct spi_device *spi)
+ }
+ pr_debug("removing max3100 driver\n");
+ uart_unregister_driver(&max3100_uart_driver);
++ uart_driver_registered = 0;
+
+ mutex_unlock(&max3100s_lock);
+ }
+--
+2.43.0
+
--- /dev/null
+From 4f9d9b0fc7902a4189b881107a0d6c814f3e7494 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Apr 2024 11:42:49 -0400
+Subject: serial: sc16is7xx: add proper sched.h include for sched_set_fifo()
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+[ Upstream commit 2a8e4ab0c93fad30769479f86849e22d63cd0e12 ]
+
+Replace incorrect include with the proper one for sched_set_fifo()
+declaration.
+
+Fixes: 28d2f209cd16 ("sched,serial: Convert to sched_set_fifo()")
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20240409154253.3043822-2-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sc16is7xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
+index 12915fffac279..ace2c4b333acc 100644
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -18,6 +18,7 @@
+ #include <linux/module.h>
+ #include <linux/property.h>
+ #include <linux/regmap.h>
++#include <linux/sched.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+@@ -25,7 +26,6 @@
+ #include <linux/spi/spi.h>
+ #include <linux/uaccess.h>
+ #include <linux/units.h>
+-#include <uapi/linux/sched/types.h>
+
+ #define SC16IS7XX_NAME "sc16is7xx"
+ #define SC16IS7XX_MAX_DEVS 8
+--
+2.43.0
+
--- /dev/null
+From dfcef6c66f51777c06cd53d6ce5742868c6776e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 May 2024 13:40:17 +0200
+Subject: serial: sh-sci: protect invalidating RXDMA on shutdown
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit aae20f6e34cd0cbd67a1d0e5877561c40109a81b ]
+
+The to-be-fixed commit removed locking when invalidating the DMA RX
+descriptors on shutdown. It overlooked that there is still a rx_timer
+running which may still access the protected data. So, re-add the
+locking.
+
+Reported-by: Dirk Behme <dirk.behme@de.bosch.com>
+Closes: https://lore.kernel.org/r/ee6c9e16-9f29-450e-81da-4a8dceaa8fc7@de.bosch.com
+Fixes: 2c4ee23530ff ("serial: sh-sci: Postpone DMA release when falling back to PIO")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20240506114016.30498-7-wsa+renesas@sang-engineering.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sh-sci.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index a85e7b9a2e492..0d9eab56747cc 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -1272,9 +1272,14 @@ static void sci_dma_rx_chan_invalidate(struct sci_port *s)
+ static void sci_dma_rx_release(struct sci_port *s)
+ {
+ struct dma_chan *chan = s->chan_rx_saved;
++ struct uart_port *port = &s->port;
++ unsigned long flags;
+
++ uart_port_lock_irqsave(port, &flags);
+ s->chan_rx_saved = NULL;
+ sci_dma_rx_chan_invalidate(s);
++ uart_port_unlock_irqrestore(port, flags);
++
+ dmaengine_terminate_sync(chan);
+ dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, s->rx_buf[0],
+ sg_dma_address(&s->sg_rx[0]));
+--
+2.43.0
+
--- /dev/null
+perf-build-fix-out-of-tree-build-related-to-installa.patch
+perf-record-delete-session-after-stopping-sideband-t.patch
+perf-probe-add-missing-libgen.h-header-needed-for-us.patch
+iio-core-leave-private-pointer-null-when-no-private-.patch
+greybus-lights-check-return-of-get_channel_from_mode.patch
+dt-bindings-pinctrl-qcom-update-functions-to-match-w.patch
+f2fs-multidev-fix-to-recognize-valid-zero-block-addr.patch
+f2fs-fix-to-wait-on-page-writeback-in-__clone_blkadd.patch
+fpga-manager-add-owner-module-and-take-its-refcount.patch
+fpga-bridge-add-owner-module-and-take-its-refcount.patch
+counter-linux-counter.h-fix-excess-kernel-doc-descri.patch
+perf-annotate-get-rid-of-duplicate-group-option-item.patch
+perf-sched-timehist-fix-g-call-graph-option-failure.patch
+usb-typec-ucsi-allow-non-partner-get_pdos-for-qualco.patch
+usb-typec-ucsi-always-register-a-link-to-usb-pd-devi.patch
+usb-typec-ucsi-simplify-partner-s-pd-caps-registrati.patch
+perf-report-fix-pai-counter-names-for-s390-virtual-m.patch
+perf-stat-do-not-fail-on-metrics-on-s390-z-vm-system.patch
+soundwire-cadence-fix-invalid-pdi-offset.patch
+dmaengine-idma64-add-check-for-dma_set_max_seg_size.patch
+firmware-dmi-id-add-a-release-callback-function.patch
+perf-annotate-fix-annotation_calc_lines-to-pass-corr.patch
+serial-max3100-lock-port-lock-when-calling-uart_hand.patch
+serial-max3100-update-uart_driver_registered-on-driv.patch
+serial-max3100-fix-bitwise-types.patch
+greybus-arche-ctrl-move-device-table-to-its-right-lo.patch
+pci-dwc-ep-fix-dbi-access-failure-for-drivers-requir.patch
+pci-tegra194-fix-probe-path-for-endpoint-mode.patch
+serial-sc16is7xx-add-proper-sched.h-include-for-sche.patch
+module-don-t-ignore-sysfs_create_link-failures.patch
+interconnect-qcom-qcm2290-fix-mas_snoc_bimc-qos-port.patch
+arm64-dts-meson-fix-s4-power-controller-node.patch
+perf-tests-make-test-data-symbol-more-robust-on-neov.patch
+perf-tests-apply-attributes-to-all-events-in-object-.patch
+perf-record-fix-debug-message-placement-for-test-con.patch
+dt-bindings-pci-rcar-pci-host-add-missing-iommu-prop.patch
+perf-bench-uprobe-remove-lib64-from-libc.so.6-binary.patch
+f2fs-compress-fix-to-relocate-check-condition-in-f2f.patch
+f2fs-compress-fix-to-relocate-check-condition-in-f2f.patch-22547
+f2fs-fix-to-relocate-check-condition-in-f2fs_falloca.patch
+f2fs-fix-to-check-pinfile-flag-in-f2fs_move_file_ran.patch
+iio-adc-stm32-fixing-err-code-to-not-indicate-succes.patch
+riscv-dts-starfive-visionfive-2-remove-non-existing-.patch
+riscv-dts-starfive-visionfive-2-remove-non-existing-.patch-1325
+remove-call_-read-write-_iter-functions.patch
+coresight-etm4x-fix-unbalanced-pm_runtime_enable.patch
+perf-docs-document-bpf-event-modifier.patch
+perf-test-shell-arm_coresight-increase-buffer-size-f.patch
+iio-pressure-dps310-support-negative-temperature-val.patch
+coresight-etm4x-do-not-hardcode-iomem-access-for-reg.patch
+coresight-etm4x-do-not-save-restore-data-trace-contr.patch
+coresight-etm4x-safe-access-for-trcqcltr.patch
+coresight-etm4x-fix-access-to-resource-selector-regi.patch
+vfio-pci-fix-potential-memory-leak-in-vfio_intx_enab.patch
+fpga-region-add-owner-module-and-take-its-refcount.patch
+udf-remove-gfp_nofs-allocation-in-udf_expand_file_ad.patch
+udf-convert-udf_expand_file_adinicb-to-use-a-folio.patch
+microblaze-remove-gcc-flag-for-non-existing-early_pr.patch
+microblaze-remove-early-printk-call-from-cpuinfo-sta.patch
+pinctrl-renesas-rzg2l-limit-2.5v-power-supply-to-eth.patch
+pci-wait-for-link-training-0-before-starting-link-re.patch
+perf-intel-pt-fix-unassigned-instruction-op-discover.patch
+riscv-flush-the-instruction-cache-during-smp-bringup.patch
+usb-xhci-check-if-requested-segments-exceeds-erst-ca.patch
+leds-pwm-disable-pwm-when-going-to-suspend.patch
+ovl-remove-upper-umask-handling-from-ovl_create_uppe.patch
+pci-of_property-return-error-for-int_map-allocation-.patch
+vmci-fix-an-error-handling-path-in-vmci_guest_probe_.patch
+dt-bindings-pinctrl-mediatek-mt7622-fix-array-proper.patch
+pinctrl-qcom-pinctrl-sm7150-fix-sdc1-and-ufs-special.patch
+watchdog-cpu5wdt.c-fix-use-after-free-bug-caused-by-.patch
+watchdog-bd9576-drop-always-running-property.patch
+watchdog-sa1100-fix-ptr_err_or_zero-vs-null-check-in.patch
+dt-bindings-phy-qcom-sc8280xp-qmp-ufs-phy-fix-msm899.patch
+dt-bindings-phy-qcom-usb-snps-femto-v2-use-correct-f.patch
+dmaengine-idxd-avoid-unnecessary-destruction-of-file.patch
+usb-gadget-u_audio-fix-race-condition-use-of-control.patch
+usb-gadget-u_audio-clear-uac-pointer-when-freed.patch
+stm-class-fix-a-double-free-in-stm_register_device.patch
+ppdev-add-an-error-check-in-register_device.patch
+i2c-cadence-avoid-fifo-clear-after-start.patch
+i2c-synquacer-fix-an-error-handling-path-in-synquace.patch
+perf-bench-internals-inject-build-id-fix-trap-divide.patch
+perf-ui-browser-don-t-save-pointer-to-stack-memory.patch
+extcon-max8997-select-irq_domain-instead-of-dependin.patch
+spmi-pmic-arb-replace-three-is_err-calls-by-null-poi.patch
+pci-edr-align-edr_port_dpc_enable_dsm-with-pci-firmw.patch
+pci-edr-align-edr_port_locate_dsm-with-pci-firmware-.patch
+f2fs-fix-block-migration-when-section-is-not-aligned.patch
+perf-ui-browser-avoid-segv-on-title.patch
+perf-report-avoid-segv-in-report__setup_sample_type.patch
+perf-thread-fixes-to-thread__new-related-to-initiali.patch
+perf-symbols-fix-ownership-of-string-in-dso__load_vm.patch
+f2fs-compress-fix-to-update-i_compr_blocks-correctly.patch
+f2fs-deprecate-io_bits.patch
+f2fs-introduce-get_available_block_count-for-cleanup.patch
+f2fs-compress-fix-error-path-of-inc_valid_block_coun.patch
+f2fs-compress-fix-to-cover-reserve-release-_compress.patch
+f2fs-fix-to-release-node-block-count-in-error-path-o.patch
+f2fs-compress-don-t-allow-unaligned-truncation-on-re.patch
+serial-sh-sci-protect-invalidating-rxdma-on-shutdown.patch
+libsubcmd-fix-parse-options-memory-leak.patch
+perf-daemon-fix-file-leak-in-daemon_session__control.patch
+f2fs-fix-to-add-missing-iput-in-gc_data_segment.patch
+usb-fotg210-add-missing-kernel-doc-description.patch
+perf-stat-don-t-display-metric-header-for-non-leader.patch
+perf-tools-use-pmus-to-describe-type-from-attribute.patch
+perf-tools-add-use-pmu-reverse-lookup-from-config-to.patch
+perf-pmu-assume-sysfs-events-are-always-the-same-cas.patch
+perf-pmu-count-sys-and-cpuid-json-events-separately.patch
+loongarch-fix-callchain-parse-error-with-kernel-trac.patch
+s390-vdso64-filter-out-munaligned-symbols-flag-for-v.patch
+s390-vdso-generate-unwind-information-for-c-modules.patch
+s390-vdso-create-.build-id-links-for-unstripped-vdso.patch
+s390-vdso-use-standard-stack-frame-layout.patch
+s390-ipl-fix-incorrect-initialization-of-len-fields-.patch
+s390-ipl-fix-incorrect-initialization-of-nvme-dump-b.patch
+s390-boot-remove-alt_stfle_fac_list-from-decompresso.patch
+dt-bindings-pci-rockchip-rk3399-pcie-add-missing-max.patch
+mailbox-mtk-cmdq-fix-pm_runtime_get_sync-warning-in-.patch
+gpiolib-acpi-fix-failed-in-acpi_gpiochip_find-by-add.patch
+usb-typec-qcom-pmic-typec-fix-arguments-of-qcom_pmic.patch
+usb-typec-qcom-pmic-typec-allow-different-implementa.patch
+usb-typec-qcom-pmic-typec-allow-different-implementa.patch-30702
+usb-typec-qcom-pmic-fix-use-after-free-on-late-probe.patch
+eventfs-create-eventfs_root_inode-to-store-dentry.patch
+eventfs-tracing-add-callback-for-release-of-an-event.patch
+eventfs-free-all-of-the-eventfs_inode-after-rcu.patch
+eventfs-do-not-differentiate-the-toplevel-events-dir.patch
+eventfs-have-events-directory-get-permissions-from-i.patch
+ksmbd-use-rwsem-instead-of-rwlock-for-lease-break.patch
+drm-xe-guc-only-take-actions-in-ct-irq-handler-if-ct.patch
+drm-xe-guc-check-error-code-when-initializing-the-ct.patch
+drm-xe-use-ordered-wq-for-g2h-handler.patch
+dt-bindings-adc-axi-adc-update-bindings-for-backend-.patch
+dt-bindings-adc-axi-adc-add-clocks-property.patch
+alsa-timer-set-lower-bound-of-start-tick-time.patch
--- /dev/null
+From 10f0f17f8d3eefe8200ada9aa08bc033a393e0b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 09:01:16 +0000
+Subject: soundwire: cadence: fix invalid PDI offset
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 8ee1b439b1540ae543149b15a2a61b9dff937d91 ]
+
+For some reason, we add an offset to the PDI, presumably to skip the
+PDI0 and PDI1 which are reserved for BPT.
+
+This code is however completely wrong and leads to an out-of-bounds
+access. We were just lucky so far since we used only a couple of PDIs
+and remained within the PDI array bounds.
+
+A Fixes: tag is not provided since there are no known platforms where
+the out-of-bounds would be accessed, and the initial code had problems
+as well.
+
+A follow-up patch completely removes this useless offset.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20240326090122.1051806-2-yung-chuan.liao@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/cadence_master.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index 0efc1c3bee5f5..3e7cf04aaf2a6 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -1880,7 +1880,7 @@ struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
+
+ /* check if we found a PDI, else find in bi-directional */
+ if (!pdi)
+- pdi = cdns_find_pdi(cdns, 2, stream->num_bd, stream->bd,
++ pdi = cdns_find_pdi(cdns, 0, stream->num_bd, stream->bd,
+ dai_id);
+
+ if (pdi) {
+--
+2.43.0
+
--- /dev/null
+From f42bff5dbcf7acfecc20a567316aa745584b78c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 14:07:42 -0700
+Subject: spmi: pmic-arb: Replace three IS_ERR() calls by null pointer checks
+ in spmi_pmic_arb_probe()
+
+From: Markus Elfring <elfring@users.sourceforge.net>
+
+[ Upstream commit c86f90e30a347ef0a28d0df3975c46389d0cc7fc ]
+
+The devm_ioremap() function does not return error pointers.
+It returns NULL on error.
+This issue was detected once more also by using the Coccinelle software.
+
+Update three checks (and corresponding error codes) for failed
+function calls accordingly.
+
+Fixes: ffdfbafdc4f4 ("spmi: Use devm_spmi_controller_alloc()")
+Fixes: 231601cd22bd ("spmi: pmic-arb: Add support for PMIC v7")
+Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
+Link: https://lore.kernel.org/r/82a0768e-95b0-4091-bdd1-14c3e893726b@web.de
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: David Collins <quic_collinsd@quicinc.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20240507210809.3479953-6-sboyd@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spmi/spmi-pmic-arb.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
+index 9ed1180fe31f1..937c15324513f 100644
+--- a/drivers/spmi/spmi-pmic-arb.c
++++ b/drivers/spmi/spmi-pmic-arb.c
+@@ -1462,8 +1462,8 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
+ */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
+ core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+- if (IS_ERR(core))
+- return PTR_ERR(core);
++ if (!core)
++ return -ENOMEM;
+
+ pmic_arb->core_size = resource_size(res);
+
+@@ -1495,15 +1495,15 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
+ "obsrvr");
+ pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
+ resource_size(res));
+- if (IS_ERR(pmic_arb->rd_base))
+- return PTR_ERR(pmic_arb->rd_base);
++ if (!pmic_arb->rd_base)
++ return -ENOMEM;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "chnls");
+ pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
+ resource_size(res));
+- if (IS_ERR(pmic_arb->wr_base))
+- return PTR_ERR(pmic_arb->wr_base);
++ if (!pmic_arb->wr_base)
++ return -ENOMEM;
+ }
+
+ pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+--
+2.43.0
+
--- /dev/null
+From 607bd65d7fb1d25e1d59c4a9cfa088826b051923 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 16:01:05 +0300
+Subject: stm class: Fix a double free in stm_register_device()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 3df463865ba42b8f88a590326f4c9ea17a1ce459 ]
+
+The put_device(&stm->dev) call will trigger stm_device_release() which
+frees "stm" so the vfree(stm) on the next line is a double free.
+
+Fixes: 389b6699a2aa ("stm class: Fix stm device initialization order")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20240429130119.1518073-2-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/stm/core.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
+index 534fbefc7f6aa..20895d3915623 100644
+--- a/drivers/hwtracing/stm/core.c
++++ b/drivers/hwtracing/stm/core.c
+@@ -868,8 +868,11 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
+ return -ENOMEM;
+
+ stm->major = register_chrdev(0, stm_data->name, &stm_fops);
+- if (stm->major < 0)
+- goto err_free;
++ if (stm->major < 0) {
++ err = stm->major;
++ vfree(stm);
++ return err;
++ }
+
+ device_initialize(&stm->dev);
+ stm->dev.devt = MKDEV(stm->major, 0);
+@@ -913,10 +916,8 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
+ err_device:
+ unregister_chrdev(stm->major, stm_data->name);
+
+- /* matches device_initialize() above */
++ /* calls stm_device_release() */
+ put_device(&stm->dev);
+-err_free:
+- vfree(stm);
+
+ return err;
+ }
+--
+2.43.0
+
--- /dev/null
+From c26e8590756a1b0ec1d9314d7bedccbcf8eb144b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Apr 2024 16:04:09 +0100
+Subject: udf: Convert udf_expand_file_adinicb() to use a folio
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit db6754090a4f99c67e05ae6b87343ba6e013531f ]
+
+Use the folio APIs throughout this function.
+
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Fixes: 1eeceaec794e ("udf: Convert udf_expand_file_adinicb() to avoid kmap_atomic()")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20240417150416.752929-4-willy@infradead.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/inode.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index 2f831a3a91afe..bbf8918417fd8 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -341,7 +341,7 @@ const struct address_space_operations udf_aops = {
+ */
+ int udf_expand_file_adinicb(struct inode *inode)
+ {
+- struct page *page;
++ struct folio *folio;
+ struct udf_inode_info *iinfo = UDF_I(inode);
+ int err;
+
+@@ -357,12 +357,13 @@ int udf_expand_file_adinicb(struct inode *inode)
+ return 0;
+ }
+
+- page = find_or_create_page(inode->i_mapping, 0, GFP_KERNEL);
+- if (!page)
+- return -ENOMEM;
++ folio = __filemap_get_folio(inode->i_mapping, 0,
++ FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_KERNEL);
++ if (IS_ERR(folio))
++ return PTR_ERR(folio);
+
+- if (!PageUptodate(page))
+- udf_adinicb_readpage(page);
++ if (!folio_test_uptodate(folio))
++ udf_adinicb_readpage(&folio->page);
+ down_write(&iinfo->i_data_sem);
+ memset(iinfo->i_data + iinfo->i_lenEAttr, 0x00,
+ iinfo->i_lenAlloc);
+@@ -371,22 +372,22 @@ int udf_expand_file_adinicb(struct inode *inode)
+ iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
+ else
+ iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
+- set_page_dirty(page);
+- unlock_page(page);
++ folio_mark_dirty(folio);
++ folio_unlock(folio);
+ up_write(&iinfo->i_data_sem);
+ err = filemap_fdatawrite(inode->i_mapping);
+ if (err) {
+ /* Restore everything back so that we don't lose data... */
+- lock_page(page);
++ folio_lock(folio);
+ down_write(&iinfo->i_data_sem);
+- memcpy_to_page(page, 0, iinfo->i_data + iinfo->i_lenEAttr,
+- inode->i_size);
+- unlock_page(page);
++ memcpy_from_folio(iinfo->i_data + iinfo->i_lenEAttr,
++ folio, 0, inode->i_size);
++ folio_unlock(folio);
+ iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
+ iinfo->i_lenAlloc = inode->i_size;
+ up_write(&iinfo->i_data_sem);
+ }
+- put_page(page);
++ folio_put(folio);
+ mark_inode_dirty(inode);
+
+ return err;
+--
+2.43.0
+
--- /dev/null
+From 8a4132622255bd65cba0f6a87388d25c0bc97514 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 11:15:43 +0100
+Subject: udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 38f8af2a7191e5da21c557210d810c6d0d34f6c4 ]
+
+udf_expand_file_adinicb() is called under inode->i_rwsem and
+mapping->invalidate_lock. i_rwsem is safe wrt fs reclaim,
+invalidate_lock on this inode is safe as well (we hold inode reference
+so reclaim will not touch it, furthermore even lockdep should not
+complain as invalidate_lock is acquired from udf_evict_inode() only when
+truncating inode which should not happen from fs reclaim).
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Stable-dep-of: db6754090a4f ("udf: Convert udf_expand_file_adinicb() to use a folio")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index d8493449d4c57..2f831a3a91afe 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -357,7 +357,7 @@ int udf_expand_file_adinicb(struct inode *inode)
+ return 0;
+ }
+
+- page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
++ page = find_or_create_page(inode->i_mapping, 0, GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+--
+2.43.0
+
--- /dev/null
+From ecaabf3a03e8a29f125b4fde050cbcceee4dc68b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 May 2024 18:26:22 +0300
+Subject: usb: fotg210: Add missing kernel doc description
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 4b653e82ae18f2dc91c7132b54f5785c4d56bab4 ]
+
+kernel-doc validator is not happy:
+
+ warning: Function parameter or struct member 'fotg' not described in 'fotg210_vbus'
+
+Add missing description.
+
+Fixes: 3e679bde529e ("usb: fotg210-udc: Implement VBUS session")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240510152641.2421298-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/fotg210/fotg210-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/fotg210/fotg210-core.c b/drivers/usb/fotg210/fotg210-core.c
+index 958fc40eae86b..0655afe7f9779 100644
+--- a/drivers/usb/fotg210/fotg210-core.c
++++ b/drivers/usb/fotg210/fotg210-core.c
+@@ -95,6 +95,7 @@ static int fotg210_gemini_init(struct fotg210 *fotg, struct resource *res,
+
+ /**
+ * fotg210_vbus() - Called by gadget driver to enable/disable VBUS
++ * @fotg: pointer to a private fotg210 object
+ * @enable: true to enable VBUS, false to disable VBUS
+ */
+ void fotg210_vbus(struct fotg210 *fotg, bool enable)
+--
+2.43.0
+
--- /dev/null
+From fb4ba5e5d042106cf127387a3613e41116103707 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Apr 2024 15:20:20 +0000
+Subject: usb: gadget: u_audio: Clear uac pointer when freed.
+
+From: Chris Wulff <Chris.Wulff@biamp.com>
+
+[ Upstream commit a2cf936ebef291ef7395172b9e2f624779fb6dc0 ]
+
+This prevents use of a stale pointer if functions are called after
+g_cleanup that shouldn't be. This doesn't fix any races, but converts
+a possibly silent kernel memory corruption into an obvious NULL pointer
+dereference report.
+
+Fixes: eb9fecb9e69b ("usb: gadget: f_uac2: split out audio core")
+Signed-off-by: Chris Wulff <chris.wulff@biamp.com>
+Link: https://lore.kernel.org/stable/CO1PR17MB54194226DA08BFC9EBD8C163E1172%40CO1PR17MB5419.namprd17.prod.outlook.com
+Link: https://lore.kernel.org/r/CO1PR17MB54194226DA08BFC9EBD8C163E1172@CO1PR17MB5419.namprd17.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/u_audio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
+index c8e8154c59f50..ec1dceb087293 100644
+--- a/drivers/usb/gadget/function/u_audio.c
++++ b/drivers/usb/gadget/function/u_audio.c
+@@ -1419,6 +1419,8 @@ void g_audio_cleanup(struct g_audio *g_audio)
+ return;
+
+ uac = g_audio->uac;
++ g_audio->uac = NULL;
++
+ card = uac->card;
+ if (card)
+ snd_card_free_when_closed(card);
+--
+2.43.0
+
--- /dev/null
+From 40a5caebd81e3db812303b4f298ab6bfd9965719 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Apr 2024 15:18:01 +0000
+Subject: usb: gadget: u_audio: Fix race condition use of controls after free
+ during gadget unbind.
+
+From: Chris Wulff <Chris.Wulff@biamp.com>
+
+[ Upstream commit 1b739388aa3f8dfb63a9fca777e6dfa6912d0464 ]
+
+Hang on to the control IDs instead of pointers since those are correctly
+handled with locks.
+
+Fixes: 8fe9a03f4331 ("usb: gadget: u_audio: Rate ctl notifies about current srate (0=stopped)")
+Fixes: c565ad07ef35 ("usb: gadget: u_audio: Support multiple sampling rates")
+Fixes: 02de698ca812 ("usb: gadget: u_audio: add bi-directional volume and mute support")
+Signed-off-by: Chris Wulff <chris.wulff@biamp.com>
+Link: https://lore.kernel.org/stable/CO1PR17MB5419C2BF44D400E4E620C1ADE1172%40CO1PR17MB5419.namprd17.prod.outlook.com
+Link: https://lore.kernel.org/r/CO1PR17MB5419C2BF44D400E4E620C1ADE1172@CO1PR17MB5419.namprd17.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/u_audio.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
+index 4a42574b4a7fe..c8e8154c59f50 100644
+--- a/drivers/usb/gadget/function/u_audio.c
++++ b/drivers/usb/gadget/function/u_audio.c
+@@ -57,13 +57,13 @@ struct uac_rtd_params {
+
+ /* Volume/Mute controls and their state */
+ int fu_id; /* Feature Unit ID */
+- struct snd_kcontrol *snd_kctl_volume;
+- struct snd_kcontrol *snd_kctl_mute;
++ struct snd_ctl_elem_id snd_kctl_volume_id;
++ struct snd_ctl_elem_id snd_kctl_mute_id;
+ s16 volume_min, volume_max, volume_res;
+ s16 volume;
+ int mute;
+
+- struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */
++ struct snd_ctl_elem_id snd_kctl_rate_id; /* read-only current rate */
+ int srate; /* selected samplerate */
+ int active; /* playback/capture running */
+
+@@ -494,14 +494,13 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep)
+ static void set_active(struct uac_rtd_params *prm, bool active)
+ {
+ // notifying through the Rate ctrl
+- struct snd_kcontrol *kctl = prm->snd_kctl_rate;
+ unsigned long flags;
+
+ spin_lock_irqsave(&prm->lock, flags);
+ if (prm->active != active) {
+ prm->active = active;
+ snd_ctl_notify(prm->uac->card, SNDRV_CTL_EVENT_MASK_VALUE,
+- &kctl->id);
++ &prm->snd_kctl_rate_id);
+ }
+ spin_unlock_irqrestore(&prm->lock, flags);
+ }
+@@ -807,7 +806,7 @@ int u_audio_set_volume(struct g_audio *audio_dev, int playback, s16 val)
+
+ if (change)
+ snd_ctl_notify(uac->card, SNDRV_CTL_EVENT_MASK_VALUE,
+- &prm->snd_kctl_volume->id);
++ &prm->snd_kctl_volume_id);
+
+ return 0;
+ }
+@@ -856,7 +855,7 @@ int u_audio_set_mute(struct g_audio *audio_dev, int playback, int val)
+
+ if (change)
+ snd_ctl_notify(uac->card, SNDRV_CTL_EVENT_MASK_VALUE,
+- &prm->snd_kctl_mute->id);
++ &prm->snd_kctl_mute_id);
+
+ return 0;
+ }
+@@ -1331,7 +1330,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
+ goto snd_fail;
+- prm->snd_kctl_mute = kctl;
++ prm->snd_kctl_mute_id = kctl->id;
+ prm->mute = 0;
+ }
+
+@@ -1359,7 +1358,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
+ goto snd_fail;
+- prm->snd_kctl_volume = kctl;
++ prm->snd_kctl_volume_id = kctl->id;
+ prm->volume = fu->volume_max;
+ prm->volume_max = fu->volume_max;
+ prm->volume_min = fu->volume_min;
+@@ -1383,7 +1382,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
+ goto snd_fail;
+- prm->snd_kctl_rate = kctl;
++ prm->snd_kctl_rate_id = kctl->id;
+ }
+
+ strscpy(card->driver, card_name, sizeof(card->driver));
+--
+2.43.0
+
--- /dev/null
+From 9e23c733a7be02e7959b01bc4540baa3e7e340fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Apr 2024 16:57:29 +0200
+Subject: usb: typec: qcom-pmic: fix use-after-free on late probe errors
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit d80eee97cb4e90768a81c856ac71d721996d86b7 ]
+
+Make sure to stop and deregister the port in case of late probe errors
+to avoid use-after-free issues when the underlying memory is released by
+devres.
+
+Fixes: a4422ff22142 ("usb: typec: qcom: Add Qualcomm PMIC Type-C driver")
+Cc: stable@vger.kernel.org # 6.5
+Cc: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240418145730.4605-2-johan+linaro@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+index 82e3f59ea471b..ee3557e0becab 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+@@ -94,14 +94,18 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+
+ ret = tcpm->port_start(tcpm, tcpm->tcpm_port);
+ if (ret)
+- goto fwnode_remove;
++ goto port_unregister;
+
+ ret = tcpm->pdphy_start(tcpm, tcpm->tcpm_port);
+ if (ret)
+- goto fwnode_remove;
++ goto port_stop;
+
+ return 0;
+
++port_stop:
++ tcpm->port_stop(tcpm);
++port_unregister:
++ tcpm_unregister_port(tcpm->tcpm_port);
+ fwnode_remove:
+ fwnode_remove_software_node(tcpm->tcpc.fwnode);
+
+--
+2.43.0
+
--- /dev/null
+From b4f110eeff8a779b915b28649796caafcdf67f6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 22:55:50 +0200
+Subject: usb: typec: qcom-pmic-typec: allow different implementations for the
+ PD PHY
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit d2f9b93de0fe71b5040be391afd3d065ab113fb7 ]
+
+Rework Qualcomm PMIC TCPM driver to allow different platform-specific
+implementations of the PD PHY interface. While majority of platforms
+has the same of register for the PD PHY, some obscure ones (PMI632) do
+not have real PD PHY support. Add proper interface between the main
+module and the PD PHY backend to allow switching the PD PHY
+implementation.
+
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20240113-pmi632-typec-v2-7-182d9aa0a5b3@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: d80eee97cb4e ("usb: typec: qcom-pmic: fix use-after-free on late probe errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 91 +----------
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h | 25 +++
+ .../typec/tcpm/qcom/qcom_pmic_typec_pdphy.c | 153 +++++++++++++++---
+ .../typec/tcpm/qcom/qcom_pmic_typec_pdphy.h | 93 +----------
+ .../typec/tcpm/qcom/qcom_pmic_typec_port.h | 4 +-
+ 5 files changed, 171 insertions(+), 195 deletions(-)
+ create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
+
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+index a243648abb4a5..4c7c38c58a026 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+@@ -20,26 +20,15 @@
+
+ #include <drm/bridge/aux-bridge.h>
+
++#include "qcom_pmic_typec.h"
+ #include "qcom_pmic_typec_pdphy.h"
+ #include "qcom_pmic_typec_port.h"
+
+ struct pmic_typec_resources {
+- struct pmic_typec_pdphy_resources *pdphy_res;
++ const struct pmic_typec_pdphy_resources *pdphy_res;
+ struct pmic_typec_port_resources *port_res;
+ };
+
+-struct pmic_typec {
+- struct device *dev;
+- struct tcpm_port *tcpm_port;
+- struct tcpc_dev tcpc;
+- struct pmic_typec_pdphy *pmic_typec_pdphy;
+- struct pmic_typec_port *pmic_typec_port;
+- bool vbus_enabled;
+- struct mutex lock; /* VBUS state serialization */
+-};
+-
+-#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
+-
+ static int qcom_pmic_typec_get_vbus(struct tcpc_dev *tcpc)
+ {
+ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+@@ -116,34 +105,6 @@ static int qcom_pmic_typec_start_toggling(struct tcpc_dev *tcpc,
+ port_type, cc);
+ }
+
+-static int qcom_pmic_typec_set_roles(struct tcpc_dev *tcpc, bool attached,
+- enum typec_role power_role,
+- enum typec_data_role data_role)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_pdphy_set_roles(tcpm->pmic_typec_pdphy,
+- power_role, data_role);
+-}
+-
+-static int qcom_pmic_typec_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_pdphy_set_pd_rx(tcpm->pmic_typec_pdphy, on);
+-}
+-
+-static int qcom_pmic_typec_pd_transmit(struct tcpc_dev *tcpc,
+- enum tcpm_transmit_type type,
+- const struct pd_message *msg,
+- unsigned int negotiated_rev)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_pdphy_pd_transmit(tcpm->pmic_typec_pdphy, type,
+- msg, negotiated_rev);
+-}
+-
+ static int qcom_pmic_typec_init(struct tcpc_dev *tcpc)
+ {
+ return 0;
+@@ -177,9 +138,6 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+ tcpm->tcpc.set_polarity = qcom_pmic_typec_set_polarity;
+ tcpm->tcpc.set_vconn = qcom_pmic_typec_set_vconn;
+ tcpm->tcpc.start_toggling = qcom_pmic_typec_start_toggling;
+- tcpm->tcpc.set_pd_rx = qcom_pmic_typec_set_pd_rx;
+- tcpm->tcpc.set_roles = qcom_pmic_typec_set_roles;
+- tcpm->tcpc.pd_transmit = qcom_pmic_typec_pd_transmit;
+
+ regmap = dev_get_regmap(dev->parent, NULL);
+ if (!regmap) {
+@@ -195,16 +153,12 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+ if (IS_ERR(tcpm->pmic_typec_port))
+ return PTR_ERR(tcpm->pmic_typec_port);
+
+- tcpm->pmic_typec_pdphy = qcom_pmic_typec_pdphy_alloc(dev);
+- if (IS_ERR(tcpm->pmic_typec_pdphy))
+- return PTR_ERR(tcpm->pmic_typec_pdphy);
+-
+ ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
+ res->port_res, regmap, base[0]);
+ if (ret)
+ return ret;
+
+- ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm->pmic_typec_pdphy,
++ ret = qcom_pmic_typec_pdphy_probe(pdev, tcpm,
+ res->pdphy_res, regmap, base[1]);
+ if (ret)
+ return ret;
+@@ -231,8 +185,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+ if (ret)
+ goto fwnode_remove;
+
+- ret = qcom_pmic_typec_pdphy_start(tcpm->pmic_typec_pdphy,
+- tcpm->tcpm_port);
++ ret = tcpm->pdphy_start(tcpm, tcpm->tcpm_port);
+ if (ret)
+ goto fwnode_remove;
+
+@@ -248,46 +201,12 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
+ {
+ struct pmic_typec *tcpm = platform_get_drvdata(pdev);
+
+- qcom_pmic_typec_pdphy_stop(tcpm->pmic_typec_pdphy);
++ tcpm->pdphy_stop(tcpm);
+ qcom_pmic_typec_port_stop(tcpm->pmic_typec_port);
+ tcpm_unregister_port(tcpm->tcpm_port);
+ fwnode_remove_software_node(tcpm->tcpc.fwnode);
+ }
+
+-static struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
+- .irq_params = {
+- {
+- .virq = PMIC_PDPHY_SIG_TX_IRQ,
+- .irq_name = "sig-tx",
+- },
+- {
+- .virq = PMIC_PDPHY_SIG_RX_IRQ,
+- .irq_name = "sig-rx",
+- },
+- {
+- .virq = PMIC_PDPHY_MSG_TX_IRQ,
+- .irq_name = "msg-tx",
+- },
+- {
+- .virq = PMIC_PDPHY_MSG_RX_IRQ,
+- .irq_name = "msg-rx",
+- },
+- {
+- .virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
+- .irq_name = "msg-tx-failed",
+- },
+- {
+- .virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
+- .irq_name = "msg-tx-discarded",
+- },
+- {
+- .virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
+- .irq_name = "msg-rx-discarded",
+- },
+- },
+- .nr_irqs = 7,
+-};
+-
+ static struct pmic_typec_port_resources pm8150b_port_res = {
+ .irq_params = {
+ {
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
+new file mode 100644
+index 0000000000000..da035916c12a0
+--- /dev/null
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
+@@ -0,0 +1,25 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
++ */
++
++#ifndef __QCOM_PMIC_TYPEC_H__
++#define __QCOM_PMIC_TYPEC_H__
++
++struct pmic_typec {
++ struct device *dev;
++ struct tcpm_port *tcpm_port;
++ struct tcpc_dev tcpc;
++ struct pmic_typec_pdphy *pmic_typec_pdphy;
++ struct pmic_typec_port *pmic_typec_port;
++ bool vbus_enabled;
++ struct mutex lock; /* VBUS state serialization */
++
++ int (*pdphy_start)(struct pmic_typec *tcpm,
++ struct tcpm_port *tcpm_port);
++ void (*pdphy_stop)(struct pmic_typec *tcpm);
++};
++
++#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
++
++#endif
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
+index 44d8342ed0ad5..984d90b0d7636 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
+@@ -14,8 +14,74 @@
+ #include <linux/slab.h>
+ #include <linux/usb/pd.h>
+ #include <linux/usb/tcpm.h>
++#include "qcom_pmic_typec.h"
+ #include "qcom_pmic_typec_pdphy.h"
+
++/* PD PHY register offsets and bit fields */
++#define USB_PDPHY_MSG_CONFIG_REG 0x40
++#define MSG_CONFIG_PORT_DATA_ROLE BIT(3)
++#define MSG_CONFIG_PORT_POWER_ROLE BIT(2)
++#define MSG_CONFIG_SPEC_REV_MASK (BIT(1) | BIT(0))
++
++#define USB_PDPHY_EN_CONTROL_REG 0x46
++#define CONTROL_ENABLE BIT(0)
++
++#define USB_PDPHY_RX_STATUS_REG 0x4A
++#define RX_FRAME_TYPE (BIT(0) | BIT(1) | BIT(2))
++
++#define USB_PDPHY_FRAME_FILTER_REG 0x4C
++#define FRAME_FILTER_EN_HARD_RESET BIT(5)
++#define FRAME_FILTER_EN_SOP BIT(0)
++
++#define USB_PDPHY_TX_SIZE_REG 0x42
++#define TX_SIZE_MASK 0xF
++
++#define USB_PDPHY_TX_CONTROL_REG 0x44
++#define TX_CONTROL_RETRY_COUNT(n) (((n) & 0x3) << 5)
++#define TX_CONTROL_FRAME_TYPE(n) (((n) & 0x7) << 2)
++#define TX_CONTROL_FRAME_TYPE_CABLE_RESET (0x1 << 2)
++#define TX_CONTROL_SEND_SIGNAL BIT(1)
++#define TX_CONTROL_SEND_MSG BIT(0)
++
++#define USB_PDPHY_RX_SIZE_REG 0x48
++
++#define USB_PDPHY_RX_ACKNOWLEDGE_REG 0x4B
++#define RX_BUFFER_TOKEN BIT(0)
++
++#define USB_PDPHY_BIST_MODE_REG 0x4E
++#define BIST_MODE_MASK 0xF
++#define BIST_ENABLE BIT(7)
++#define PD_MSG_BIST 0x3
++#define PD_BIST_TEST_DATA_MODE 0x8
++
++#define USB_PDPHY_TX_BUFFER_HDR_REG 0x60
++#define USB_PDPHY_TX_BUFFER_DATA_REG 0x62
++
++#define USB_PDPHY_RX_BUFFER_REG 0x80
++
++/* VDD regulator */
++#define VDD_PDPHY_VOL_MIN 2800000 /* uV */
++#define VDD_PDPHY_VOL_MAX 3300000 /* uV */
++#define VDD_PDPHY_HPM_LOAD 3000 /* uA */
++
++/* Message Spec Rev field */
++#define PD_MSG_HDR_REV(hdr) (((hdr) >> 6) & 3)
++
++/* timers */
++#define RECEIVER_RESPONSE_TIME 15 /* tReceiverResponse */
++#define HARD_RESET_COMPLETE_TIME 5 /* tHardResetComplete */
++
++/* Interrupt numbers */
++#define PMIC_PDPHY_SIG_TX_IRQ 0x0
++#define PMIC_PDPHY_SIG_RX_IRQ 0x1
++#define PMIC_PDPHY_MSG_TX_IRQ 0x2
++#define PMIC_PDPHY_MSG_RX_IRQ 0x3
++#define PMIC_PDPHY_MSG_TX_FAIL_IRQ 0x4
++#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ 0x5
++#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ 0x6
++#define PMIC_PDPHY_FR_SWAP_IRQ 0x7
++
++
+ struct pmic_typec_pdphy_irq_data {
+ int virq;
+ int irq;
+@@ -231,11 +297,13 @@ qcom_pmic_typec_pdphy_pd_transmit_payload(struct pmic_typec_pdphy *pmic_typec_pd
+ return ret;
+ }
+
+-int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- enum tcpm_transmit_type type,
+- const struct pd_message *msg,
+- unsigned int negotiated_rev)
++static int qcom_pmic_typec_pdphy_pd_transmit(struct tcpc_dev *tcpc,
++ enum tcpm_transmit_type type,
++ const struct pd_message *msg,
++ unsigned int negotiated_rev)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
+ struct device *dev = pmic_typec_pdphy->dev;
+ int ret;
+
+@@ -336,8 +404,10 @@ static irqreturn_t qcom_pmic_typec_pdphy_isr(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on)
++static int qcom_pmic_typec_pdphy_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
+ unsigned long flags;
+ int ret;
+
+@@ -353,10 +423,12 @@ int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, b
+ return ret;
+ }
+
+-int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- enum typec_role power_role,
+- enum typec_data_role data_role)
++static int qcom_pmic_typec_pdphy_set_roles(struct tcpc_dev *tcpc, bool attached,
++ enum typec_role power_role,
++ enum typec_data_role data_role)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
+ struct device *dev = pmic_typec_pdphy->dev;
+ unsigned long flags;
+ int ret;
+@@ -437,9 +509,10 @@ static int pmic_typec_pdphy_reset(struct pmic_typec_pdphy *pmic_typec_pdphy)
+ return ret;
+ }
+
+-int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- struct tcpm_port *tcpm_port)
++static int qcom_pmic_typec_pdphy_start(struct pmic_typec *tcpm,
++ struct tcpm_port *tcpm_port)
+ {
++ struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
+ int i;
+ int ret;
+
+@@ -459,8 +532,9 @@ int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
+ return 0;
+ }
+
+-void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
++static void qcom_pmic_typec_pdphy_stop(struct pmic_typec *tcpm)
+ {
++ struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
+ int i;
+
+ for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
+@@ -471,21 +545,21 @@ void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy)
+ regulator_disable(pmic_typec_pdphy->vdd_pdphy);
+ }
+
+-struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev)
+-{
+- return devm_kzalloc(dev, sizeof(struct pmic_typec_pdphy), GFP_KERNEL);
+-}
+-
+ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
+- struct pmic_typec_pdphy *pmic_typec_pdphy,
+- struct pmic_typec_pdphy_resources *res,
++ struct pmic_typec *tcpm,
++ const struct pmic_typec_pdphy_resources *res,
+ struct regmap *regmap,
+ u32 base)
+ {
++ struct pmic_typec_pdphy *pmic_typec_pdphy;
+ struct device *dev = &pdev->dev;
+ struct pmic_typec_pdphy_irq_data *irq_data;
+ int i, ret, irq;
+
++ pmic_typec_pdphy = devm_kzalloc(dev, sizeof(*pmic_typec_pdphy), GFP_KERNEL);
++ if (!pmic_typec_pdphy)
++ return -ENOMEM;
++
+ if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
+ return -EINVAL;
+
+@@ -524,5 +598,48 @@ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
+ return ret;
+ }
+
++ tcpm->pmic_typec_pdphy = pmic_typec_pdphy;
++
++ tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_set_pd_rx;
++ tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_set_roles;
++ tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_pd_transmit;
++
++ tcpm->pdphy_start = qcom_pmic_typec_pdphy_start;
++ tcpm->pdphy_stop = qcom_pmic_typec_pdphy_stop;
++
+ return 0;
+ }
++
++const struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
++ .irq_params = {
++ {
++ .virq = PMIC_PDPHY_SIG_TX_IRQ,
++ .irq_name = "sig-tx",
++ },
++ {
++ .virq = PMIC_PDPHY_SIG_RX_IRQ,
++ .irq_name = "sig-rx",
++ },
++ {
++ .virq = PMIC_PDPHY_MSG_TX_IRQ,
++ .irq_name = "msg-tx",
++ },
++ {
++ .virq = PMIC_PDPHY_MSG_RX_IRQ,
++ .irq_name = "msg-rx",
++ },
++ {
++ .virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
++ .irq_name = "msg-tx-failed",
++ },
++ {
++ .virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
++ .irq_name = "msg-tx-discarded",
++ },
++ {
++ .virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
++ .irq_name = "msg-rx-discarded",
++ },
++ },
++ .nr_irqs = 7,
++};
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
+index 070822dc6f177..5f428e67ccfe2 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
+@@ -8,74 +8,6 @@
+
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+-#include <linux/usb/tcpm.h>
+-
+-#define USB_PDPHY_MAX_DATA_OBJ_LEN 28
+-#define USB_PDPHY_MSG_HDR_LEN 2
+-
+-/* PD PHY register offsets and bit fields */
+-#define USB_PDPHY_MSG_CONFIG_REG 0x40
+-#define MSG_CONFIG_PORT_DATA_ROLE BIT(3)
+-#define MSG_CONFIG_PORT_POWER_ROLE BIT(2)
+-#define MSG_CONFIG_SPEC_REV_MASK (BIT(1) | BIT(0))
+-
+-#define USB_PDPHY_EN_CONTROL_REG 0x46
+-#define CONTROL_ENABLE BIT(0)
+-
+-#define USB_PDPHY_RX_STATUS_REG 0x4A
+-#define RX_FRAME_TYPE (BIT(0) | BIT(1) | BIT(2))
+-
+-#define USB_PDPHY_FRAME_FILTER_REG 0x4C
+-#define FRAME_FILTER_EN_HARD_RESET BIT(5)
+-#define FRAME_FILTER_EN_SOP BIT(0)
+-
+-#define USB_PDPHY_TX_SIZE_REG 0x42
+-#define TX_SIZE_MASK 0xF
+-
+-#define USB_PDPHY_TX_CONTROL_REG 0x44
+-#define TX_CONTROL_RETRY_COUNT(n) (((n) & 0x3) << 5)
+-#define TX_CONTROL_FRAME_TYPE(n) (((n) & 0x7) << 2)
+-#define TX_CONTROL_FRAME_TYPE_CABLE_RESET (0x1 << 2)
+-#define TX_CONTROL_SEND_SIGNAL BIT(1)
+-#define TX_CONTROL_SEND_MSG BIT(0)
+-
+-#define USB_PDPHY_RX_SIZE_REG 0x48
+-
+-#define USB_PDPHY_RX_ACKNOWLEDGE_REG 0x4B
+-#define RX_BUFFER_TOKEN BIT(0)
+-
+-#define USB_PDPHY_BIST_MODE_REG 0x4E
+-#define BIST_MODE_MASK 0xF
+-#define BIST_ENABLE BIT(7)
+-#define PD_MSG_BIST 0x3
+-#define PD_BIST_TEST_DATA_MODE 0x8
+-
+-#define USB_PDPHY_TX_BUFFER_HDR_REG 0x60
+-#define USB_PDPHY_TX_BUFFER_DATA_REG 0x62
+-
+-#define USB_PDPHY_RX_BUFFER_REG 0x80
+-
+-/* VDD regulator */
+-#define VDD_PDPHY_VOL_MIN 2800000 /* uV */
+-#define VDD_PDPHY_VOL_MAX 3300000 /* uV */
+-#define VDD_PDPHY_HPM_LOAD 3000 /* uA */
+-
+-/* Message Spec Rev field */
+-#define PD_MSG_HDR_REV(hdr) (((hdr) >> 6) & 3)
+-
+-/* timers */
+-#define RECEIVER_RESPONSE_TIME 15 /* tReceiverResponse */
+-#define HARD_RESET_COMPLETE_TIME 5 /* tHardResetComplete */
+-
+-/* Interrupt numbers */
+-#define PMIC_PDPHY_SIG_TX_IRQ 0x0
+-#define PMIC_PDPHY_SIG_RX_IRQ 0x1
+-#define PMIC_PDPHY_MSG_TX_IRQ 0x2
+-#define PMIC_PDPHY_MSG_RX_IRQ 0x3
+-#define PMIC_PDPHY_MSG_TX_FAIL_IRQ 0x4
+-#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ 0x5
+-#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ 0x6
+-#define PMIC_PDPHY_FR_SWAP_IRQ 0x7
+
+ /* Resources */
+ #define PMIC_PDPHY_MAX_IRQS 0x08
+@@ -87,34 +19,17 @@ struct pmic_typec_pdphy_irq_params {
+
+ struct pmic_typec_pdphy_resources {
+ unsigned int nr_irqs;
+- struct pmic_typec_pdphy_irq_params irq_params[PMIC_PDPHY_MAX_IRQS];
++ const struct pmic_typec_pdphy_irq_params irq_params[PMIC_PDPHY_MAX_IRQS];
+ };
+
+ /* API */
+ struct pmic_typec_pdphy;
+
+-struct pmic_typec_pdphy *qcom_pmic_typec_pdphy_alloc(struct device *dev);
+-
++extern const struct pmic_typec_pdphy_resources pm8150b_pdphy_res;
+ int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
+- struct pmic_typec_pdphy *pmic_typec_pdphy,
+- struct pmic_typec_pdphy_resources *res,
++ struct pmic_typec *tcpm,
++ const struct pmic_typec_pdphy_resources *res,
+ struct regmap *regmap,
+ u32 base);
+
+-int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- struct tcpm_port *tcpm_port);
+-
+-void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy);
+-
+-int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- enum typec_role power_role,
+- enum typec_data_role data_role);
+-
+-int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on);
+-
+-int qcom_pmic_typec_pdphy_pd_transmit(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- enum tcpm_transmit_type type,
+- const struct pd_message *msg,
+- unsigned int negotiated_rev);
+-
+ #endif /* __QCOM_PMIC_TYPEC_PDPHY_H__ */
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
+index d4d358c680b6b..4a892048908e7 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
+@@ -3,8 +3,8 @@
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+-#ifndef __QCOM_PMIC_TYPEC_H__
+-#define __QCOM_PMIC_TYPEC_H__
++#ifndef __QCOM_PMIC_TYPEC_PORT_H__
++#define __QCOM_PMIC_TYPEC_PORT_H__
+
+ #include <linux/platform_device.h>
+ #include <linux/usb/tcpm.h>
+--
+2.43.0
+
--- /dev/null
+From 368ddbdd39bfd1fbf4a8b5efddf355f99ab8939b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 22:55:51 +0200
+Subject: usb: typec: qcom-pmic-typec: allow different implementations for the
+ port backend
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit f1a27f081c1fa1eeebf38406e45f29636114470f ]
+
+Follow the PD PHY changes and rework Type-C port implementation to
+become an encapsulated backend. While this is not required for the
+PMI632, it will us later to enable Type-C handling on earlier platforms,
+including, but not limited to SDM845, SDM660 and MSM8998.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Link: https://lore.kernel.org/r/20240113-pmi632-typec-v2-8-182d9aa0a5b3@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: d80eee97cb4e ("usb: typec: qcom-pmic: fix use-after-free on late probe errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 137 +--------
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h | 6 +-
+ .../typec/tcpm/qcom/qcom_pmic_typec_port.c | 290 ++++++++++++++++--
+ .../typec/tcpm/qcom/qcom_pmic_typec_port.h | 168 +---------
+ 4 files changed, 282 insertions(+), 319 deletions(-)
+
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+index 4c7c38c58a026..82e3f59ea471b 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+@@ -26,85 +26,9 @@
+
+ struct pmic_typec_resources {
+ const struct pmic_typec_pdphy_resources *pdphy_res;
+- struct pmic_typec_port_resources *port_res;
++ const struct pmic_typec_port_resources *port_res;
+ };
+
+-static int qcom_pmic_typec_get_vbus(struct tcpc_dev *tcpc)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+- int ret;
+-
+- mutex_lock(&tcpm->lock);
+- ret = tcpm->vbus_enabled || qcom_pmic_typec_port_get_vbus(tcpm->pmic_typec_port);
+- mutex_unlock(&tcpm->lock);
+-
+- return ret;
+-}
+-
+-static int qcom_pmic_typec_set_vbus(struct tcpc_dev *tcpc, bool on, bool sink)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+- int ret = 0;
+-
+- mutex_lock(&tcpm->lock);
+- if (tcpm->vbus_enabled == on)
+- goto done;
+-
+- ret = qcom_pmic_typec_port_set_vbus(tcpm->pmic_typec_port, on);
+- if (ret)
+- goto done;
+-
+- tcpm->vbus_enabled = on;
+- tcpm_vbus_change(tcpm->tcpm_port);
+-
+-done:
+- dev_dbg(tcpm->dev, "set_vbus set: %d result %d\n", on, ret);
+- mutex_unlock(&tcpm->lock);
+-
+- return ret;
+-}
+-
+-static int qcom_pmic_typec_set_vconn(struct tcpc_dev *tcpc, bool on)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_port_set_vconn(tcpm->pmic_typec_port, on);
+-}
+-
+-static int qcom_pmic_typec_get_cc(struct tcpc_dev *tcpc,
+- enum typec_cc_status *cc1,
+- enum typec_cc_status *cc2)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_port_get_cc(tcpm->pmic_typec_port, cc1, cc2);
+-}
+-
+-static int qcom_pmic_typec_set_cc(struct tcpc_dev *tcpc,
+- enum typec_cc_status cc)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_port_set_cc(tcpm->pmic_typec_port, cc);
+-}
+-
+-static int qcom_pmic_typec_set_polarity(struct tcpc_dev *tcpc,
+- enum typec_cc_polarity pol)
+-{
+- /* Polarity is set separately by phy-qcom-qmp.c */
+- return 0;
+-}
+-
+-static int qcom_pmic_typec_start_toggling(struct tcpc_dev *tcpc,
+- enum typec_port_type port_type,
+- enum typec_cc_status cc)
+-{
+- struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+-
+- return qcom_pmic_typec_port_start_toggling(tcpm->pmic_typec_port,
+- port_type, cc);
+-}
+-
+ static int qcom_pmic_typec_init(struct tcpc_dev *tcpc)
+ {
+ return 0;
+@@ -131,13 +55,6 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+
+ tcpm->dev = dev;
+ tcpm->tcpc.init = qcom_pmic_typec_init;
+- tcpm->tcpc.get_vbus = qcom_pmic_typec_get_vbus;
+- tcpm->tcpc.set_vbus = qcom_pmic_typec_set_vbus;
+- tcpm->tcpc.set_cc = qcom_pmic_typec_set_cc;
+- tcpm->tcpc.get_cc = qcom_pmic_typec_get_cc;
+- tcpm->tcpc.set_polarity = qcom_pmic_typec_set_polarity;
+- tcpm->tcpc.set_vconn = qcom_pmic_typec_set_vconn;
+- tcpm->tcpc.start_toggling = qcom_pmic_typec_start_toggling;
+
+ regmap = dev_get_regmap(dev->parent, NULL);
+ if (!regmap) {
+@@ -149,11 +66,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- tcpm->pmic_typec_port = qcom_pmic_typec_port_alloc(dev);
+- if (IS_ERR(tcpm->pmic_typec_port))
+- return PTR_ERR(tcpm->pmic_typec_port);
+-
+- ret = qcom_pmic_typec_port_probe(pdev, tcpm->pmic_typec_port,
++ ret = qcom_pmic_typec_port_probe(pdev, tcpm,
+ res->port_res, regmap, base[0]);
+ if (ret)
+ return ret;
+@@ -163,7 +76,6 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- mutex_init(&tcpm->lock);
+ platform_set_drvdata(pdev, tcpm);
+
+ tcpm->tcpc.fwnode = device_get_named_child_node(tcpm->dev, "connector");
+@@ -180,8 +92,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+ goto fwnode_remove;
+ }
+
+- ret = qcom_pmic_typec_port_start(tcpm->pmic_typec_port,
+- tcpm->tcpm_port);
++ ret = tcpm->port_start(tcpm, tcpm->tcpm_port);
+ if (ret)
+ goto fwnode_remove;
+
+@@ -202,50 +113,12 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
+ struct pmic_typec *tcpm = platform_get_drvdata(pdev);
+
+ tcpm->pdphy_stop(tcpm);
+- qcom_pmic_typec_port_stop(tcpm->pmic_typec_port);
++ tcpm->port_stop(tcpm);
+ tcpm_unregister_port(tcpm->tcpm_port);
+ fwnode_remove_software_node(tcpm->tcpc.fwnode);
+ }
+
+-static struct pmic_typec_port_resources pm8150b_port_res = {
+- .irq_params = {
+- {
+- .irq_name = "vpd-detect",
+- .virq = PMIC_TYPEC_VPD_IRQ,
+- },
+-
+- {
+- .irq_name = "cc-state-change",
+- .virq = PMIC_TYPEC_CC_STATE_IRQ,
+- },
+- {
+- .irq_name = "vconn-oc",
+- .virq = PMIC_TYPEC_VCONN_OC_IRQ,
+- },
+-
+- {
+- .irq_name = "vbus-change",
+- .virq = PMIC_TYPEC_VBUS_IRQ,
+- },
+-
+- {
+- .irq_name = "attach-detach",
+- .virq = PMIC_TYPEC_ATTACH_DETACH_IRQ,
+- },
+- {
+- .irq_name = "legacy-cable-detect",
+- .virq = PMIC_TYPEC_LEGACY_CABLE_IRQ,
+- },
+-
+- {
+- .irq_name = "try-snk-src-detect",
+- .virq = PMIC_TYPEC_TRY_SNK_SRC_IRQ,
+- },
+- },
+- .nr_irqs = 7,
+-};
+-
+-static struct pmic_typec_resources pm8150b_typec_res = {
++static const struct pmic_typec_resources pm8150b_typec_res = {
+ .pdphy_res = &pm8150b_pdphy_res,
+ .port_res = &pm8150b_port_res,
+ };
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
+index da035916c12a0..3c75820c91876 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
+@@ -12,12 +12,14 @@ struct pmic_typec {
+ struct tcpc_dev tcpc;
+ struct pmic_typec_pdphy *pmic_typec_pdphy;
+ struct pmic_typec_port *pmic_typec_port;
+- bool vbus_enabled;
+- struct mutex lock; /* VBUS state serialization */
+
+ int (*pdphy_start)(struct pmic_typec *tcpm,
+ struct tcpm_port *tcpm_port);
+ void (*pdphy_stop)(struct pmic_typec *tcpm);
++
++ int (*port_start)(struct pmic_typec *tcpm,
++ struct tcpm_port *tcpm_port);
++ void (*port_stop)(struct pmic_typec *tcpm);
+ };
+
+ #define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_typec, tcpc)
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c
+index a8f3f4d3a4509..a747baa297849 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c
+@@ -16,8 +16,147 @@
+ #include <linux/usb/tcpm.h>
+ #include <linux/usb/typec_mux.h>
+ #include <linux/workqueue.h>
++
++#include "qcom_pmic_typec.h"
+ #include "qcom_pmic_typec_port.h"
+
++#define TYPEC_SNK_STATUS_REG 0x06
++#define DETECTED_SNK_TYPE_MASK GENMASK(6, 0)
++#define SNK_DAM_MASK GENMASK(6, 4)
++#define SNK_DAM_500MA BIT(6)
++#define SNK_DAM_1500MA BIT(5)
++#define SNK_DAM_3000MA BIT(4)
++#define SNK_RP_STD BIT(3)
++#define SNK_RP_1P5 BIT(2)
++#define SNK_RP_3P0 BIT(1)
++#define SNK_RP_SHORT BIT(0)
++
++#define TYPEC_SRC_STATUS_REG 0x08
++#define DETECTED_SRC_TYPE_MASK GENMASK(4, 0)
++#define SRC_HIGH_BATT BIT(5)
++#define SRC_DEBUG_ACCESS BIT(4)
++#define SRC_RD_OPEN BIT(3)
++#define SRC_RD_RA_VCONN BIT(2)
++#define SRC_RA_OPEN BIT(1)
++#define AUDIO_ACCESS_RA_RA BIT(0)
++
++#define TYPEC_STATE_MACHINE_STATUS_REG 0x09
++#define TYPEC_ATTACH_DETACH_STATE BIT(5)
++
++#define TYPEC_SM_STATUS_REG 0x0A
++#define TYPEC_SM_VBUS_VSAFE5V BIT(5)
++#define TYPEC_SM_VBUS_VSAFE0V BIT(6)
++#define TYPEC_SM_USBIN_LT_LV BIT(7)
++
++#define TYPEC_MISC_STATUS_REG 0x0B
++#define TYPEC_WATER_DETECTION_STATUS BIT(7)
++#define SNK_SRC_MODE BIT(6)
++#define TYPEC_VBUS_DETECT BIT(5)
++#define TYPEC_VBUS_ERROR_STATUS BIT(4)
++#define TYPEC_DEBOUNCE_DONE BIT(3)
++#define CC_ORIENTATION BIT(1)
++#define CC_ATTACHED BIT(0)
++
++#define LEGACY_CABLE_STATUS_REG 0x0D
++#define TYPEC_LEGACY_CABLE_STATUS BIT(1)
++#define TYPEC_NONCOMP_LEGACY_CABLE_STATUS BIT(0)
++
++#define TYPEC_U_USB_STATUS_REG 0x0F
++#define U_USB_GROUND_NOVBUS BIT(6)
++#define U_USB_GROUND BIT(4)
++#define U_USB_FMB1 BIT(3)
++#define U_USB_FLOAT1 BIT(2)
++#define U_USB_FMB2 BIT(1)
++#define U_USB_FLOAT2 BIT(0)
++
++#define TYPEC_MODE_CFG_REG 0x44
++#define TYPEC_TRY_MODE_MASK GENMASK(4, 3)
++#define EN_TRY_SNK BIT(4)
++#define EN_TRY_SRC BIT(3)
++#define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 0)
++#define EN_SRC_ONLY BIT(2)
++#define EN_SNK_ONLY BIT(1)
++#define TYPEC_DISABLE_CMD BIT(0)
++
++#define TYPEC_VCONN_CONTROL_REG 0x46
++#define VCONN_EN_ORIENTATION BIT(2)
++#define VCONN_EN_VALUE BIT(1)
++#define VCONN_EN_SRC BIT(0)
++
++#define TYPEC_CCOUT_CONTROL_REG 0x48
++#define TYPEC_CCOUT_BUFFER_EN BIT(2)
++#define TYPEC_CCOUT_VALUE BIT(1)
++#define TYPEC_CCOUT_SRC BIT(0)
++
++#define DEBUG_ACCESS_SRC_CFG_REG 0x4C
++#define EN_UNORIENTED_DEBUG_ACCESS_SRC BIT(0)
++
++#define TYPE_C_CRUDE_SENSOR_CFG_REG 0x4e
++#define EN_SRC_CRUDE_SENSOR BIT(1)
++#define EN_SNK_CRUDE_SENSOR BIT(0)
++
++#define TYPEC_EXIT_STATE_CFG_REG 0x50
++#define BYPASS_VSAFE0V_DURING_ROLE_SWAP BIT(3)
++#define SEL_SRC_UPPER_REF BIT(2)
++#define USE_TPD_FOR_EXITING_ATTACHSRC BIT(1)
++#define EXIT_SNK_BASED_ON_CC BIT(0)
++
++#define TYPEC_CURRSRC_CFG_REG 0x52
++#define TYPEC_SRC_RP_SEL_330UA BIT(1)
++#define TYPEC_SRC_RP_SEL_180UA BIT(0)
++#define TYPEC_SRC_RP_SEL_80UA 0
++#define TYPEC_SRC_RP_SEL_MASK GENMASK(1, 0)
++
++#define TYPEC_INTERRUPT_EN_CFG_1_REG 0x5E
++#define TYPEC_LEGACY_CABLE_INT_EN BIT(7)
++#define TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN BIT(6)
++#define TYPEC_TRYSOURCE_DETECT_INT_EN BIT(5)
++#define TYPEC_TRYSINK_DETECT_INT_EN BIT(4)
++#define TYPEC_CCOUT_DETACH_INT_EN BIT(3)
++#define TYPEC_CCOUT_ATTACH_INT_EN BIT(2)
++#define TYPEC_VBUS_DEASSERT_INT_EN BIT(1)
++#define TYPEC_VBUS_ASSERT_INT_EN BIT(0)
++
++#define TYPEC_INTERRUPT_EN_CFG_2_REG 0x60
++#define TYPEC_SRC_BATT_HPWR_INT_EN BIT(6)
++#define MICRO_USB_STATE_CHANGE_INT_EN BIT(5)
++#define TYPEC_STATE_MACHINE_CHANGE_INT_EN BIT(4)
++#define TYPEC_DEBUG_ACCESS_DETECT_INT_EN BIT(3)
++#define TYPEC_WATER_DETECTION_INT_EN BIT(2)
++#define TYPEC_VBUS_ERROR_INT_EN BIT(1)
++#define TYPEC_DEBOUNCE_DONE_INT_EN BIT(0)
++
++#define TYPEC_DEBOUNCE_OPTION_REG 0x62
++#define REDUCE_TCCDEBOUNCE_TO_2MS BIT(2)
++
++#define TYPE_C_SBU_CFG_REG 0x6A
++#define SEL_SBU1_ISRC_VAL 0x04
++#define SEL_SBU2_ISRC_VAL 0x01
++
++#define TYPEC_U_USB_CFG_REG 0x70
++#define EN_MICRO_USB_FACTORY_MODE BIT(1)
++#define EN_MICRO_USB_MODE BIT(0)
++
++#define TYPEC_PMI632_U_USB_WATER_PROTECTION_CFG_REG 0x72
++
++#define TYPEC_U_USB_WATER_PROTECTION_CFG_REG 0x73
++#define EN_MICRO_USB_WATER_PROTECTION BIT(4)
++#define MICRO_USB_DETECTION_ON_TIME_CFG_MASK GENMASK(3, 2)
++#define MICRO_USB_DETECTION_PERIOD_CFG_MASK GENMASK(1, 0)
++
++#define TYPEC_PMI632_MICRO_USB_MODE_REG 0x73
++#define MICRO_USB_MODE_ONLY BIT(0)
++
++/* Interrupt numbers */
++#define PMIC_TYPEC_OR_RID_IRQ 0x0
++#define PMIC_TYPEC_VPD_IRQ 0x1
++#define PMIC_TYPEC_CC_STATE_IRQ 0x2
++#define PMIC_TYPEC_VCONN_OC_IRQ 0x3
++#define PMIC_TYPEC_VBUS_IRQ 0x4
++#define PMIC_TYPEC_ATTACH_DETACH_IRQ 0x5
++#define PMIC_TYPEC_LEGACY_CABLE_IRQ 0x6
++#define PMIC_TYPEC_TRY_SNK_SRC_IRQ 0x7
++
+ struct pmic_typec_port_irq_data {
+ int virq;
+ int irq;
+@@ -33,6 +172,8 @@ struct pmic_typec_port {
+ struct pmic_typec_port_irq_data *irq_data;
+
+ struct regulator *vdd_vbus;
++ bool vbus_enabled;
++ struct mutex vbus_lock; /* VBUS state serialization */
+
+ int cc;
+ bool debouncing_cc;
+@@ -131,7 +272,7 @@ static irqreturn_t pmic_typec_port_isr(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-int qcom_pmic_typec_port_get_vbus(struct pmic_typec_port *pmic_typec_port)
++static int qcom_pmic_typec_port_vbus_detect(struct pmic_typec_port *pmic_typec_port)
+ {
+ struct device *dev = pmic_typec_port->dev;
+ unsigned int misc;
+@@ -148,7 +289,7 @@ int qcom_pmic_typec_port_get_vbus(struct pmic_typec_port *pmic_typec_port)
+ return !!(misc & TYPEC_VBUS_DETECT);
+ }
+
+-int qcom_pmic_typec_port_set_vbus(struct pmic_typec_port *pmic_typec_port, bool on)
++static int qcom_pmic_typec_port_vbus_toggle(struct pmic_typec_port *pmic_typec_port, bool on)
+ {
+ u32 sm_stat;
+ u32 val;
+@@ -179,10 +320,49 @@ int qcom_pmic_typec_port_set_vbus(struct pmic_typec_port *pmic_typec_port, bool
+ return 0;
+ }
+
+-int qcom_pmic_typec_port_get_cc(struct pmic_typec_port *pmic_typec_port,
+- enum typec_cc_status *cc1,
+- enum typec_cc_status *cc2)
++static int qcom_pmic_typec_port_get_vbus(struct tcpc_dev *tcpc)
++{
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
++ int ret;
++
++ mutex_lock(&pmic_typec_port->vbus_lock);
++ ret = pmic_typec_port->vbus_enabled || qcom_pmic_typec_port_vbus_detect(pmic_typec_port);
++ mutex_unlock(&pmic_typec_port->vbus_lock);
++
++ return ret;
++}
++
++static int qcom_pmic_typec_port_set_vbus(struct tcpc_dev *tcpc, bool on, bool sink)
++{
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
++ int ret = 0;
++
++ mutex_lock(&pmic_typec_port->vbus_lock);
++ if (pmic_typec_port->vbus_enabled == on)
++ goto done;
++
++ ret = qcom_pmic_typec_port_vbus_toggle(pmic_typec_port, on);
++ if (ret)
++ goto done;
++
++ pmic_typec_port->vbus_enabled = on;
++ tcpm_vbus_change(tcpm->tcpm_port);
++
++done:
++ dev_dbg(tcpm->dev, "set_vbus set: %d result %d\n", on, ret);
++ mutex_unlock(&pmic_typec_port->vbus_lock);
++
++ return ret;
++}
++
++static int qcom_pmic_typec_port_get_cc(struct tcpc_dev *tcpc,
++ enum typec_cc_status *cc1,
++ enum typec_cc_status *cc2)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
+ struct device *dev = pmic_typec_port->dev;
+ unsigned int misc, val;
+ bool attached;
+@@ -275,9 +455,11 @@ static void qcom_pmic_set_cc_debounce(struct pmic_typec_port *pmic_typec_port)
+ msecs_to_jiffies(2));
+ }
+
+-int qcom_pmic_typec_port_set_cc(struct pmic_typec_port *pmic_typec_port,
+- enum typec_cc_status cc)
++static int qcom_pmic_typec_port_set_cc(struct tcpc_dev *tcpc,
++ enum typec_cc_status cc)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
+ struct device *dev = pmic_typec_port->dev;
+ unsigned int mode, currsrc;
+ unsigned int misc;
+@@ -341,8 +523,17 @@ int qcom_pmic_typec_port_set_cc(struct pmic_typec_port *pmic_typec_port,
+ return ret;
+ }
+
+-int qcom_pmic_typec_port_set_vconn(struct pmic_typec_port *pmic_typec_port, bool on)
++static int qcom_pmic_typec_port_set_polarity(struct tcpc_dev *tcpc,
++ enum typec_cc_polarity pol)
++{
++ /* Polarity is set separately by phy-qcom-qmp.c */
++ return 0;
++}
++
++static int qcom_pmic_typec_port_set_vconn(struct tcpc_dev *tcpc, bool on)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
+ struct device *dev = pmic_typec_port->dev;
+ unsigned int orientation, misc, mask, value;
+ unsigned long flags;
+@@ -377,10 +568,12 @@ int qcom_pmic_typec_port_set_vconn(struct pmic_typec_port *pmic_typec_port, bool
+ return ret;
+ }
+
+-int qcom_pmic_typec_port_start_toggling(struct pmic_typec_port *pmic_typec_port,
+- enum typec_port_type port_type,
+- enum typec_cc_status cc)
++static int qcom_pmic_typec_port_start_toggling(struct tcpc_dev *tcpc,
++ enum typec_port_type port_type,
++ enum typec_cc_status cc)
+ {
++ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
+ struct device *dev = pmic_typec_port->dev;
+ unsigned int misc;
+ u8 mode = 0;
+@@ -441,9 +634,10 @@ int qcom_pmic_typec_port_start_toggling(struct pmic_typec_port *pmic_typec_port,
+ (TYPEC_STATE_MACHINE_CHANGE_INT_EN | TYPEC_VBUS_ERROR_INT_EN | \
+ TYPEC_DEBOUNCE_DONE_INT_EN)
+
+-int qcom_pmic_typec_port_start(struct pmic_typec_port *pmic_typec_port,
+- struct tcpm_port *tcpm_port)
++static int qcom_pmic_typec_port_start(struct pmic_typec *tcpm,
++ struct tcpm_port *tcpm_port)
+ {
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
+ int i;
+ int mask;
+ int ret;
+@@ -491,29 +685,30 @@ int qcom_pmic_typec_port_start(struct pmic_typec_port *pmic_typec_port,
+ return ret;
+ }
+
+-void qcom_pmic_typec_port_stop(struct pmic_typec_port *pmic_typec_port)
++static void qcom_pmic_typec_port_stop(struct pmic_typec *tcpm)
+ {
++ struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
+ int i;
+
+ for (i = 0; i < pmic_typec_port->nr_irqs; i++)
+ disable_irq(pmic_typec_port->irq_data[i].irq);
+ }
+
+-struct pmic_typec_port *qcom_pmic_typec_port_alloc(struct device *dev)
+-{
+- return devm_kzalloc(dev, sizeof(struct pmic_typec_port), GFP_KERNEL);
+-}
+-
+ int qcom_pmic_typec_port_probe(struct platform_device *pdev,
+- struct pmic_typec_port *pmic_typec_port,
+- struct pmic_typec_port_resources *res,
++ struct pmic_typec *tcpm,
++ const struct pmic_typec_port_resources *res,
+ struct regmap *regmap,
+ u32 base)
+ {
+ struct device *dev = &pdev->dev;
+ struct pmic_typec_port_irq_data *irq_data;
++ struct pmic_typec_port *pmic_typec_port;
+ int i, ret, irq;
+
++ pmic_typec_port = devm_kzalloc(dev, sizeof(*pmic_typec_port), GFP_KERNEL);
++ if (!pmic_typec_port)
++ return -ENOMEM;
++
+ if (!res->nr_irqs || res->nr_irqs > PMIC_TYPEC_MAX_IRQS)
+ return -EINVAL;
+
+@@ -522,6 +717,8 @@ int qcom_pmic_typec_port_probe(struct platform_device *pdev,
+ if (!irq_data)
+ return -ENOMEM;
+
++ mutex_init(&pmic_typec_port->vbus_lock);
++
+ pmic_typec_port->vdd_vbus = devm_regulator_get(dev, "vdd-vbus");
+ if (IS_ERR(pmic_typec_port->vdd_vbus))
+ return PTR_ERR(pmic_typec_port->vdd_vbus);
+@@ -556,5 +753,56 @@ int qcom_pmic_typec_port_probe(struct platform_device *pdev,
+ return ret;
+ }
+
++ tcpm->pmic_typec_port = pmic_typec_port;
++
++ tcpm->tcpc.get_vbus = qcom_pmic_typec_port_get_vbus;
++ tcpm->tcpc.set_vbus = qcom_pmic_typec_port_set_vbus;
++ tcpm->tcpc.set_cc = qcom_pmic_typec_port_set_cc;
++ tcpm->tcpc.get_cc = qcom_pmic_typec_port_get_cc;
++ tcpm->tcpc.set_polarity = qcom_pmic_typec_port_set_polarity;
++ tcpm->tcpc.set_vconn = qcom_pmic_typec_port_set_vconn;
++ tcpm->tcpc.start_toggling = qcom_pmic_typec_port_start_toggling;
++
++ tcpm->port_start = qcom_pmic_typec_port_start;
++ tcpm->port_stop = qcom_pmic_typec_port_stop;
++
+ return 0;
+ }
++
++const struct pmic_typec_port_resources pm8150b_port_res = {
++ .irq_params = {
++ {
++ .irq_name = "vpd-detect",
++ .virq = PMIC_TYPEC_VPD_IRQ,
++ },
++
++ {
++ .irq_name = "cc-state-change",
++ .virq = PMIC_TYPEC_CC_STATE_IRQ,
++ },
++ {
++ .irq_name = "vconn-oc",
++ .virq = PMIC_TYPEC_VCONN_OC_IRQ,
++ },
++
++ {
++ .irq_name = "vbus-change",
++ .virq = PMIC_TYPEC_VBUS_IRQ,
++ },
++
++ {
++ .irq_name = "attach-detach",
++ .virq = PMIC_TYPEC_ATTACH_DETACH_IRQ,
++ },
++ {
++ .irq_name = "legacy-cable-detect",
++ .virq = PMIC_TYPEC_LEGACY_CABLE_IRQ,
++ },
++
++ {
++ .irq_name = "try-snk-src-detect",
++ .virq = PMIC_TYPEC_TRY_SNK_SRC_IRQ,
++ },
++ },
++ .nr_irqs = 7,
++};
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
+index 4a892048908e7..2ca83a46cf3b5 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.h
+@@ -9,143 +9,6 @@
+ #include <linux/platform_device.h>
+ #include <linux/usb/tcpm.h>
+
+-#define TYPEC_SNK_STATUS_REG 0x06
+-#define DETECTED_SNK_TYPE_MASK GENMASK(6, 0)
+-#define SNK_DAM_MASK GENMASK(6, 4)
+-#define SNK_DAM_500MA BIT(6)
+-#define SNK_DAM_1500MA BIT(5)
+-#define SNK_DAM_3000MA BIT(4)
+-#define SNK_RP_STD BIT(3)
+-#define SNK_RP_1P5 BIT(2)
+-#define SNK_RP_3P0 BIT(1)
+-#define SNK_RP_SHORT BIT(0)
+-
+-#define TYPEC_SRC_STATUS_REG 0x08
+-#define DETECTED_SRC_TYPE_MASK GENMASK(4, 0)
+-#define SRC_HIGH_BATT BIT(5)
+-#define SRC_DEBUG_ACCESS BIT(4)
+-#define SRC_RD_OPEN BIT(3)
+-#define SRC_RD_RA_VCONN BIT(2)
+-#define SRC_RA_OPEN BIT(1)
+-#define AUDIO_ACCESS_RA_RA BIT(0)
+-
+-#define TYPEC_STATE_MACHINE_STATUS_REG 0x09
+-#define TYPEC_ATTACH_DETACH_STATE BIT(5)
+-
+-#define TYPEC_SM_STATUS_REG 0x0A
+-#define TYPEC_SM_VBUS_VSAFE5V BIT(5)
+-#define TYPEC_SM_VBUS_VSAFE0V BIT(6)
+-#define TYPEC_SM_USBIN_LT_LV BIT(7)
+-
+-#define TYPEC_MISC_STATUS_REG 0x0B
+-#define TYPEC_WATER_DETECTION_STATUS BIT(7)
+-#define SNK_SRC_MODE BIT(6)
+-#define TYPEC_VBUS_DETECT BIT(5)
+-#define TYPEC_VBUS_ERROR_STATUS BIT(4)
+-#define TYPEC_DEBOUNCE_DONE BIT(3)
+-#define CC_ORIENTATION BIT(1)
+-#define CC_ATTACHED BIT(0)
+-
+-#define LEGACY_CABLE_STATUS_REG 0x0D
+-#define TYPEC_LEGACY_CABLE_STATUS BIT(1)
+-#define TYPEC_NONCOMP_LEGACY_CABLE_STATUS BIT(0)
+-
+-#define TYPEC_U_USB_STATUS_REG 0x0F
+-#define U_USB_GROUND_NOVBUS BIT(6)
+-#define U_USB_GROUND BIT(4)
+-#define U_USB_FMB1 BIT(3)
+-#define U_USB_FLOAT1 BIT(2)
+-#define U_USB_FMB2 BIT(1)
+-#define U_USB_FLOAT2 BIT(0)
+-
+-#define TYPEC_MODE_CFG_REG 0x44
+-#define TYPEC_TRY_MODE_MASK GENMASK(4, 3)
+-#define EN_TRY_SNK BIT(4)
+-#define EN_TRY_SRC BIT(3)
+-#define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 0)
+-#define EN_SRC_ONLY BIT(2)
+-#define EN_SNK_ONLY BIT(1)
+-#define TYPEC_DISABLE_CMD BIT(0)
+-
+-#define TYPEC_VCONN_CONTROL_REG 0x46
+-#define VCONN_EN_ORIENTATION BIT(2)
+-#define VCONN_EN_VALUE BIT(1)
+-#define VCONN_EN_SRC BIT(0)
+-
+-#define TYPEC_CCOUT_CONTROL_REG 0x48
+-#define TYPEC_CCOUT_BUFFER_EN BIT(2)
+-#define TYPEC_CCOUT_VALUE BIT(1)
+-#define TYPEC_CCOUT_SRC BIT(0)
+-
+-#define DEBUG_ACCESS_SRC_CFG_REG 0x4C
+-#define EN_UNORIENTED_DEBUG_ACCESS_SRC BIT(0)
+-
+-#define TYPE_C_CRUDE_SENSOR_CFG_REG 0x4e
+-#define EN_SRC_CRUDE_SENSOR BIT(1)
+-#define EN_SNK_CRUDE_SENSOR BIT(0)
+-
+-#define TYPEC_EXIT_STATE_CFG_REG 0x50
+-#define BYPASS_VSAFE0V_DURING_ROLE_SWAP BIT(3)
+-#define SEL_SRC_UPPER_REF BIT(2)
+-#define USE_TPD_FOR_EXITING_ATTACHSRC BIT(1)
+-#define EXIT_SNK_BASED_ON_CC BIT(0)
+-
+-#define TYPEC_CURRSRC_CFG_REG 0x52
+-#define TYPEC_SRC_RP_SEL_330UA BIT(1)
+-#define TYPEC_SRC_RP_SEL_180UA BIT(0)
+-#define TYPEC_SRC_RP_SEL_80UA 0
+-#define TYPEC_SRC_RP_SEL_MASK GENMASK(1, 0)
+-
+-#define TYPEC_INTERRUPT_EN_CFG_1_REG 0x5E
+-#define TYPEC_LEGACY_CABLE_INT_EN BIT(7)
+-#define TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN BIT(6)
+-#define TYPEC_TRYSOURCE_DETECT_INT_EN BIT(5)
+-#define TYPEC_TRYSINK_DETECT_INT_EN BIT(4)
+-#define TYPEC_CCOUT_DETACH_INT_EN BIT(3)
+-#define TYPEC_CCOUT_ATTACH_INT_EN BIT(2)
+-#define TYPEC_VBUS_DEASSERT_INT_EN BIT(1)
+-#define TYPEC_VBUS_ASSERT_INT_EN BIT(0)
+-
+-#define TYPEC_INTERRUPT_EN_CFG_2_REG 0x60
+-#define TYPEC_SRC_BATT_HPWR_INT_EN BIT(6)
+-#define MICRO_USB_STATE_CHANGE_INT_EN BIT(5)
+-#define TYPEC_STATE_MACHINE_CHANGE_INT_EN BIT(4)
+-#define TYPEC_DEBUG_ACCESS_DETECT_INT_EN BIT(3)
+-#define TYPEC_WATER_DETECTION_INT_EN BIT(2)
+-#define TYPEC_VBUS_ERROR_INT_EN BIT(1)
+-#define TYPEC_DEBOUNCE_DONE_INT_EN BIT(0)
+-
+-#define TYPEC_DEBOUNCE_OPTION_REG 0x62
+-#define REDUCE_TCCDEBOUNCE_TO_2MS BIT(2)
+-
+-#define TYPE_C_SBU_CFG_REG 0x6A
+-#define SEL_SBU1_ISRC_VAL 0x04
+-#define SEL_SBU2_ISRC_VAL 0x01
+-
+-#define TYPEC_U_USB_CFG_REG 0x70
+-#define EN_MICRO_USB_FACTORY_MODE BIT(1)
+-#define EN_MICRO_USB_MODE BIT(0)
+-
+-#define TYPEC_PMI632_U_USB_WATER_PROTECTION_CFG_REG 0x72
+-
+-#define TYPEC_U_USB_WATER_PROTECTION_CFG_REG 0x73
+-#define EN_MICRO_USB_WATER_PROTECTION BIT(4)
+-#define MICRO_USB_DETECTION_ON_TIME_CFG_MASK GENMASK(3, 2)
+-#define MICRO_USB_DETECTION_PERIOD_CFG_MASK GENMASK(1, 0)
+-
+-#define TYPEC_PMI632_MICRO_USB_MODE_REG 0x73
+-#define MICRO_USB_MODE_ONLY BIT(0)
+-
+-/* Interrupt numbers */
+-#define PMIC_TYPEC_OR_RID_IRQ 0x0
+-#define PMIC_TYPEC_VPD_IRQ 0x1
+-#define PMIC_TYPEC_CC_STATE_IRQ 0x2
+-#define PMIC_TYPEC_VCONN_OC_IRQ 0x3
+-#define PMIC_TYPEC_VBUS_IRQ 0x4
+-#define PMIC_TYPEC_ATTACH_DETACH_IRQ 0x5
+-#define PMIC_TYPEC_LEGACY_CABLE_IRQ 0x6
+-#define PMIC_TYPEC_TRY_SNK_SRC_IRQ 0x7
+-
+ /* Resources */
+ #define PMIC_TYPEC_MAX_IRQS 0x08
+
+@@ -156,40 +19,17 @@ struct pmic_typec_port_irq_params {
+
+ struct pmic_typec_port_resources {
+ unsigned int nr_irqs;
+- struct pmic_typec_port_irq_params irq_params[PMIC_TYPEC_MAX_IRQS];
++ const struct pmic_typec_port_irq_params irq_params[PMIC_TYPEC_MAX_IRQS];
+ };
+
+ /* API */
+-struct pmic_typec;
+
+-struct pmic_typec_port *qcom_pmic_typec_port_alloc(struct device *dev);
++extern const struct pmic_typec_port_resources pm8150b_port_res;
+
+ int qcom_pmic_typec_port_probe(struct platform_device *pdev,
+- struct pmic_typec_port *pmic_typec_port,
+- struct pmic_typec_port_resources *res,
++ struct pmic_typec *tcpm,
++ const struct pmic_typec_port_resources *res,
+ struct regmap *regmap,
+ u32 base);
+
+-int qcom_pmic_typec_port_start(struct pmic_typec_port *pmic_typec_port,
+- struct tcpm_port *tcpm_port);
+-
+-void qcom_pmic_typec_port_stop(struct pmic_typec_port *pmic_typec_port);
+-
+-int qcom_pmic_typec_port_get_cc(struct pmic_typec_port *pmic_typec_port,
+- enum typec_cc_status *cc1,
+- enum typec_cc_status *cc2);
+-
+-int qcom_pmic_typec_port_set_cc(struct pmic_typec_port *pmic_typec_port,
+- enum typec_cc_status cc);
+-
+-int qcom_pmic_typec_port_get_vbus(struct pmic_typec_port *pmic_typec_port);
+-
+-int qcom_pmic_typec_port_set_vconn(struct pmic_typec_port *pmic_typec_port, bool on);
+-
+-int qcom_pmic_typec_port_start_toggling(struct pmic_typec_port *pmic_typec_port,
+- enum typec_port_type port_type,
+- enum typec_cc_status cc);
+-
+-int qcom_pmic_typec_port_set_vbus(struct pmic_typec_port *pmic_typec_port, bool on);
+-
+ #endif /* __QCOM_PMIC_TYPE_C_PORT_H__ */
+--
+2.43.0
+
--- /dev/null
+From 19d4a394b9a49304e355fccd74ee71317dae6eed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 22:55:49 +0200
+Subject: usb: typec: qcom-pmic-typec: fix arguments of
+ qcom_pmic_typec_pdphy_set_roles
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 65145a03d65be80d389bf24c1874c634527de849 ]
+
+The function qcom_pmic_typec_set_roles() passes enum values as boolean
+values to qcom_pmic_typec_pdphy_set_roles(), which then interprets them
+as bit values. Be more explicit about it, pass enum values directly and
+compute corresponding bit masks in qcom_pmic_typec_pdphy_set_roles().
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Link: https://lore.kernel.org/r/20240113-pmi632-typec-v2-6-182d9aa0a5b3@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: d80eee97cb4e ("usb: typec: qcom-pmic: fix use-after-free on late probe errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 2 +-
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c | 8 +++++---
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h | 3 ++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+index 1a2b4bddaa97e..a243648abb4a5 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+@@ -123,7 +123,7 @@ static int qcom_pmic_typec_set_roles(struct tcpc_dev *tcpc, bool attached,
+ struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
+
+ return qcom_pmic_typec_pdphy_set_roles(tcpm->pmic_typec_pdphy,
+- data_role, power_role);
++ power_role, data_role);
+ }
+
+ static int qcom_pmic_typec_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
+index 52c81378e36ef..44d8342ed0ad5 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
+@@ -354,7 +354,8 @@ int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, b
+ }
+
+ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- bool data_role_host, bool power_role_src)
++ enum typec_role power_role,
++ enum typec_data_role data_role)
+ {
+ struct device *dev = pmic_typec_pdphy->dev;
+ unsigned long flags;
+@@ -366,12 +367,13 @@ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
+ pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
+ MSG_CONFIG_PORT_DATA_ROLE |
+ MSG_CONFIG_PORT_POWER_ROLE,
+- data_role_host << 3 | power_role_src << 2);
++ (data_role == TYPEC_HOST ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
++ (power_role == TYPEC_SOURCE ? MSG_CONFIG_PORT_POWER_ROLE : 0));
+
+ spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
+
+ dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
+- data_role_host, power_role_src);
++ data_role, power_role);
+
+ return ret;
+ }
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
+index e67954e31b149..070822dc6f177 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.h
+@@ -107,7 +107,8 @@ int qcom_pmic_typec_pdphy_start(struct pmic_typec_pdphy *pmic_typec_pdphy,
+ void qcom_pmic_typec_pdphy_stop(struct pmic_typec_pdphy *pmic_typec_pdphy);
+
+ int qcom_pmic_typec_pdphy_set_roles(struct pmic_typec_pdphy *pmic_typec_pdphy,
+- bool power_role_src, bool data_role_host);
++ enum typec_role power_role,
++ enum typec_data_role data_role);
+
+ int qcom_pmic_typec_pdphy_set_pd_rx(struct pmic_typec_pdphy *pmic_typec_pdphy, bool on);
+
+--
+2.43.0
+
--- /dev/null
+From 32338d65589b63f7f8fdcc4116f673ca5d029be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 08:15:33 +0200
+Subject: usb: typec: ucsi: allow non-partner GET_PDOS for Qualcomm devices
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 897d68d4ce7d50ca45a31e10c0e61597257b32d3 ]
+
+The name and description of the USB_NO_PARTNER_PDOS quirk specifies that
+only retrieving PDOS of the attached device is crashing. Retrieving PDOS
+of the UCSI device works. Fix the condition to limit the workaround only
+to is_partner cases.
+
+Fixes: 1d103d6af241 ("usb: typec: ucsi: fix UCSI on buggy Qualcomm devices")
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20240329-qcom-ucsi-fixes-v2-1-0f5d37ed04db@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index b501760012c4f..147ce1a2a2885 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -595,7 +595,8 @@ static int ucsi_read_pdos(struct ucsi_connector *con,
+ u64 command;
+ int ret;
+
+- if (ucsi->quirks & UCSI_NO_PARTNER_PDOS)
++ if (is_partner &&
++ ucsi->quirks & UCSI_NO_PARTNER_PDOS)
+ return 0;
+
+ command = UCSI_COMMAND(UCSI_GET_PDOS) | UCSI_CONNECTOR_NUMBER(con->num);
+--
+2.43.0
+
--- /dev/null
+From 4c7d6521ab1cd0e480c4acf0b3a8c57569f0c8e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 08:15:36 +0200
+Subject: usb: typec: ucsi: always register a link to USB PD device
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit c0f66d78f42353d38b9608c05f211cf0773d93ac ]
+
+UCSI driver will attempt to set a USB PD device only if it was able to
+read PDOs from the firmware. This results in suboptimal behaviour, since
+the PD device will be created anyway. Move calls to
+typec_port_set_usb_power_delivery() out of conditional code and call it
+after reading capabilities.
+
+Fixes: b04e1747fbcc ("usb: typec: ucsi: Register USB Power Delivery Capabilities")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240329-qcom-ucsi-fixes-v2-4-0f5d37ed04db@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 147ce1a2a2885..ce2411c8daf37 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1301,7 +1301,6 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
+ }
+
+ con->port_source_caps = pd_cap;
+- typec_port_set_usb_power_delivery(con->port, con->pd);
+ }
+
+ memset(&pd_caps, 0, sizeof(pd_caps));
+@@ -1318,9 +1317,10 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
+ }
+
+ con->port_sink_caps = pd_cap;
+- typec_port_set_usb_power_delivery(con->port, con->pd);
+ }
+
++ typec_port_set_usb_power_delivery(con->port, con->pd);
++
+ /* Alternate modes */
+ ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_CON);
+ if (ret) {
+--
+2.43.0
+
--- /dev/null
+From 596e30945521037005e19c6a49e092b9336ad8b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 08:15:37 +0200
+Subject: usb: typec: ucsi: simplify partner's PD caps registration
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 41e1cd1401fcd1f1ae9e47574af2d9fc44a870b3 ]
+
+In a way similar to the previous commit, move
+typec_partner_set_usb_power_delivery() to be called after reading the PD
+caps. This also removes calls to
+usb_power_delivery_unregister_capabilities() from the error path. Keep
+all capabilities registered until they are cleared by
+ucsi_unregister_partner_pdos().
+
+Fixes: b04e1747fbcc ("usb: typec: ucsi: Register USB Power Delivery Capabilities")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240329-qcom-ucsi-fixes-v2-5-0f5d37ed04db@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 14 +-------------
+ 1 file changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index ce2411c8daf37..b6a900cb657c6 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -698,12 +698,6 @@ static int ucsi_register_partner_pdos(struct ucsi_connector *con)
+ return PTR_ERR(cap);
+
+ con->partner_source_caps = cap;
+-
+- ret = typec_partner_set_usb_power_delivery(con->partner, con->partner_pd);
+- if (ret) {
+- usb_power_delivery_unregister_capabilities(con->partner_source_caps);
+- return ret;
+- }
+ }
+
+ ret = ucsi_get_pdos(con, TYPEC_SINK, 1, caps.pdo);
+@@ -718,15 +712,9 @@ static int ucsi_register_partner_pdos(struct ucsi_connector *con)
+ return PTR_ERR(cap);
+
+ con->partner_sink_caps = cap;
+-
+- ret = typec_partner_set_usb_power_delivery(con->partner, con->partner_pd);
+- if (ret) {
+- usb_power_delivery_unregister_capabilities(con->partner_sink_caps);
+- return ret;
+- }
+ }
+
+- return 0;
++ return typec_partner_set_usb_power_delivery(con->partner, con->partner_pd);
+ }
+
+ static void ucsi_unregister_partner_pdos(struct ucsi_connector *con)
+--
+2.43.0
+
--- /dev/null
+From d2b506d4c9b8db4e2bba4060da8f88fe28ed4cfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 17:02:30 +0300
+Subject: usb: xhci: check if 'requested segments' exceeds ERST capacity
+
+From: Niklas Neronin <niklas.neronin@linux.intel.com>
+
+[ Upstream commit db4460b6ecf07574d580f01cd88054a62607068c ]
+
+Check if requested segments ('segs' or 'ERST_DEFAULT_SEGS') exceeds the
+maximum amount ERST supports.
+
+When 'segs' is '0', 'ERST_DEFAULT_SEGS' is used instead. But both values
+may not exceed ERST max.
+
+Macro 'ERST_MAX_SEGS' is renamed to 'ERST_DEFAULT_SEGS'. The new name
+better represents the macros, which is the number of Event Ring segments
+to allocate, when the amount is not specified.
+
+Additionally, rename and change xhci_create_secondary_interrupter()'s
+argument 'int num_segs' to 'unsigned int segs'. This makes it the same
+as its counter part in xhci_alloc_interrupter().
+
+Fixes: c99b38c41234 ("xhci: add support to allocate several interrupters")
+Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240429140245.3955523-4-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mem.c | 22 +++++++++++-----------
+ drivers/usb/host/xhci.h | 6 +++---
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 450adaca68eeb..2246bb0dea191 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2280,24 +2280,24 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
+ }
+
+ static struct xhci_interrupter *
+-xhci_alloc_interrupter(struct xhci_hcd *xhci, int segs, gfp_t flags)
++xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
+ {
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+ struct xhci_interrupter *ir;
+- unsigned int num_segs = segs;
++ unsigned int max_segs;
+ int ret;
+
++ if (!segs)
++ segs = ERST_DEFAULT_SEGS;
++
++ max_segs = BIT(HCS_ERST_MAX(xhci->hcs_params2));
++ segs = min(segs, max_segs);
++
+ ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
+ if (!ir)
+ return NULL;
+
+- /* number of ring segments should be greater than 0 */
+- if (segs <= 0)
+- num_segs = min_t(unsigned int, 1 << HCS_ERST_MAX(xhci->hcs_params2),
+- ERST_MAX_SEGS);
+-
+- ir->event_ring = xhci_ring_alloc(xhci, num_segs, 1, TYPE_EVENT, 0,
+- flags);
++ ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, flags);
+ if (!ir->event_ring) {
+ xhci_warn(xhci, "Failed to allocate interrupter event ring\n");
+ kfree(ir);
+@@ -2355,7 +2355,7 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
+ }
+
+ struct xhci_interrupter *
+-xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg)
++xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs)
+ {
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct xhci_interrupter *ir;
+@@ -2365,7 +2365,7 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg)
+ if (!xhci->interrupters || xhci->max_interrupters <= 1)
+ return NULL;
+
+- ir = xhci_alloc_interrupter(xhci, num_seg, GFP_KERNEL);
++ ir = xhci_alloc_interrupter(xhci, segs, GFP_KERNEL);
+ if (!ir)
+ return NULL;
+
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index bf05103aa68a0..a736b3cf366d3 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1649,8 +1649,8 @@ struct urb_priv {
+ struct xhci_td td[] __counted_by(num_tds);
+ };
+
+-/* Reasonable limit for number of Event Ring segments (spec allows 32k) */
+-#define ERST_MAX_SEGS 2
++/* Number of Event Ring segments to allocate, when amount is not specified. (spec allows 32k) */
++#define ERST_DEFAULT_SEGS 2
+ /* Poll every 60 seconds */
+ #define POLL_TIMEOUT 60
+ /* Stop endpoint command timeout (secs) for URB cancellation watchdog timer */
+@@ -2088,7 +2088,7 @@ struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
+ void xhci_free_container_ctx(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *ctx);
+ struct xhci_interrupter *
+-xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg);
++xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs);
+ void xhci_remove_secondary_interrupter(struct usb_hcd
+ *hcd, struct xhci_interrupter *ir);
+
+--
+2.43.0
+
--- /dev/null
+From d38a2d654b046eaf82ab1f630bddaac99708e81e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 09:50:29 +0800
+Subject: vfio/pci: fix potential memory leak in vfio_intx_enable()
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 82b951e6fbd31d85ae7f4feb5f00ddd4c5d256e2 ]
+
+If vfio_irq_ctx_alloc() failed will lead to 'name' memory leak.
+
+Fixes: 18c198c96a81 ("vfio/pci: Create persistent INTx handler")
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Acked-by: Reinette Chatre <reinette.chatre@intel.com>
+Link: https://lore.kernel.org/r/20240415015029.3699844-1-yebin10@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/vfio_pci_intrs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
+index fb5392b749fff..e80c5d75b5419 100644
+--- a/drivers/vfio/pci/vfio_pci_intrs.c
++++ b/drivers/vfio/pci/vfio_pci_intrs.c
+@@ -277,8 +277,10 @@ static int vfio_intx_enable(struct vfio_pci_core_device *vdev,
+ return -ENOMEM;
+
+ ctx = vfio_irq_ctx_alloc(vdev, 0);
+- if (!ctx)
++ if (!ctx) {
++ kfree(name);
+ return -ENOMEM;
++ }
+
+ ctx->name = name;
+ ctx->trigger = trigger;
+--
+2.43.0
+
--- /dev/null
+From 248cb4fab31926195f58433bfdb49df06e1d7c99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Apr 2024 14:27:23 +0200
+Subject: VMCI: Fix an error handling path in vmci_guest_probe_device()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 73df3d6f2e9533e93a5039a33c40dd7216b81801 ]
+
+After a successful pci_iomap_range() call, pci_iounmap() should be called
+in the error handling path, as already done in the remove function.
+
+Add the missing call.
+
+The corresponding call was added in the remove function in commit
+5ee109828e73 ("VMCI: dma dg: allocate send and receive buffers for DMA
+datagrams")
+
+Fixes: e283a0e8b7ea ("VMCI: dma dg: add MMIO access to registers")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Vishnu Dasa <vishnu.dasa@broadcom.com>
+Link: https://lore.kernel.org/r/a35bbc3876ae1da70e49dafde4435750e1477be3.1713961553.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/vmw_vmci/vmci_guest.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
+index 4f8d962bb5b2a..1300ccab3d21b 100644
+--- a/drivers/misc/vmw_vmci/vmci_guest.c
++++ b/drivers/misc/vmw_vmci/vmci_guest.c
+@@ -625,7 +625,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
+ if (!vmci_dev) {
+ dev_err(&pdev->dev,
+ "Can't allocate memory for VMCI device\n");
+- return -ENOMEM;
++ error = -ENOMEM;
++ goto err_unmap_mmio_base;
+ }
+
+ vmci_dev->dev = &pdev->dev;
+@@ -642,7 +643,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
+ if (!vmci_dev->tx_buffer) {
+ dev_err(&pdev->dev,
+ "Can't allocate memory for datagram tx buffer\n");
+- return -ENOMEM;
++ error = -ENOMEM;
++ goto err_unmap_mmio_base;
+ }
+
+ vmci_dev->data_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
+@@ -893,6 +895,10 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
+ err_free_data_buffers:
+ vmci_free_dg_buffers(vmci_dev);
+
++err_unmap_mmio_base:
++ if (mmio_base != NULL)
++ pci_iounmap(pdev, mmio_base);
++
+ /* The rest are managed resources and will be freed by PCI core */
+ return error;
+ }
+--
+2.43.0
+
--- /dev/null
+From 3275ae81a8317fa8106b17ae8afa036c1819e4ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Apr 2024 13:02:31 +0300
+Subject: watchdog: bd9576: Drop "always-running" property
+
+From: Matti Vaittinen <mazziesaccount@gmail.com>
+
+[ Upstream commit e3b3afd34d84efcbe4543deb966b1990f43584b8 ]
+
+The always-running (from linux,wdt-gpio.yaml) is abused by the BD9576
+watchdog driver. It's defined meaning is "the watchdog is always running
+and can not be stopped". The BD9576 watchdog driver has implemented it
+as "start watchdog when loading the module and prevent it from being
+stopped".
+
+Furthermore, the implementation does not set the WDOG_HW_RUNNING when
+enabling the watchdog due to the "always-running" at module loading.
+This will end up resulting a watchdog timeout if the device is not
+opened.
+
+The culprit was pointed out by Guenter, discussion can be found from
+https://lore.kernel.org/lkml/4fa3a64b-60fb-4e5e-8785-0f14da37eea2@roeck-us.net/
+
+Drop the invalid "always-running" handling.
+
+Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Fixes: b237bcac557a ("wdt: Support wdt on ROHM BD9576MUF and BD9573MUF")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/ZhPAt76yaJMersXf@fedora
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/bd9576_wdt.c | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/drivers/watchdog/bd9576_wdt.c b/drivers/watchdog/bd9576_wdt.c
+index 4a20e07fbb699..f00ea1b4e40b6 100644
+--- a/drivers/watchdog/bd9576_wdt.c
++++ b/drivers/watchdog/bd9576_wdt.c
+@@ -29,7 +29,6 @@ struct bd9576_wdt_priv {
+ struct gpio_desc *gpiod_en;
+ struct device *dev;
+ struct regmap *regmap;
+- bool always_running;
+ struct watchdog_device wdd;
+ };
+
+@@ -62,10 +61,7 @@ static int bd9576_wdt_stop(struct watchdog_device *wdd)
+ {
+ struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd);
+
+- if (!priv->always_running)
+- bd9576_wdt_disable(priv);
+- else
+- set_bit(WDOG_HW_RUNNING, &wdd->status);
++ bd9576_wdt_disable(priv);
+
+ return 0;
+ }
+@@ -264,9 +260,6 @@ static int bd9576_wdt_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- priv->always_running = device_property_read_bool(dev->parent,
+- "always-running");
+-
+ watchdog_set_drvdata(&priv->wdd, priv);
+
+ priv->wdd.info = &bd957x_wdt_ident;
+@@ -281,9 +274,6 @@ static int bd9576_wdt_probe(struct platform_device *pdev)
+
+ watchdog_stop_on_reboot(&priv->wdd);
+
+- if (priv->always_running)
+- bd9576_wdt_start(&priv->wdd);
+-
+ return devm_watchdog_register_device(dev, &priv->wdd);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From fe607c546ebfd6deae3815254cf61033f37ba6b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Mar 2024 22:04:44 +0800
+Subject: watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit 573601521277119f2e2ba5f28ae6e87fc594f4d4 ]
+
+When the cpu5wdt module is removing, the origin code uses del_timer() to
+de-activate the timer. If the timer handler is running, del_timer() could
+not stop it and will return directly. If the port region is released by
+release_region() and then the timer handler cpu5wdt_trigger() calls outb()
+to write into the region that is released, the use-after-free bug will
+happen.
+
+Change del_timer() to timer_shutdown_sync() in order that the timer handler
+could be finished before the port region is released.
+
+Fixes: e09d9c3e9f85 ("watchdog: cpu5wdt.c: add missing del_timer call")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20240324140444.119584-1-duoming@zju.edu.cn
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/cpu5wdt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
+index 688b112e712ba..9f279c0e13a66 100644
+--- a/drivers/watchdog/cpu5wdt.c
++++ b/drivers/watchdog/cpu5wdt.c
+@@ -252,7 +252,7 @@ static void cpu5wdt_exit(void)
+ if (cpu5wdt_device.queue) {
+ cpu5wdt_device.queue = 0;
+ wait_for_completion(&cpu5wdt_device.stop);
+- del_timer(&cpu5wdt_device.timer);
++ timer_shutdown_sync(&cpu5wdt_device.timer);
+ }
+
+ misc_deregister(&cpu5wdt_misc);
+--
+2.43.0
+
--- /dev/null
+From 1bcf6a59c37308e0abf96dfa0e08d7364325bed6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Apr 2024 15:58:08 +0800
+Subject: watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in
+ sa1100dog_probe()
+
+From: Chen Ni <nichen@iscas.ac.cn>
+
+[ Upstream commit 413bf4e857fd79617524d5dcd35f463e9aa2dd41 ]
+
+devm_ioremap() doesn't return error pointers, it returns NULL on error.
+Update the check accordingly.
+
+Fixes: e86bd43bcfc5 ("watchdog: sa1100: use platform device registration")
+Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20240426075808.1582678-1-nichen@iscas.ac.cn
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/sa1100_wdt.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
+index 5d2df008b92a5..34a917221e316 100644
+--- a/drivers/watchdog/sa1100_wdt.c
++++ b/drivers/watchdog/sa1100_wdt.c
+@@ -191,9 +191,8 @@ static int sa1100dog_probe(struct platform_device *pdev)
+ if (!res)
+ return -ENXIO;
+ reg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+- ret = PTR_ERR_OR_ZERO(reg_base);
+- if (ret)
+- return ret;
++ if (!reg_base)
++ return -ENOMEM;
+
+ clk = clk_get(NULL, "OSTIMER0");
+ if (IS_ERR(clk)) {
+--
+2.43.0
+