--- /dev/null
+From 2923cbf8428120e8752ecf0982e36e8e17f0bd01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Oct 2021 16:33:22 +0200
+Subject: ASoC: Intel: Move soc_intel_is_foo() helpers to a generic header
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit cd45c9bf8b43cd387e167cf166ae5c517f56d658 ]
+
+The soc_intel_is_foo() helpers from
+sound/soc/intel/common/soc-intel-quirks.h are useful outside of the
+sound subsystem too.
+
+Move these to include/linux/platform_data/x86/soc.h, so that
+other code can use them too.
+
+Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20211018143324.296961-2-hdegoede@redhat.com
+Stable-dep-of: 7dd692217b86 ("ASoC: SOF: sof-pci-dev: Fix community key quirk detection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/platform_data/x86/soc.h | 65 +++++++++++++++++++++++
+ sound/soc/intel/common/soc-intel-quirks.h | 51 ++----------------
+ 2 files changed, 68 insertions(+), 48 deletions(-)
+ create mode 100644 include/linux/platform_data/x86/soc.h
+
+diff --git a/include/linux/platform_data/x86/soc.h b/include/linux/platform_data/x86/soc.h
+new file mode 100644
+index 0000000000000..da05f425587a0
+--- /dev/null
++++ b/include/linux/platform_data/x86/soc.h
+@@ -0,0 +1,65 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Helpers for Intel SoC model detection
++ *
++ * Copyright (c) 2019, Intel Corporation.
++ */
++
++#ifndef __PLATFORM_DATA_X86_SOC_H
++#define __PLATFORM_DATA_X86_SOC_H
++
++#if IS_ENABLED(CONFIG_X86)
++
++#include <asm/cpu_device_id.h>
++#include <asm/intel-family.h>
++
++#define SOC_INTEL_IS_CPU(soc, type) \
++static inline bool soc_intel_is_##soc(void) \
++{ \
++ static const struct x86_cpu_id soc##_cpu_ids[] = { \
++ X86_MATCH_INTEL_FAM6_MODEL(type, NULL), \
++ {} \
++ }; \
++ const struct x86_cpu_id *id; \
++ \
++ id = x86_match_cpu(soc##_cpu_ids); \
++ if (id) \
++ return true; \
++ return false; \
++}
++
++SOC_INTEL_IS_CPU(byt, ATOM_SILVERMONT);
++SOC_INTEL_IS_CPU(cht, ATOM_AIRMONT);
++SOC_INTEL_IS_CPU(apl, ATOM_GOLDMONT);
++SOC_INTEL_IS_CPU(glk, ATOM_GOLDMONT_PLUS);
++SOC_INTEL_IS_CPU(cml, KABYLAKE_L);
++
++#else /* IS_ENABLED(CONFIG_X86) */
++
++static inline bool soc_intel_is_byt(void)
++{
++ return false;
++}
++
++static inline bool soc_intel_is_cht(void)
++{
++ return false;
++}
++
++static inline bool soc_intel_is_apl(void)
++{
++ return false;
++}
++
++static inline bool soc_intel_is_glk(void)
++{
++ return false;
++}
++
++static inline bool soc_intel_is_cml(void)
++{
++ return false;
++}
++#endif /* IS_ENABLED(CONFIG_X86) */
++
++#endif /* __PLATFORM_DATA_X86_SOC_H */
+diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h
+index a93987ab7f4d7..de4e550c5b34d 100644
+--- a/sound/soc/intel/common/soc-intel-quirks.h
++++ b/sound/soc/intel/common/soc-intel-quirks.h
+@@ -9,34 +9,13 @@
+ #ifndef _SND_SOC_INTEL_QUIRKS_H
+ #define _SND_SOC_INTEL_QUIRKS_H
+
++#include <linux/platform_data/x86/soc.h>
++
+ #if IS_ENABLED(CONFIG_X86)
+
+ #include <linux/dmi.h>
+-#include <asm/cpu_device_id.h>
+-#include <asm/intel-family.h>
+ #include <asm/iosf_mbi.h>
+
+-#define SOC_INTEL_IS_CPU(soc, type) \
+-static inline bool soc_intel_is_##soc(void) \
+-{ \
+- static const struct x86_cpu_id soc##_cpu_ids[] = { \
+- X86_MATCH_INTEL_FAM6_MODEL(type, NULL), \
+- {} \
+- }; \
+- const struct x86_cpu_id *id; \
+- \
+- id = x86_match_cpu(soc##_cpu_ids); \
+- if (id) \
+- return true; \
+- return false; \
+-}
+-
+-SOC_INTEL_IS_CPU(byt, ATOM_SILVERMONT);
+-SOC_INTEL_IS_CPU(cht, ATOM_AIRMONT);
+-SOC_INTEL_IS_CPU(apl, ATOM_GOLDMONT);
+-SOC_INTEL_IS_CPU(glk, ATOM_GOLDMONT_PLUS);
+-SOC_INTEL_IS_CPU(cml, KABYLAKE_L);
+-
+ static inline bool soc_intel_is_byt_cr(struct platform_device *pdev)
+ {
+ /*
+@@ -114,30 +93,6 @@ static inline bool soc_intel_is_byt_cr(struct platform_device *pdev)
+ return false;
+ }
+
+-static inline bool soc_intel_is_byt(void)
+-{
+- return false;
+-}
+-
+-static inline bool soc_intel_is_cht(void)
+-{
+- return false;
+-}
+-
+-static inline bool soc_intel_is_apl(void)
+-{
+- return false;
+-}
+-
+-static inline bool soc_intel_is_glk(void)
+-{
+- return false;
+-}
+-
+-static inline bool soc_intel_is_cml(void)
+-{
+- return false;
+-}
+ #endif
+
+- #endif /* _SND_SOC_INTEL_QUIRKS_H */
++#endif /* _SND_SOC_INTEL_QUIRKS_H */
+--
+2.42.0
+
--- /dev/null
+From 4681a858c83430f29850d1da6eb86354a08df94a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 13:48:08 -0500
+Subject: ASoC: SOF: sof-pci-dev: add parameter to override topology filename
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 772627acfeb0e670ede534b7d5502dae9668d3ee ]
+
+The existing 'tplg_path' module parameter can be used to load
+alternate firmware files, be it for development or to handle
+OEM-specific or board-specific releases. However the topology filename
+is either hard-coded in machine descriptors or modified by specific
+DMI-quirks.
+
+For additional flexibility, this patch adds the 'tplg_filename' module
+parameter to override topology names.
+
+To avoid any confusion between DMI- and parameter-override, a variable
+rename is added.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Reviewed-by: Paul Olaru <paul.olaru@oss.nxp.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://lore.kernel.org/r/20220414184817.362215-7-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 7dd692217b86 ("ASoC: SOF: sof-pci-dev: Fix community key quirk detection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/sof-pci-dev.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index c1cd156996b43..6b103118cfd1b 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -27,17 +27,21 @@ static char *tplg_path;
+ module_param(tplg_path, charp, 0444);
+ MODULE_PARM_DESC(tplg_path, "alternate path for SOF topology.");
+
++static char *tplg_filename;
++module_param(tplg_filename, charp, 0444);
++MODULE_PARM_DESC(tplg_filename, "alternate filename for SOF topology.");
++
+ static int sof_pci_debug;
+ module_param_named(sof_pci_debug, sof_pci_debug, int, 0444);
+ MODULE_PARM_DESC(sof_pci_debug, "SOF PCI debug options (0x0 all off)");
+
+-static const char *sof_override_tplg_name;
++static const char *sof_dmi_override_tplg_name;
+
+ #define SOF_PCI_DISABLE_PM_RUNTIME BIT(0)
+
+ static int sof_tplg_cb(const struct dmi_system_id *id)
+ {
+- sof_override_tplg_name = id->driver_data;
++ sof_dmi_override_tplg_name = id->driver_data;
+ return 1;
+ }
+
+@@ -183,9 +187,20 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+ sof_pdata->tplg_filename_prefix =
+ sof_pdata->desc->default_tplg_path;
+
+- dmi_check_system(sof_tplg_table);
+- if (sof_override_tplg_name)
+- sof_pdata->tplg_filename = sof_override_tplg_name;
++ /*
++ * the topology filename will be provided in the machine descriptor, unless
++ * it is overridden by a module parameter or DMI quirk.
++ */
++ if (tplg_filename) {
++ sof_pdata->tplg_filename = tplg_filename;
++
++ dev_dbg(dev, "Module parameter used, changed tplg filename to %s\n",
++ sof_pdata->tplg_filename);
++ } else {
++ dmi_check_system(sof_tplg_table);
++ if (sof_dmi_override_tplg_name)
++ sof_pdata->tplg_filename = sof_dmi_override_tplg_name;
++ }
+
+ /* set callback to be called on successful device probe to enable runtime_pm */
+ sof_pdata->sof_probe_complete = sof_pci_probe_complete;
+--
+2.42.0
+
--- /dev/null
+From 3409972a3909f24c0fbb41356193bfeb5f8308a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Apr 2022 11:33:55 -0500
+Subject: ASoC: SOF: sof-pci-dev: don't use the community key on APL
+ Chromebooks
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit d81e4ba5ef1c1033b6c720b22fc99feeb71e71a0 ]
+
+As suggested by MrChromebox, the SOF driver can be used with the SOF
+firmware binary signed with the production key. This patch adds an
+additional check for the ApolloLake SoC before modifying the default
+firmware path.
+
+Note that ApolloLake Chromebooks officially ship with the Skylake
+driver, so to use SOF the users have to explicitly opt-in with
+'options intel-dspcfg dsp_driver=3'. There is no plan to change the
+default selection.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Link: https://lore.kernel.org/r/20220421163358.319489-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 7dd692217b86 ("ASoC: SOF: sof-pci-dev: Fix community key quirk detection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/sof-pci-dev.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index 6b103118cfd1b..9f0732461a611 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -12,6 +12,7 @@
+ #include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <linux/platform_data/x86/soc.h>
+ #include <linux/pm_runtime.h>
+ #include <sound/soc-acpi.h>
+ #include <sound/soc-acpi-intel-match.h>
+@@ -36,6 +37,7 @@ module_param_named(sof_pci_debug, sof_pci_debug, int, 0444);
+ MODULE_PARM_DESC(sof_pci_debug, "SOF PCI debug options (0x0 all off)");
+
+ static const char *sof_dmi_override_tplg_name;
++static bool sof_dmi_use_community_key;
+
+ #define SOF_PCI_DISABLE_PM_RUNTIME BIT(0)
+
+@@ -66,15 +68,35 @@ static const struct dmi_system_id sof_tplg_table[] = {
+ {}
+ };
+
++/* all Up boards use the community key */
++static int up_use_community_key(const struct dmi_system_id *id)
++{
++ sof_dmi_use_community_key = true;
++ return 1;
++}
++
++/*
++ * For ApolloLake Chromebooks we want to force the use of the Intel production key.
++ * All newer platforms use the community key
++ */
++static int chromebook_use_community_key(const struct dmi_system_id *id)
++{
++ if (!soc_intel_is_apl())
++ sof_dmi_use_community_key = true;
++ return 1;
++}
++
+ static const struct dmi_system_id community_key_platforms[] = {
+ {
+ .ident = "Up boards",
++ .callback = up_use_community_key,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ }
+ },
+ {
+ .ident = "Google Chromebooks",
++ .callback = chromebook_use_community_key,
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"),
+ }
+@@ -167,7 +189,7 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+ "Module parameter used, changed fw path to %s\n",
+ sof_pdata->fw_filename_prefix);
+
+- } else if (dmi_check_system(community_key_platforms)) {
++ } else if (dmi_check_system(community_key_platforms) && sof_dmi_use_community_key) {
+ sof_pdata->fw_filename_prefix =
+ devm_kasprintf(dev, GFP_KERNEL, "%s/%s",
+ sof_pdata->desc->default_fw_path,
+--
+2.42.0
+
--- /dev/null
+From 5483b479d7a82ad63a17eae085aa325b53141aef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 14:59:53 -0600
+Subject: ASoC: SOF: sof-pci-dev: Fix community key quirk detection
+
+From: Mark Hasemeyer <markhas@chromium.org>
+
+[ Upstream commit 7dd692217b861a8292ff8ac2c9d4458538fd6b96 ]
+
+Some Chromebooks do not populate the product family DMI value resulting
+in firmware load failures.
+
+Add another quirk detection entry that looks for "Google" in the BIOS
+version. Theoretically, PRODUCT_FAMILY could be replaced with
+BIOS_VERSION, but it is left as a quirk to be conservative.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mark Hasemeyer <markhas@chromium.org>
+Acked-by: Curtis Malainey <cujomalainey@chromium.org>
+Link: https://lore.kernel.org/r/20231020145953.v1.1.Iaf5702dc3f8af0fd2f81a22ba2da1a5e15b3604c@changeid
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/sof-pci-dev.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index 9f0732461a611..ec40053041e15 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -101,6 +101,13 @@ static const struct dmi_system_id community_key_platforms[] = {
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"),
+ }
+ },
++ {
++ .ident = "Google firmware",
++ .callback = chromebook_use_community_key,
++ .matches = {
++ DMI_MATCH(DMI_BIOS_VERSION, "Google"),
++ }
++ },
+ {},
+ };
+
+--
+2.42.0
+
--- /dev/null
+From 6c0c3a4b6e5988f5d4df82c904ea0b661e2d3773 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Nov 2021 17:13:27 -0600
+Subject: ASoC: SOF: sof-pci-dev: use community key on all Up boards
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 405e52f412b85b581899f5e1b82d25a7c8959d89 ]
+
+There are already 3 versions of the Up boards with support for the SOF
+community key (ApolloLake, WhiskyLake, TigerLake). Rather than
+continue to add quirks for each version, let's add a wildcard.
+
+For WHL and TGL, the authentication supports both the SOF community
+key and the firmware signed with the Intel production key. Given two
+choices, the community key is the preferred option to allow developers
+to sign their own firmware. The firmware signed with production key
+can still be selected if needed with a kernel module
+option (snd-sof-pci.fw_path="intel/sof")
+
+Tested-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://lore.kernel.org/r/20211119231327.211946-1-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 7dd692217b86 ("ASoC: SOF: sof-pci-dev: Fix community key quirk detection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/sof-pci-dev.c | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index 3b4c011e02834..c1cd156996b43 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -64,17 +64,9 @@ static const struct dmi_system_id sof_tplg_table[] = {
+
+ static const struct dmi_system_id community_key_platforms[] = {
+ {
+- .ident = "Up Squared",
++ .ident = "Up boards",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
+- DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
+- }
+- },
+- {
+- .ident = "Up Extreme",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
+- DMI_MATCH(DMI_BOARD_NAME, "UP-WHL01"),
+ }
+ },
+ {
+--
+2.42.0
+
--- /dev/null
+From 936763b2345cee656f115db5a86371f8e4d99dd6 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 37d30fa2df5fa..67f98a083d223 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 f0041e826bf3e7cd2dd219b3c2c9ac0326946ac2 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 90beb26ed34e9..37d30fa2df5fa 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 1646b97d762e54474cd127562c8be083d277e4be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Oct 2023 14:13:50 +0200
+Subject: ext4: properly sync file size update after O_SYNC direct IO
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 91562895f8030cb9a0470b1db49de79346a69f91 ]
+
+Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly
+sync file size update and thus if we crash at unfortunate moment, the
+file can have smaller size although O_SYNC IO has reported successful
+completion. The problem happens because update of on-disk inode size is
+handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus
+dio_complete() in particular) has returned and generic_file_sync() gets
+called by dio_complete(). Fix the problem by handling on-disk inode size
+update directly in our ->end_io completion handler.
+
+References: https://lore.kernel.org/all/02d18236-26ef-09b0-90ad-030c4fe3ee20@linux.alibaba.com
+Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+CC: stable@vger.kernel.org
+Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Tested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reviewed-by: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20231013121350.26872-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/file.c | 153 +++++++++++++++++++++----------------------------
+ 1 file changed, 65 insertions(+), 88 deletions(-)
+
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 4704fe627c4e2..94ce73fadcba6 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -279,80 +279,38 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
+ }
+
+ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
+- ssize_t written, size_t count)
++ ssize_t count)
+ {
+ handle_t *handle;
+- bool truncate = false;
+- u8 blkbits = inode->i_blkbits;
+- ext4_lblk_t written_blk, end_blk;
+- int ret;
+-
+- /*
+- * Note that EXT4_I(inode)->i_disksize can get extended up to
+- * inode->i_size while the I/O was running due to writeback of delalloc
+- * blocks. But, the code in ext4_iomap_alloc() is careful to use
+- * zeroed/unwritten extents if this is possible; thus we won't leave
+- * uninitialized blocks in a file even if we didn't succeed in writing
+- * as much as we intended.
+- */
+- WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize);
+- if (offset + count <= EXT4_I(inode)->i_disksize) {
+- /*
+- * We need to ensure that the inode is removed from the orphan
+- * list if it has been added prematurely, due to writeback of
+- * delalloc blocks.
+- */
+- if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
+- handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+-
+- if (IS_ERR(handle)) {
+- ext4_orphan_del(NULL, inode);
+- return PTR_ERR(handle);
+- }
+-
+- ext4_orphan_del(handle, inode);
+- ext4_journal_stop(handle);
+- }
+-
+- return written;
+- }
+-
+- if (written < 0)
+- goto truncate;
+
++ lockdep_assert_held_write(&inode->i_rwsem);
+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+- if (IS_ERR(handle)) {
+- written = PTR_ERR(handle);
+- goto truncate;
+- }
++ if (IS_ERR(handle))
++ return PTR_ERR(handle);
+
+- if (ext4_update_inode_size(inode, offset + written)) {
+- ret = ext4_mark_inode_dirty(handle, inode);
++ if (ext4_update_inode_size(inode, offset + count)) {
++ int ret = ext4_mark_inode_dirty(handle, inode);
+ if (unlikely(ret)) {
+- written = ret;
+ ext4_journal_stop(handle);
+- goto truncate;
++ return ret;
+ }
+ }
+
+- /*
+- * We may need to truncate allocated but not written blocks beyond EOF.
+- */
+- written_blk = ALIGN(offset + written, 1 << blkbits);
+- end_blk = ALIGN(offset + count, 1 << blkbits);
+- if (written_blk < end_blk && ext4_can_truncate(inode))
+- truncate = true;
+-
+- /*
+- * Remove the inode from the orphan list if it has been extended and
+- * everything went OK.
+- */
+- if (!truncate && inode->i_nlink)
++ if (inode->i_nlink)
+ ext4_orphan_del(handle, inode);
+ ext4_journal_stop(handle);
+
+- if (truncate) {
+-truncate:
++ return count;
++}
++
++/*
++ * Clean up the inode after DIO or DAX extending write has completed and the
++ * inode size has been updated using ext4_handle_inode_extension().
++ */
++static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
++{
++ lockdep_assert_held_write(&inode->i_rwsem);
++ if (count < 0) {
+ ext4_truncate_failed_write(inode);
+ /*
+ * If the truncate operation failed early, then the inode may
+@@ -361,9 +319,28 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
+ */
+ if (inode->i_nlink)
+ ext4_orphan_del(NULL, inode);
++ return;
+ }
++ /*
++ * If i_disksize got extended due to writeback of delalloc blocks while
++ * the DIO was running we could fail to cleanup the orphan list in
++ * ext4_handle_inode_extension(). Do it now.
++ */
++ if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
++ handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+
+- return written;
++ if (IS_ERR(handle)) {
++ /*
++ * The write has successfully completed. Not much to
++ * do with the error here so just cleanup the orphan
++ * list and hope for the best.
++ */
++ ext4_orphan_del(NULL, inode);
++ return;
++ }
++ ext4_orphan_del(handle, inode);
++ ext4_journal_stop(handle);
++ }
+ }
+
+ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
+@@ -372,31 +349,22 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
+ loff_t pos = iocb->ki_pos;
+ struct inode *inode = file_inode(iocb->ki_filp);
+
++ if (!error && size && flags & IOMAP_DIO_UNWRITTEN)
++ error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
+ if (error)
+ return error;
+-
+- if (size && flags & IOMAP_DIO_UNWRITTEN) {
+- error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
+- if (error < 0)
+- return error;
+- }
+ /*
+- * If we are extending the file, we have to update i_size here before
+- * page cache gets invalidated in iomap_dio_rw(). Otherwise racing
+- * buffered reads could zero out too much from page cache pages. Update
+- * of on-disk size will happen later in ext4_dio_write_iter() where
+- * we have enough information to also perform orphan list handling etc.
+- * Note that we perform all extending writes synchronously under
+- * i_rwsem held exclusively so i_size update is safe here in that case.
+- * If the write was not extending, we cannot see pos > i_size here
+- * because operations reducing i_size like truncate wait for all
+- * outstanding DIO before updating i_size.
++ * Note that EXT4_I(inode)->i_disksize can get extended up to
++ * inode->i_size while the I/O was running due to writeback of delalloc
++ * blocks. But the code in ext4_iomap_alloc() is careful to use
++ * zeroed/unwritten extents if this is possible; thus we won't leave
++ * uninitialized blocks in a file even if we didn't succeed in writing
++ * as much as we intended.
+ */
+- pos += size;
+- if (pos > i_size_read(inode))
+- i_size_write(inode, pos);
+-
+- return 0;
++ WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize));
++ if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize))
++ return size;
++ return ext4_handle_inode_extension(inode, pos, size);
+ }
+
+ static const struct iomap_dio_ops ext4_dio_write_ops = {
+@@ -572,9 +540,16 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
+ 0);
+ if (ret == -ENOTBLK)
+ ret = 0;
+-
+- if (extend)
+- ret = ext4_handle_inode_extension(inode, offset, ret, count);
++ if (extend) {
++ /*
++ * We always perform extending DIO write synchronously so by
++ * now the IO is completed and ext4_handle_inode_extension()
++ * was called. Cleanup the inode in case of error or race with
++ * writeback of delalloc blocks.
++ */
++ WARN_ON_ONCE(ret == -EIOCBQUEUED);
++ ext4_inode_extension_cleanup(inode, ret);
++ }
+
+ out:
+ if (ilock_shared)
+@@ -655,8 +630,10 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
+
+ ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops);
+
+- if (extend)
+- ret = ext4_handle_inode_extension(inode, offset, ret, count);
++ if (extend) {
++ ret = ext4_handle_inode_extension(inode, offset, ret);
++ ext4_inode_extension_cleanup(inode, ret);
++ }
+ out:
+ inode_unlock(inode);
+ if (ret > 0)
+--
+2.42.0
+
--- /dev/null
+From c539321ecbf8b8022fc8dd5eb254b548696a427b 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 102f8eb622ca6d1bf0ac754a29fcf4c9540f2aa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 14:58:10 -0400
+Subject: fs: add ctime accessors infrastructure
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 9b6304c1d53745c300b86f202d0dcff395e2d2db ]
+
+struct timespec64 has unused bits in the tv_nsec field that can be used
+for other purposes. In future patches, we're going to change how the
+inode->i_ctime is accessed in certain inodes in order to make use of
+them. In order to do that safely though, we'll need to eradicate raw
+accesses of the inode->i_ctime field from the kernel.
+
+Add new accessor functions for the ctime that we use to replace them.
+
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Message-Id: <20230705185812.579118-2-jlayton@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 5923d6686a10 ("smb3: fix caching of ctime on setxattr")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/inode.c | 16 ++++++++++++++++
+ include/linux/fs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 60 insertions(+), 1 deletion(-)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 7cb048a3b3bdb..ec41a11e2f8fe 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -2335,6 +2335,22 @@ struct timespec64 current_time(struct inode *inode)
+ }
+ EXPORT_SYMBOL(current_time);
+
++/**
++ * inode_set_ctime_current - set the ctime to current_time
++ * @inode: inode
++ *
++ * Set the inode->i_ctime to the current value for the inode. Returns
++ * the current value that was assigned to i_ctime.
++ */
++struct timespec64 inode_set_ctime_current(struct inode *inode)
++{
++ struct timespec64 now = current_time(inode);
++
++ inode_set_ctime(inode, now.tv_sec, now.tv_nsec);
++ return now;
++}
++EXPORT_SYMBOL(inode_set_ctime_current);
++
+ /**
+ * in_group_or_capable - check whether caller is CAP_FSETID privileged
+ * @mnt_userns: user namespace of the mount @inode was found from
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 6bba7a58c95c6..6f287fac0ecee 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1722,7 +1722,50 @@ static inline bool fsuidgid_has_mapping(struct super_block *sb,
+ kgid_has_mapping(fs_userns, kgid);
+ }
+
+-extern struct timespec64 current_time(struct inode *inode);
++struct timespec64 current_time(struct inode *inode);
++struct timespec64 inode_set_ctime_current(struct inode *inode);
++
++/**
++ * inode_get_ctime - fetch the current ctime from the inode
++ * @inode: inode from which to fetch ctime
++ *
++ * Grab the current ctime from the inode and return it.
++ */
++static inline struct timespec64 inode_get_ctime(const struct inode *inode)
++{
++ return inode->i_ctime;
++}
++
++/**
++ * inode_set_ctime_to_ts - set the ctime in the inode
++ * @inode: inode in which to set the ctime
++ * @ts: value to set in the ctime field
++ *
++ * Set the ctime in @inode to @ts
++ */
++static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode,
++ struct timespec64 ts)
++{
++ inode->i_ctime = ts;
++ return ts;
++}
++
++/**
++ * inode_set_ctime - set the ctime in the inode
++ * @inode: inode in which to set the ctime
++ * @sec: tv_sec value to set
++ * @nsec: tv_nsec value to set
++ *
++ * Set the ctime in @inode to { @sec, @nsec }
++ */
++static inline struct timespec64 inode_set_ctime(struct inode *inode,
++ time64_t sec, long nsec)
++{
++ struct timespec64 ts = { .tv_sec = sec,
++ .tv_nsec = nsec };
++
++ return inode_set_ctime_to_ts(inode, ts);
++}
+
+ /*
+ * Snapshotting support.
+--
+2.42.0
+
--- /dev/null
+From 155c41a0f96213a7ecc87af31f9427177e8deb5d 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 51f008398c0cc..46b2751c3f003 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -4465,8 +4465,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 14fb6de186bc26fde42e6f13e066dcad06086d2a 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 7c20083d4a798..0ad33d8d99d1f 100644
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -1518,6 +1518,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;
+@@ -1583,6 +1592,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 218a9122675a93d0d8e02c1984e309d377905c63 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 0c0c9a0fdf578..a4ec7269b6295 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -428,6 +428,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 */
+@@ -574,6 +575,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 1e1631a43e7007f1f1d641736a051cc3496f7f09 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 256260339f692..1cfc1aed44528 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -392,12 +392,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,
+@@ -663,6 +684,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 4d41b4f758a5ff3924dfcdc1dc3aa459a7e7cfda 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 84fb739679298..c640896f7b7e2 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -588,6 +588,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
+ };
+
+@@ -4029,7 +4030,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,
+@@ -4624,6 +4625,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();
+
+@@ -4631,7 +4633,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 60f79042ed7b15c39a1059d022982da853739119 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 c640896f7b7e2..d2fbd169f25b9 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -588,6 +588,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
+ };
+@@ -4646,6 +4647,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();
+@@ -4679,7 +4682,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
+
cpufreq-imx6q-don-t-disable-792-mhz-opp-unnecessaril.patch
iommu-vt-d-omit-devtlb-invalidation-requests-when-te.patch
iommu-vt-d-make-context-clearing-consistent-with-con.patch
+smb3-fix-touch-h-of-symlink.patch-27885
+asoc-intel-move-soc_intel_is_foo-helpers-to-a-generi.patch-4193
+asoc-sof-sof-pci-dev-use-community-key-on-all-up-boa.patch-6898
+asoc-sof-sof-pci-dev-add-parameter-to-override-topol.patch-4431
+asoc-sof-sof-pci-dev-don-t-use-the-community-key-on-.patch-15789
+asoc-sof-sof-pci-dev-fix-community-key-quirk-detecti.patch-6356
+fbdev-stifb-make-the-sti-next-font-pointer-a-32-bit-.patch-17578
+ext4-properly-sync-file-size-update-after-o_sync-dir.patch-12628
+fs-add-ctime-accessors-infrastructure.patch-279
+smb3-fix-caching-of-ctime-on-setxattr.patch-25511
+cpufreq-imx6q-don-t-warn-for-disabling-a-non-existin.patch-28374
+cpufreq-imx6q-don-t-disable-792-mhz-opp-unnecessaril.patch-21745
+iommu-vt-d-omit-devtlb-invalidation-requests-when-te.patch-28521
+iommu-vt-d-make-context-clearing-consistent-with-con.patch-18873
+mmc-core-add-helpers-mmc_regulator_enable-disable_vq.patch
+mmc-sdhci-sprd-fix-vqmmc-not-shutting-down-after-the.patch
+r8169-disable-aspm-in-case-of-tx-timeout.patch
+r8169-fix-deadlock-on-rtl8125-in-jumbo-mtu-mode.patch
--- /dev/null
+From 093384d22a09f364bccddcf1ada2ac154087db60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 21:38:13 -0600
+Subject: smb3: fix caching of ctime on setxattr
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 5923d6686a100c2b4cabd4c2ca9d5a12579c7614 ]
+
+Fixes xfstest generic/728 which had been failing due to incorrect
+ctime after setxattr and removexattr
+
+Update ctime on successful set of xattr
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/xattr.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
+index 9d486fbbfbbde..6f719b9cf9e9e 100644
+--- a/fs/cifs/xattr.c
++++ b/fs/cifs/xattr.c
+@@ -150,10 +150,13 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+ goto out;
+
+- if (pTcon->ses->server->ops->set_EA)
++ if (pTcon->ses->server->ops->set_EA) {
+ rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
+ full_path, name, value, (__u16)size,
+ cifs_sb->local_nls, cifs_sb);
++ if (rc == 0)
++ inode_set_ctime_current(inode);
++ }
+ break;
+
+ case XATTR_CIFS_ACL:
+--
+2.42.0
+
--- /dev/null
+From 606596ae10df37697930a0e646cadc15eaa44ef7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Oct 2023 12:18:23 -0500
+Subject: smb3: fix touch -h of symlink
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 475efd9808a3094944a56240b2711349e433fb66 ]
+
+For example:
+ touch -h -t 02011200 testfile
+where testfile is a symlink would not change the timestamp, but
+ touch -t 02011200 testfile
+does work to change the timestamp of the target
+
+Suggested-by: David Howells <dhowells@redhat.com>
+Reported-by: Micah Veilleux <micah.veilleux@iba-group.com>
+Closes: https://bugzilla.samba.org/show_bug.cgi?id=14476
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifsfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index b5ae209539ff1..af688e39f31ac 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1127,6 +1127,7 @@ const struct inode_operations cifs_file_inode_ops = {
+
+ const struct inode_operations cifs_symlink_inode_ops = {
+ .get_link = cifs_get_link,
++ .setattr = cifs_setattr,
+ .permission = cifs_permission,
+ .listxattr = cifs_listxattr,
+ };
+--
+2.42.0
+