--- /dev/null
+From 1a18355fedff8e2975a28471a199f453456c36b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Nov 2023 14:41:13 +0100
+Subject: cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily
+
+From: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+
+[ Upstream commit 2e4e0984c7d696cc74cf2fd7e7f62997f0e9ebe6 ]
+
+For a 900MHz i.MX6ULL CPU the 792MHz OPP is disabled. There is no
+convincing reason to disable this OPP. If a CPU can run at 900MHz,
+it should also be able to cope with 792MHz. Looking at the voltage
+level of 792MHz in [1] (page 24, table 10. "Operating Ranges") the
+current defined OPP is above the minimum. So the voltage level
+shouldn't be a problem. However in [2] (page 24, table 10.
+"Operating Ranges"), it is not mentioned that 792MHz OPP isn't
+allowed. Change it to only disable 792MHz OPP for i.MX6ULL types
+below 792 MHz.
+
+[1] https://www.nxp.com/docs/en/data-sheet/IMX6ULLIEC.pdf
+[2] https://www.nxp.com/docs/en/data-sheet/IMX6ULLCEC.pdf
+
+Fixes: 0aa9abd4c212 ("cpufreq: imx6q: check speed grades for i.MX6ULL")
+Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Fabio Estevam <festevam@denx.de>
+[ Viresh: Edited subject ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/imx6q-cpufreq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
+index ae834fb9bfbd5..925fc17eaacb2 100644
+--- a/drivers/cpufreq/imx6q-cpufreq.c
++++ b/drivers/cpufreq/imx6q-cpufreq.c
+@@ -327,7 +327,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
+ imx6x_disable_freq_in_opp(dev, 696000000);
+
+ if (of_machine_is_compatible("fsl,imx6ull")) {
+- if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ)
++ if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ)
+ imx6x_disable_freq_in_opp(dev, 792000000);
+
+ if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)
+--
+2.42.0
+
--- /dev/null
+From f4f9a24d653af85716dcd22d63d58e452076b60f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 17:07:11 +0200
+Subject: cpufreq: imx6q: don't warn for disabling a non-existing frequency
+
+From: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+
+[ Upstream commit 11a3b0ac33d95aa84be426e801f800997262a225 ]
+
+It is confusing if a warning is given for disabling a non-existent
+frequency of the operating performance points (OPP). In this case
+the function dev_pm_opp_disable() returns -ENODEV. Check the return
+value and avoid the output of a warning in this case. Avoid code
+duplication by using a separate function.
+
+Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+[ Viresh : Updated commit subject ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Stable-dep-of: 2e4e0984c7d6 ("cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/imx6q-cpufreq.c | 30 ++++++++++++++++--------------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
+index ad4ce84931446..ae834fb9bfbd5 100644
+--- a/drivers/cpufreq/imx6q-cpufreq.c
++++ b/drivers/cpufreq/imx6q-cpufreq.c
+@@ -209,6 +209,14 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
+ .suspend = cpufreq_generic_suspend,
+ };
+
++static void imx6x_disable_freq_in_opp(struct device *dev, unsigned long freq)
++{
++ int ret = dev_pm_opp_disable(dev, freq);
++
++ if (ret < 0 && ret != -ENODEV)
++ dev_warn(dev, "failed to disable %ldMHz OPP\n", freq / 1000000);
++}
++
+ #define OCOTP_CFG3 0x440
+ #define OCOTP_CFG3_SPEED_SHIFT 16
+ #define OCOTP_CFG3_SPEED_1P2GHZ 0x3
+@@ -254,17 +262,15 @@ static int imx6q_opp_check_speed_grading(struct device *dev)
+ val &= 0x3;
+
+ if (val < OCOTP_CFG3_SPEED_996MHZ)
+- if (dev_pm_opp_disable(dev, 996000000))
+- dev_warn(dev, "failed to disable 996MHz OPP\n");
++ imx6x_disable_freq_in_opp(dev, 996000000);
+
+ if (of_machine_is_compatible("fsl,imx6q") ||
+ of_machine_is_compatible("fsl,imx6qp")) {
+ if (val != OCOTP_CFG3_SPEED_852MHZ)
+- if (dev_pm_opp_disable(dev, 852000000))
+- dev_warn(dev, "failed to disable 852MHz OPP\n");
++ imx6x_disable_freq_in_opp(dev, 852000000);
++
+ if (val != OCOTP_CFG3_SPEED_1P2GHZ)
+- if (dev_pm_opp_disable(dev, 1200000000))
+- dev_warn(dev, "failed to disable 1.2GHz OPP\n");
++ imx6x_disable_freq_in_opp(dev, 1200000000);
+ }
+
+ return 0;
+@@ -316,20 +322,16 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
+ val >>= OCOTP_CFG3_SPEED_SHIFT;
+ val &= 0x3;
+
+- if (of_machine_is_compatible("fsl,imx6ul")) {
++ if (of_machine_is_compatible("fsl,imx6ul"))
+ if (val != OCOTP_CFG3_6UL_SPEED_696MHZ)
+- if (dev_pm_opp_disable(dev, 696000000))
+- dev_warn(dev, "failed to disable 696MHz OPP\n");
+- }
++ imx6x_disable_freq_in_opp(dev, 696000000);
+
+ if (of_machine_is_compatible("fsl,imx6ull")) {
+ if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ)
+- if (dev_pm_opp_disable(dev, 792000000))
+- dev_warn(dev, "failed to disable 792MHz OPP\n");
++ imx6x_disable_freq_in_opp(dev, 792000000);
+
+ if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)
+- if (dev_pm_opp_disable(dev, 900000000))
+- dev_warn(dev, "failed to disable 900MHz OPP\n");
++ imx6x_disable_freq_in_opp(dev, 900000000);
+ }
+
+ return ret;
+--
+2.42.0
+
--- /dev/null
+From fce90e5ebd105c64d036cdbe8ad7fd2a9141b07c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 11:14:02 -0100
+Subject: drm/amd/display: clean code-style issues in
+ dcn30_set_mpc_shaper_3dlut
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Melissa Wen <mwen@igalia.com>
+
+[ Upstream commit 94369589e4ec13c762fe10a1fdc4463bdfee5d5f ]
+
+This function has many conditions and all code style issues (identation,
+missing braces, etc.) make reading it really annoying.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Melissa Wen <mwen@igalia.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 6f395cebdd89 ("drm/amd/display: Fix MPCC 1DLUT programming")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/dcn30/dcn30_hwseq.c | 37 ++++++++++---------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index a1b312483d7f1..07691b487e28c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -91,8 +91,8 @@ bool dcn30_set_blend_lut(
+ return result;
+ }
+
+-static bool dcn30_set_mpc_shaper_3dlut(
+- struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
++static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
++ const struct dc_stream_state *stream)
+ {
+ struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
+ int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+@@ -104,19 +104,18 @@ static bool dcn30_set_mpc_shaper_3dlut(
+ const struct pwl_params *shaper_lut = NULL;
+ //get the shaper lut params
+ if (stream->func_shaper) {
+- if (stream->func_shaper->type == TF_TYPE_HWPWL)
++ if (stream->func_shaper->type == TF_TYPE_HWPWL) {
+ shaper_lut = &stream->func_shaper->pwl;
+- else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(
+- stream->func_shaper,
+- &dpp_base->shaper_params, true);
++ } else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
++ cm_helper_translate_curve_to_hw_format(stream->func_shaper,
++ &dpp_base->shaper_params, true);
+ shaper_lut = &dpp_base->shaper_params;
+ }
+ }
+
+ if (stream->lut3d_func &&
+- stream->lut3d_func->state.bits.initialized == 1 &&
+- stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
++ stream->lut3d_func->state.bits.initialized == 1 &&
++ stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
+ if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
+ mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux;
+ else if (stream->lut3d_func->state.bits.rmu_mux_num == 1)
+@@ -125,20 +124,22 @@ static bool dcn30_set_mpc_shaper_3dlut(
+ mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu2_mux;
+ if (mpcc_id_projected != mpcc_id)
+ BREAK_TO_DEBUGGER();
+- /*find the reason why logical layer assigned a differant mpcc_id into acquire_post_bldn_3dlut*/
++ /* find the reason why logical layer assigned a different
++ * mpcc_id into acquire_post_bldn_3dlut
++ */
+ acquired_rmu = mpc->funcs->acquire_rmu(mpc, mpcc_id,
+- stream->lut3d_func->state.bits.rmu_mux_num);
++ stream->lut3d_func->state.bits.rmu_mux_num);
+ if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
+ BREAK_TO_DEBUGGER();
+- result = mpc->funcs->program_3dlut(mpc,
+- &stream->lut3d_func->lut_3d,
+- stream->lut3d_func->state.bits.rmu_mux_num);
++
++ result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
++ stream->lut3d_func->state.bits.rmu_mux_num);
+ result = mpc->funcs->program_shaper(mpc, shaper_lut,
+- stream->lut3d_func->state.bits.rmu_mux_num);
+- } else
+- /*loop through the available mux and release the requested mpcc_id*/
++ stream->lut3d_func->state.bits.rmu_mux_num);
++ } else {
++ // loop through the available mux and release the requested mpcc_id
+ mpc->funcs->release_rmu(mpc, mpcc_id);
+-
++ }
+
+ return result;
+ }
+--
+2.42.0
+
--- /dev/null
+From c101fb783547c5d86fa25b6cba02741a7ad2867f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 11:46:57 -0400
+Subject: drm/amd/display: Expand kernel doc for DC
+
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+
+[ Upstream commit 1682bd1a6b5fb094e914d9b73b711821fd84dcbd ]
+
+This commit adds extra documentation for elements related to FAMs.
+
+Tested-by: Mark Broadworth <mark.broadworth@amd.com>
+Reviewed-by: Aurabindo Pillai <Aurabindo.Pillai@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 67e38874b85b ("drm/amd/display: Increase num voltage states to 40")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dc.h | 19 +++++++++++---
+ drivers/gpu/drm/amd/display/dc/dc_stream.h | 11 ++++++++
+ .../gpu/drm/amd/display/dc/dml/dc_features.h | 7 ++++++
+ .../amd/display/dc/dml/display_mode_enums.h | 25 +++++++++++++++++++
+ .../drm/amd/display/dc/dml/display_mode_vba.h | 9 +++++++
+ .../gpu/drm/amd/display/dc/inc/core_types.h | 7 ++++++
+ .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 7 ++++++
+ 7 files changed, 82 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index f773a467fef54..7e775cec06927 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -499,9 +499,12 @@ enum dcn_zstate_support_state {
+ DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY,
+ DCN_ZSTATE_SUPPORT_DISALLOW,
+ };
+-/*
+- * For any clocks that may differ per pipe
+- * only the max is stored in this structure
++
++/**
++ * dc_clocks - DC pipe clocks
++ *
++ * For any clocks that may differ per pipe only the max is stored in this
++ * structure
+ */
+ struct dc_clocks {
+ int dispclk_khz;
+@@ -528,6 +531,16 @@ struct dc_clocks {
+ bool prev_p_state_change_support;
+ bool fclk_prev_p_state_change_support;
+ int num_ways;
++
++ /**
++ * @fw_based_mclk_switching
++ *
++ * DC has a mechanism that leverage the variable refresh rate to switch
++ * memory clock in cases that we have a large latency to achieve the
++ * memory clock change and a short vblank window. DC has some
++ * requirements to enable this feature, and this field describes if the
++ * system support or not such a feature.
++ */
+ bool fw_based_mclk_switching;
+ bool fw_based_mclk_switching_shut_down;
+ int prev_num_ways;
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+index 364ff913527d8..31c6a80c216ff 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+@@ -202,7 +202,18 @@ struct dc_stream_state {
+ bool use_vsc_sdp_for_colorimetry;
+ bool ignore_msa_timing_param;
+
++ /**
++ * @allow_freesync:
++ *
++ * It say if Freesync is enabled or not.
++ */
+ bool allow_freesync;
++
++ /**
++ * @vrr_active_variable:
++ *
++ * It describes if VRR is in use.
++ */
+ bool vrr_active_variable;
+ bool freesync_on_desktop;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
+index 74e86732e3010..2cbdd75429ffd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
+@@ -29,6 +29,13 @@
+ #define DC__PRESENT 1
+ #define DC__PRESENT__1 1
+ #define DC__NUM_DPP 4
++
++/**
++ * @DC__VOLTAGE_STATES:
++ *
++ * Define the maximum amount of states supported by the ASIC. Every ASIC has a
++ * specific number of states; this macro defines the maximum number of states.
++ */
+ #define DC__VOLTAGE_STATES 20
+ #define DC__NUM_DPP__4 1
+ #define DC__NUM_DPP__0_PRESENT 1
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
+index f394b3f3922a8..0bffae95f3a29 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
+@@ -105,14 +105,39 @@ enum source_macro_tile_size {
+ enum cursor_bpp {
+ dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2
+ };
++
++/**
++ * @enum clock_change_support - It represents possible reasons to change the DRAM clock.
++ *
++ * DC may change the DRAM clock during its execution, and this enum tracks all
++ * the available methods. Note that every ASIC has their specific way to deal
++ * with these clock switch.
++ */
+ enum clock_change_support {
++ /**
++ * @dm_dram_clock_change_uninitialized: If you see this, we might have
++ * a code initialization issue
++ */
+ dm_dram_clock_change_uninitialized = 0,
++
++ /**
++ * @dm_dram_clock_change_vactive: Support DRAM switch in VActive
++ */
+ dm_dram_clock_change_vactive,
++
++ /**
++ * @dm_dram_clock_change_vblank: Support DRAM switch in VBlank
++ */
+ dm_dram_clock_change_vblank,
++
+ dm_dram_clock_change_vactive_w_mall_full_frame,
+ dm_dram_clock_change_vactive_w_mall_sub_vp,
+ dm_dram_clock_change_vblank_w_mall_full_frame,
+ dm_dram_clock_change_vblank_w_mall_sub_vp,
++
++ /**
++ * @dm_dram_clock_change_unsupported: Do not support DRAM switch
++ */
+ dm_dram_clock_change_unsupported
+ };
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+index 2b34b02dbd459..81e53e67cd0b0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+@@ -419,6 +419,15 @@ struct vba_vars_st {
+ double MinPixelChunkSizeBytes;
+ unsigned int DCCMetaBufferSizeBytes;
+ // Pipe/Plane Parameters
++
++ /** @VoltageLevel:
++ * Every ASIC has a fixed number of DPM states, and some devices might
++ * have some particular voltage configuration that does not map
++ * directly to the DPM states. This field tells how many states the
++ * target device supports; even though this field combines the DPM and
++ * special SOC voltages, it mostly matches the total number of DPM
++ * states.
++ */
+ int VoltageLevel;
+ double FabricClock;
+ double DRAMSpeed;
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+index 5fa7c4772af4f..d2b9e3f83fc3b 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+@@ -115,6 +115,13 @@ struct resource_funcs {
+ int vlevel);
+ void (*update_soc_for_wm_a)(
+ struct dc *dc, struct dc_state *context);
++
++ /**
++ * @populate_dml_pipes - Populate pipe data struct
++ *
++ * Returns:
++ * Total of pipes available in the specific ASIC.
++ */
+ int (*populate_dml_pipes)(
+ struct dc *dc,
+ struct dc_state *context,
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+index cd2be729846b4..a819f0f97c5f3 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+@@ -35,6 +35,13 @@
+ ******************************************************************************/
+
+ #define MAX_AUDIOS 7
++
++/**
++ * @MAX_PIPES:
++ *
++ * Every ASIC support a fixed number of pipes; MAX_PIPES defines a large number
++ * to be used inside loops and for determining array sizes.
++ */
+ #define MAX_PIPES 6
+ #define MAX_DIG_LINK_ENCODERS 7
+ #define MAX_DWB_PIPES 1
+--
+2.42.0
+
--- /dev/null
+From 8f71032bb89af422fd91617c7b0bb23fe18a7fa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 15:07:56 -0500
+Subject: drm/amd/display: Fix MPCC 1DLUT programming
+
+From: Ilya Bakoulin <ilya.bakoulin@amd.com>
+
+[ Upstream commit 6f395cebdd8927fbffdc3a55a14fcacf93634359 ]
+
+[Why]
+Wrong function is used to translate LUT values to HW format, leading to
+visible artifacting in some cases.
+
+[How]
+Use the correct cm3_helper function.
+
+Cc: stable@vger.kernel.org # 6.1+
+Reviewed-by: Krunoslav Kovac <krunoslav.kovac@amd.com>
+Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Ilya Bakoulin <ilya.bakoulin@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index f69e7d748e68b..bd75d3cba0980 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -566,8 +566,7 @@ bool dcn32_set_mcm_luts(
+ if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->blend_tf->pwl;
+ else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+- plane_state->blend_tf,
++ cm3_helper_translate_curve_to_hw_format(plane_state->blend_tf,
+ &dpp_base->regamma_params, false);
+ lut_params = &dpp_base->regamma_params;
+ }
+@@ -581,8 +580,7 @@ bool dcn32_set_mcm_luts(
+ else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+ // TODO: dpp_base replace
+ ASSERT(false);
+- cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+- plane_state->in_shaper_func,
++ cm3_helper_translate_curve_to_hw_format(plane_state->in_shaper_func,
+ &dpp_base->shaper_params, true);
+ lut_params = &dpp_base->shaper_params;
+ }
+--
+2.42.0
+
--- /dev/null
+From 6be30829253ead6f1bda97937b28bd9667106bb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 18:06:27 -0400
+Subject: drm/amd/display: Fix the delta clamping for shaper LUT
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+[ Upstream commit 27fc10d1095f7a7de7c917638d7134033a190dd8 ]
+
+The shaper LUT requires a 10-bit value of the delta between segments. We
+were using dc_fixpt_clamp_u0d10() to do that but it doesn't do what we
+want it to do. It will preserve 10-bit precision after the decimal
+point, but that's not quite what we want. We want 14-bit precision and
+discard the 4 most-significant bytes.
+
+To do that we'll do dc_fixpt_clamp_u0d14() & 0x3ff instead.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Reviewed-by: Krunoslav Kovac <krunoslav.kovac@amd.com>
+Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 6f395cebdd89 ("drm/amd/display: Fix MPCC 1DLUT programming")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/dc/dcn10/dcn10_cm_common.c | 19 +++++++++++++++----
+ .../amd/display/dc/dcn10/dcn10_cm_common.h | 1 +
+ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +-
+ .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 6 +++---
+ .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c | 2 +-
+ .../drm/amd/display/dc/dcn30/dcn30_hwseq.c | 2 +-
+ .../drm/amd/display/dc/dcn32/dcn32_hwseq.c | 6 +++---
+ 7 files changed, 25 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+index 7a00fe525dfba..3538973bd0c6c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+@@ -308,7 +308,10 @@ bool cm_helper_convert_to_custom_float(
+ #define NUMBER_REGIONS 32
+ #define NUMBER_SW_SEGMENTS 16
+
+-bool cm_helper_translate_curve_to_hw_format(
++#define DC_LOGGER \
++ ctx->logger
++
++bool cm_helper_translate_curve_to_hw_format(struct dc_context *ctx,
+ const struct dc_transfer_func *output_tf,
+ struct pwl_params *lut_params, bool fixpoint)
+ {
+@@ -482,10 +485,18 @@ bool cm_helper_translate_curve_to_hw_format(
+ rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
+ rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
+
++
+ if (fixpoint == true) {
+- rgb->delta_red_reg = dc_fixpt_clamp_u0d10(rgb->delta_red);
+- rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green);
+- rgb->delta_blue_reg = dc_fixpt_clamp_u0d10(rgb->delta_blue);
++ uint32_t red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red);
++ uint32_t green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green);
++ uint32_t blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue);
++
++ if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10)
++ DC_LOG_WARNING("Losing delta precision while programming shaper LUT.");
++
++ rgb->delta_red_reg = red_clamp & 0x3ff;
++ rgb->delta_green_reg = green_clamp & 0x3ff;
++ rgb->delta_blue_reg = blue_clamp & 0x3ff;
+ rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red);
+ rgb->green_reg = dc_fixpt_clamp_u0d14(rgb->green);
+ rgb->blue_reg = dc_fixpt_clamp_u0d14(rgb->blue);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
+index 3b8cd7410498a..0a68b63d61260 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
+@@ -106,6 +106,7 @@ bool cm_helper_convert_to_custom_float(
+ bool fixpoint);
+
+ bool cm_helper_translate_curve_to_hw_format(
++ struct dc_context *ctx,
+ const struct dc_transfer_func *output_tf,
+ struct pwl_params *lut_params, bool fixpoint);
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 3940271189632..d84579da64003 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -1867,7 +1867,7 @@ bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ /* dcn10_translate_regamma_to_hw_format takes 750us, only do it when full
+ * update.
+ */
+- else if (cm_helper_translate_curve_to_hw_format(
++ else if (cm_helper_translate_curve_to_hw_format(dc->ctx,
+ stream->out_transfer_func,
+ &dpp->regamma_params, false)) {
+ dpp->funcs->dpp_program_regamma_pwl(
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+index fbc188812ccc9..9bd6a5716cdc1 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -843,7 +843,7 @@ bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ params = &stream->out_transfer_func->pwl;
+ else if (pipe_ctx->stream->out_transfer_func->type ==
+ TF_TYPE_DISTRIBUTED_POINTS &&
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(dc->ctx,
+ stream->out_transfer_func,
+ &mpc->blender_params, false))
+ params = &mpc->blender_params;
+@@ -872,7 +872,7 @@ bool dcn20_set_blend_lut(
+ if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
+ blend_lut = &plane_state->blend_tf->pwl;
+ else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+ plane_state->blend_tf,
+ &dpp_base->regamma_params, false);
+ blend_lut = &dpp_base->regamma_params;
+@@ -894,7 +894,7 @@ bool dcn20_set_shaper_3dlut(
+ if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL)
+ shaper_lut = &plane_state->in_shaper_func->pwl;
+ else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+ plane_state->in_shaper_func,
+ &dpp_base->shaper_params, true);
+ shaper_lut = &dpp_base->shaper_params;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
+index 6a3d3a0ec0a36..701c7d8bc038a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
+@@ -280,7 +280,7 @@ bool dwb3_ogam_set_input_transfer_func(
+ dwb_ogam_lut = kzalloc(sizeof(*dwb_ogam_lut), GFP_KERNEL);
+
+ if (dwb_ogam_lut) {
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(dwbc->ctx,
+ in_transfer_func_dwb_ogam,
+ dwb_ogam_lut, false);
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index 07691b487e28c..53262f6bc40b0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -107,7 +107,7 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
+ if (stream->func_shaper->type == TF_TYPE_HWPWL) {
+ shaper_lut = &stream->func_shaper->pwl;
+ } else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(stream->func_shaper,
++ cm_helper_translate_curve_to_hw_format(stream->ctx, stream->func_shaper,
+ &dpp_base->shaper_params, true);
+ shaper_lut = &dpp_base->shaper_params;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index 50b3547977281..f69e7d748e68b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -530,7 +530,7 @@ static bool dcn32_set_mpc_shaper_3dlut(
+ if (stream->func_shaper->type == TF_TYPE_HWPWL)
+ shaper_lut = &stream->func_shaper->pwl;
+ else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(stream->ctx,
+ stream->func_shaper,
+ &dpp_base->shaper_params, true);
+ shaper_lut = &dpp_base->shaper_params;
+@@ -566,7 +566,7 @@ bool dcn32_set_mcm_luts(
+ if (plane_state->blend_tf->type == TF_TYPE_HWPWL)
+ lut_params = &plane_state->blend_tf->pwl;
+ else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+ plane_state->blend_tf,
+ &dpp_base->regamma_params, false);
+ lut_params = &dpp_base->regamma_params;
+@@ -581,7 +581,7 @@ bool dcn32_set_mcm_luts(
+ else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+ // TODO: dpp_base replace
+ ASSERT(false);
+- cm_helper_translate_curve_to_hw_format(
++ cm_helper_translate_curve_to_hw_format(plane_state->ctx,
+ plane_state->in_shaper_func,
+ &dpp_base->shaper_params, true);
+ lut_params = &dpp_base->shaper_params;
+--
+2.42.0
+
--- /dev/null
+From fcf2e91100e8a324ce35013028fc94e429898425 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 16:18:44 -0400
+Subject: drm/amd/display: Guard against invalid RPTR/WPTR being set
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 1ffa8602e39b89469dc703ebab7a7e44c33da0f7 ]
+
+[WHY]
+HW can return invalid values on register read, guard against these being
+set and causing us to access memory out of range and page fault.
+
+[HOW]
+Guard at sync_inbox1 and guard at pushing commands.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Hansen Dsouza <hansen.dsouza@amd.com>
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+index 6b8bd556c872f..e951fd837aa27 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+@@ -675,9 +675,16 @@ enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub)
+ return DMUB_STATUS_INVALID;
+
+ if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) {
+- dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
+- dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub);
+- dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
++ uint32_t rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
++ uint32_t wptr = dmub->hw_funcs.get_inbox1_wptr(dmub);
++
++ if (rptr > dmub->inbox1_rb.capacity || wptr > dmub->inbox1_rb.capacity) {
++ return DMUB_STATUS_HW_FAILURE;
++ } else {
++ dmub->inbox1_rb.rptr = rptr;
++ dmub->inbox1_rb.wrpt = wptr;
++ dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
++ }
+ }
+
+ return DMUB_STATUS_OK;
+@@ -711,6 +718,11 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
+ if (!dmub->hw_init)
+ return DMUB_STATUS_INVALID;
+
++ if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity ||
++ dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {
++ return DMUB_STATUS_HW_FAILURE;
++ }
++
+ if (dmub_rb_push_front(&dmub->inbox1_rb, cmd))
+ return DMUB_STATUS_OK;
+
+--
+2.42.0
+
--- /dev/null
+From 7d3753da147bad48fff2c5a1b9b2a8b11f4b1760 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 17:16:28 -0500
+Subject: drm/amd/display: Increase num voltage states to 40
+
+From: Alvin Lee <alvin.lee2@amd.com>
+
+[ Upstream commit 67e38874b85b8df7b23d29f78ac3d7ecccd9519d ]
+
+[Description]
+If during driver init stage there are greater than 20
+intermediary voltage states while constructing the SOC
+BB we could hit issues because we will index outside of the
+clock_limits array and start overwriting data. Increase the
+total number of states to 40 to avoid this issue.
+
+Cc: stable@vger.kernel.org # 6.1+
+Reviewed-by: Samson Tam <samson.tam@amd.com>
+Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dml/dc_features.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
+index 2cbdd75429ffd..6e669a2c5b2d4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
+@@ -36,7 +36,7 @@
+ * Define the maximum amount of states supported by the ASIC. Every ASIC has a
+ * specific number of states; this macro defines the maximum number of states.
+ */
+-#define DC__VOLTAGE_STATES 20
++#define DC__VOLTAGE_STATES 40
+ #define DC__NUM_DPP__4 1
+ #define DC__NUM_DPP__0_PRESENT 1
+ #define DC__NUM_DPP__1_PRESENT 1
+--
+2.42.0
+
--- /dev/null
+From a2401fd2f99240d3ac49504c1d9347aacccfa577 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 23:23:37 +0800
+Subject: drm/amd/display: Restore rptr/wptr for DMCUB as workaround
+
+From: JinZe.Xu <JinZe.Xu@amd.com>
+
+[ Upstream commit 8f3589bb6fcea397775398cba4fbcc46829a60ed ]
+
+[Why]
+States may be desync after resume.
+
+[How]
+Sync sw state with hw state.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: JinZe.Xu <JinZe.Xu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 1ffa8602e39b ("drm/amd/display: Guard against invalid RPTR/WPTR being set")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 14 ++++++++++++++
+ .../gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 5 +++++
+ .../gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 2 ++
+ .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 5 +++++
+ .../gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 2 ++
+ .../gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 5 +++++
+ .../gpu/drm/amd/display/dmub/src/dmub_dcn32.h | 2 ++
+ drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 17 +++++++++++++++++
+ 8 files changed, 52 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+index a21fe7b037d1f..aaabaab49809d 100644
+--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
++++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+@@ -332,6 +332,8 @@ struct dmub_srv_hw_funcs {
+ void (*setup_mailbox)(struct dmub_srv *dmub,
+ const struct dmub_region *inbox1);
+
++ uint32_t (*get_inbox1_wptr)(struct dmub_srv *dmub);
++
+ uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub);
+
+ void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
+@@ -590,6 +592,18 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
+ */
+ enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
+
++/**
++ * dmub_srv_sync_inbox1() - sync sw state with hw state
++ * @dmub: the dmub service
++ *
++ * Sync sw state with hw state when resume from S0i3
++ *
++ * Return:
++ * DMUB_STATUS_OK - success
++ * DMUB_STATUS_INVALID - unspecified error
++ */
++enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub);
++
+ /**
+ * dmub_srv_cmd_queue() - queues a command to the DMUB
+ * @dmub: the dmub service
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
+index a6540e27044d2..98dad0d47e72c 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
+@@ -282,6 +282,11 @@ void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub,
+ REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
+ }
+
++uint32_t dmub_dcn20_get_inbox1_wptr(struct dmub_srv *dmub)
++{
++ return REG_READ(DMCUB_INBOX1_WPTR);
++}
++
+ uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub)
+ {
+ return REG_READ(DMCUB_INBOX1_RPTR);
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h
+index c2e5831ac52cc..1df128e57ed3b 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h
+@@ -202,6 +202,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub,
+ void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub,
+ const struct dmub_region *inbox1);
+
++uint32_t dmub_dcn20_get_inbox1_wptr(struct dmub_srv *dmub);
++
+ uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub);
+
+ void dmub_dcn20_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset);
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
+index 89d24fb7024e2..5e952541e72d5 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
+@@ -242,6 +242,11 @@ void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub,
+ REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
+ }
+
++uint32_t dmub_dcn31_get_inbox1_wptr(struct dmub_srv *dmub)
++{
++ return REG_READ(DMCUB_INBOX1_WPTR);
++}
++
+ uint32_t dmub_dcn31_get_inbox1_rptr(struct dmub_srv *dmub)
+ {
+ return REG_READ(DMCUB_INBOX1_RPTR);
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h
+index eb62410941473..89c5a948b67d5 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h
+@@ -204,6 +204,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub,
+ void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub,
+ const struct dmub_region *inbox1);
+
++uint32_t dmub_dcn31_get_inbox1_wptr(struct dmub_srv *dmub);
++
+ uint32_t dmub_dcn31_get_inbox1_rptr(struct dmub_srv *dmub);
+
+ void dmub_dcn31_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset);
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
+index 9c20516be066c..d2f03f797279f 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
+@@ -266,6 +266,11 @@ void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub,
+ REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
+ }
+
++uint32_t dmub_dcn32_get_inbox1_wptr(struct dmub_srv *dmub)
++{
++ return REG_READ(DMCUB_INBOX1_WPTR);
++}
++
+ uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub)
+ {
+ return REG_READ(DMCUB_INBOX1_RPTR);
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h
+index 7d1a6eb4d6657..f15336b6e22be 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h
+@@ -206,6 +206,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub,
+ void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub,
+ const struct dmub_region *inbox1);
+
++uint32_t dmub_dcn32_get_inbox1_wptr(struct dmub_srv *dmub);
++
+ uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub);
+
+ void dmub_dcn32_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset);
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+index f58803de37cb0..6b8bd556c872f 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+@@ -167,6 +167,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
+ funcs->backdoor_load = dmub_dcn20_backdoor_load;
+ funcs->setup_windows = dmub_dcn20_setup_windows;
+ funcs->setup_mailbox = dmub_dcn20_setup_mailbox;
++ funcs->get_inbox1_wptr = dmub_dcn20_get_inbox1_wptr;
+ funcs->get_inbox1_rptr = dmub_dcn20_get_inbox1_rptr;
+ funcs->set_inbox1_wptr = dmub_dcn20_set_inbox1_wptr;
+ funcs->is_supported = dmub_dcn20_is_supported;
+@@ -243,6 +244,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
+ funcs->backdoor_load = dmub_dcn31_backdoor_load;
+ funcs->setup_windows = dmub_dcn31_setup_windows;
+ funcs->setup_mailbox = dmub_dcn31_setup_mailbox;
++ funcs->get_inbox1_wptr = dmub_dcn31_get_inbox1_wptr;
+ funcs->get_inbox1_rptr = dmub_dcn31_get_inbox1_rptr;
+ funcs->set_inbox1_wptr = dmub_dcn31_set_inbox1_wptr;
+ funcs->setup_out_mailbox = dmub_dcn31_setup_out_mailbox;
+@@ -281,6 +283,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
+ funcs->backdoor_load_zfb_mode = dmub_dcn32_backdoor_load_zfb_mode;
+ funcs->setup_windows = dmub_dcn32_setup_windows;
+ funcs->setup_mailbox = dmub_dcn32_setup_mailbox;
++ funcs->get_inbox1_wptr = dmub_dcn32_get_inbox1_wptr;
+ funcs->get_inbox1_rptr = dmub_dcn32_get_inbox1_rptr;
+ funcs->set_inbox1_wptr = dmub_dcn32_set_inbox1_wptr;
+ funcs->setup_out_mailbox = dmub_dcn32_setup_out_mailbox;
+@@ -666,6 +669,20 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
+ return DMUB_STATUS_OK;
+ }
+
++enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub)
++{
++ if (!dmub->sw_init)
++ return DMUB_STATUS_INVALID;
++
++ if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) {
++ dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
++ dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub);
++ dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
++ }
++
++ return DMUB_STATUS_OK;
++}
++
+ enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub)
+ {
+ if (!dmub->sw_init)
+--
+2.42.0
+
--- /dev/null
+From 05fe29bbcb5dc12f806196de7d350eb44c8d2639 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Nov 2023 15:33:22 +0800
+Subject: drm/amd/pm: fix a memleak in aldebaran_tables_init
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit 7a88f23e768491bae653b444a96091d2aaeb0818 ]
+
+When kzalloc() for smu_table->ecc_table fails, we should free
+the previously allocated resources to prevent memleak.
+
+Fixes: edd794208555 ("drm/amd/pm: add message smu to get ecc_table v2")
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+index d30ec3005ea19..cd8b0ab0112ae 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+@@ -258,8 +258,11 @@ static int aldebaran_tables_init(struct smu_context *smu)
+ }
+
+ smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL);
+- if (!smu_table->ecc_table)
++ if (!smu_table->ecc_table) {
++ kfree(smu_table->metrics_table);
++ kfree(smu_table->gpu_metrics_table);
+ return -ENOMEM;
++ }
+
+ return 0;
+ }
+--
+2.42.0
+
--- /dev/null
+From ad928967f1fc1951f16e2190472fb5c50401be74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 07:43:15 +0200
+Subject: drm/i915: Call intel_pre_plane_updates() also for pipes getting
+ enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+[ Upstream commit d21a3962d3042e6f56ad324cf18bdd64a1e6ecfa ]
+
+We used to call intel_pre_plane_updates() for any pipe going through
+a modeset whether the pipe was previously enabled or not. This in
+fact needed to apply all the necessary clock gating workarounds/etc.
+Restore the correct behaviour.
+
+Fixes: 39919997322f ("drm/i915: Disable all planes before modesetting any pipes")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231121054324.9988-3-ville.syrjala@linux.intel.com
+(cherry picked from commit e0d5ce11ed0a21bb2bf328ad82fd261783c7ad88)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_display.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
+index 96e679a176e94..1977f4c6fd889 100644
+--- a/drivers/gpu/drm/i915/display/intel_display.c
++++ b/drivers/gpu/drm/i915/display/intel_display.c
+@@ -7188,10 +7188,11 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
+ if (!intel_crtc_needs_modeset(new_crtc_state))
+ continue;
+
++ intel_pre_plane_update(state, crtc);
++
+ if (!old_crtc_state->hw.active)
+ continue;
+
+- intel_pre_plane_update(state, crtc);
+ intel_crtc_disable_planes(state, crtc);
+ }
+
+--
+2.42.0
+
--- /dev/null
+From 2c88833bba061e302bcc2f6ded10d3c6a27b68b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 13:36:48 +0200
+Subject: fbdev: stifb: Make the STI next font pointer a 32-bit signed offset
+
+From: Helge Deller <deller@gmx.de>
+
+[ Upstream commit 8a32aa17c1cd48df1ddaa78e45abcb8c7a2220d6 ]
+
+The pointer to the next STI font is actually a signed 32-bit
+offset. With this change the 64-bit kernel will correctly subract
+the (signed 32-bit) offset instead of adding a (unsigned 32-bit)
+offset. It has no effect on 32-bit kernels.
+
+This fixes the stifb driver with a 64-bit kernel on qemu.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/sticore.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/sticore.h b/drivers/video/fbdev/sticore.h
+index 0ebdd28a0b813..d83ab3ded5f3d 100644
+--- a/drivers/video/fbdev/sticore.h
++++ b/drivers/video/fbdev/sticore.h
+@@ -231,7 +231,7 @@ struct sti_rom_font {
+ u8 height;
+ u8 font_type; /* language type */
+ u8 bytes_per_char;
+- u32 next_font;
++ s32 next_font; /* note: signed int */
+ u8 underline_height;
+ u8 underline_pos;
+ u8 res008[2];
+--
+2.42.0
+
--- /dev/null
+From d64cadc39a352d8917825546b2641aaa0b90714e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 08:29:44 +0800
+Subject: iommu/vt-d: Add device_block_translation() helper
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+[ Upstream commit c7be17c2903d4acbf9aa372bfb6e2a418387fce0 ]
+
+If domain attaching to device fails, the IOMMU driver should bring the
+device to blocking DMA state. The upper layer is expected to recover it
+by attaching a new domain. Use device_block_translation() in the error
+path of dev_attach to make the behavior specific.
+
+The difference between device_block_translation() and the previous
+dmar_remove_one_dev_info() is that, in the scalable mode, it is the
+RID2PASID entry instead of context entry being cleared. As a result,
+enabling PCI capabilities is moved up.
+
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20221118132451.114406-3-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: da37dddcf4ca ("iommu/vt-d: Disable PCI ATS in legacy passthrough mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/iommu.c | 44 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 38 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index 3dbf86c61f073..de76272d0fb02 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -277,7 +277,7 @@ static LIST_HEAD(dmar_satc_units);
+ #define for_each_rmrr_units(rmrr) \
+ list_for_each_entry(rmrr, &dmar_rmrr_units, list)
+
+-static void dmar_remove_one_dev_info(struct device *dev);
++static void device_block_translation(struct device *dev);
+
+ int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
+ int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
+@@ -1418,7 +1418,7 @@ static void iommu_enable_pci_caps(struct device_domain_info *info)
+ {
+ struct pci_dev *pdev;
+
+- if (!info || !dev_is_pci(info->dev))
++ if (!dev_is_pci(info->dev))
+ return;
+
+ pdev = to_pci_dev(info->dev);
+@@ -2064,7 +2064,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
+ } else {
+ iommu_flush_write_buffer(iommu);
+ }
+- iommu_enable_pci_caps(info);
+
+ ret = 0;
+
+@@ -2506,7 +2505,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
+ dev, PASID_RID2PASID);
+ if (ret) {
+ dev_err(dev, "Setup RID2PASID failed\n");
+- dmar_remove_one_dev_info(dev);
++ device_block_translation(dev);
+ return ret;
+ }
+ }
+@@ -2514,10 +2513,12 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
+ ret = domain_context_mapping(domain, dev);
+ if (ret) {
+ dev_err(dev, "Domain context map failed\n");
+- dmar_remove_one_dev_info(dev);
++ device_block_translation(dev);
+ return ret;
+ }
+
++ iommu_enable_pci_caps(info);
++
+ return 0;
+ }
+
+@@ -4115,6 +4116,37 @@ static void dmar_remove_one_dev_info(struct device *dev)
+ info->domain = NULL;
+ }
+
++/*
++ * Clear the page table pointer in context or pasid table entries so that
++ * all DMA requests without PASID from the device are blocked. If the page
++ * table has been set, clean up the data structures.
++ */
++static void device_block_translation(struct device *dev)
++{
++ struct device_domain_info *info = dev_iommu_priv_get(dev);
++ struct intel_iommu *iommu = info->iommu;
++ unsigned long flags;
++
++ iommu_disable_dev_iotlb(info);
++ if (!dev_is_real_dma_subdevice(dev)) {
++ if (sm_supported(iommu))
++ intel_pasid_tear_down_entry(iommu, dev,
++ PASID_RID2PASID, false);
++ else
++ domain_context_clear(info);
++ }
++
++ if (!info->domain)
++ return;
++
++ spin_lock_irqsave(&info->domain->lock, flags);
++ list_del(&info->link);
++ spin_unlock_irqrestore(&info->domain->lock, flags);
++
++ domain_detach_iommu(info->domain, iommu);
++ info->domain = NULL;
++}
++
+ static int md_domain_init(struct dmar_domain *domain, int guest_width)
+ {
+ int adjust_width;
+@@ -4238,7 +4270,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+
+ if (info->domain)
+- dmar_remove_one_dev_info(dev);
++ device_block_translation(dev);
+ }
+
+ ret = prepare_domain_attach_device(domain, dev);
+--
+2.42.0
+
--- /dev/null
+From 9bca0c9bf6f44644f491b0bdf313086fc144a0fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 08:29:43 +0800
+Subject: iommu/vt-d: Allocate pasid table in device probe path
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+[ Upstream commit ec62b4424174f41bdcedd08d12d7bed80088453d ]
+
+Whether or not a domain is attached to the device, the pasid table should
+always be valid as long as it has been probed. This moves the pasid table
+allocation from the domain attaching device path to device probe path and
+frees it in the device release path.
+
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20221118132451.114406-2-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: da37dddcf4ca ("iommu/vt-d: Disable PCI ATS in legacy passthrough mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/iommu.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index bd34fcc5a5274..3dbf86c61f073 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -2494,13 +2494,6 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
+
+ /* PASID table is mandatory for a PCI device in scalable mode. */
+ if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
+- ret = intel_pasid_alloc_table(dev);
+- if (ret) {
+- dev_err(dev, "PASID table allocation failed\n");
+- dmar_remove_one_dev_info(dev);
+- return ret;
+- }
+-
+ /* Setup the PASID entry for requests without PASID: */
+ if (hw_pass_through && domain_type_is_si(domain))
+ ret = intel_pasid_setup_pass_through(iommu, domain,
+@@ -4112,7 +4105,6 @@ static void dmar_remove_one_dev_info(struct device *dev)
+
+ iommu_disable_dev_iotlb(info);
+ domain_context_clear(info);
+- intel_pasid_free_table(info->dev);
+ }
+
+ spin_lock_irqsave(&domain->lock, flags);
+@@ -4477,6 +4469,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
+ struct device_domain_info *info;
+ struct intel_iommu *iommu;
+ u8 bus, devfn;
++ int ret;
+
+ iommu = device_to_iommu(dev, &bus, &devfn);
+ if (!iommu || !iommu->iommu.ops)
+@@ -4521,6 +4514,16 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
+
+ dev_iommu_priv_set(dev, info);
+
++ if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
++ ret = intel_pasid_alloc_table(dev);
++ if (ret) {
++ dev_err(dev, "PASID table allocation failed\n");
++ dev_iommu_priv_set(dev, NULL);
++ kfree(info);
++ return ERR_PTR(ret);
++ }
++ }
++
+ return &iommu->iommu;
+ }
+
+@@ -4529,6 +4532,7 @@ static void intel_iommu_release_device(struct device *dev)
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+
+ dmar_remove_one_dev_info(dev);
++ intel_pasid_free_table(dev);
+ dev_iommu_priv_set(dev, NULL);
+ kfree(info);
+ set_dma_ops(dev, NULL);
+--
+2.42.0
+
--- /dev/null
+From c77bc80790d78b3019d3adde7f596ac088b1988c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Nov 2023 11:26:04 +0800
+Subject: iommu/vt-d: Disable PCI ATS in legacy passthrough mode
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+[ Upstream commit da37dddcf4caf015c400a930301d2ee27a7a15fb ]
+
+When IOMMU hardware operates in legacy mode, the TT field of the context
+entry determines the translation type, with three supported types (Section
+9.3 Context Entry):
+
+- DMA translation without device TLB support
+- DMA translation with device TLB support
+- Passthrough mode with translated and translation requests blocked
+
+Device TLB support is absent when hardware is configured in passthrough
+mode.
+
+Disable the PCI ATS feature when IOMMU is configured for passthrough
+translation type in legacy (non-scalable) mode.
+
+Fixes: 0faa19a1515f ("iommu/vt-d: Decouple PASID & PRI enabling from SVA")
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20231114011036.70142-3-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/iommu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index de76272d0fb02..807abf4707be7 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -2517,7 +2517,8 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
+ return ret;
+ }
+
+- iommu_enable_pci_caps(info);
++ if (sm_supported(info->iommu) || !domain_type_is_si(info->domain))
++ iommu_enable_pci_caps(info);
+
+ return 0;
+ }
+--
+2.42.0
+
--- /dev/null
+From f4ad3e82b6088edca3445daa6cae5e7b046b8b33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Nov 2023 11:26:05 +0800
+Subject: iommu/vt-d: Make context clearing consistent with context mapping
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+[ Upstream commit 9a16ab9d640274b20813d2d17475e18d3e99d834 ]
+
+In the iommu probe_device path, domain_context_mapping() allows setting
+up the context entry for a non-PCI device. However, in the iommu
+release_device path, domain_context_clear() only clears context entries
+for PCI devices.
+
+Make domain_context_clear() behave consistently with
+domain_context_mapping() by clearing context entries for both PCI and
+non-PCI devices.
+
+Fixes: 579305f75d34 ("iommu/vt-d: Update to use PCI DMA aliases")
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20231114011036.70142-4-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/iommu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index 807abf4707be7..e111b35a7aff2 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -4086,8 +4086,8 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op
+ */
+ static void domain_context_clear(struct device_domain_info *info)
+ {
+- if (!info->iommu || !info->dev || !dev_is_pci(info->dev))
+- return;
++ if (!dev_is_pci(info->dev))
++ domain_context_clear_one(info, info->bus, info->devfn);
+
+ pci_for_each_dma_alias(to_pci_dev(info->dev),
+ &domain_context_clear_one_cb, info);
+--
+2.42.0
+
--- /dev/null
+From a345a9eb682af6391e25e0a9bb9dd0b1e9440a89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Nov 2023 11:26:03 +0800
+Subject: iommu/vt-d: Omit devTLB invalidation requests when TES=0
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+[ Upstream commit 0f5432a9b839847dcfe9fa369d72e3d646102ddf ]
+
+The latest VT-d spec indicates that when remapping hardware is disabled
+(TES=0 in Global Status Register), upstream ATS Invalidation Completion
+requests are treated as UR (Unsupported Request).
+
+Consequently, the spec recommends in section 4.3 Handling of Device-TLB
+Invalidations that software refrain from submitting any Device-TLB
+invalidation requests when address remapping hardware is disabled.
+
+Verify address remapping hardware is enabled prior to submitting Device-
+TLB invalidation requests.
+
+Fixes: 792fb43ce2c9 ("iommu/vt-d: Enable Intel IOMMU scalable mode by default")
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20231114011036.70142-2-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/dmar.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
+index f800989ea0462..418af1db0192d 100644
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -1495,6 +1495,15 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+ {
+ struct qi_desc desc;
+
++ /*
++ * VT-d spec, section 4.3:
++ *
++ * Software is recommended to not submit any Device-TLB invalidation
++ * requests while address remapping hardware is disabled.
++ */
++ if (!(iommu->gcmd & DMA_GCMD_TE))
++ return;
++
+ if (mask) {
+ addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;
+ desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
+@@ -1560,6 +1569,15 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+ unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size_order - 1);
+ struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0};
+
++ /*
++ * VT-d spec, section 4.3:
++ *
++ * Software is recommended to not submit any Device-TLB invalidation
++ * requests while address remapping hardware is disabled.
++ */
++ if (!(iommu->gcmd & DMA_GCMD_TE))
++ return;
++
+ desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
+ QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE |
+ QI_DEV_IOTLB_PFSID(pfsid);
+--
+2.42.0
+
--- /dev/null
+From 8d36348ade8ed54b714e993500cc36344adc9d65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Mar 2023 23:39:55 +0100
+Subject: mmc: core: add helpers mmc_regulator_enable/disable_vqmmc
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 8d91f3f8ae57e6292142ca89f322e90fa0d6ac02 ]
+
+There's a number of drivers (e.g. dw_mmc, meson-gx, mmci, sunxi) using
+the same mechanism and a private flag vqmmc_enabled to deal with
+enabling/disabling the vqmmc regulator.
+
+Move this to the core and create new helpers mmc_regulator_enable_vqmmc
+and mmc_regulator_disable_vqmmc.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/71586432-360f-9b92-17f6-b05a8a971bc2@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 477865af60b2 ("mmc: sdhci-sprd: Fix vqmmc not shutting down after the card was pulled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/regulator.c | 41 ++++++++++++++++++++++++++++++++++++
+ include/linux/mmc/host.h | 3 +++
+ 2 files changed, 44 insertions(+)
+
+diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c
+index 609201a467ef9..4dcbc2281d2b5 100644
+--- a/drivers/mmc/core/regulator.c
++++ b/drivers/mmc/core/regulator.c
+@@ -271,3 +271,44 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
++
++/**
++ * mmc_regulator_enable_vqmmc - enable VQMMC regulator for a host
++ * @mmc: the host to regulate
++ *
++ * Returns 0 or errno. Enables the regulator for vqmmc.
++ * Keeps track of the enable status for ensuring that calls to
++ * regulator_enable/disable are balanced.
++ */
++int mmc_regulator_enable_vqmmc(struct mmc_host *mmc)
++{
++ int ret = 0;
++
++ if (!IS_ERR(mmc->supply.vqmmc) && !mmc->vqmmc_enabled) {
++ ret = regulator_enable(mmc->supply.vqmmc);
++ if (ret < 0)
++ dev_err(mmc_dev(mmc), "enabling vqmmc regulator failed\n");
++ else
++ mmc->vqmmc_enabled = true;
++ }
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(mmc_regulator_enable_vqmmc);
++
++/**
++ * mmc_regulator_disable_vqmmc - disable VQMMC regulator for a host
++ * @mmc: the host to regulate
++ *
++ * Returns 0 or errno. Disables the regulator for vqmmc.
++ * Keeps track of the enable status for ensuring that calls to
++ * regulator_enable/disable are balanced.
++ */
++void mmc_regulator_disable_vqmmc(struct mmc_host *mmc)
++{
++ if (!IS_ERR(mmc->supply.vqmmc) && mmc->vqmmc_enabled) {
++ regulator_disable(mmc->supply.vqmmc);
++ mmc->vqmmc_enabled = false;
++ }
++}
++EXPORT_SYMBOL_GPL(mmc_regulator_disable_vqmmc);
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index 8fdd3cf971a30..8f918f9a1228d 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -450,6 +450,7 @@ struct mmc_host {
+ unsigned int retune_paused:1; /* re-tuning is temporarily disabled */
+ unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */
+ unsigned int can_dma_map_merge:1; /* merging can be used */
++ unsigned int vqmmc_enabled:1; /* vqmmc regulator is enabled */
+
+ int rescan_disable; /* disable card detection */
+ int rescan_entered; /* used with nonremovable devices */
+@@ -597,6 +598,8 @@ static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc,
+ #endif
+
+ int mmc_regulator_get_supply(struct mmc_host *mmc);
++int mmc_regulator_enable_vqmmc(struct mmc_host *mmc);
++void mmc_regulator_disable_vqmmc(struct mmc_host *mmc);
+
+ static inline int mmc_card_is_removable(struct mmc_host *host)
+ {
+--
+2.42.0
+
--- /dev/null
+From 30ef2d267e0dbed29df0aff53d5842f198e9289c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Nov 2023 16:34:06 +0800
+Subject: mmc: sdhci-sprd: Fix vqmmc not shutting down after the card was
+ pulled
+
+From: Wenchao Chen <wenchao.chen@unisoc.com>
+
+[ Upstream commit 477865af60b2117ceaa1d558e03559108c15c78c ]
+
+With cat regulator_summary, we found that vqmmc was not shutting
+down after the card was pulled.
+
+cat /sys/kernel/debug/regulator/regulator_summary
+1.before fix
+1)Insert SD card
+ vddsdio 1 1 0 unknown 3500mV 0mA 1200mV 3750mV
+ 71100000.mmc-vqmmc 1 0mA 3500mV 3600mV
+
+2)Pull out the SD card
+ vddsdio 1 1 0 unknown 3500mV 0mA 1200mV 3750mV
+ 71100000.mmc-vqmmc 1 0mA 3500mV 3600mV
+
+2.after fix
+1)Insert SD cardt
+ vddsdio 1 1 0 unknown 3500mV 0mA 1200mV 3750mV
+ 71100000.mmc-vqmmc 1 0mA 3500mV 3600mV
+
+2)Pull out the SD card
+ vddsdio 0 1 0 unknown 3500mV 0mA 1200mV 3750mV
+ 71100000.mmc-vqmmc 0 0mA 3500mV 3600mV
+
+Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
+Signed-off-by: Wenchao Chen <wenchao.chen@unisoc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20231115083406.7368-1-wenchao.chen@unisoc.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-sprd.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index 525f979e2a974..2101b6e794c0e 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -405,12 +405,33 @@ static void sdhci_sprd_request_done(struct sdhci_host *host,
+ mmc_request_done(host->mmc, mrq);
+ }
+
++static void sdhci_sprd_set_power(struct sdhci_host *host, unsigned char mode,
++ unsigned short vdd)
++{
++ struct mmc_host *mmc = host->mmc;
++
++ switch (mode) {
++ case MMC_POWER_OFF:
++ mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0);
++
++ mmc_regulator_disable_vqmmc(mmc);
++ break;
++ case MMC_POWER_ON:
++ mmc_regulator_enable_vqmmc(mmc);
++ break;
++ case MMC_POWER_UP:
++ mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd);
++ break;
++ }
++}
++
+ static struct sdhci_ops sdhci_sprd_ops = {
+ .read_l = sdhci_sprd_readl,
+ .write_l = sdhci_sprd_writel,
+ .write_w = sdhci_sprd_writew,
+ .write_b = sdhci_sprd_writeb,
+ .set_clock = sdhci_sprd_set_clock,
++ .set_power = sdhci_sprd_set_power,
+ .get_max_clock = sdhci_sprd_get_max_clock,
+ .get_min_clock = sdhci_sprd_get_min_clock,
+ .set_bus_width = sdhci_set_bus_width,
+@@ -676,6 +697,10 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
+ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
+ SDHCI_SUPPORT_DDR50);
+
++ ret = mmc_regulator_get_supply(host->mmc);
++ if (ret)
++ goto pm_runtime_disable;
++
+ ret = sdhci_setup_host(host);
+ if (ret)
+ goto pm_runtime_disable;
+--
+2.42.0
+
--- /dev/null
+From 2daa2a2adcbaf45f17b14546a31f32ab9f0150f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Oct 2023 18:30:29 +0530
+Subject: PCI: qcom-ep: Add dedicated callback for writing to DBI2 registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit a07d2497ed657eb2efeb967af47e22f573dcd1d6 ]
+
+The DWC core driver exposes the write_dbi2() callback for writing to the
+DBI2 registers in a vendor-specific way.
+
+On the Qcom EP platforms, the DBI_CS2 bit in the ELBI region needs to be
+asserted before writing to any DBI2 registers and deasserted once done.
+
+So, let's implement the callback for the Qcom PCIe EP driver so that the
+DBI2 writes are correctly handled in the hardware.
+
+Without this callback, the DBI2 register writes like BAR size won't go
+through and as a result, the default BAR size is set for all BARs.
+
+[kwilczynski: commit log, renamed function to match the DWC convention]
+Fixes: f55fee56a631 ("PCI: qcom-ep: Add Qualcomm PCIe Endpoint controller driver")
+Suggested-by: Serge Semin <fancer.lancer@gmail.com>
+Link: https://lore.kernel.org/linux-pci/20231025130029.74693-2-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Cc: stable@vger.kernel.org # 5.16+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom-ep.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
+index d4c566c1c8725..1c7fd05ce0280 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
++++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
+@@ -120,6 +120,7 @@
+
+ /* ELBI registers */
+ #define ELBI_SYS_STTS 0x08
++#define ELBI_CS2_ENABLE 0xa4
+
+ /* DBI registers */
+ #define DBI_CON_STATUS 0x44
+@@ -252,6 +253,21 @@ static void qcom_pcie_dw_stop_link(struct dw_pcie *pci)
+ disable_irq(pcie_ep->perst_irq);
+ }
+
++static void qcom_pcie_dw_write_dbi2(struct dw_pcie *pci, void __iomem *base,
++ u32 reg, size_t size, u32 val)
++{
++ struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci);
++ int ret;
++
++ writel(1, pcie_ep->elbi + ELBI_CS2_ENABLE);
++
++ ret = dw_pcie_write(pci->dbi_base2 + reg, size, val);
++ if (ret)
++ dev_err(pci->dev, "Failed to write DBI2 register (0x%x): %d\n", reg, ret);
++
++ writel(0, pcie_ep->elbi + ELBI_CS2_ENABLE);
++}
++
+ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
+ {
+ int ret;
+@@ -446,6 +462,7 @@ static const struct dw_pcie_ops pci_ops = {
+ .link_up = qcom_pcie_dw_link_up,
+ .start_link = qcom_pcie_dw_start_link,
+ .stop_link = qcom_pcie_dw_stop_link,
++ .write_dbi2 = qcom_pcie_dw_write_dbi2,
+ };
+
+ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,
+--
+2.42.0
+
--- /dev/null
+From c0068db8508bb78ac8843cdb2dee689741051410 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 23:03:18 +0100
+Subject: r8169: disable ASPM in case of tx timeout
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 80c0576ef179311f624bc450fede30a89afe9792 ]
+
+There are still single reports of systems where ASPM incompatibilities
+cause tx timeouts. It's not clear whom to blame, so let's disable
+ASPM in case of a tx timeout.
+
+v2:
+- add one-time warning for informing the user
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Link: https://lore.kernel.org/r/92369a92-dc32-4529-0509-11459ba0e391@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 59d395ed606d ("r8169: fix deadlock on RTL8125 in jumbo mtu mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index d293c996252cd..7cb09ba14533c 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -576,6 +576,7 @@ struct rtl8169_tc_offsets {
+ enum rtl_flag {
+ RTL_FLAG_TASK_ENABLED = 0,
+ RTL_FLAG_TASK_RESET_PENDING,
++ RTL_FLAG_TASK_TX_TIMEOUT,
+ RTL_FLAG_MAX
+ };
+
+@@ -3943,7 +3944,7 @@ static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+- rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
++ rtl_schedule_task(tp, RTL_FLAG_TASK_TX_TIMEOUT);
+ }
+
+ static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len,
+@@ -4537,6 +4538,7 @@ static void rtl_task(struct work_struct *work)
+ {
+ struct rtl8169_private *tp =
+ container_of(work, struct rtl8169_private, wk.work);
++ int ret;
+
+ rtnl_lock();
+
+@@ -4544,7 +4546,17 @@ static void rtl_task(struct work_struct *work)
+ !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
+ goto out_unlock;
+
++ if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
++ /* ASPM compatibility issues are a typical reason for tx timeouts */
++ ret = pci_disable_link_state(tp->pci_dev, PCIE_LINK_STATE_L1 |
++ PCIE_LINK_STATE_L0S);
++ if (!ret)
++ netdev_warn_once(tp->dev, "ASPM disabled on Tx timeout\n");
++ goto reset;
++ }
++
+ if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) {
++reset:
+ rtl_reset_work(tp);
+ netif_wake_queue(tp->dev);
+ }
+--
+2.42.0
+
--- /dev/null
+From ed7cb964af5d7f9eb9e14ce8d75624756f51e2d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Nov 2023 19:36:46 +0100
+Subject: r8169: fix deadlock on RTL8125 in jumbo mtu mode
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 59d395ed606d8df14615712b0cdcdadb2d962175 ]
+
+The original change results in a deadlock if jumbo mtu mode is used.
+Reason is that the phydev lock is held when rtl_reset_work() is called
+here, and rtl_jumbo_config() calls phy_start_aneg() which also tries
+to acquire the phydev lock. Fix this by calling rtl_reset_work()
+asynchronously.
+
+Fixes: 621735f59064 ("r8169: fix rare issue with broken rx after link-down on RTL8125")
+Reported-by: Ian Chen <free122448@hotmail.com>
+Tested-by: Ian Chen <free122448@hotmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/caf6a487-ef8c-4570-88f9-f47a659faf33@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 7cb09ba14533c..abfa375b08878 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -576,6 +576,7 @@ struct rtl8169_tc_offsets {
+ enum rtl_flag {
+ RTL_FLAG_TASK_ENABLED = 0,
+ RTL_FLAG_TASK_RESET_PENDING,
++ RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE,
+ RTL_FLAG_TASK_TX_TIMEOUT,
+ RTL_FLAG_MAX
+ };
+@@ -4559,6 +4560,8 @@ static void rtl_task(struct work_struct *work)
+ reset:
+ rtl_reset_work(tp);
+ netif_wake_queue(tp->dev);
++ } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
++ rtl_reset_work(tp);
+ }
+ out_unlock:
+ rtnl_unlock();
+@@ -4592,7 +4595,7 @@ static void r8169_phylink_handler(struct net_device *ndev)
+ } else {
+ /* In few cases rx is broken after link-down otherwise */
+ if (rtl_is_8125(tp))
+- rtl_reset_work(tp);
++ rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE);
+ pm_runtime_idle(d);
+ }
+
+--
+2.42.0
+
iommu-vt-d-make-context-clearing-consistent-with-con.patch
drm-i915-call-intel_pre_plane_updates-also-for-pipes.patch
drm-amd-pm-fix-a-memleak-in-aldebaran_tables_init.patch
+pci-qcom-ep-add-dedicated-callback-for-writing-to-db.patch-19858
+fbdev-stifb-make-the-sti-next-font-pointer-a-32-bit-.patch-14283
+spi-fix-null-dereference-on-suspend.patch-13256
+drm-amd-display-restore-rptr-wptr-for-dmcub-as-worka.patch-32587
+drm-amd-display-guard-against-invalid-rptr-wptr-bein.patch-19687
+cpufreq-imx6q-don-t-warn-for-disabling-a-non-existin.patch-8216
+cpufreq-imx6q-don-t-disable-792-mhz-opp-unnecessaril.patch-9104
+iommu-vt-d-omit-devtlb-invalidation-requests-when-te.patch-10784
+iommu-vt-d-allocate-pasid-table-in-device-probe-path.patch-8635
+iommu-vt-d-add-device_block_translation-helper.patch-1231
+iommu-vt-d-disable-pci-ats-in-legacy-passthrough-mod.patch-15652
+iommu-vt-d-make-context-clearing-consistent-with-con.patch-12070
+drm-i915-call-intel_pre_plane_updates-also-for-pipes.patch-32435
+drm-amd-pm-fix-a-memleak-in-aldebaran_tables_init.patch-16085
+mmc-core-add-helpers-mmc_regulator_enable-disable_vq.patch
+mmc-sdhci-sprd-fix-vqmmc-not-shutting-down-after-the.patch
+drm-amd-display-expand-kernel-doc-for-dc.patch
+drm-amd-display-increase-num-voltage-states-to-40.patch
+drm-amd-display-clean-code-style-issues-in-dcn30_set.patch
+drm-amd-display-fix-the-delta-clamping-for-shaper-lu.patch
+drm-amd-display-fix-mpcc-1dlut-programming.patch
+r8169-disable-aspm-in-case-of-tx-timeout.patch
+r8169-fix-deadlock-on-rtl8125-in-jumbo-mtu-mode.patch
+xen-allow-platform-pci-interrupt-to-be-shared.patch
+xen-simplify-evtchn_do_upcall-call-maze.patch
+x86-xen-fix-percpu-vcpu_info-allocation.patch
--- /dev/null
+From d817e2fd7ff98ee3f819cf0c5c7f81c5da26a904 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 14:47:43 -0700
+Subject: spi: Fix null dereference on suspend
+
+From: Mark Hasemeyer <markhas@chromium.org>
+
+[ Upstream commit bef4a48f4ef798c4feddf045d49e53c8a97d5e37 ]
+
+A race condition exists where a synchronous (noqueue) transfer can be
+active during a system suspend. This can cause a null pointer
+dereference exception to occur when the system resumes.
+
+Example order of events leading to the exception:
+1. spi_sync() calls __spi_transfer_message_noqueue() which sets
+ ctlr->cur_msg
+2. Spi transfer begins via spi_transfer_one_message()
+3. System is suspended interrupting the transfer context
+4. System is resumed
+6. spi_controller_resume() calls spi_start_queue() which resets cur_msg
+ to NULL
+7. Spi transfer context resumes and spi_finalize_current_message() is
+ called which dereferences cur_msg (which is now NULL)
+
+Wait for synchronous transfers to complete before suspending by
+acquiring the bus mutex and setting/checking a suspend flag.
+
+Signed-off-by: Mark Hasemeyer <markhas@chromium.org>
+Link: https://lore.kernel.org/r/20231107144743.v1.1.I7987f05f61901f567f7661763646cb7d7919b528@changeid
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 56 ++++++++++++++++++++++++++++-------------
+ include/linux/spi/spi.h | 1 +
+ 2 files changed, 40 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 151fef199c380..5d046be8b2dd5 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -3299,33 +3299,52 @@ void spi_unregister_controller(struct spi_controller *ctlr)
+ }
+ EXPORT_SYMBOL_GPL(spi_unregister_controller);
+
++static inline int __spi_check_suspended(const struct spi_controller *ctlr)
++{
++ return ctlr->flags & SPI_CONTROLLER_SUSPENDED ? -ESHUTDOWN : 0;
++}
++
++static inline void __spi_mark_suspended(struct spi_controller *ctlr)
++{
++ mutex_lock(&ctlr->bus_lock_mutex);
++ ctlr->flags |= SPI_CONTROLLER_SUSPENDED;
++ mutex_unlock(&ctlr->bus_lock_mutex);
++}
++
++static inline void __spi_mark_resumed(struct spi_controller *ctlr)
++{
++ mutex_lock(&ctlr->bus_lock_mutex);
++ ctlr->flags &= ~SPI_CONTROLLER_SUSPENDED;
++ mutex_unlock(&ctlr->bus_lock_mutex);
++}
++
+ int spi_controller_suspend(struct spi_controller *ctlr)
+ {
+- int ret;
++ int ret = 0;
+
+ /* Basically no-ops for non-queued controllers */
+- if (!ctlr->queued)
+- return 0;
+-
+- ret = spi_stop_queue(ctlr);
+- if (ret)
+- dev_err(&ctlr->dev, "queue stop failed\n");
++ if (ctlr->queued) {
++ ret = spi_stop_queue(ctlr);
++ if (ret)
++ dev_err(&ctlr->dev, "queue stop failed\n");
++ }
+
++ __spi_mark_suspended(ctlr);
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(spi_controller_suspend);
+
+ int spi_controller_resume(struct spi_controller *ctlr)
+ {
+- int ret;
+-
+- if (!ctlr->queued)
+- return 0;
++ int ret = 0;
+
+- ret = spi_start_queue(ctlr);
+- if (ret)
+- dev_err(&ctlr->dev, "queue restart failed\n");
++ __spi_mark_resumed(ctlr);
+
++ if (ctlr->queued) {
++ ret = spi_start_queue(ctlr);
++ if (ret)
++ dev_err(&ctlr->dev, "queue restart failed\n");
++ }
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(spi_controller_resume);
+@@ -4050,8 +4069,7 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s
+ ctlr->cur_msg = msg;
+ ret = __spi_pump_transfer_message(ctlr, msg, was_busy);
+ if (ret)
+- goto out;
+-
++ dev_err(&ctlr->dev, "noqueue transfer failed\n");
+ ctlr->cur_msg = NULL;
+ ctlr->fallback = false;
+
+@@ -4067,7 +4085,6 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s
+ spi_idle_runtime_pm(ctlr);
+ }
+
+-out:
+ mutex_unlock(&ctlr->io_mutex);
+ }
+
+@@ -4090,6 +4107,11 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
+ int status;
+ struct spi_controller *ctlr = spi->controller;
+
++ if (__spi_check_suspended(ctlr)) {
++ dev_warn_once(&spi->dev, "Attempted to sync while suspend\n");
++ return -ESHUTDOWN;
++ }
++
+ status = __spi_validate(spi, message);
+ if (status != 0)
+ return status;
+diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
+index fbf8c0d95968e..877395e075afe 100644
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -531,6 +531,7 @@ struct spi_controller {
+ #define SPI_CONTROLLER_MUST_TX BIT(4) /* Requires tx */
+
+ #define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */
++#define SPI_CONTROLLER_SUSPENDED BIT(6) /* Currently suspended */
+
+ /* Flag indicating if the allocation of this struct is devres-managed */
+ bool devm_allocated;
+--
+2.42.0
+
--- /dev/null
+From e6ce0c0778365fdfea5f68195c036304f761a33b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Nov 2023 08:48:52 +0100
+Subject: x86/xen: fix percpu vcpu_info allocation
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit db2832309a82b9acc4b8cc33a1831d36507ec13e ]
+
+Today the percpu struct vcpu_info is allocated via DEFINE_PER_CPU(),
+meaning that it could cross a page boundary. In this case registering
+it with the hypervisor will fail, resulting in a panic().
+
+This can easily be fixed by using DEFINE_PER_CPU_ALIGNED() instead,
+as struct vcpu_info is guaranteed to have a size of 64 bytes, matching
+the cache line size of x86 64-bit processors (Xen doesn't support
+32-bit processors).
+
+Fixes: 5ead97c84fa7 ("xen: Core Xen implementation")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.con>
+Link: https://lore.kernel.org/r/20231124074852.25161-1-jgross@suse.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/enlighten.c | 6 +++++-
+ arch/x86/xen/xen-ops.h | 2 +-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 0337392a31214..3c61bb98c10e2 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -33,9 +33,12 @@ EXPORT_SYMBOL_GPL(hypercall_page);
+ * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info
+ * but during boot it is switched to point to xen_vcpu_info.
+ * The pointer is used in xen_evtchn_do_upcall to acknowledge pending events.
++ * Make sure that xen_vcpu_info doesn't cross a page boundary by making it
++ * cache-line aligned (the struct is guaranteed to have a size of 64 bytes,
++ * which matches the cache line size of 64-bit x86 processors).
+ */
+ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+-DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
++DEFINE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info);
+
+ /* Linux <-> Xen vCPU id mapping */
+ DEFINE_PER_CPU(uint32_t, xen_vcpu_id);
+@@ -160,6 +163,7 @@ void xen_vcpu_setup(int cpu)
+ int err;
+ struct vcpu_info *vcpup;
+
++ BUILD_BUG_ON(sizeof(*vcpup) > SMP_CACHE_BYTES);
+ BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
+
+ /*
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index a10903785a338..b2b2f4315b78d 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -21,7 +21,7 @@ extern void *xen_initial_gdt;
+ struct trap_info;
+ void xen_copy_trap_info(struct trap_info *traps);
+
+-DECLARE_PER_CPU(struct vcpu_info, xen_vcpu_info);
++DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info);
+ DECLARE_PER_CPU(unsigned long, xen_cr3);
+ DECLARE_PER_CPU(unsigned long, xen_current_cr3);
+
+--
+2.42.0
+
--- /dev/null
+From 45f06636dee425f0cc781c1865c2e73b38158f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 12:22:38 +0000
+Subject: xen: Allow platform PCI interrupt to be shared
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+[ Upstream commit 3e8cd711c3da6c3d724076048038cd666bdbb2b5 ]
+
+When we don't use the per-CPU vector callback, we ask Xen to deliver event
+channel interrupts as INTx on the PCI platform device. As such, it can be
+shared with INTx on other PCI devices.
+
+Set IRQF_SHARED, and make it return IRQ_HANDLED or IRQ_NONE according to
+whether the evtchn_upcall_pending flag was actually set. Now I can share
+the interrupt:
+
+ 11: 82 0 IO-APIC 11-fasteoi xen-platform-pci, ens4
+
+Drop the IRQF_TRIGGER_RISING. It has no effect when the IRQ is shared,
+and besides, the only effect it was having even beforehand was to trigger
+a debug message in both I/OAPIC and legacy PIC cases:
+
+[ 0.915441] genirq: No set_type function for IRQ 11 (IO-APIC)
+[ 0.951939] genirq: No set_type function for IRQ 11 (XT-PIC)
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/f9a29a68d05668a3636dd09acd94d970269eaec6.camel@infradead.org
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: db2832309a82 ("x86/xen: fix percpu vcpu_info allocation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/events/events_base.c | 9 ++++++---
+ drivers/xen/platform-pci.c | 5 ++---
+ include/xen/events.h | 2 +-
+ 3 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
+index af9115d648092..014a83d016f59 100644
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -1710,9 +1710,10 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl)
+ generic_handle_irq(irq);
+ }
+
+-static void __xen_evtchn_do_upcall(void)
++static int __xen_evtchn_do_upcall(void)
+ {
+ struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
++ int ret = vcpu_info->evtchn_upcall_pending ? IRQ_HANDLED : IRQ_NONE;
+ int cpu = smp_processor_id();
+ struct evtchn_loop_ctrl ctrl = { 0 };
+
+@@ -1744,6 +1745,8 @@ static void __xen_evtchn_do_upcall(void)
+ * above.
+ */
+ __this_cpu_inc(irq_epoch);
++
++ return ret;
+ }
+
+ void xen_evtchn_do_upcall(struct pt_regs *regs)
+@@ -1758,9 +1761,9 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
+ set_irq_regs(old_regs);
+ }
+
+-void xen_hvm_evtchn_do_upcall(void)
++int xen_hvm_evtchn_do_upcall(void)
+ {
+- __xen_evtchn_do_upcall();
++ return __xen_evtchn_do_upcall();
+ }
+ EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
+
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index cd07e3fed0faf..fcc8191315723 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -64,14 +64,13 @@ static uint64_t get_callback_via(struct pci_dev *pdev)
+
+ static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
+ {
+- xen_hvm_evtchn_do_upcall();
+- return IRQ_HANDLED;
++ return xen_hvm_evtchn_do_upcall();
+ }
+
+ static int xen_allocate_irq(struct pci_dev *pdev)
+ {
+ return request_irq(pdev->irq, do_hvm_evtchn_intr,
+- IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
++ IRQF_NOBALANCING | IRQF_SHARED,
+ "xen-platform-pci", pdev);
+ }
+
+diff --git a/include/xen/events.h b/include/xen/events.h
+index 344081e71584b..44c2855c76d1f 100644
+--- a/include/xen/events.h
++++ b/include/xen/events.h
+@@ -107,7 +107,7 @@ evtchn_port_t evtchn_from_irq(unsigned irq);
+
+ int xen_set_callback_via(uint64_t via);
+ void xen_evtchn_do_upcall(struct pt_regs *regs);
+-void xen_hvm_evtchn_do_upcall(void);
++int xen_hvm_evtchn_do_upcall(void);
+
+ /* Bind a pirq for a physical interrupt to an irq. */
+ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
+--
+2.42.0
+
--- /dev/null
+From 55208844db8d2e3a343b2a8d6b4e0da8178772b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 17:34:21 +0200
+Subject: xen: simplify evtchn_do_upcall() call maze
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 37510dd566bdbff31a769cde2fa6654bccdb8b24 ]
+
+There are several functions involved for performing the functionality
+of evtchn_do_upcall():
+
+- __xen_evtchn_do_upcall() doing the real work
+- xen_hvm_evtchn_do_upcall() just being a wrapper for
+ __xen_evtchn_do_upcall(), exposed for external callers
+- xen_evtchn_do_upcall() calling __xen_evtchn_do_upcall(), too, but
+ without any user
+
+Simplify this maze by:
+
+- removing the unused xen_evtchn_do_upcall()
+- removing xen_hvm_evtchn_do_upcall() as the only left caller of
+ __xen_evtchn_do_upcall(), while renaming __xen_evtchn_do_upcall() to
+ xen_evtchn_do_upcall()
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: db2832309a82 ("x86/xen: fix percpu vcpu_info allocation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/xen/enlighten.c | 2 +-
+ arch/x86/entry/common.c | 2 +-
+ arch/x86/xen/enlighten.c | 2 +-
+ arch/x86/xen/enlighten_hvm.c | 2 +-
+ drivers/xen/events/events_base.c | 21 ++-------------------
+ drivers/xen/platform-pci.c | 2 +-
+ include/xen/events.h | 3 +--
+ 7 files changed, 8 insertions(+), 26 deletions(-)
+
+diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
+index d12fdb9c05a89..eace3607fef41 100644
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -204,7 +204,7 @@ static void xen_power_off(void)
+
+ static irqreturn_t xen_arm_callback(int irq, void *arg)
+ {
+- xen_hvm_evtchn_do_upcall();
++ xen_evtchn_do_upcall();
+ return IRQ_HANDLED;
+ }
+
+diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
+index 6c2826417b337..93c60c0c9d4a7 100644
+--- a/arch/x86/entry/common.c
++++ b/arch/x86/entry/common.c
+@@ -294,7 +294,7 @@ static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs)
+
+ inc_irq_stat(irq_hv_callback_count);
+
+- xen_hvm_evtchn_do_upcall();
++ xen_evtchn_do_upcall();
+
+ set_irq_regs(old_regs);
+ }
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index b8db2148c07d5..0337392a31214 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(hypercall_page);
+ * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info
+ * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info
+ * but during boot it is switched to point to xen_vcpu_info.
+- * The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events.
++ * The pointer is used in xen_evtchn_do_upcall to acknowledge pending events.
+ */
+ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
+diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
+index c1cd28e915a3a..c66807dd02703 100644
+--- a/arch/x86/xen/enlighten_hvm.c
++++ b/arch/x86/xen/enlighten_hvm.c
+@@ -136,7 +136,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback)
+
+ inc_irq_stat(irq_hv_callback_count);
+
+- xen_hvm_evtchn_do_upcall();
++ xen_evtchn_do_upcall();
+
+ set_irq_regs(old_regs);
+ }
+diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
+index 014a83d016f59..00f8e349921d4 100644
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -1710,7 +1710,7 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl)
+ generic_handle_irq(irq);
+ }
+
+-static int __xen_evtchn_do_upcall(void)
++int xen_evtchn_do_upcall(void)
+ {
+ struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
+ int ret = vcpu_info->evtchn_upcall_pending ? IRQ_HANDLED : IRQ_NONE;
+@@ -1748,24 +1748,7 @@ static int __xen_evtchn_do_upcall(void)
+
+ return ret;
+ }
+-
+-void xen_evtchn_do_upcall(struct pt_regs *regs)
+-{
+- struct pt_regs *old_regs = set_irq_regs(regs);
+-
+- irq_enter();
+-
+- __xen_evtchn_do_upcall();
+-
+- irq_exit();
+- set_irq_regs(old_regs);
+-}
+-
+-int xen_hvm_evtchn_do_upcall(void)
+-{
+- return __xen_evtchn_do_upcall();
+-}
+-EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
++EXPORT_SYMBOL_GPL(xen_evtchn_do_upcall);
+
+ /* Rebind a new event channel to an existing irq. */
+ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index fcc8191315723..544d3f9010b92 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -64,7 +64,7 @@ static uint64_t get_callback_via(struct pci_dev *pdev)
+
+ static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
+ {
+- return xen_hvm_evtchn_do_upcall();
++ return xen_evtchn_do_upcall();
+ }
+
+ static int xen_allocate_irq(struct pci_dev *pdev)
+diff --git a/include/xen/events.h b/include/xen/events.h
+index 44c2855c76d1f..b303bd24e2a6c 100644
+--- a/include/xen/events.h
++++ b/include/xen/events.h
+@@ -106,8 +106,7 @@ int irq_from_virq(unsigned int cpu, unsigned int virq);
+ evtchn_port_t evtchn_from_irq(unsigned irq);
+
+ int xen_set_callback_via(uint64_t via);
+-void xen_evtchn_do_upcall(struct pt_regs *regs);
+-int xen_hvm_evtchn_do_upcall(void);
++int xen_evtchn_do_upcall(void);
+
+ /* Bind a pirq for a physical interrupt to an irq. */
+ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
+--
+2.42.0
+