]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Tue, 10 Sep 2024 00:36:19 +0000 (20:36 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 10 Sep 2024 00:36:19 +0000 (20:36 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
37 files changed:
queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch [new file with mode: 0644]
queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch [new file with mode: 0644]
queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch [new file with mode: 0644]
queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch [new file with mode: 0644]
queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch [new file with mode: 0644]
queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch [new file with mode: 0644]
queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch [new file with mode: 0644]
queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch [new file with mode: 0644]
queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch [new file with mode: 0644]
queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch [new file with mode: 0644]
queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch [new file with mode: 0644]
queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch [new file with mode: 0644]
queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch [new file with mode: 0644]
queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch [new file with mode: 0644]
queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch [new file with mode: 0644]
queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch [new file with mode: 0644]
queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch [new file with mode: 0644]
queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch [new file with mode: 0644]
queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch [new file with mode: 0644]
queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch [new file with mode: 0644]
queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch [new file with mode: 0644]
queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch [new file with mode: 0644]
queue-6.6/gpio-modepin-enable-module-autoloading.patch [new file with mode: 0644]
queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch [new file with mode: 0644]
queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch [new file with mode: 0644]
queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch [new file with mode: 0644]
queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch [new file with mode: 0644]
queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch [new file with mode: 0644]
queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch [new file with mode: 0644]
queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch [new file with mode: 0644]
queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch [new file with mode: 0644]
queue-6.6/riscv-fix-toolchain-vector-detection.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch [new file with mode: 0644]
queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch [new file with mode: 0644]
queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch [new file with mode: 0644]
queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch [new file with mode: 0644]

diff --git a/queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch b/queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch
new file mode 100644 (file)
index 0000000..dba1f80
--- /dev/null
@@ -0,0 +1,83 @@
+From 8476f48348420777ebd36484841bc8158bce1630 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 14:34:32 +0100
+Subject: ACPI: processor: Fix memory leaks in error paths of processor_add()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 47ec9b417ed9b6b8ec2a941cd84d9de62adc358a ]
+
+If acpi_processor_get_info() returned an error, pr and the associated
+pr->throttling.shared_cpu_map were leaked.
+
+The unwind code was in the wrong order wrt to setup, relying on
+some unwind actions having no affect (clearing variables that were
+never set etc).  That makes it harder to reason about so reorder
+and add appropriate labels to only undo what was actually set up
+in the first place.
+
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/20240529133446.28446-6-Jonathan.Cameron@huawei.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpi_processor.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
+index 5f760bc62219..7053f1b9fc1d 100644
+--- a/drivers/acpi/acpi_processor.c
++++ b/drivers/acpi/acpi_processor.c
+@@ -415,7 +415,7 @@ static int acpi_processor_add(struct acpi_device *device,
+       result = acpi_processor_get_info(device);
+       if (result) /* Processor is not physically present or unavailable */
+-              return result;
++              goto err_clear_driver_data;
+       BUG_ON(pr->id >= nr_cpu_ids);
+@@ -430,7 +430,7 @@ static int acpi_processor_add(struct acpi_device *device,
+                       "BIOS reported wrong ACPI id %d for the processor\n",
+                       pr->id);
+               /* Give up, but do not abort the namespace scan. */
+-              goto err;
++              goto err_clear_driver_data;
+       }
+       /*
+        * processor_device_array is not cleared on errors to allow buggy BIOS
+@@ -442,12 +442,12 @@ static int acpi_processor_add(struct acpi_device *device,
+       dev = get_cpu_device(pr->id);
+       if (!dev) {
+               result = -ENODEV;
+-              goto err;
++              goto err_clear_per_cpu;
+       }
+       result = acpi_bind_one(dev, device);
+       if (result)
+-              goto err;
++              goto err_clear_per_cpu;
+       pr->dev = dev;
+@@ -458,10 +458,11 @@ static int acpi_processor_add(struct acpi_device *device,
+       dev_err(dev, "Processor driver could not be attached\n");
+       acpi_unbind_one(dev);
+- err:
+-      free_cpumask_var(pr->throttling.shared_cpu_map);
+-      device->driver_data = NULL;
++ err_clear_per_cpu:
+       per_cpu(processors, pr->id) = NULL;
++ err_clear_driver_data:
++      device->driver_data = NULL;
++      free_cpumask_var(pr->throttling.shared_cpu_map);
+  err_free_pr:
+       kfree(pr);
+       return result;
+-- 
+2.43.0
+
diff --git a/queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch b/queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch
new file mode 100644 (file)
index 0000000..89921e6
--- /dev/null
@@ -0,0 +1,44 @@
+From fecad7e9f49b78c919c6dee9dc7841cb6cc32b9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 14:34:31 +0100
+Subject: ACPI: processor: Return an error if acpi_processor_get_info() fails
+ in processor_add()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit fadf231f0a06a6748a7fc4a2c29ac9ef7bca6bfd ]
+
+Rafael observed [1] that returning 0 from processor_add() will result in
+acpi_default_enumeration() being called which will attempt to create a
+platform device, but that makes little sense when the processor is known
+to be not available.  So just return the error code from acpi_processor_get_info()
+instead.
+
+Link: https://lore.kernel.org/all/CAJZ5v0iKU8ra9jR+EmgxbuNm=Uwx2m1-8vn_RAZ+aCiUVLe3Pw@mail.gmail.com/ [1]
+Suggested-by: Rafael J. Wysocki <rafael@kernel.org>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/20240529133446.28446-5-Jonathan.Cameron@huawei.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpi_processor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
+index 0f5218e361df..5f760bc62219 100644
+--- a/drivers/acpi/acpi_processor.c
++++ b/drivers/acpi/acpi_processor.c
+@@ -415,7 +415,7 @@ static int acpi_processor_add(struct acpi_device *device,
+       result = acpi_processor_get_info(device);
+       if (result) /* Processor is not physically present or unavailable */
+-              return 0;
++              return result;
+       BUG_ON(pr->id >= nr_cpu_ids);
+-- 
+2.43.0
+
diff --git a/queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch b/queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch
new file mode 100644 (file)
index 0000000..d306c83
--- /dev/null
@@ -0,0 +1,46 @@
+From 56e68fd0af2a34acf6517b9d4d820442c614f7b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 14:34:39 +0100
+Subject: arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 2488444274c70038eb6b686cba5f1ce48ebb9cdd ]
+
+In a review discussion of the changes to support vCPU hotplug where
+a check was added on the GICC being enabled if was online, it was
+noted that there is need to map back to the cpu and use that to index
+into a cpumask. As such, a valid ID is needed.
+
+If an MPIDR check fails in acpi_map_gic_cpu_interface() it is possible
+for the entry in cpu_madt_gicc[cpu] == NULL.  This function would
+then cause a NULL pointer dereference.   Whilst a path to trigger
+this has not been established, harden this caller against the
+possibility.
+
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/20240529133446.28446-13-Jonathan.Cameron@huawei.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/acpi.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
+index bc9a6656fc0c..a407f9cd549e 100644
+--- a/arch/arm64/include/asm/acpi.h
++++ b/arch/arm64/include/asm/acpi.h
+@@ -124,7 +124,8 @@ static inline int get_cpu_for_acpi_id(u32 uid)
+       int cpu;
+       for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+-              if (uid == get_acpi_id_for_cpu(cpu))
++              if (acpi_cpu_get_madt_gicc(cpu) &&
++                  uid == get_acpi_id_for_cpu(cpu))
+                       return cpu;
+       return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch b/queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch
new file mode 100644 (file)
index 0000000..e1791e2
--- /dev/null
@@ -0,0 +1,82 @@
+From b72e13006aa037d1439d3f90c362413d58d694fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 14:34:38 +0100
+Subject: arm64: acpi: Move get_cpu_for_acpi_id() to a header
+
+From: James Morse <james.morse@arm.com>
+
+[ Upstream commit 8d34b6f17b9ac93faa2791eb037dcb08bdf755de ]
+
+ACPI identifies CPUs by UID. get_cpu_for_acpi_id() maps the ACPI UID
+to the Linux CPU number.
+
+The helper to retrieve this mapping is only available in arm64's NUMA
+code.
+
+Move it to live next to get_acpi_id_for_cpu().
+
+Signed-off-by: James Morse <james.morse@arm.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Tested-by: Miguel Luis <miguel.luis@oracle.com>
+Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
+Tested-by: Jianyong Wu <jianyong.wu@arm.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Acked-by: Hanjun Guo <guohanjun@huawei.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Link: https://lore.kernel.org/r/20240529133446.28446-12-Jonathan.Cameron@huawei.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/acpi.h | 11 +++++++++++
+ arch/arm64/kernel/acpi_numa.c | 11 -----------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
+index 6792a1f83f2a..bc9a6656fc0c 100644
+--- a/arch/arm64/include/asm/acpi.h
++++ b/arch/arm64/include/asm/acpi.h
+@@ -119,6 +119,17 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
+       return  acpi_cpu_get_madt_gicc(cpu)->uid;
+ }
++static inline int get_cpu_for_acpi_id(u32 uid)
++{
++      int cpu;
++
++      for (cpu = 0; cpu < nr_cpu_ids; cpu++)
++              if (uid == get_acpi_id_for_cpu(cpu))
++                      return cpu;
++
++      return -EINVAL;
++}
++
+ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
+ void __init acpi_init_cpus(void);
+ int apei_claim_sea(struct pt_regs *regs);
+diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
+index ccbff21ce1fa..2465f291c7e1 100644
+--- a/arch/arm64/kernel/acpi_numa.c
++++ b/arch/arm64/kernel/acpi_numa.c
+@@ -34,17 +34,6 @@ int __init acpi_numa_get_nid(unsigned int cpu)
+       return acpi_early_node_map[cpu];
+ }
+-static inline int get_cpu_for_acpi_id(u32 uid)
+-{
+-      int cpu;
+-
+-      for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+-              if (uid == get_acpi_id_for_cpu(cpu))
+-                      return cpu;
+-
+-      return -EINVAL;
+-}
+-
+ static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header,
+                                     const unsigned long end)
+ {
+-- 
+2.43.0
+
diff --git a/queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch b/queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch
new file mode 100644 (file)
index 0000000..e3fe45a
--- /dev/null
@@ -0,0 +1,47 @@
+From c963aa883ea3a8cf7425e1b24617ee12f2f60132 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 12:10:04 +0800
+Subject: ASoc: SOF: topology: Clear SOF link platform name upon unload
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit e0be875c5bf03a9676a6bfed9e0f1766922a7dbd ]
+
+The SOF topology loading function sets the device name for the platform
+component link. This should be unset when unloading the topology,
+otherwise a machine driver unbind/bind or reprobe would complain about
+an invalid component as having both its component name and of_node set:
+
+    mt8186_mt6366 sound: ASoC: Both Component name/of_node are set for AFE_SOF_DL1
+    mt8186_mt6366 sound: error -EINVAL: Cannot register card
+    mt8186_mt6366 sound: probe with driver mt8186_mt6366 failed with error -22
+
+This happens with machine drivers that set the of_node separately.
+
+Clear the SOF link platform name in the topology unload callback.
+
+Fixes: 311ce4fe7637 ("ASoC: SOF: Add support for loading topologies")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://patch.msgid.link/20240821041006.2618855-1-wenst@chromium.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/topology.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
+index 7133ec13322b..cf1e63daad86 100644
+--- a/sound/soc/sof/topology.c
++++ b/sound/soc/sof/topology.c
+@@ -2040,6 +2040,8 @@ static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj
+       if (!slink)
+               return 0;
++      slink->link->platforms->name = NULL;
++
+       kfree(slink->tuples);
+       list_del(&slink->list);
+       kfree(slink->hw_configs);
+-- 
+2.43.0
+
diff --git a/queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch b/queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch
new file mode 100644 (file)
index 0000000..077e9d7
--- /dev/null
@@ -0,0 +1,272 @@
+From b065b7523b2dda0d6d9c1424888d4f6c0325719b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 14:07:19 +0200
+Subject: ASoC: sunxi: sun4i-i2s: fix LRCLK polarity in i2s mode
+
+From: Matteo Martelli <matteomartelli3@gmail.com>
+
+[ Upstream commit 3e83957e8dd7433a69116780d9bad217b00913ea ]
+
+This fixes the LRCLK polarity for sun8i-h3 and sun50i-h6 in i2s mode
+which was wrongly inverted.
+
+The LRCLK was being set in reversed logic compared to the DAI format:
+inverted LRCLK for SND_SOC_DAIFMT_IB_NF and SND_SOC_DAIFMT_NB_NF; normal
+LRCLK for SND_SOC_DAIFMT_IB_IF and SND_SOC_DAIFMT_NB_IF. Such reversed
+logic applies properly for DSP_A, DSP_B, LEFT_J and RIGHT_J modes but
+not for I2S mode, for which the LRCLK signal results reversed to what
+expected on the bus. The issue is due to a misinterpretation of the
+LRCLK polarity bit of the H3 and H6 i2s controllers. Such bit in this
+case does not mean "0 => normal" or "1 => inverted" according to the
+expected bus operation, but it means "0 => frame starts on low edge" and
+"1 => frame starts on high edge" (from the User Manuals).
+
+This commit fixes the LRCLK polarity by setting the LRCLK polarity bit
+according to the selected bus mode and renames the LRCLK polarity bit
+definition to avoid further confusion.
+
+Fixes: dd657eae8164 ("ASoC: sun4i-i2s: Fix the LRCK polarity")
+Fixes: 73adf87b7a58 ("ASoC: sun4i-i2s: Add support for H6 I2S")
+Signed-off-by: Matteo Martelli <matteomartelli3@gmail.com>
+Link: https://patch.msgid.link/20240801-asoc-fix-sun4i-i2s-v2-1-a8e4e9daa363@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sunxi/sun4i-i2s.c | 143 ++++++++++++++++++------------------
+ 1 file changed, 73 insertions(+), 70 deletions(-)
+
+diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
+index 5124b6c9ceb4..d1cb49d54f00 100644
+--- a/sound/soc/sunxi/sun4i-i2s.c
++++ b/sound/soc/sunxi/sun4i-i2s.c
+@@ -100,8 +100,8 @@
+ #define SUN8I_I2S_CTRL_MODE_PCM                       (0 << 4)
+ #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK    BIT(19)
+-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED                (1 << 19)
+-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL          (0 << 19)
++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH      (1 << 19)
++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW               (0 << 19)
+ #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK               GENMASK(17, 8)
+ #define SUN8I_I2S_FMT0_LRCK_PERIOD(period)    ((period - 1) << 8)
+ #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK     BIT(7)
+@@ -727,65 +727,37 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+                                unsigned int fmt)
+ {
+-      u32 mode, val;
++      u32 mode, lrclk_pol, bclk_pol, val;
+       u8 offset;
+-      /*
+-       * DAI clock polarity
+-       *
+-       * The setup for LRCK contradicts the datasheet, but under a
+-       * scope it's clear that the LRCK polarity is reversed
+-       * compared to the expected polarity on the bus.
+-       */
+-      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+-      case SND_SOC_DAIFMT_IB_IF:
+-              /* Invert both clocks */
+-              val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
+-              break;
+-      case SND_SOC_DAIFMT_IB_NF:
+-              /* Invert bit clock */
+-              val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
+-                    SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
+-              break;
+-      case SND_SOC_DAIFMT_NB_IF:
+-              /* Invert frame clock */
+-              val = 0;
+-              break;
+-      case SND_SOC_DAIFMT_NB_NF:
+-              val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
+-                         SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
+-                         SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
+-                         val);
+-
+       /* DAI Mode */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_DSP_A:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_PCM;
+               offset = 1;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_PCM;
+               offset = 0;
+               break;
+       case SND_SOC_DAIFMT_I2S:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW;
+               mode = SUN8I_I2S_CTRL_MODE_LEFT;
+               offset = 1;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_LEFT;
+               offset = 0;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_RIGHT;
+               offset = 0;
+               break;
+@@ -803,6 +775,35 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+                          SUN8I_I2S_TX_CHAN_OFFSET_MASK,
+                          SUN8I_I2S_TX_CHAN_OFFSET(offset));
++      /* DAI clock polarity */
++      bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL;
++
++      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++      case SND_SOC_DAIFMT_IB_IF:
++              /* Invert both clocks */
++              lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
++              bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
++              break;
++      case SND_SOC_DAIFMT_IB_NF:
++              /* Invert bit clock */
++              bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
++              break;
++      case SND_SOC_DAIFMT_NB_IF:
++              /* Invert frame clock */
++              lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
++              break;
++      case SND_SOC_DAIFMT_NB_NF:
++              /* No inversion */
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
++                         SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
++                         SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
++                         lrclk_pol | bclk_pol);
++
+       /* DAI clock master masks */
+       switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+       case SND_SOC_DAIFMT_BP_FP:
+@@ -834,65 +835,37 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+                                    unsigned int fmt)
+ {
+-      u32 mode, val;
++      u32 mode, lrclk_pol, bclk_pol, val;
+       u8 offset;
+-      /*
+-       * DAI clock polarity
+-       *
+-       * The setup for LRCK contradicts the datasheet, but under a
+-       * scope it's clear that the LRCK polarity is reversed
+-       * compared to the expected polarity on the bus.
+-       */
+-      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+-      case SND_SOC_DAIFMT_IB_IF:
+-              /* Invert both clocks */
+-              val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
+-              break;
+-      case SND_SOC_DAIFMT_IB_NF:
+-              /* Invert bit clock */
+-              val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
+-                    SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
+-              break;
+-      case SND_SOC_DAIFMT_NB_IF:
+-              /* Invert frame clock */
+-              val = 0;
+-              break;
+-      case SND_SOC_DAIFMT_NB_NF:
+-              val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
+-                         SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
+-                         SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
+-                         val);
+-
+       /* DAI Mode */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_DSP_A:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_PCM;
+               offset = 1;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_PCM;
+               offset = 0;
+               break;
+       case SND_SOC_DAIFMT_I2S:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW;
+               mode = SUN8I_I2S_CTRL_MODE_LEFT;
+               offset = 1;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_LEFT;
+               offset = 0;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
++              lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
+               mode = SUN8I_I2S_CTRL_MODE_RIGHT;
+               offset = 0;
+               break;
+@@ -910,6 +883,36 @@ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+                          SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
+                          SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
++      /* DAI clock polarity */
++      bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL;
++
++      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++      case SND_SOC_DAIFMT_IB_IF:
++              /* Invert both clocks */
++              lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
++              bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
++              break;
++      case SND_SOC_DAIFMT_IB_NF:
++              /* Invert bit clock */
++              bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
++              break;
++      case SND_SOC_DAIFMT_NB_IF:
++              /* Invert frame clock */
++              lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
++              break;
++      case SND_SOC_DAIFMT_NB_NF:
++              /* No inversion */
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
++                         SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
++                         SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
++                         lrclk_pol | bclk_pol);
++
++
+       /* DAI clock master masks */
+       switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+       case SND_SOC_DAIFMT_BP_FP:
+-- 
+2.43.0
+
diff --git a/queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch b/queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch
new file mode 100644 (file)
index 0000000..e7f1b11
--- /dev/null
@@ -0,0 +1,92 @@
+From 4c12d6162b46478dab68654f8d458044f8e7722d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 14:43:42 +0000
+Subject: ASoC: tegra: Fix CBB error during probe()
+
+From: Mohan Kumar <mkumard@nvidia.com>
+
+[ Upstream commit 6781b962d97bc52715a8db8cc17278cc3c23ebe8 ]
+
+When Tegra audio drivers are built as part of the kernel image,
+TIMEOUT_ERR is observed from cbb-fabric. Following is seen on
+Jetson AGX Orin during boot:
+
+[    8.012482] **************************************
+[    8.017423] CPU:0, Error:cbb-fabric, Errmon:2
+[    8.021922]    Error Code            : TIMEOUT_ERR
+[    8.025966]    Overflow              : Multiple TIMEOUT_ERR
+[    8.030644]
+[    8.032175]    Error Code            : TIMEOUT_ERR
+[    8.036217]    MASTER_ID             : CCPLEX
+[    8.039722]    Address               : 0x290a0a8
+[    8.043318]    Cache                 : 0x1 -- Bufferable
+[    8.047630]    Protection            : 0x2 -- Unprivileged, Non-Secure, Data Access
+[    8.054628]    Access_Type           : Write
+
+[    8.106130] WARNING: CPU: 0 PID: 124 at drivers/soc/tegra/cbb/tegra234-cbb.c:604 tegra234_cbb_isr+0x134/0x178
+
+[    8.240602] Call trace:
+[    8.243126]  tegra234_cbb_isr+0x134/0x178
+[    8.247261]  __handle_irq_event_percpu+0x60/0x238
+[    8.252132]  handle_irq_event+0x54/0xb8
+
+These errors happen when MVC device, which is a child of AHUB
+device, tries to access its device registers. This happens as
+part of call tegra210_mvc_reset_vol_settings() in MVC device
+probe().
+
+The root cause of this problem is, the child MVC device gets
+probed before the AHUB clock gets enabled. The AHUB clock is
+enabled in runtime PM resume of parent AHUB device and due to
+the wrong sequence of pm_runtime_enable() in AHUB driver,
+runtime PM resume doesn't happen for AHUB device when MVC makes
+register access.
+
+Fix this by calling pm_runtime_enable() for parent AHUB device
+before of_platform_populate() in AHUB driver. This ensures that
+clock becomes available when MVC makes register access.
+
+Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver")
+Signed-off-by: Mohan Kumar <mkumard@nvidia.com>
+Signed-off-by: Ritu Chaudhary <rituc@nvidia.com>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Link: https://patch.msgid.link/20240823144342.4123814-3-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/tegra/tegra210_ahub.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
+index 3f114a2adfce..ab3c6b2544d2 100644
+--- a/sound/soc/tegra/tegra210_ahub.c
++++ b/sound/soc/tegra/tegra210_ahub.c
+@@ -2,7 +2,7 @@
+ //
+ // tegra210_ahub.c - Tegra210 AHUB driver
+ //
+-// Copyright (c) 2020-2022, NVIDIA CORPORATION.  All rights reserved.
++// Copyright (c) 2020-2024, NVIDIA CORPORATION.  All rights reserved.
+ #include <linux/clk.h>
+ #include <linux/device.h>
+@@ -1391,11 +1391,13 @@ static int tegra_ahub_probe(struct platform_device *pdev)
+               return err;
+       }
++      pm_runtime_enable(&pdev->dev);
++
+       err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+-      if (err)
++      if (err) {
++              pm_runtime_disable(&pdev->dev);
+               return err;
+-
+-      pm_runtime_enable(&pdev->dev);
++      }
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch b/queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch
new file mode 100644 (file)
index 0000000..ffd8bda
--- /dev/null
@@ -0,0 +1,81 @@
+From d7b1d425d26e98eaa851318c5deabd4806c5d59a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 02:47:35 +0000
+Subject: ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf
+
+From: Igor Pylypiv <ipylypiv@google.com>
+
+[ Upstream commit 816be86c7993d3c5832c3017c0056297e86f978c ]
+
+qc->result_tf contents are only valid when the ATA_QCFLAG_RTF_FILLED flag
+is set. The ATA_QCFLAG_RTF_FILLED flag should be always set for commands
+that failed or for commands that have the ATA_QCFLAG_RESULT_TF flag set.
+
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Igor Pylypiv <ipylypiv@google.com>
+Link: https://lore.kernel.org/r/20240702024735.1152293-8-ipylypiv@google.com
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-scsi.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 27e0c87236ac..c91f8746289f 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -242,10 +242,17 @@ void ata_scsi_set_sense_information(struct ata_device *dev,
+  */
+ static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc)
+ {
++      struct ata_device *dev = qc->dev;
+       struct scsi_cmnd *cmd = qc->scsicmd;
+       struct ata_taskfile *tf = &qc->result_tf;
+       unsigned char *sb = cmd->sense_buffer;
++      if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
++              ata_dev_dbg(dev,
++                          "missing result TF: can't set ATA PT sense fields\n");
++              return;
++      }
++
+       if ((sb[0] & 0x7f) >= 0x72) {
+               unsigned char *desc;
+               u8 len;
+@@ -924,10 +931,17 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
+  */
+ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
+ {
++      struct ata_device *dev = qc->dev;
+       struct scsi_cmnd *cmd = qc->scsicmd;
+       struct ata_taskfile *tf = &qc->result_tf;
+       u8 sense_key, asc, ascq;
++      if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
++              ata_dev_dbg(dev,
++                          "missing result TF: can't generate ATA PT sense data\n");
++              return;
++      }
++
+       /*
+        * Use ata_to_sense_error() to map status register bits
+        * onto sense key, asc & ascq.
+@@ -979,6 +993,13 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
+               ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21);
+               return;
+       }
++
++      if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
++              ata_dev_dbg(dev,
++                          "missing result TF: can't generate sense data\n");
++              return;
++      }
++
+       /* Use ata_to_sense_error() to map status register bits
+        * onto sense key, asc & ascq.
+        */
+-- 
+2.43.0
+
diff --git a/queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch b/queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch
new file mode 100644 (file)
index 0000000..3629c5b
--- /dev/null
@@ -0,0 +1,51 @@
+From 0ba8d14a4da3911cc47823206f101e74af2b89d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 02:47:32 +0000
+Subject: ata: libata-scsi: Remove redundant sense_buffer memsets
+
+From: Igor Pylypiv <ipylypiv@google.com>
+
+[ Upstream commit 3f6d903b54a137e9e438d9c3b774b5d0432917bc ]
+
+SCSI layer clears sense_buffer in scsi_queue_rq() so there is no need for
+libata to clear it again.
+
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Igor Pylypiv <ipylypiv@google.com>
+Link: https://lore.kernel.org/r/20240702024735.1152293-5-ipylypiv@google.com
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-scsi.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 277bf0e8ed09..27e0c87236ac 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -926,11 +926,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
+ {
+       struct scsi_cmnd *cmd = qc->scsicmd;
+       struct ata_taskfile *tf = &qc->result_tf;
+-      unsigned char *sb = cmd->sense_buffer;
+       u8 sense_key, asc, ascq;
+-      memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+-
+       /*
+        * Use ata_to_sense_error() to map status register bits
+        * onto sense key, asc & ascq.
+@@ -976,8 +973,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
+       u64 block;
+       u8 sense_key, asc, ascq;
+-      memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+-
+       if (ata_dev_disabled(dev)) {
+               /* Device disabled after error recovery */
+               /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
+-- 
+2.43.0
+
diff --git a/queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch b/queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch
new file mode 100644 (file)
index 0000000..948ec6a
--- /dev/null
@@ -0,0 +1,296 @@
+From 0a789d4e09b508b6cd10847e720d149b985c5f24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 11:48:16 +0100
+Subject: can: mcp251xfd: clarify the meaning of timestamp
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit e793c724b48ca8cae9693bc3be528e85284c126a ]
+
+The mcp251xfd chip is configured to provide a timestamp with each
+received and transmitted CAN frame. The timestamp is derived from the
+internal free-running timer, which can also be read from the TBC
+register via SPI. The timer is 32 bits wide and is clocked by the
+external oscillator (typically 20 or 40 MHz).
+
+To avoid confusion, we call this timestamp "timestamp_raw" or "ts_raw"
+for short.
+
+Using the timecounter framework, the "ts_raw" is converted to 64 bit
+nanoseconds since the epoch. This is what we call "timestamp".
+
+This is a preparation for the next patches which use the "timestamp"
+to work around a bug where so far only the "ts_raw" is used.
+
+Tested-by: Stefan Althöfer <Stefan.Althoefer@janztec.com>
+Tested-by: Thomas Kopp <thomas.kopp@microchip.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/spi/mcp251xfd/mcp251xfd-core.c    | 28 +++++++++----------
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c  |  2 +-
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c |  2 +-
+ .../can/spi/mcp251xfd/mcp251xfd-timestamp.c   | 22 ++++-----------
+ drivers/net/can/spi/mcp251xfd/mcp251xfd.h     | 27 ++++++++++++++----
+ 5 files changed, 43 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+index 1665f78abb5c..a9bafa96e2f9 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+@@ -2,7 +2,7 @@
+ //
+ // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
+ //
+-// Copyright (c) 2019, 2020, 2021 Pengutronix,
++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
+ //               Marc Kleine-Budde <kernel@pengutronix.de>
+ //
+ // Based on:
+@@ -867,18 +867,18 @@ static int mcp251xfd_get_berr_counter(const struct net_device *ndev,
+ static struct sk_buff *
+ mcp251xfd_alloc_can_err_skb(struct mcp251xfd_priv *priv,
+-                          struct can_frame **cf, u32 *timestamp)
++                          struct can_frame **cf, u32 *ts_raw)
+ {
+       struct sk_buff *skb;
+       int err;
+-      err = mcp251xfd_get_timestamp(priv, timestamp);
++      err = mcp251xfd_get_timestamp_raw(priv, ts_raw);
+       if (err)
+               return NULL;
+       skb = alloc_can_err_skb(priv->ndev, cf);
+       if (skb)
+-              mcp251xfd_skb_set_timestamp(priv, skb, *timestamp);
++              mcp251xfd_skb_set_timestamp_raw(priv, skb, *ts_raw);
+       return skb;
+ }
+@@ -889,7 +889,7 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv)
+       struct mcp251xfd_rx_ring *ring;
+       struct sk_buff *skb;
+       struct can_frame *cf;
+-      u32 timestamp, rxovif;
++      u32 ts_raw, rxovif;
+       int err, i;
+       stats->rx_over_errors++;
+@@ -924,14 +924,14 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv)
+                       return err;
+       }
+-      skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &timestamp);
++      skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw);
+       if (!skb)
+               return 0;
+       cf->can_id |= CAN_ERR_CRTL;
+       cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+-      err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
++      err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw);
+       if (err)
+               stats->rx_fifo_errors++;
+@@ -948,12 +948,12 @@ static int mcp251xfd_handle_txatif(struct mcp251xfd_priv *priv)
+ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv)
+ {
+       struct net_device_stats *stats = &priv->ndev->stats;
+-      u32 bdiag1, timestamp;
++      u32 bdiag1, ts_raw;
+       struct sk_buff *skb;
+       struct can_frame *cf = NULL;
+       int err;
+-      err = mcp251xfd_get_timestamp(priv, &timestamp);
++      err = mcp251xfd_get_timestamp_raw(priv, &ts_raw);
+       if (err)
+               return err;
+@@ -1035,8 +1035,8 @@ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv)
+       if (!cf)
+               return 0;
+-      mcp251xfd_skb_set_timestamp(priv, skb, timestamp);
+-      err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
++      mcp251xfd_skb_set_timestamp_raw(priv, skb, ts_raw);
++      err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw);
+       if (err)
+               stats->rx_fifo_errors++;
+@@ -1049,7 +1049,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
+       struct sk_buff *skb;
+       struct can_frame *cf = NULL;
+       enum can_state new_state, rx_state, tx_state;
+-      u32 trec, timestamp;
++      u32 trec, ts_raw;
+       int err;
+       err = regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec);
+@@ -1079,7 +1079,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
+       /* The skb allocation might fail, but can_change_state()
+        * handles cf == NULL.
+        */
+-      skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &timestamp);
++      skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw);
+       can_change_state(priv->ndev, cf, tx_state, rx_state);
+       if (new_state == CAN_STATE_BUS_OFF) {
+@@ -1110,7 +1110,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
+               cf->data[7] = bec.rxerr;
+       }
+-      err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
++      err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw);
+       if (err)
+               stats->rx_fifo_errors++;
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+index 5d0fb1c454cd..a79e6c661ecc 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+@@ -160,7 +160,7 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv,
+       if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR))
+               memcpy(cfd->data, hw_rx_obj->data, cfd->len);
+-      mcp251xfd_skb_set_timestamp(priv, skb, hw_rx_obj->ts);
++      mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_rx_obj->ts);
+ }
+ static int
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
+index 5b0c7890d4b4..3886476a8f8e 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
+@@ -97,7 +97,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
+       tef_tail = mcp251xfd_get_tef_tail(priv);
+       skb = priv->can.echo_skb[tef_tail];
+       if (skb)
+-              mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts);
++              mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_tef_obj->ts);
+       stats->tx_bytes +=
+               can_rx_offload_get_echo_skb_queue_timestamp(&priv->offload,
+                                                           tef_tail, hw_tef_obj->ts,
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
+index 712e09186987..1db99aabe85c 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
+@@ -2,7 +2,7 @@
+ //
+ // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
+ //
+-// Copyright (c) 2021 Pengutronix,
++// Copyright (c) 2021, 2023 Pengutronix,
+ //               Marc Kleine-Budde <kernel@pengutronix.de>
+ //
+@@ -11,20 +11,20 @@
+ #include "mcp251xfd.h"
+-static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc)
++static u64 mcp251xfd_timestamp_raw_read(const struct cyclecounter *cc)
+ {
+       const struct mcp251xfd_priv *priv;
+-      u32 timestamp = 0;
++      u32 ts_raw = 0;
+       int err;
+       priv = container_of(cc, struct mcp251xfd_priv, cc);
+-      err = mcp251xfd_get_timestamp(priv, &timestamp);
++      err = mcp251xfd_get_timestamp_raw(priv, &ts_raw);
+       if (err)
+               netdev_err(priv->ndev,
+                          "Error %d while reading timestamp. HW timestamps may be inaccurate.",
+                          err);
+-      return timestamp;
++      return ts_raw;
+ }
+ static void mcp251xfd_timestamp_work(struct work_struct *work)
+@@ -39,21 +39,11 @@ static void mcp251xfd_timestamp_work(struct work_struct *work)
+                             MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ);
+ }
+-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv,
+-                               struct sk_buff *skb, u32 timestamp)
+-{
+-      struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
+-      u64 ns;
+-
+-      ns = timecounter_cyc2time(&priv->tc, timestamp);
+-      hwtstamps->hwtstamp = ns_to_ktime(ns);
+-}
+-
+ void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv)
+ {
+       struct cyclecounter *cc = &priv->cc;
+-      cc->read = mcp251xfd_timestamp_read;
++      cc->read = mcp251xfd_timestamp_raw_read;
+       cc->mask = CYCLECOUNTER_MASK(32);
+       cc->shift = 1;
+       cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift);
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+index 2e5cee6ad0c4..ae35845d4ce1 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+@@ -2,7 +2,7 @@
+  *
+  * mcp251xfd - Microchip MCP251xFD Family CAN controller driver
+  *
+- * Copyright (c) 2019, 2020, 2021 Pengutronix,
++ * Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
+  *               Marc Kleine-Budde <kernel@pengutronix.de>
+  * Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
+  */
+@@ -812,10 +812,27 @@ mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv,
+       return data;
+ }
+-static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv,
+-                                        u32 *timestamp)
++static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv,
++                                            u32 *ts_raw)
+ {
+-      return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp);
++      return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw);
++}
++
++static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns)
++{
++      struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
++
++      hwtstamps->hwtstamp = ns_to_ktime(ns);
++}
++
++static inline
++void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv,
++                                   struct sk_buff *skb, u32 ts_raw)
++{
++      u64 ns;
++
++      ns = timecounter_cyc2time(&priv->tc, ts_raw);
++      mcp251xfd_skb_set_timestamp(skb, ns);
+ }
+ static inline u16 mcp251xfd_get_tef_obj_addr(u8 n)
+@@ -936,8 +953,6 @@ void mcp251xfd_ring_free(struct mcp251xfd_priv *priv);
+ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv);
+ int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv);
+ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv);
+-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv,
+-                               struct sk_buff *skb, u32 timestamp);
+ void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv);
+ void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv);
+-- 
+2.43.0
+
diff --git a/queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch b/queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch
new file mode 100644 (file)
index 0000000..429a5ac
--- /dev/null
@@ -0,0 +1,108 @@
+From e2e5cebd9a70392b20b829170e31c271d8769998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 20:25:48 +0100
+Subject: can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in
+ separate function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit d49184b7b585f9da7ee546b744525f62117019f6 ]
+
+This is a preparation patch.
+
+Sending the UINC messages followed by incrementing the tail pointer
+will be called in more than one place in upcoming patches, so factor
+this out into a separate function.
+
+Also make mcp251xfd_handle_rxif_ring_uinc() safe to be called with a
+"len" of 0.
+
+Tested-by: Stefan Althöfer <Stefan.Althoefer@janztec.com>
+Tested-by: Thomas Kopp <thomas.kopp@microchip.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c | 48 +++++++++++++-------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+index ced8d9c81f8c..5e2f39de88f3 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+@@ -197,6 +197,37 @@ mcp251xfd_rx_obj_read(const struct mcp251xfd_priv *priv,
+       return err;
+ }
++static int
++mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv,
++                              struct mcp251xfd_rx_ring *ring,
++                              u8 len)
++{
++      int offset;
++      int err;
++
++      if (!len)
++              return 0;
++
++      /* Increment the RX FIFO tail pointer 'len' times in a
++       * single SPI message.
++       *
++       * Note:
++       * Calculate offset, so that the SPI transfer ends on
++       * the last message of the uinc_xfer array, which has
++       * "cs_change == 0", to properly deactivate the chip
++       * select.
++       */
++      offset = ARRAY_SIZE(ring->uinc_xfer) - len;
++      err = spi_sync_transfer(priv->spi,
++                              ring->uinc_xfer + offset, len);
++      if (err)
++              return err;
++
++      ring->tail += len;
++
++      return 0;
++}
++
+ static int
+ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
+                          struct mcp251xfd_rx_ring *ring)
+@@ -210,8 +241,6 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
+               return err;
+       while ((len = mcp251xfd_get_rx_linear_len(ring))) {
+-              int offset;
+-
+               rx_tail = mcp251xfd_get_rx_tail(ring);
+               err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
+@@ -227,22 +256,9 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
+                               return err;
+               }
+-              /* Increment the RX FIFO tail pointer 'len' times in a
+-               * single SPI message.
+-               *
+-               * Note:
+-               * Calculate offset, so that the SPI transfer ends on
+-               * the last message of the uinc_xfer array, which has
+-               * "cs_change == 0", to properly deactivate the chip
+-               * select.
+-               */
+-              offset = ARRAY_SIZE(ring->uinc_xfer) - len;
+-              err = spi_sync_transfer(priv->spi,
+-                                      ring->uinc_xfer + offset, len);
++              err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, len);
+               if (err)
+                       return err;
+-
+-              ring->tail += len;
+       }
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch b/queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch
new file mode 100644 (file)
index 0000000..1b618ba
--- /dev/null
@@ -0,0 +1,146 @@
+From 0c94a525e9837cd49d2b3031a6215faaf6d3e713 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 11:53:50 +0100
+Subject: can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of
+ mcp2518fd
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 24436be590c6fbb05f6161b0dfba7d9da60214aa ]
+
+This patch tries to works around erratum DS80000789E 6 of the
+mcp2518fd, the other variants of the chip family (mcp2517fd and
+mcp251863) are probably also affected.
+
+In the bad case, the driver reads a too large head index. In the
+original code, the driver always trusted the read value, which caused
+old, already processed CAN frames or new, incompletely written CAN
+frames to be (re-)processed.
+
+To work around this issue, keep a per FIFO timestamp [1] of the last
+valid received CAN frame and compare against the timestamp of every
+received CAN frame. If an old CAN frame is detected, abort the
+iteration and mark the number of valid CAN frames as processed in the
+chip by incrementing the FIFO's tail index.
+
+Further tests showed that this workaround can recognize old CAN
+frames, but a small time window remains in which partially written CAN
+frames [2] are not recognized but then processed. These CAN frames
+have the correct data and time stamps, but the DLC has not yet been
+updated.
+
+[1] As the raw timestamp overflows every 107 seconds (at the usual
+    clock rate of 40 MHz) convert it to nanoseconds with the
+    timecounter framework and use this to detect stale CAN frames.
+
+Link: https://lore.kernel.org/all/BL3PR11MB64844C1C95CA3BDADAE4D8CCFBC99@BL3PR11MB6484.namprd11.prod.outlook.com [2]
+Reported-by: Stefan Althöfer <Stefan.Althoefer@janztec.com>
+Closes: https://lore.kernel.org/all/FR0P281MB1966273C216630B120ABB6E197E89@FR0P281MB1966.DEUP281.PROD.OUTLOOK.COM
+Tested-by: Stefan Althöfer <Stefan.Althoefer@janztec.com>
+Tested-by: Thomas Kopp <thomas.kopp@microchip.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/spi/mcp251xfd/mcp251xfd-ring.c    |  1 +
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c  | 32 +++++++++++++++++--
+ drivers/net/can/spi/mcp251xfd/mcp251xfd.h     |  3 ++
+ 3 files changed, 33 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
+index 5f92aed62ff9..f72582d4d3e8 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
+@@ -206,6 +206,7 @@ mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
+       int i, j;
+       mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
++              rx_ring->last_valid = timecounter_read(&priv->tc);
+               rx_ring->head = 0;
+               rx_ring->tail = 0;
+               rx_ring->base = *base;
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+index a79e6c661ecc..fe897f3e4c12 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+@@ -159,8 +159,6 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv,
+       if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR))
+               memcpy(cfd->data, hw_rx_obj->data, cfd->len);
+-
+-      mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_rx_obj->ts);
+ }
+ static int
+@@ -171,8 +169,26 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv,
+       struct net_device_stats *stats = &priv->ndev->stats;
+       struct sk_buff *skb;
+       struct canfd_frame *cfd;
++      u64 timestamp;
+       int err;
++      /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
++       * bits of a FIFOSTA register, here the RX FIFO head index
++       * might be corrupted and we might process past the RX FIFO's
++       * head into old CAN frames.
++       *
++       * Compare the timestamp of currently processed CAN frame with
++       * last valid frame received. Abort with -EBADMSG if an old
++       * CAN frame is detected.
++       */
++      timestamp = timecounter_cyc2time(&priv->tc, hw_rx_obj->ts);
++      if (timestamp <= ring->last_valid) {
++              stats->rx_fifo_errors++;
++
++              return -EBADMSG;
++      }
++      ring->last_valid = timestamp;
++
+       if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF)
+               skb = alloc_canfd_skb(priv->ndev, &cfd);
+       else
+@@ -183,6 +199,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv,
+               return 0;
+       }
++      mcp251xfd_skb_set_timestamp(skb, timestamp);
+       mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb);
+       err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts);
+       if (err)
+@@ -265,7 +282,16 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
+                       err = mcp251xfd_handle_rxif_one(priv, ring,
+                                                       (void *)hw_rx_obj +
+                                                       i * ring->obj_size);
+-                      if (err)
++
++                      /* -EBADMSG means we're affected by mcp2518fd
++                       * erratum DS80000789E 6., i.e. the timestamp
++                       * in the RX object is older that the last
++                       * valid received CAN frame. Don't process any
++                       * further and mark processed frames as good.
++                       */
++                      if (err == -EBADMSG)
++                              return mcp251xfd_handle_rxif_ring_uinc(priv, ring, i);
++                      else if (err)
+                               return err;
+               }
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+index ae35845d4ce1..991662fbba42 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+@@ -554,6 +554,9 @@ struct mcp251xfd_rx_ring {
+       unsigned int head;
+       unsigned int tail;
++      /* timestamp of the last valid received CAN frame */
++      u64 last_valid;
++
+       u16 base;
+       u8 nr;
+       u8 fifo_nr;
+-- 
+2.43.0
+
diff --git a/queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch b/queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch
new file mode 100644 (file)
index 0000000..74301e1
--- /dev/null
@@ -0,0 +1,255 @@
+From bb7f55b3b253cbee9d1dceadda3c75a5732e7a89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 21:07:03 +0100
+Subject: can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index
+ erratum
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 85505e585637a737e4713c1386c30e37c325b82e ]
+
+This is a preparatory patch to work around erratum DS80000789E 6 of
+the mcp2518fd, the other variants of the chip family (mcp2517fd and
+mcp251863) are probably also affected.
+
+When handling the RX interrupt, the driver iterates over all pending
+FIFOs (which are implemented as ring buffers in hardware) and reads
+the FIFO header index from the RX FIFO STA register of the chip.
+
+In the bad case, the driver reads a too large head index. In the
+original code, the driver always trusted the read value, which caused
+old CAN frames that were already processed, or new, incompletely
+written CAN frames to be (re-)processed.
+
+Instead of reading and trusting the head index, read the head index
+and calculate the number of CAN frames that were supposedly received -
+replace mcp251xfd_rx_ring_update() with mcp251xfd_get_rx_len().
+
+The mcp251xfd_handle_rxif_ring() function reads the received CAN
+frames from the chip, iterates over them and pushes them into the
+network stack. Prepare that the iteration can be stopped if an old CAN
+frame is detected. The actual code to detect old or incomplete frames
+and abort will be added in the next patch.
+
+Link: https://lore.kernel.org/all/BL3PR11MB64844C1C95CA3BDADAE4D8CCFBC99@BL3PR11MB6484.namprd11.prod.outlook.com
+Reported-by: Stefan Althöfer <Stefan.Althoefer@janztec.com>
+Closes: https://lore.kernel.org/all/FR0P281MB1966273C216630B120ABB6E197E89@FR0P281MB1966.DEUP281.PROD.OUTLOOK.COM
+Tested-by: Stefan Althöfer <Stefan.Althoefer@janztec.com>
+Tested-by: Thomas Kopp <thomas.kopp@microchip.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/can/spi/mcp251xfd/mcp251xfd-ring.c    |  2 +
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c  | 89 +++++++++++--------
+ drivers/net/can/spi/mcp251xfd/mcp251xfd.h     | 12 +--
+ 3 files changed, 56 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
+index 3a941a71c78f..5f92aed62ff9 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
+@@ -523,6 +523,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
+               }
+               rx_ring->obj_num = rx_obj_num;
++              rx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(rx_ring->obj_num_shift_to_u8) -
++                      ilog2(rx_obj_num);
+               rx_ring->obj_size = rx_obj_size;
+               priv->rx[i] = rx_ring;
+       }
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+index 5e2f39de88f3..5d0fb1c454cd 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+@@ -2,7 +2,7 @@
+ //
+ // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
+ //
+-// Copyright (c) 2019, 2020, 2021 Pengutronix,
++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
+ //               Marc Kleine-Budde <kernel@pengutronix.de>
+ //
+ // Based on:
+@@ -16,23 +16,14 @@
+ #include "mcp251xfd.h"
+-static inline int
+-mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv *priv,
+-                              const struct mcp251xfd_rx_ring *ring,
+-                              u8 *rx_head, bool *fifo_empty)
++static inline bool mcp251xfd_rx_fifo_sta_empty(const u32 fifo_sta)
+ {
+-      u32 fifo_sta;
+-      int err;
+-
+-      err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr),
+-                        &fifo_sta);
+-      if (err)
+-              return err;
+-
+-      *rx_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
+-      *fifo_empty = !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
++      return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
++}
+-      return 0;
++static inline bool mcp251xfd_rx_fifo_sta_full(const u32 fifo_sta)
++{
++      return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF;
+ }
+ static inline int
+@@ -80,29 +71,49 @@ mcp251xfd_check_rx_tail(const struct mcp251xfd_priv *priv,
+ }
+ static int
+-mcp251xfd_rx_ring_update(const struct mcp251xfd_priv *priv,
+-                       struct mcp251xfd_rx_ring *ring)
++mcp251xfd_get_rx_len(const struct mcp251xfd_priv *priv,
++                   const struct mcp251xfd_rx_ring *ring,
++                   u8 *len_p)
+ {
+-      u32 new_head;
+-      u8 chip_rx_head;
+-      bool fifo_empty;
++      const u8 shift = ring->obj_num_shift_to_u8;
++      u8 chip_head, tail, len;
++      u32 fifo_sta;
+       int err;
+-      err = mcp251xfd_rx_head_get_from_chip(priv, ring, &chip_rx_head,
+-                                            &fifo_empty);
+-      if (err || fifo_empty)
++      err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr),
++                        &fifo_sta);
++      if (err)
++              return err;
++
++      if (mcp251xfd_rx_fifo_sta_empty(fifo_sta)) {
++              *len_p = 0;
++              return 0;
++      }
++
++      if (mcp251xfd_rx_fifo_sta_full(fifo_sta)) {
++              *len_p = ring->obj_num;
++              return 0;
++      }
++
++      chip_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
++
++      err =  mcp251xfd_check_rx_tail(priv, ring);
++      if (err)
+               return err;
++      tail = mcp251xfd_get_rx_tail(ring);
+-      /* chip_rx_head, is the next RX-Object filled by the HW.
+-       * The new RX head must be >= the old head.
++      /* First shift to full u8. The subtraction works on signed
++       * values, that keeps the difference steady around the u8
++       * overflow. The right shift acts on len, which is an u8.
+        */
+-      new_head = round_down(ring->head, ring->obj_num) + chip_rx_head;
+-      if (new_head <= ring->head)
+-              new_head += ring->obj_num;
++      BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(chip_head));
++      BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(tail));
++      BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(len));
+-      ring->head = new_head;
++      len = (chip_head << shift) - (tail << shift);
++      *len_p = len >> shift;
+-      return mcp251xfd_check_rx_tail(priv, ring);
++      return 0;
+ }
+ static void
+@@ -208,6 +219,8 @@ mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv,
+       if (!len)
+               return 0;
++      ring->head += len;
++
+       /* Increment the RX FIFO tail pointer 'len' times in a
+        * single SPI message.
+        *
+@@ -233,22 +246,22 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
+                          struct mcp251xfd_rx_ring *ring)
+ {
+       struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj;
+-      u8 rx_tail, len;
++      u8 rx_tail, len, l;
+       int err, i;
+-      err = mcp251xfd_rx_ring_update(priv, ring);
++      err = mcp251xfd_get_rx_len(priv, ring, &len);
+       if (err)
+               return err;
+-      while ((len = mcp251xfd_get_rx_linear_len(ring))) {
++      while ((l = mcp251xfd_get_rx_linear_len(ring, len))) {
+               rx_tail = mcp251xfd_get_rx_tail(ring);
+               err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
+-                                          rx_tail, len);
++                                          rx_tail, l);
+               if (err)
+                       return err;
+-              for (i = 0; i < len; i++) {
++              for (i = 0; i < l; i++) {
+                       err = mcp251xfd_handle_rxif_one(priv, ring,
+                                                       (void *)hw_rx_obj +
+                                                       i * ring->obj_size);
+@@ -256,9 +269,11 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
+                               return err;
+               }
+-              err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, len);
++              err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, l);
+               if (err)
+                       return err;
++
++              len -= l;
+       }
+       return 0;
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+index 4628bf847bc9..2e5cee6ad0c4 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+@@ -558,6 +558,7 @@ struct mcp251xfd_rx_ring {
+       u8 nr;
+       u8 fifo_nr;
+       u8 obj_num;
++      u8 obj_num_shift_to_u8;
+       u8 obj_size;
+       union mcp251xfd_write_reg_buf irq_enable_buf;
+@@ -907,18 +908,9 @@ static inline u8 mcp251xfd_get_rx_tail(const struct mcp251xfd_rx_ring *ring)
+       return ring->tail & (ring->obj_num - 1);
+ }
+-static inline u8 mcp251xfd_get_rx_len(const struct mcp251xfd_rx_ring *ring)
+-{
+-      return ring->head - ring->tail;
+-}
+-
+ static inline u8
+-mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring)
++mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring, u8 len)
+ {
+-      u8 len;
+-
+-      len = mcp251xfd_get_rx_len(ring);
+-
+       return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring));
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch b/queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch
new file mode 100644 (file)
index 0000000..32a9e2d
--- /dev/null
@@ -0,0 +1,106 @@
+From 6f77e927f029cd5c958341d30aa8285043fb6f5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 16:36:27 -0700
+Subject: clk: qcom: gcc-sm8550: Don't park the USB RCG at registration time
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit 7b6dfa1bbe7f727315d2e05a2fc8e4cfeb779156 ]
+
+Amit Pundir reports that audio and USB-C host mode stops working if the
+gcc_usb30_prim_master_clk_src clk is registered and
+clk_rcg2_shared_init() parks it on XO. Skip parking this clk at
+registration time to fix those issues.
+
+Partially revert commit 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon
+registration") by skipping the parking bit for this clk, but keep the
+part where we cache the config register. That's still necessary to
+figure out the true parent of the clk at registration time.
+
+Fixes: 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration")
+Fixes: 929c75d57566 ("clk: qcom: gcc-sm8550: Mark RCGs shared where applicable")
+Cc: Konrad Dybcio <konradybcio@kernel.org>
+Cc: Bjorn Andersson <andersson@kernel.org>
+Cc: Taniya Das <quic_tdas@quicinc.com>
+Reported-by: Amit Pundir <amit.pundir@linaro.org>
+Closes: https://lore.kernel.org/CAMi1Hd1KQBE4kKUdAn8E5FV+BiKzuv+8FoyWQrrTHPDoYTuhgA@mail.gmail.com
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/20240819233628.2074654-3-swboyd@chromium.org
+Tested-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-rcg.h    |  1 +
+ drivers/clk/qcom/clk-rcg2.c   | 30 ++++++++++++++++++++++++++++++
+ drivers/clk/qcom/gcc-sm8550.c |  2 +-
+ 3 files changed, 32 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
+index e6d84c8c7989..84c497f361bc 100644
+--- a/drivers/clk/qcom/clk-rcg.h
++++ b/drivers/clk/qcom/clk-rcg.h
+@@ -176,6 +176,7 @@ extern const struct clk_ops clk_byte2_ops;
+ extern const struct clk_ops clk_pixel_ops;
+ extern const struct clk_ops clk_gfx3d_ops;
+ extern const struct clk_ops clk_rcg2_shared_ops;
++extern const struct clk_ops clk_rcg2_shared_no_init_park_ops;
+ extern const struct clk_ops clk_dp_ops;
+ struct clk_rcg_dfs_data {
+diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
+index b9f2a29be927..461f54fe5e4f 100644
+--- a/drivers/clk/qcom/clk-rcg2.c
++++ b/drivers/clk/qcom/clk-rcg2.c
+@@ -1182,6 +1182,36 @@ const struct clk_ops clk_rcg2_shared_ops = {
+ };
+ EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
++static int clk_rcg2_shared_no_init_park(struct clk_hw *hw)
++{
++      struct clk_rcg2 *rcg = to_clk_rcg2(hw);
++
++      /*
++       * Read the config register so that the parent is properly mapped at
++       * registration time.
++       */
++      regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &rcg->parked_cfg);
++
++      return 0;
++}
++
++/*
++ * Like clk_rcg2_shared_ops but skip the init so that the clk frequency is left
++ * unchanged at registration time.
++ */
++const struct clk_ops clk_rcg2_shared_no_init_park_ops = {
++      .init = clk_rcg2_shared_no_init_park,
++      .enable = clk_rcg2_shared_enable,
++      .disable = clk_rcg2_shared_disable,
++      .get_parent = clk_rcg2_shared_get_parent,
++      .set_parent = clk_rcg2_shared_set_parent,
++      .recalc_rate = clk_rcg2_shared_recalc_rate,
++      .determine_rate = clk_rcg2_determine_rate,
++      .set_rate = clk_rcg2_shared_set_rate,
++      .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
++};
++EXPORT_SYMBOL_GPL(clk_rcg2_shared_no_init_park_ops);
++
+ /* Common APIs to be used for DFS based RCGR */
+ static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l,
+                                      struct freq_tbl *f)
+diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c
+index bf7b7c5d4606..eb3765c57b65 100644
+--- a/drivers/clk/qcom/gcc-sm8550.c
++++ b/drivers/clk/qcom/gcc-sm8550.c
+@@ -1159,7 +1159,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_shared_no_init_park_ops,
+       },
+ };
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch b/queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch
new file mode 100644 (file)
index 0000000..0d0edd2
--- /dev/null
@@ -0,0 +1,285 @@
+From a3b4a42a75776e4375a924ecc57465e5c276e447 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 16:36:26 -0700
+Subject: clk: qcom: gcc-sm8550: Don't use parking clk_ops for QUPs
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit d10eeb75168b84ed9559c58efe2756c2e0bc052a ]
+
+The QUPs aren't shared in a way that requires parking the RCG at an
+always on parent in case some other entity turns on the clk. The
+hardware is capable of setting a new frequency itself with the DFS mode,
+so parking is unnecessary. Furthermore, there aren't any GDSCs for these
+devices, so there isn't a possibility of the GDSC turning on the clks
+for housekeeping purposes.
+
+This wasn't a problem to mark these clks shared until we started parking
+shared RCGs at clk registration time in commit 01a0a6cc8cfd ("clk: qcom:
+Park shared RCGs upon registration"). Parking at init is actually
+harmful to the UART when earlycon is used. If the device is pumping out
+data while the frequency changes you'll see garbage on the serial
+console until the driver can probe and actually set a proper frequency.
+
+Revert the QUP part of commit 929c75d57566 ("clk: qcom: gcc-sm8550: Mark
+RCGs shared where applicable") so that the QUPs don't get parked during
+clk registration and break UART operations.
+
+Fixes: 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration")
+Fixes: 929c75d57566 ("clk: qcom: gcc-sm8550: Mark RCGs shared where applicable")
+Cc: Konrad Dybcio <konradybcio@kernel.org>
+Cc: Bjorn Andersson <andersson@kernel.org>
+Cc: Taniya Das <quic_tdas@quicinc.com>
+Reported-by: Amit Pundir <amit.pundir@linaro.org>
+Closes: https://lore.kernel.org/CAMi1Hd1KQBE4kKUdAn8E5FV+BiKzuv+8FoyWQrrTHPDoYTuhgA@mail.gmail.com
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/20240819233628.2074654-2-swboyd@chromium.org
+Tested-by: Amit Pundir <amit.pundir@linaro.org>
+Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm8550.c | 52 +++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c
+index b883dffe5f7a..bf7b7c5d4606 100644
+--- a/drivers/clk/qcom/gcc-sm8550.c
++++ b/drivers/clk/qcom/gcc-sm8550.c
+@@ -536,7 +536,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -551,7 +551,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -566,7 +566,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -581,7 +581,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -596,7 +596,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -611,7 +611,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s5_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -626,7 +626,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s6_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -641,7 +641,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s7_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -656,7 +656,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s8_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -671,7 +671,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s9_clk_src = {
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+-              .ops = &clk_rcg2_shared_ops,
++              .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -700,7 +700,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+@@ -717,7 +717,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+@@ -750,7 +750,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+@@ -767,7 +767,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+@@ -784,7 +784,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+@@ -801,7 +801,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+@@ -818,7 +818,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
+@@ -835,7 +835,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
+@@ -852,7 +852,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
+@@ -869,7 +869,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
+@@ -886,7 +886,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
+@@ -903,7 +903,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
+@@ -920,7 +920,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
+@@ -937,7 +937,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
+@@ -975,7 +975,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = {
+       .parent_data = gcc_parent_data_8,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_8),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
+@@ -992,7 +992,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = {
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+-      .ops = &clk_rcg2_shared_ops,
++      .ops = &clk_rcg2_ops,
+ };
+ static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = {
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch b/queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch
new file mode 100644 (file)
index 0000000..6255ce6
--- /dev/null
@@ -0,0 +1,101 @@
+From 6d90019599f844b1f26df6e8d551c316bfb713ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 11:41:05 +0530
+Subject: clk: qcom: ipq9574: Update the alpha PLL type for GPLLs
+
+From: devi priya <quic_devipriy@quicinc.com>
+
+[ Upstream commit 6357efe3abead68048729adf11a9363881657939 ]
+
+Update PLL offsets to DEFAULT_EVO to configure MDIO to 800MHz.
+
+The incorrect clock frequency leads to an incorrect MDIO clock. This,
+in turn, affects the MDIO hardware configurations as the divider is
+calculated from the MDIO clock frequency. If the clock frequency is
+not as expected, the MDIO register fails due to the generation of an
+incorrect MDIO frequency.
+
+This issue is critical as it results in incorrect MDIO configurations
+and ultimately leads to the MDIO function not working. This results in
+a complete feature failure affecting all Ethernet PHYs. Specifically,
+Ethernet will not work on IPQ9574 due to this issue.
+
+Currently, the clock frequency is set to CLK_ALPHA_PLL_TYPE_DEFAULT.
+However, this setting does not yield the expected clock frequency.
+To rectify this, we need to change this to CLK_ALPHA_PLL_TYPE_DEFAULT_EVO.
+
+This modification ensures that the clock frequency aligns with our
+expectations, thereby resolving the MDIO register failure and ensuring
+the proper functioning of the Ethernet on IPQ9574.
+
+Fixes: d75b82cff488 ("clk: qcom: Add Global Clock Controller driver for IPQ9574")
+Signed-off-by: devi priya <quic_devipriy@quicinc.com>
+Signed-off-by: Amandeep Singh <quic_amansing@quicinc.com>
+Link: https://lore.kernel.org/r/20240806061105.2849944-1-quic_amansing@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq9574.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c
+index f8b9a1e93bef..cdbbf2cc9c5d 100644
+--- a/drivers/clk/qcom/gcc-ipq9574.c
++++ b/drivers/clk/qcom/gcc-ipq9574.c
+@@ -65,7 +65,7 @@ static const struct clk_parent_data gcc_sleep_clk_data[] = {
+ static struct clk_alpha_pll gpll0_main = {
+       .offset = 0x20000,
+-      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(0),
+@@ -93,7 +93,7 @@ static struct clk_fixed_factor gpll0_out_main_div2 = {
+ static struct clk_alpha_pll_postdiv gpll0 = {
+       .offset = 0x20000,
+-      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+       .width = 4,
+       .clkr.hw.init = &(const struct clk_init_data) {
+               .name = "gpll0",
+@@ -107,7 +107,7 @@ static struct clk_alpha_pll_postdiv gpll0 = {
+ static struct clk_alpha_pll gpll4_main = {
+       .offset = 0x22000,
+-      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(2),
+@@ -122,7 +122,7 @@ static struct clk_alpha_pll gpll4_main = {
+ static struct clk_alpha_pll_postdiv gpll4 = {
+       .offset = 0x22000,
+-      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+       .width = 4,
+       .clkr.hw.init = &(const struct clk_init_data) {
+               .name = "gpll4",
+@@ -136,7 +136,7 @@ static struct clk_alpha_pll_postdiv gpll4 = {
+ static struct clk_alpha_pll gpll2_main = {
+       .offset = 0x21000,
+-      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(1),
+@@ -151,7 +151,7 @@ static struct clk_alpha_pll gpll2_main = {
+ static struct clk_alpha_pll_postdiv gpll2 = {
+       .offset = 0x21000,
+-      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+       .width = 4,
+       .clkr.hw.init = &(const struct clk_init_data) {
+               .name = "gpll2",
+-- 
+2.43.0
+
diff --git a/queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch b/queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch
new file mode 100644 (file)
index 0000000..271b87c
--- /dev/null
@@ -0,0 +1,86 @@
+From c84c7de31dd31b2cbe3adf0a2e396e1047fa9452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jun 2024 09:40:42 +0800
+Subject: crypto: starfive - Align rsa input data to 32-bit
+
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+
+[ Upstream commit 6aad7019f697ab0bed98eba737d19bd7f67713de ]
+
+Hardware expects RSA input plain/ciphertext to be 32-bit aligned.
+Set fixed length for preallocated buffer to the maximum supported
+keysize of the hardware and shift input text accordingly.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/starfive/jh7110-cryp.h |  3 ++-
+ drivers/crypto/starfive/jh7110-rsa.c  | 12 ++++++++----
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h
+index fe011d50473d..f386e9897896 100644
+--- a/drivers/crypto/starfive/jh7110-cryp.h
++++ b/drivers/crypto/starfive/jh7110-cryp.h
+@@ -30,6 +30,7 @@
+ #define MAX_KEY_SIZE                          SHA512_BLOCK_SIZE
+ #define STARFIVE_AES_IV_LEN                   AES_BLOCK_SIZE
+ #define STARFIVE_AES_CTR_LEN                  AES_BLOCK_SIZE
++#define STARFIVE_RSA_MAX_KEYSZ                        256
+ union starfive_aes_csr {
+       u32 v;
+@@ -217,7 +218,7 @@ struct starfive_cryp_request_ctx {
+       unsigned int                            digsize;
+       unsigned long                           in_sg_len;
+       unsigned char                           *adata;
+-      u8 rsa_data[] __aligned(sizeof(u32));
++      u8 rsa_data[STARFIVE_RSA_MAX_KEYSZ] __aligned(sizeof(u32));
+ };
+ struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
+diff --git a/drivers/crypto/starfive/jh7110-rsa.c b/drivers/crypto/starfive/jh7110-rsa.c
+index f31bbd825f88..fbc06f8ee95f 100644
+--- a/drivers/crypto/starfive/jh7110-rsa.c
++++ b/drivers/crypto/starfive/jh7110-rsa.c
+@@ -37,7 +37,6 @@
+ // A * A * R mod N ==> A
+ #define CRYPTO_CMD_AARN                       0x7
+-#define STARFIVE_RSA_MAX_KEYSZ                256
+ #define STARFIVE_RSA_RESET            0x2
+ static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
+@@ -91,7 +90,7 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx,
+ {
+       struct starfive_cryp_dev *cryp = ctx->cryp;
+       struct starfive_cryp_request_ctx *rctx = ctx->rctx;
+-      int count = rctx->total / sizeof(u32) - 1;
++      int count = (ALIGN(rctx->total, 4) / 4) - 1;
+       int loop;
+       u32 temp;
+       u8 opsize;
+@@ -274,12 +273,17 @@ static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc)
+       struct starfive_cryp_dev *cryp = ctx->cryp;
+       struct starfive_cryp_request_ctx *rctx = ctx->rctx;
+       struct starfive_rsa_key *key = &ctx->rsa_key;
+-      int ret = 0;
++      int ret = 0, shift = 0;
+       writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);
++      if (!IS_ALIGNED(rctx->total, sizeof(u32))) {
++              shift = sizeof(u32) - (rctx->total & 0x3);
++              memset(rctx->rsa_data, 0, shift);
++      }
++
+       rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents,
+-                                      rctx->rsa_data, rctx->total);
++                                      rctx->rsa_data + shift, rctx->total);
+       if (enc) {
+               key->bitlen = key->e_bitlen;
+-- 
+2.43.0
+
diff --git a/queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch b/queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch
new file mode 100644 (file)
index 0000000..bc7b188
--- /dev/null
@@ -0,0 +1,57 @@
+From a4334a723769472c50893e63f03dc66fc08dda44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jun 2024 09:40:43 +0800
+Subject: crypto: starfive - Fix nent assignment in rsa dec
+
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+
+[ Upstream commit 8323c036789b8b4a61925fce439a89dba17b7f2f ]
+
+Missing src scatterlist nent assignment in rsa decrypt function.
+Removing all unneeded assignment and use nents value from req->src
+instead.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/starfive/jh7110-cryp.h | 1 -
+ drivers/crypto/starfive/jh7110-rsa.c  | 3 +--
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h
+index f386e9897896..607f70292b21 100644
+--- a/drivers/crypto/starfive/jh7110-cryp.h
++++ b/drivers/crypto/starfive/jh7110-cryp.h
+@@ -213,7 +213,6 @@ struct starfive_cryp_request_ctx {
+       struct scatterlist                      *out_sg;
+       struct ahash_request                    ahash_fbk_req;
+       size_t                                  total;
+-      size_t                                  nents;
+       unsigned int                            blksize;
+       unsigned int                            digsize;
+       unsigned long                           in_sg_len;
+diff --git a/drivers/crypto/starfive/jh7110-rsa.c b/drivers/crypto/starfive/jh7110-rsa.c
+index fbc06f8ee95f..1db9a3d02848 100644
+--- a/drivers/crypto/starfive/jh7110-rsa.c
++++ b/drivers/crypto/starfive/jh7110-rsa.c
+@@ -282,7 +282,7 @@ static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc)
+               memset(rctx->rsa_data, 0, shift);
+       }
+-      rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents,
++      rctx->total = sg_copy_to_buffer(rctx->in_sg, sg_nents(rctx->in_sg),
+                                       rctx->rsa_data + shift, rctx->total);
+       if (enc) {
+@@ -333,7 +333,6 @@ static int starfive_rsa_enc(struct akcipher_request *req)
+       rctx->in_sg = req->src;
+       rctx->out_sg = req->dst;
+       rctx->total = req->src_len;
+-      rctx->nents = sg_nents(rctx->in_sg);
+       ctx->rctx = rctx;
+       return starfive_rsa_enc_core(ctx, 1);
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch b/queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch
new file mode 100644 (file)
index 0000000..c584e54
--- /dev/null
@@ -0,0 +1,63 @@
+From b82fcd8d702fe9ef09528f84d66d302ed5e84f3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 14:00:27 -0500
+Subject: drm/amd: Add gfx12 swizzle mode defs
+
+From: Aurabindo Pillai <aurabindo.pillai@amd.com>
+
+[ Upstream commit 7ceb94e87bffff7c12b61eb29749e1d8ac976896 ]
+
+Add GFX12 swizzle mode definitions for use with DCN401
+
+Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/drm/drm_fourcc.h | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
+index 8db7fd3f743e..fb3040677815 100644
+--- a/include/uapi/drm/drm_fourcc.h
++++ b/include/uapi/drm/drm_fourcc.h
+@@ -1474,6 +1474,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
+ #define AMD_FMT_MOD_TILE_VER_GFX10 2
+ #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+ #define AMD_FMT_MOD_TILE_VER_GFX11 4
++#define AMD_FMT_MOD_TILE_VER_GFX12 5
+ /*
+  * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical
+@@ -1484,6 +1485,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
+ /*
+  * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+  * GFX9 as canonical version.
++ *
++ * 64K_D_2D on GFX12 is identical to 64K_D on GFX11.
+  */
+ #define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+ #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+@@ -1491,6 +1494,19 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
+ #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+ #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31
++/* Gfx12 swizzle modes:
++ *    0 - LINEAR
++ *    1 - 256B_2D  - 2D block dimensions
++ *    2 - 4KB_2D
++ *    3 - 64KB_2D
++ *    4 - 256KB_2D
++ *    5 - 4KB_3D   - 3D block dimensions
++ *    6 - 64KB_3D
++ *    7 - 256KB_3D
++ */
++#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3
++#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4
++
+ #define AMD_FMT_MOD_DCC_BLOCK_64B 0
+ #define AMD_FMT_MOD_DCC_BLOCK_128B 1
+ #define AMD_FMT_MOD_DCC_BLOCK_256B 2
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch b/queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch
new file mode 100644 (file)
index 0000000..08eac7b
--- /dev/null
@@ -0,0 +1,84 @@
+From 2ac02f4d4ef4c1ece373031d988f86e757b310c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Jun 2024 19:53:01 -0400
+Subject: drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Olšák <marek.olsak@amd.com>
+
+[ Upstream commit 8dd1426e2c80e32ac1995007330c8f95ffa28ebb ]
+
+It verified GFX9-11 swizzle modes on GFX12, which has undefined behavior.
+
+Signed-off-by: Marek Olšák <marek.olsak@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 27 ++++++++++++++++++++-
+ include/uapi/drm/drm_fourcc.h               |  2 ++
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+index 82ad2b01f2e9..5fbb9caa7415 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+@@ -1033,6 +1033,30 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
+                       block_width = 256 / format_info->cpp[i];
+                       block_height = 1;
+                       block_size_log2 = 8;
++              } else if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12) {
++                      int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
++
++                      switch (swizzle) {
++                      case AMD_FMT_MOD_TILE_GFX12_256B_2D:
++                              block_size_log2 = 8;
++                              break;
++                      case AMD_FMT_MOD_TILE_GFX12_4K_2D:
++                              block_size_log2 = 12;
++                              break;
++                      case AMD_FMT_MOD_TILE_GFX12_64K_2D:
++                              block_size_log2 = 16;
++                              break;
++                      case AMD_FMT_MOD_TILE_GFX12_256K_2D:
++                              block_size_log2 = 18;
++                              break;
++                      default:
++                              drm_dbg_kms(rfb->base.dev,
++                                          "Gfx12 swizzle mode with unknown block size: %d\n", swizzle);
++                              return -EINVAL;
++                      }
++
++                      get_block_dimensions(block_size_log2, format_info->cpp[i],
++                                           &block_width, &block_height);
+               } else {
+                       int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
+@@ -1068,7 +1092,8 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
+                       return ret;
+       }
+-      if (AMD_FMT_MOD_GET(DCC, modifier)) {
++      if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11 &&
++          AMD_FMT_MOD_GET(DCC, modifier)) {
+               if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) {
+                       block_size_log2 = get_dcc_block_size(modifier, false, false);
+                       get_block_dimensions(block_size_log2 + 8, format_info->cpp[0],
+diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
+index fb3040677815..5eed091d4c29 100644
+--- a/include/uapi/drm/drm_fourcc.h
++++ b/include/uapi/drm/drm_fourcc.h
+@@ -1504,6 +1504,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
+  *    6 - 64KB_3D
+  *    7 - 256KB_3D
+  */
++#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1
++#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2
+ #define AMD_FMT_MOD_TILE_GFX12_64K_2D 3
+ #define AMD_FMT_MOD_TILE_GFX12_256K_2D 4
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch b/queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch
new file mode 100644 (file)
index 0000000..3949d49
--- /dev/null
@@ -0,0 +1,59 @@
+From 306b4aabb8c035d57e856aed581e7b7cb9f7952e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 18:58:38 +0300
+Subject: drm/i915/fence: Mark debug_fence_free() with __maybe_unused
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit f99999536128b14b5d765a9982763b5134efdd79 ]
+
+When debug_fence_free() is unused
+(CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS=n), it prevents kernel builds
+with clang, `make W=1` and CONFIG_WERROR=y:
+
+.../i915_sw_fence.c:118:20: error: unused function 'debug_fence_free' [-Werror,-Wunused-function]
+  118 | static inline void debug_fence_free(struct i915_sw_fence *fence)
+      |                    ^~~~~~~~~~~~~~~~
+
+Fix this by marking debug_fence_free() with __maybe_unused.
+
+See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static
+inline functions for W=1 build").
+
+Fixes: fc1584059d6c ("drm/i915: Integrate i915_sw_fence with debugobjects")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240829155950.1141978-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit 8be4dce5ea6f2368cc25edc71989c4690fa66964)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/i915_sw_fence.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
+index d4020ff3549a..1d4cc91c0e40 100644
+--- a/drivers/gpu/drm/i915/i915_sw_fence.c
++++ b/drivers/gpu/drm/i915/i915_sw_fence.c
+@@ -77,7 +77,7 @@ static inline void debug_fence_destroy(struct i915_sw_fence *fence)
+       debug_object_destroy(fence, &i915_sw_fence_debug_descr);
+ }
+-static inline void debug_fence_free(struct i915_sw_fence *fence)
++static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence)
+ {
+       debug_object_free(fence, &i915_sw_fence_debug_descr);
+       smp_wmb(); /* flush the change in state before reallocation */
+@@ -115,7 +115,7 @@ static inline void debug_fence_destroy(struct i915_sw_fence *fence)
+ {
+ }
+-static inline void debug_fence_free(struct i915_sw_fence *fence)
++static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence)
+ {
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch b/queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch
new file mode 100644 (file)
index 0000000..5f9335e
--- /dev/null
@@ -0,0 +1,58 @@
+From 13a6d4c7f105a5092c52df6e747925e263ebe167 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 18:58:37 +0300
+Subject: drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit fcd9e8afd546f6ced378d078345a89bf346d065e ]
+
+When debug_fence_init_onstack() is unused (CONFIG_DRM_I915_SELFTEST=n),
+it prevents kernel builds with clang, `make W=1` and CONFIG_WERROR=y:
+
+.../i915_sw_fence.c:97:20: error: unused function 'debug_fence_init_onstack' [-Werror,-Wunused-function]
+   97 | static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
+      |                    ^~~~~~~~~~~~~~~~~~~~~~~~
+
+Fix this by marking debug_fence_init_onstack() with __maybe_unused.
+
+See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static
+inline functions for W=1 build").
+
+Fixes: 214707fc2ce0 ("drm/i915/selftests: Wrap a timer into a i915_sw_fence")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240829155950.1141978-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit 5bf472058ffb43baf6a4cdfe1d7f58c4c194c688)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/i915_sw_fence.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
+index 8a9aad523eec..d4020ff3549a 100644
+--- a/drivers/gpu/drm/i915/i915_sw_fence.c
++++ b/drivers/gpu/drm/i915/i915_sw_fence.c
+@@ -51,7 +51,7 @@ static inline void debug_fence_init(struct i915_sw_fence *fence)
+       debug_object_init(fence, &i915_sw_fence_debug_descr);
+ }
+-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
++static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence)
+ {
+       debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr);
+ }
+@@ -94,7 +94,7 @@ static inline void debug_fence_init(struct i915_sw_fence *fence)
+ {
+ }
+-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
++static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence)
+ {
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/gpio-modepin-enable-module-autoloading.patch b/queue-6.6/gpio-modepin-enable-module-autoloading.patch
new file mode 100644 (file)
index 0000000..b0b4dd8
--- /dev/null
@@ -0,0 +1,37 @@
+From bdfc4fc4830a81c9c00c223491e54a2565dcc078 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 11:58:48 +0000
+Subject: gpio: modepin: Enable module autoloading
+
+From: Liao Chen <liaochen4@huawei.com>
+
+[ Upstream commit a5135526426df5319d5f4bcd15ae57c45a97714b ]
+
+Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based
+on the alias from of_device_id table.
+
+Fixes: 7687a5b0ee93 ("gpio: modepin: Add driver support for modepin GPIO controller")
+Signed-off-by: Liao Chen <liaochen4@huawei.com>
+Reviewed-by: Michal Simek <michal.simek@amd.com>
+Link: https://lore.kernel.org/r/20240902115848.904227-1-liaochen4@huawei.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-zynqmp-modepin.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c
+index a0d69387c153..2f3c9ebfa78d 100644
+--- a/drivers/gpio/gpio-zynqmp-modepin.c
++++ b/drivers/gpio/gpio-zynqmp-modepin.c
+@@ -146,6 +146,7 @@ static const struct of_device_id modepin_platform_id[] = {
+       { .compatible = "xlnx,zynqmp-gpio-modepin", },
+       { }
+ };
++MODULE_DEVICE_TABLE(of, modepin_platform_id);
+ static struct platform_driver modepin_platform_driver = {
+       .driver = {
+-- 
+2.43.0
+
diff --git a/queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch b/queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch
new file mode 100644 (file)
index 0000000..07c3451
--- /dev/null
@@ -0,0 +1,38 @@
+From 4ac663fa429b8dfa4570a35c82be326aca3e7c2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 17:08:32 +0200
+Subject: gpio: rockchip: fix OF node leak in probe()
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit adad2e460e505a556f5ea6f0dc16fe95e62d5d76 ]
+
+Driver code is leaking OF node reference from of_get_parent() in
+probe().
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
+Link: https://lore.kernel.org/r/20240826150832.65657-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index b35b9604413f..caeb3bdc78f8 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -713,6 +713,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+               return -ENODEV;
+       pctldev = of_pinctrl_get(pctlnp);
++      of_node_put(pctlnp);
+       if (!pctldev)
+               return -EPROBE_DEFER;
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch b/queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch
new file mode 100644 (file)
index 0000000..289451a
--- /dev/null
@@ -0,0 +1,43 @@
+From cf4ca3642d32cbbe78bf1034aaed7a7b39050316 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 11:20:57 -0700
+Subject: nvme-pci: allocate tagset on reset if necessary
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit 6f01bdbfef3b62955cf6503a8425d527b3a5cf94 ]
+
+If a drive is unable to create IO queues on the initial probe, a
+subsequent reset will need to allocate the tagset if IO queue creation
+is successful. Without this, blk_mq_update_nr_hw_queues will crash on a
+bad pointer due to the invalid tagset.
+
+Fixes: eac3ef262941f62 ("nvme-pci: split the initial probe from the rest path")
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/pci.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 89e0798af780..7fc1ab4d9e7d 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2471,6 +2471,12 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev)
+ static void nvme_pci_update_nr_queues(struct nvme_dev *dev)
+ {
++      if (!dev->ctrl.tagset) {
++              nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops,
++                              nvme_pci_nr_maps(dev), sizeof(struct nvme_iod));
++              return;
++      }
++
+       blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
+       /* free previously allocated queues that are no longer usable */
+       nvme_free_queues(dev, dev->online_queues);
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch b/queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch
new file mode 100644 (file)
index 0000000..af6c8ed
--- /dev/null
@@ -0,0 +1,48 @@
+From 281c5c0e41765cdc44791e3332336739c0d682bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 16:28:26 +0200
+Subject: nvmet-tcp: fix kernel crash if commands allocation fails
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 5572a55a6f830ee3f3a994b6b962a5c327d28cb3 ]
+
+If the commands allocation fails in nvmet_tcp_alloc_cmds()
+the kernel crashes in nvmet_tcp_release_queue_work() because of
+a NULL pointer dereference.
+
+  nvmet: failed to install queue 0 cntlid 1 ret 6
+  Unable to handle kernel NULL pointer dereference at
+         virtual address 0000000000000008
+
+Fix the bug by setting queue->nr_cmds to zero in case
+nvmet_tcp_alloc_cmd() fails.
+
+Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index c65a1f4421f6..bd142aed20f4 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -1859,8 +1859,10 @@ static u16 nvmet_tcp_install_queue(struct nvmet_sq *sq)
+       }
+       queue->nr_cmds = sq->size * 2;
+-      if (nvmet_tcp_alloc_cmds(queue))
++      if (nvmet_tcp_alloc_cmds(queue)) {
++              queue->nr_cmds = 0;
+               return NVME_SC_INTERNAL;
++      }
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch b/queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch
new file mode 100644 (file)
index 0000000..27bf33f
--- /dev/null
@@ -0,0 +1,38 @@
+From 9f5bea0c165045bd8bd6a50d9bc22581088e4f29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 14:42:38 +0200
+Subject: powerpc/64e: Define mmu_pte_psize static
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit d92b5cc29c792f1d3f0aaa3b29dddfe816c03e88 ]
+
+mmu_pte_psize is only used in the tlb_64e.c, define it static.
+
+Fixes: 25d21ad6e799 ("powerpc: Add TLB management code for 64-bit Book3E")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202408011256.1O99IB0s-lkp@intel.com/
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/beb30d280eaa5d857c38a0834b147dffd6b28aa9.1724157750.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/nohash/tlb_64e.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/mm/nohash/tlb_64e.c b/arch/powerpc/mm/nohash/tlb_64e.c
+index 1dcda261554c..b6af3ec4d001 100644
+--- a/arch/powerpc/mm/nohash/tlb_64e.c
++++ b/arch/powerpc/mm/nohash/tlb_64e.c
+@@ -33,7 +33,7 @@
+  * though this will probably be made common with other nohash
+  * implementations at some point
+  */
+-int mmu_pte_psize;            /* Page size used for PTE pages */
++static int mmu_pte_psize;     /* Page size used for PTE pages */
+ int mmu_vmemmap_psize;                /* Page size used for the virtual mem map */
+ int book3e_htw_mode;          /* HW tablewalk?  Value is PPC_HTW_* */
+ unsigned long linear_map_top; /* Top of linear mapping */
+-- 
+2.43.0
+
diff --git a/queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch b/queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch
new file mode 100644 (file)
index 0000000..0e04f1c
--- /dev/null
@@ -0,0 +1,380 @@
+From 3e86587442166b6a746e49d83f70afca56019922 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 15:51:13 +0200
+Subject: powerpc/64e: remove unused IBM HTW code
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 88715b6e5d529f4ef3830ad2a893e4624c6af0b8 ]
+
+Patch series "Reimplement huge pages without hugepd on powerpc (8xx, e500,
+book3s/64)", v7.
+
+Unlike most architectures, powerpc 8xx HW requires a two-level pagetable
+topology for all page sizes.  So a leaf PMD-contig approach is not
+feasible as such.
+
+Possible sizes on 8xx are 4k, 16k, 512k and 8M.
+
+First level (PGD/PMD) covers 4M per entry.  For 8M pages, two PMD entries
+must point to a single entry level-2 page table.  Until now that was done
+using hugepd.  This series changes it to use standard page tables where
+the entry is replicated 1024 times on each of the two pagetables refered
+by the two associated PMD entries for that 8M page.
+
+For e500 and book3s/64 there are less constraints because it is not tied
+to the HW assisted tablewalk like on 8xx, so it is easier to use leaf PMDs
+(and PUDs).
+
+On e500 the supported page sizes are 4M, 16M, 64M, 256M and 1G.  All at
+PMD level on e500/32 (mpc85xx) and mix of PMD and PUD for e500/64.  We
+encode page size with 4 available bits in PTE entries.  On e300/32 PGD
+entries size is increases to 64 bits in order to allow leaf-PMD entries
+because PTE are 64 bits on e500.
+
+On book3s/64 only the hash-4k mode is concerned.  It supports 16M pages as
+cont-PMD and 16G pages as cont-PUD.  In other modes (radix-4k, radix-6k
+and hash-64k) the sizes match with PMD and PUD sizes so that's just leaf
+entries.  The hash processing make things a bit more complex.  To ease
+things, __hash_page_huge() is modified to bail out when DIRTY or ACCESSED
+bits are missing, leaving it to mm core to fix it.
+
+This patch (of 23):
+
+The nohash HTW_IBM (Hardware Table Walk) code is unused since support for
+A2 was removed in commit fb5a515704d7 ("powerpc: Remove platforms/ wsp and
+associated pieces") (2014).
+
+The remaining supported CPUs use either no HTW (data_tlb_miss_bolted), or
+the e6500 HTW (data_tlb_miss_e6500).
+
+Link: https://lkml.kernel.org/r/cover.1719928057.git.christophe.leroy@csgroup.eu
+Link: https://lkml.kernel.org/r/820dd1385ecc931f07b0d7a0fa827b1613917ab6.1719928057.git.christophe.leroy@csgroup.eu
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: d92b5cc29c79 ("powerpc/64e: Define mmu_pte_psize static")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/nohash/mmu-e500.h |   3 +-
+ arch/powerpc/mm/nohash/tlb.c               |  57 +-----
+ arch/powerpc/mm/nohash/tlb_low_64e.S       | 195 ---------------------
+ 3 files changed, 2 insertions(+), 253 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/nohash/mmu-e500.h b/arch/powerpc/include/asm/nohash/mmu-e500.h
+index 6ddced0415cb..7dc24b8632d7 100644
+--- a/arch/powerpc/include/asm/nohash/mmu-e500.h
++++ b/arch/powerpc/include/asm/nohash/mmu-e500.h
+@@ -303,8 +303,7 @@ extern unsigned long linear_map_top;
+ extern int book3e_htw_mode;
+ #define PPC_HTW_NONE  0
+-#define PPC_HTW_IBM   1
+-#define PPC_HTW_E6500 2
++#define PPC_HTW_E6500 1
+ /*
+  * 64-bit booke platforms don't load the tlb in the tlb miss handler code.
+diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c
+index 5ffa0af4328a..a5bb87ec8578 100644
+--- a/arch/powerpc/mm/nohash/tlb.c
++++ b/arch/powerpc/mm/nohash/tlb.c
+@@ -400,9 +400,8 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
+ static void __init setup_page_sizes(void)
+ {
+       unsigned int tlb0cfg;
+-      unsigned int tlb0ps;
+       unsigned int eptcfg;
+-      int i, psize;
++      int psize;
+ #ifdef CONFIG_PPC_E500
+       unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+@@ -471,50 +470,6 @@ static void __init setup_page_sizes(void)
+               goto out;
+       }
+ #endif
+-
+-      tlb0cfg = mfspr(SPRN_TLB0CFG);
+-      tlb0ps = mfspr(SPRN_TLB0PS);
+-      eptcfg = mfspr(SPRN_EPTCFG);
+-
+-      /* Look for supported direct sizes */
+-      for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+-              struct mmu_psize_def *def = &mmu_psize_defs[psize];
+-
+-              if (tlb0ps & (1U << (def->shift - 10)))
+-                      def->flags |= MMU_PAGE_SIZE_DIRECT;
+-      }
+-
+-      /* Indirect page sizes supported ? */
+-      if ((tlb0cfg & TLBnCFG_IND) == 0 ||
+-          (tlb0cfg & TLBnCFG_PT) == 0)
+-              goto out;
+-
+-      book3e_htw_mode = PPC_HTW_IBM;
+-
+-      /* Now, we only deal with one IND page size for each
+-       * direct size. Hopefully all implementations today are
+-       * unambiguous, but we might want to be careful in the
+-       * future.
+-       */
+-      for (i = 0; i < 3; i++) {
+-              unsigned int ps, sps;
+-
+-              sps = eptcfg & 0x1f;
+-              eptcfg >>= 5;
+-              ps = eptcfg & 0x1f;
+-              eptcfg >>= 5;
+-              if (!ps || !sps)
+-                      continue;
+-              for (psize = 0; psize < MMU_PAGE_COUNT; psize++) {
+-                      struct mmu_psize_def *def = &mmu_psize_defs[psize];
+-
+-                      if (ps == (def->shift - 10))
+-                              def->flags |= MMU_PAGE_SIZE_INDIRECT;
+-                      if (sps == (def->shift - 10))
+-                              def->ind = ps + 10;
+-              }
+-      }
+-
+ out:
+       /* Cleanup array and print summary */
+       pr_info("MMU: Supported page sizes\n");
+@@ -543,10 +498,6 @@ static void __init setup_mmu_htw(void)
+        */
+       switch (book3e_htw_mode) {
+-      case PPC_HTW_IBM:
+-              patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e);
+-              patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e);
+-              break;
+ #ifdef CONFIG_PPC_E500
+       case PPC_HTW_E6500:
+               extlb_level_exc = EX_TLB_SIZE;
+@@ -577,12 +528,6 @@ static void early_init_this_mmu(void)
+               mmu_pte_psize = MMU_PAGE_2M;
+               break;
+-      case PPC_HTW_IBM:
+-              mas4 |= MAS4_INDD;
+-              mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT;
+-              mmu_pte_psize = MMU_PAGE_1M;
+-              break;
+-
+       case PPC_HTW_NONE:
+               mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
+               mmu_pte_psize = mmu_virtual_psize;
+diff --git a/arch/powerpc/mm/nohash/tlb_low_64e.S b/arch/powerpc/mm/nohash/tlb_low_64e.S
+index 7e0b8fe1c279..b0eb3f7eaed1 100644
+--- a/arch/powerpc/mm/nohash/tlb_low_64e.S
++++ b/arch/powerpc/mm/nohash/tlb_low_64e.S
+@@ -893,201 +893,6 @@ virt_page_table_tlb_miss_whacko_fault:
+       TLB_MISS_EPILOG_ERROR
+       b       exc_data_storage_book3e
+-
+-/**************************************************************
+- *                                                            *
+- * TLB miss handling for Book3E with hw page table support    *
+- *                                                            *
+- **************************************************************/
+-
+-
+-/* Data TLB miss */
+-      START_EXCEPTION(data_tlb_miss_htw)
+-      TLB_MISS_PROLOG
+-
+-      /* Now we handle the fault proper. We only save DEAR in normal
+-       * fault case since that's the only interesting values here.
+-       * We could probably also optimize by not saving SRR0/1 in the
+-       * linear mapping case but I'll leave that for later
+-       */
+-      mfspr   r14,SPRN_ESR
+-      mfspr   r16,SPRN_DEAR           /* get faulting address */
+-      srdi    r11,r16,44              /* get region */
+-      xoris   r11,r11,0xc
+-      cmpldi  cr0,r11,0               /* linear mapping ? */
+-      beq     tlb_load_linear         /* yes -> go to linear map load */
+-      cmpldi  cr1,r11,1               /* vmalloc mapping ? */
+-
+-      /* We do the user/kernel test for the PID here along with the RW test
+-       */
+-      srdi.   r11,r16,60              /* Check for user region */
+-      ld      r15,PACAPGD(r13)        /* Load user pgdir */
+-      beq     htw_tlb_miss
+-
+-      /* XXX replace the RMW cycles with immediate loads + writes */
+-1:    mfspr   r10,SPRN_MAS1
+-      rlwinm  r10,r10,0,16,1          /* Clear TID */
+-      mtspr   SPRN_MAS1,r10
+-      ld      r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */
+-      beq+    cr1,htw_tlb_miss
+-
+-      /* We got a crappy address, just fault with whatever DEAR and ESR
+-       * are here
+-       */
+-      TLB_MISS_EPILOG_ERROR
+-      b       exc_data_storage_book3e
+-
+-/* Instruction TLB miss */
+-      START_EXCEPTION(instruction_tlb_miss_htw)
+-      TLB_MISS_PROLOG
+-
+-      /* If we take a recursive fault, the second level handler may need
+-       * to know whether we are handling a data or instruction fault in
+-       * order to get to the right store fault handler. We provide that
+-       * info by keeping a crazy value for ESR in r14
+-       */
+-      li      r14,-1  /* store to exception frame is done later */
+-
+-      /* Now we handle the fault proper. We only save DEAR in the non
+-       * linear mapping case since we know the linear mapping case will
+-       * not re-enter. We could indeed optimize and also not save SRR0/1
+-       * in the linear mapping case but I'll leave that for later
+-       *
+-       * Faulting address is SRR0 which is already in r16
+-       */
+-      srdi    r11,r16,44              /* get region */
+-      xoris   r11,r11,0xc
+-      cmpldi  cr0,r11,0               /* linear mapping ? */
+-      beq     tlb_load_linear         /* yes -> go to linear map load */
+-      cmpldi  cr1,r11,1               /* vmalloc mapping ? */
+-
+-      /* We do the user/kernel test for the PID here along with the RW test
+-       */
+-      srdi.   r11,r16,60              /* Check for user region */
+-      ld      r15,PACAPGD(r13)                /* Load user pgdir */
+-      beq     htw_tlb_miss
+-
+-      /* XXX replace the RMW cycles with immediate loads + writes */
+-1:    mfspr   r10,SPRN_MAS1
+-      rlwinm  r10,r10,0,16,1                  /* Clear TID */
+-      mtspr   SPRN_MAS1,r10
+-      ld      r15,PACA_KERNELPGD(r13)         /* Load kernel pgdir */
+-      beq+    htw_tlb_miss
+-
+-      /* We got a crappy address, just fault */
+-      TLB_MISS_EPILOG_ERROR
+-      b       exc_instruction_storage_book3e
+-
+-
+-/*
+- * This is the guts of the second-level TLB miss handler for direct
+- * misses. We are entered with:
+- *
+- * r16 = virtual page table faulting address
+- * r15 = PGD pointer
+- * r14 = ESR
+- * r13 = PACA
+- * r12 = TLB exception frame in PACA
+- * r11 = crap (free to use)
+- * r10 = crap (free to use)
+- *
+- * It can be re-entered by the linear mapping miss handler. However, to
+- * avoid too much complication, it will save/restore things for us
+- */
+-htw_tlb_miss:
+-#ifdef CONFIG_PPC_KUAP
+-      mfspr   r10,SPRN_MAS1
+-      rlwinm. r10,r10,0,0x3fff0000
+-      beq-    htw_tlb_miss_fault /* KUAP fault */
+-#endif
+-      /* Search if we already have a TLB entry for that virtual address, and
+-       * if we do, bail out.
+-       *
+-       * MAS1:IND should be already set based on MAS4
+-       */
+-      PPC_TLBSRX_DOT(0,R16)
+-      beq     htw_tlb_miss_done
+-
+-      /* Now, we need to walk the page tables. First check if we are in
+-       * range.
+-       */
+-      rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4
+-      bne-    htw_tlb_miss_fault
+-
+-      /* Get the PGD pointer */
+-      cmpldi  cr0,r15,0
+-      beq-    htw_tlb_miss_fault
+-
+-      /* Get to PGD entry */
+-      rldicl  r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3
+-      clrrdi  r10,r11,3
+-      ldx     r15,r10,r15
+-      cmpdi   cr0,r15,0
+-      bge     htw_tlb_miss_fault
+-
+-      /* Get to PUD entry */
+-      rldicl  r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
+-      clrrdi  r10,r11,3
+-      ldx     r15,r10,r15
+-      cmpdi   cr0,r15,0
+-      bge     htw_tlb_miss_fault
+-
+-      /* Get to PMD entry */
+-      rldicl  r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
+-      clrrdi  r10,r11,3
+-      ldx     r15,r10,r15
+-      cmpdi   cr0,r15,0
+-      bge     htw_tlb_miss_fault
+-
+-      /* Ok, we're all right, we can now create an indirect entry for
+-       * a 1M or 256M page.
+-       *
+-       * The last trick is now that because we use "half" pages for
+-       * the HTW (1M IND is 2K and 256M IND is 32K) we need to account
+-       * for an added LSB bit to the RPN. For 64K pages, there is no
+-       * problem as we already use 32K arrays (half PTE pages), but for
+-       * 4K page we need to extract a bit from the virtual address and
+-       * insert it into the "PA52" bit of the RPN.
+-       */
+-      rlwimi  r15,r16,32-9,20,20
+-      /* Now we build the MAS:
+-       *
+-       * MAS 0   :    Fully setup with defaults in MAS4 and TLBnCFG
+-       * MAS 1   :    Almost fully setup
+-       *               - PID already updated by caller if necessary
+-       *               - TSIZE for now is base ind page size always
+-       * MAS 2   :    Use defaults
+-       * MAS 3+7 :    Needs to be done
+-       */
+-      ori     r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
+-
+-      srdi    r16,r10,32
+-      mtspr   SPRN_MAS3,r10
+-      mtspr   SPRN_MAS7,r16
+-
+-      tlbwe
+-
+-htw_tlb_miss_done:
+-      /* We don't bother with restoring DEAR or ESR since we know we are
+-       * level 0 and just going back to userland. They are only needed
+-       * if you are going to take an access fault
+-       */
+-      TLB_MISS_EPILOG_SUCCESS
+-      rfi
+-
+-htw_tlb_miss_fault:
+-      /* We need to check if it was an instruction miss. We know this
+-       * though because r14 would contain -1
+-       */
+-      cmpdi   cr0,r14,-1
+-      beq     1f
+-      mtspr   SPRN_DEAR,r16
+-      mtspr   SPRN_ESR,r14
+-      TLB_MISS_EPILOG_ERROR
+-      b       exc_data_storage_book3e
+-1:    TLB_MISS_EPILOG_ERROR
+-      b       exc_instruction_storage_book3e
+-
+ /*
+  * This is the guts of "any" level TLB miss handler for kernel linear
+  * mapping misses. We are entered with:
+-- 
+2.43.0
+
diff --git a/queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch b/queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch
new file mode 100644 (file)
index 0000000..e57ba82
--- /dev/null
@@ -0,0 +1,773 @@
+From e914138cb80f239dd64c099a01e6a1fa3d62336c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 15:51:14 +0200
+Subject: powerpc/64e: split out nohash Book3E 64-bit code
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit a898530eea3d0ba08c17a60865995a3bb468d1bc ]
+
+A reasonable chunk of nohash/tlb.c is 64-bit only code, split it out into
+a separate file.
+
+Link: https://lkml.kernel.org/r/cb2b118f9d8a86f82d01bfb9ad309d1d304480a1.1719928057.git.christophe.leroy@csgroup.eu
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: d92b5cc29c79 ("powerpc/64e: Define mmu_pte_psize static")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/nohash/Makefile  |   2 +-
+ arch/powerpc/mm/nohash/tlb.c     | 343 +----------------------------
+ arch/powerpc/mm/nohash/tlb_64e.c | 361 +++++++++++++++++++++++++++++++
+ 3 files changed, 363 insertions(+), 343 deletions(-)
+ create mode 100644 arch/powerpc/mm/nohash/tlb_64e.c
+
+diff --git a/arch/powerpc/mm/nohash/Makefile b/arch/powerpc/mm/nohash/Makefile
+index f3894e79d5f7..24b445a5fcac 100644
+--- a/arch/powerpc/mm/nohash/Makefile
++++ b/arch/powerpc/mm/nohash/Makefile
+@@ -3,7 +3,7 @@
+ ccflags-$(CONFIG_PPC64)       := $(NO_MINIMAL_TOC)
+ obj-y                         += mmu_context.o tlb.o tlb_low.o kup.o
+-obj-$(CONFIG_PPC_BOOK3E_64)   += tlb_low_64e.o book3e_pgtable.o
++obj-$(CONFIG_PPC_BOOK3E_64)   += tlb_64e.o tlb_low_64e.o book3e_pgtable.o
+ obj-$(CONFIG_40x)             += 40x.o
+ obj-$(CONFIG_44x)             += 44x.o
+ obj-$(CONFIG_PPC_8xx)         += 8xx.o
+diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c
+index a5bb87ec8578..f57dc721d063 100644
+--- a/arch/powerpc/mm/nohash/tlb.c
++++ b/arch/powerpc/mm/nohash/tlb.c
+@@ -110,28 +110,6 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
+ };
+ #endif
+-/* The variables below are currently only used on 64-bit Book3E
+- * though this will probably be made common with other nohash
+- * implementations at some point
+- */
+-#ifdef CONFIG_PPC64
+-
+-int mmu_pte_psize;            /* Page size used for PTE pages */
+-int mmu_vmemmap_psize;                /* Page size used for the virtual mem map */
+-int book3e_htw_mode;          /* HW tablewalk?  Value is PPC_HTW_* */
+-unsigned long linear_map_top; /* Top of linear mapping */
+-
+-
+-/*
+- * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
+- * exceptions.  This is used for bolted and e6500 TLB miss handlers which
+- * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
+- * this is set to zero.
+- */
+-int extlb_level_exc;
+-
+-#endif /* CONFIG_PPC64 */
+-
+ #ifdef CONFIG_PPC_E500
+ /* next_tlbcam_idx is used to round-robin tlbcam entry assignment */
+ DEFINE_PER_CPU(int, next_tlbcam_idx);
+@@ -358,326 +336,7 @@ void tlb_flush(struct mmu_gather *tlb)
+       flush_tlb_mm(tlb->mm);
+ }
+-/*
+- * Below are functions specific to the 64-bit variant of Book3E though that
+- * may change in the future
+- */
+-
+-#ifdef CONFIG_PPC64
+-
+-/*
+- * Handling of virtual linear page tables or indirect TLB entries
+- * flushing when PTE pages are freed
+- */
+-void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
+-{
+-      int tsize = mmu_psize_defs[mmu_pte_psize].enc;
+-
+-      if (book3e_htw_mode != PPC_HTW_NONE) {
+-              unsigned long start = address & PMD_MASK;
+-              unsigned long end = address + PMD_SIZE;
+-              unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
+-
+-              /* This isn't the most optimal, ideally we would factor out the
+-               * while preempt & CPU mask mucking around, or even the IPI but
+-               * it will do for now
+-               */
+-              while (start < end) {
+-                      __flush_tlb_page(tlb->mm, start, tsize, 1);
+-                      start += size;
+-              }
+-      } else {
+-              unsigned long rmask = 0xf000000000000000ul;
+-              unsigned long rid = (address & rmask) | 0x1000000000000000ul;
+-              unsigned long vpte = address & ~rmask;
+-
+-              vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
+-              vpte |= rid;
+-              __flush_tlb_page(tlb->mm, vpte, tsize, 0);
+-      }
+-}
+-
+-static void __init setup_page_sizes(void)
+-{
+-      unsigned int tlb0cfg;
+-      unsigned int eptcfg;
+-      int psize;
+-
+-#ifdef CONFIG_PPC_E500
+-      unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+-      int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E);
+-
+-      if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
+-              unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
+-              unsigned int min_pg, max_pg;
+-
+-              min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+-              max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
+-
+-              for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+-                      struct mmu_psize_def *def;
+-                      unsigned int shift;
+-
+-                      def = &mmu_psize_defs[psize];
+-                      shift = def->shift;
+-
+-                      if (shift == 0 || shift & 1)
+-                              continue;
+-
+-                      /* adjust to be in terms of 4^shift Kb */
+-                      shift = (shift - 10) >> 1;
+-
+-                      if ((shift >= min_pg) && (shift <= max_pg))
+-                              def->flags |= MMU_PAGE_SIZE_DIRECT;
+-              }
+-
+-              goto out;
+-      }
+-
+-      if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
+-              u32 tlb1cfg, tlb1ps;
+-
+-              tlb0cfg = mfspr(SPRN_TLB0CFG);
+-              tlb1cfg = mfspr(SPRN_TLB1CFG);
+-              tlb1ps = mfspr(SPRN_TLB1PS);
+-              eptcfg = mfspr(SPRN_EPTCFG);
+-
+-              if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
+-                      book3e_htw_mode = PPC_HTW_E6500;
+-
+-              /*
+-               * We expect 4K subpage size and unrestricted indirect size.
+-               * The lack of a restriction on indirect size is a Freescale
+-               * extension, indicated by PSn = 0 but SPSn != 0.
+-               */
+-              if (eptcfg != 2)
+-                      book3e_htw_mode = PPC_HTW_NONE;
+-
+-              for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+-                      struct mmu_psize_def *def = &mmu_psize_defs[psize];
+-
+-                      if (!def->shift)
+-                              continue;
+-
+-                      if (tlb1ps & (1U << (def->shift - 10))) {
+-                              def->flags |= MMU_PAGE_SIZE_DIRECT;
+-
+-                              if (book3e_htw_mode && psize == MMU_PAGE_2M)
+-                                      def->flags |= MMU_PAGE_SIZE_INDIRECT;
+-                      }
+-              }
+-
+-              goto out;
+-      }
+-#endif
+-out:
+-      /* Cleanup array and print summary */
+-      pr_info("MMU: Supported page sizes\n");
+-      for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+-              struct mmu_psize_def *def = &mmu_psize_defs[psize];
+-              const char *__page_type_names[] = {
+-                      "unsupported",
+-                      "direct",
+-                      "indirect",
+-                      "direct & indirect"
+-              };
+-              if (def->flags == 0) {
+-                      def->shift = 0; 
+-                      continue;
+-              }
+-              pr_info("  %8ld KB as %s\n", 1ul << (def->shift - 10),
+-                      __page_type_names[def->flags & 0x3]);
+-      }
+-}
+-
+-static void __init setup_mmu_htw(void)
+-{
+-      /*
+-       * If we want to use HW tablewalk, enable it by patching the TLB miss
+-       * handlers to branch to the one dedicated to it.
+-       */
+-
+-      switch (book3e_htw_mode) {
+-#ifdef CONFIG_PPC_E500
+-      case PPC_HTW_E6500:
+-              extlb_level_exc = EX_TLB_SIZE;
+-              patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
+-              patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
+-              break;
+-#endif
+-      }
+-      pr_info("MMU: Book3E HW tablewalk %s\n",
+-              book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
+-}
+-
+-/*
+- * Early initialization of the MMU TLB code
+- */
+-static void early_init_this_mmu(void)
+-{
+-      unsigned int mas4;
+-
+-      /* Set MAS4 based on page table setting */
+-
+-      mas4 = 0x4 << MAS4_WIMGED_SHIFT;
+-      switch (book3e_htw_mode) {
+-      case PPC_HTW_E6500:
+-              mas4 |= MAS4_INDD;
+-              mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
+-              mas4 |= MAS4_TLBSELD(1);
+-              mmu_pte_psize = MMU_PAGE_2M;
+-              break;
+-
+-      case PPC_HTW_NONE:
+-              mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
+-              mmu_pte_psize = mmu_virtual_psize;
+-              break;
+-      }
+-      mtspr(SPRN_MAS4, mas4);
+-
+-#ifdef CONFIG_PPC_E500
+-      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+-              unsigned int num_cams;
+-              bool map = true;
+-
+-              /* use a quarter of the TLBCAM for bolted linear map */
+-              num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+-
+-              /*
+-               * Only do the mapping once per core, or else the
+-               * transient mapping would cause problems.
+-               */
+-#ifdef CONFIG_SMP
+-              if (hweight32(get_tensr()) > 1)
+-                      map = false;
+-#endif
+-
+-              if (map)
+-                      linear_map_top = map_mem_in_cams(linear_map_top,
+-                                                       num_cams, false, true);
+-      }
+-#endif
+-
+-      /* A sync won't hurt us after mucking around with
+-       * the MMU configuration
+-       */
+-      mb();
+-}
+-
+-static void __init early_init_mmu_global(void)
+-{
+-      /* XXX This should be decided at runtime based on supported
+-       * page sizes in the TLB, but for now let's assume 16M is
+-       * always there and a good fit (which it probably is)
+-       *
+-       * Freescale booke only supports 4K pages in TLB0, so use that.
+-       */
+-      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
+-              mmu_vmemmap_psize = MMU_PAGE_4K;
+-      else
+-              mmu_vmemmap_psize = MMU_PAGE_16M;
+-
+-      /* XXX This code only checks for TLB 0 capabilities and doesn't
+-       *     check what page size combos are supported by the HW. It
+-       *     also doesn't handle the case where a separate array holds
+-       *     the IND entries from the array loaded by the PT.
+-       */
+-      /* Look for supported page sizes */
+-      setup_page_sizes();
+-
+-      /* Look for HW tablewalk support */
+-      setup_mmu_htw();
+-
+-#ifdef CONFIG_PPC_E500
+-      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+-              if (book3e_htw_mode == PPC_HTW_NONE) {
+-                      extlb_level_exc = EX_TLB_SIZE;
+-                      patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
+-                      patch_exception(0x1e0,
+-                              exc_instruction_tlb_miss_bolted_book3e);
+-              }
+-      }
+-#endif
+-
+-      /* Set the global containing the top of the linear mapping
+-       * for use by the TLB miss code
+-       */
+-      linear_map_top = memblock_end_of_DRAM();
+-
+-      ioremap_bot = IOREMAP_BASE;
+-}
+-
+-static void __init early_mmu_set_memory_limit(void)
+-{
+-#ifdef CONFIG_PPC_E500
+-      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+-              /*
+-               * Limit memory so we dont have linear faults.
+-               * Unlike memblock_set_current_limit, which limits
+-               * memory available during early boot, this permanently
+-               * reduces the memory available to Linux.  We need to
+-               * do this because highmem is not supported on 64-bit.
+-               */
+-              memblock_enforce_memory_limit(linear_map_top);
+-      }
+-#endif
+-
+-      memblock_set_current_limit(linear_map_top);
+-}
+-
+-/* boot cpu only */
+-void __init early_init_mmu(void)
+-{
+-      early_init_mmu_global();
+-      early_init_this_mmu();
+-      early_mmu_set_memory_limit();
+-}
+-
+-void early_init_mmu_secondary(void)
+-{
+-      early_init_this_mmu();
+-}
+-
+-void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+-                              phys_addr_t first_memblock_size)
+-{
+-      /* On non-FSL Embedded 64-bit, we adjust the RMA size to match
+-       * the bolted TLB entry. We know for now that only 1G
+-       * entries are supported though that may eventually
+-       * change.
+-       *
+-       * on FSL Embedded 64-bit, usually all RAM is bolted, but with
+-       * unusual memory sizes it's possible for some RAM to not be mapped
+-       * (such RAM is not used at all by Linux, since we don't support
+-       * highmem on 64-bit).  We limit ppc64_rma_size to what would be
+-       * mappable if this memblock is the only one.  Additional memblocks
+-       * can only increase, not decrease, the amount that ends up getting
+-       * mapped.  We still limit max to 1G even if we'll eventually map
+-       * more.  This is due to what the early init code is set up to do.
+-       *
+-       * We crop it to the size of the first MEMBLOCK to
+-       * avoid going over total available memory just in case...
+-       */
+-#ifdef CONFIG_PPC_E500
+-      if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+-              unsigned long linear_sz;
+-              unsigned int num_cams;
+-
+-              /* use a quarter of the TLBCAM for bolted linear map */
+-              num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+-
+-              linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
+-                                          true, true);
+-
+-              ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
+-      } else
+-#endif
+-              ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
+-
+-      /* Finally limit subsequent allocations */
+-      memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
+-}
+-#else /* ! CONFIG_PPC64 */
++#ifndef CONFIG_PPC64
+ void __init early_init_mmu(void)
+ {
+       unsigned long root = of_get_flat_dt_root();
+diff --git a/arch/powerpc/mm/nohash/tlb_64e.c b/arch/powerpc/mm/nohash/tlb_64e.c
+new file mode 100644
+index 000000000000..1dcda261554c
+--- /dev/null
++++ b/arch/powerpc/mm/nohash/tlb_64e.c
+@@ -0,0 +1,361 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright 2008,2009 Ben Herrenschmidt <benh@kernel.crashing.org>
++ *                     IBM Corp.
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ */
++
++#include <linux/kernel.h>
++#include <linux/export.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/pagemap.h>
++#include <linux/memblock.h>
++
++#include <asm/pgalloc.h>
++#include <asm/tlbflush.h>
++#include <asm/tlb.h>
++#include <asm/code-patching.h>
++#include <asm/cputhreads.h>
++
++#include <mm/mmu_decl.h>
++
++/* The variables below are currently only used on 64-bit Book3E
++ * though this will probably be made common with other nohash
++ * implementations at some point
++ */
++int mmu_pte_psize;            /* Page size used for PTE pages */
++int mmu_vmemmap_psize;                /* Page size used for the virtual mem map */
++int book3e_htw_mode;          /* HW tablewalk?  Value is PPC_HTW_* */
++unsigned long linear_map_top; /* Top of linear mapping */
++
++
++/*
++ * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
++ * exceptions.  This is used for bolted and e6500 TLB miss handlers which
++ * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
++ * this is set to zero.
++ */
++int extlb_level_exc;
++
++/*
++ * Handling of virtual linear page tables or indirect TLB entries
++ * flushing when PTE pages are freed
++ */
++void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
++{
++      int tsize = mmu_psize_defs[mmu_pte_psize].enc;
++
++      if (book3e_htw_mode != PPC_HTW_NONE) {
++              unsigned long start = address & PMD_MASK;
++              unsigned long end = address + PMD_SIZE;
++              unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
++
++              /* This isn't the most optimal, ideally we would factor out the
++               * while preempt & CPU mask mucking around, or even the IPI but
++               * it will do for now
++               */
++              while (start < end) {
++                      __flush_tlb_page(tlb->mm, start, tsize, 1);
++                      start += size;
++              }
++      } else {
++              unsigned long rmask = 0xf000000000000000ul;
++              unsigned long rid = (address & rmask) | 0x1000000000000000ul;
++              unsigned long vpte = address & ~rmask;
++
++              vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
++              vpte |= rid;
++              __flush_tlb_page(tlb->mm, vpte, tsize, 0);
++      }
++}
++
++static void __init setup_page_sizes(void)
++{
++      unsigned int tlb0cfg;
++      unsigned int eptcfg;
++      int psize;
++
++#ifdef CONFIG_PPC_E500
++      unsigned int mmucfg = mfspr(SPRN_MMUCFG);
++      int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E);
++
++      if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
++              unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
++              unsigned int min_pg, max_pg;
++
++              min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
++              max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
++
++              for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
++                      struct mmu_psize_def *def;
++                      unsigned int shift;
++
++                      def = &mmu_psize_defs[psize];
++                      shift = def->shift;
++
++                      if (shift == 0 || shift & 1)
++                              continue;
++
++                      /* adjust to be in terms of 4^shift Kb */
++                      shift = (shift - 10) >> 1;
++
++                      if ((shift >= min_pg) && (shift <= max_pg))
++                              def->flags |= MMU_PAGE_SIZE_DIRECT;
++              }
++
++              goto out;
++      }
++
++      if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
++              u32 tlb1cfg, tlb1ps;
++
++              tlb0cfg = mfspr(SPRN_TLB0CFG);
++              tlb1cfg = mfspr(SPRN_TLB1CFG);
++              tlb1ps = mfspr(SPRN_TLB1PS);
++              eptcfg = mfspr(SPRN_EPTCFG);
++
++              if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
++                      book3e_htw_mode = PPC_HTW_E6500;
++
++              /*
++               * We expect 4K subpage size and unrestricted indirect size.
++               * The lack of a restriction on indirect size is a Freescale
++               * extension, indicated by PSn = 0 but SPSn != 0.
++               */
++              if (eptcfg != 2)
++                      book3e_htw_mode = PPC_HTW_NONE;
++
++              for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
++                      struct mmu_psize_def *def = &mmu_psize_defs[psize];
++
++                      if (!def->shift)
++                              continue;
++
++                      if (tlb1ps & (1U << (def->shift - 10))) {
++                              def->flags |= MMU_PAGE_SIZE_DIRECT;
++
++                              if (book3e_htw_mode && psize == MMU_PAGE_2M)
++                                      def->flags |= MMU_PAGE_SIZE_INDIRECT;
++                      }
++              }
++
++              goto out;
++      }
++#endif
++out:
++      /* Cleanup array and print summary */
++      pr_info("MMU: Supported page sizes\n");
++      for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
++              struct mmu_psize_def *def = &mmu_psize_defs[psize];
++              const char *__page_type_names[] = {
++                      "unsupported",
++                      "direct",
++                      "indirect",
++                      "direct & indirect"
++              };
++              if (def->flags == 0) {
++                      def->shift = 0;
++                      continue;
++              }
++              pr_info("  %8ld KB as %s\n", 1ul << (def->shift - 10),
++                      __page_type_names[def->flags & 0x3]);
++      }
++}
++
++static void __init setup_mmu_htw(void)
++{
++      /*
++       * If we want to use HW tablewalk, enable it by patching the TLB miss
++       * handlers to branch to the one dedicated to it.
++       */
++
++      switch (book3e_htw_mode) {
++#ifdef CONFIG_PPC_E500
++      case PPC_HTW_E6500:
++              extlb_level_exc = EX_TLB_SIZE;
++              patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
++              patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
++              break;
++#endif
++      }
++      pr_info("MMU: Book3E HW tablewalk %s\n",
++              book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
++}
++
++/*
++ * Early initialization of the MMU TLB code
++ */
++static void early_init_this_mmu(void)
++{
++      unsigned int mas4;
++
++      /* Set MAS4 based on page table setting */
++
++      mas4 = 0x4 << MAS4_WIMGED_SHIFT;
++      switch (book3e_htw_mode) {
++      case PPC_HTW_E6500:
++              mas4 |= MAS4_INDD;
++              mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
++              mas4 |= MAS4_TLBSELD(1);
++              mmu_pte_psize = MMU_PAGE_2M;
++              break;
++
++      case PPC_HTW_NONE:
++              mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
++              mmu_pte_psize = mmu_virtual_psize;
++              break;
++      }
++      mtspr(SPRN_MAS4, mas4);
++
++#ifdef CONFIG_PPC_E500
++      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
++              unsigned int num_cams;
++              bool map = true;
++
++              /* use a quarter of the TLBCAM for bolted linear map */
++              num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
++
++              /*
++               * Only do the mapping once per core, or else the
++               * transient mapping would cause problems.
++               */
++#ifdef CONFIG_SMP
++              if (hweight32(get_tensr()) > 1)
++                      map = false;
++#endif
++
++              if (map)
++                      linear_map_top = map_mem_in_cams(linear_map_top,
++                                                       num_cams, false, true);
++      }
++#endif
++
++      /* A sync won't hurt us after mucking around with
++       * the MMU configuration
++       */
++      mb();
++}
++
++static void __init early_init_mmu_global(void)
++{
++      /* XXX This should be decided at runtime based on supported
++       * page sizes in the TLB, but for now let's assume 16M is
++       * always there and a good fit (which it probably is)
++       *
++       * Freescale booke only supports 4K pages in TLB0, so use that.
++       */
++      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
++              mmu_vmemmap_psize = MMU_PAGE_4K;
++      else
++              mmu_vmemmap_psize = MMU_PAGE_16M;
++
++      /* XXX This code only checks for TLB 0 capabilities and doesn't
++       *     check what page size combos are supported by the HW. It
++       *     also doesn't handle the case where a separate array holds
++       *     the IND entries from the array loaded by the PT.
++       */
++      /* Look for supported page sizes */
++      setup_page_sizes();
++
++      /* Look for HW tablewalk support */
++      setup_mmu_htw();
++
++#ifdef CONFIG_PPC_E500
++      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
++              if (book3e_htw_mode == PPC_HTW_NONE) {
++                      extlb_level_exc = EX_TLB_SIZE;
++                      patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
++                      patch_exception(0x1e0,
++                              exc_instruction_tlb_miss_bolted_book3e);
++              }
++      }
++#endif
++
++      /* Set the global containing the top of the linear mapping
++       * for use by the TLB miss code
++       */
++      linear_map_top = memblock_end_of_DRAM();
++
++      ioremap_bot = IOREMAP_BASE;
++}
++
++static void __init early_mmu_set_memory_limit(void)
++{
++#ifdef CONFIG_PPC_E500
++      if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
++              /*
++               * Limit memory so we dont have linear faults.
++               * Unlike memblock_set_current_limit, which limits
++               * memory available during early boot, this permanently
++               * reduces the memory available to Linux.  We need to
++               * do this because highmem is not supported on 64-bit.
++               */
++              memblock_enforce_memory_limit(linear_map_top);
++      }
++#endif
++
++      memblock_set_current_limit(linear_map_top);
++}
++
++/* boot cpu only */
++void __init early_init_mmu(void)
++{
++      early_init_mmu_global();
++      early_init_this_mmu();
++      early_mmu_set_memory_limit();
++}
++
++void early_init_mmu_secondary(void)
++{
++      early_init_this_mmu();
++}
++
++void setup_initial_memory_limit(phys_addr_t first_memblock_base,
++                              phys_addr_t first_memblock_size)
++{
++      /* On non-FSL Embedded 64-bit, we adjust the RMA size to match
++       * the bolted TLB entry. We know for now that only 1G
++       * entries are supported though that may eventually
++       * change.
++       *
++       * on FSL Embedded 64-bit, usually all RAM is bolted, but with
++       * unusual memory sizes it's possible for some RAM to not be mapped
++       * (such RAM is not used at all by Linux, since we don't support
++       * highmem on 64-bit).  We limit ppc64_rma_size to what would be
++       * mappable if this memblock is the only one.  Additional memblocks
++       * can only increase, not decrease, the amount that ends up getting
++       * mapped.  We still limit max to 1G even if we'll eventually map
++       * more.  This is due to what the early init code is set up to do.
++       *
++       * We crop it to the size of the first MEMBLOCK to
++       * avoid going over total available memory just in case...
++       */
++#ifdef CONFIG_PPC_E500
++      if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
++              unsigned long linear_sz;
++              unsigned int num_cams;
++
++              /* use a quarter of the TLBCAM for bolted linear map */
++              num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
++
++              linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
++                                          true, true);
++
++              ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
++      } else
++#endif
++              ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
++
++      /* Finally limit subsequent allocations */
++      memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
++}
+-- 
+2.43.0
+
diff --git a/queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch b/queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch
new file mode 100644 (file)
index 0000000..6126bd5
--- /dev/null
@@ -0,0 +1,73 @@
+From 1ebf3fbd3b35addfa7757a95b7b55d61d93861f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 13:28:07 +0200
+Subject: powerpc/vdso: Don't discard rela sections
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 6114139c3bdde992f4a19264e4f9bfc100d8d776 ]
+
+After building the VDSO, there is a verification that it contains
+no dynamic relocation, see commit aff69273af61 ("vdso: Improve
+cmd_vdso_check to check all dynamic relocations").
+
+This verification uses readelf -r and doesn't work if rela sections
+are discarded.
+
+Fixes: 8ad57add77d3 ("powerpc/build: vdso linker warning for orphan sections")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/45c3e6fc76cad05ad2cac0f5b5dfb4fae86dc9d6.1724153239.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/vdso/vdso32.lds.S | 4 +++-
+ arch/powerpc/kernel/vdso/vdso64.lds.S | 4 ++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/kernel/vdso/vdso32.lds.S b/arch/powerpc/kernel/vdso/vdso32.lds.S
+index 426e1ccc6971..8f57107000a2 100644
+--- a/arch/powerpc/kernel/vdso/vdso32.lds.S
++++ b/arch/powerpc/kernel/vdso/vdso32.lds.S
+@@ -74,6 +74,8 @@ SECTIONS
+       .got            : { *(.got) }                   :text
+       .plt            : { *(.plt) }
++      .rela.dyn       : { *(.rela .rela*) }
++
+       _end = .;
+       __end = .;
+       PROVIDE(end = .);
+@@ -87,7 +89,7 @@ SECTIONS
+               *(.branch_lt)
+               *(.data .data.* .gnu.linkonce.d.* .sdata*)
+               *(.bss .sbss .dynbss .dynsbss)
+-              *(.got1 .glink .iplt .rela*)
++              *(.got1 .glink .iplt)
+       }
+ }
+diff --git a/arch/powerpc/kernel/vdso/vdso64.lds.S b/arch/powerpc/kernel/vdso/vdso64.lds.S
+index bda6c8cdd459..400819258c06 100644
+--- a/arch/powerpc/kernel/vdso/vdso64.lds.S
++++ b/arch/powerpc/kernel/vdso/vdso64.lds.S
+@@ -69,7 +69,7 @@ SECTIONS
+       .eh_frame_hdr   : { *(.eh_frame_hdr) }          :text   :eh_frame_hdr
+       .eh_frame       : { KEEP (*(.eh_frame)) }       :text
+       .gcc_except_table : { *(.gcc_except_table) }
+-      .rela.dyn ALIGN(8) : { *(.rela.dyn) }
++      .rela.dyn ALIGN(8) : { *(.rela .rela*) }
+       .got ALIGN(8)   : { *(.got .toc) }
+@@ -86,7 +86,7 @@ SECTIONS
+               *(.data .data.* .gnu.linkonce.d.* .sdata*)
+               *(.bss .sbss .dynbss .dynsbss)
+               *(.opd)
+-              *(.glink .iplt .plt .rela*)
++              *(.glink .iplt .plt)
+       }
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch b/queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch
new file mode 100644 (file)
index 0000000..a30b206
--- /dev/null
@@ -0,0 +1,41 @@
+From fcd7693588f55b07bbf63aef27102535ca245611 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Aug 2024 08:52:30 +0200
+Subject: riscv: Do not restrict memory size because of linear mapping on nommu
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 5f771088a2b5edd6f2c5c9f34484ca18dc389f3e ]
+
+It makes no sense to restrict physical memory size because of linear
+mapping size constraints when there is no linear mapping, so only do
+that when mmu is enabled.
+
+Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Closes: https://lore.kernel.org/linux-riscv/CAMuHMdW0bnJt5GMRtOZGkTiM7GK4UaLJCDMF_Ouq++fnDKi3_A@mail.gmail.com/
+Fixes: 3b6564427aea ("riscv: Fix linear mapping checks for non-contiguous memory regions")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20240827065230.145021-1-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/mm/init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index abe7a7a7686c..3245bb525212 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -235,7 +235,7 @@ static void __init setup_bootmem(void)
+        * The size of the linear page mapping may restrict the amount of
+        * usable RAM.
+        */
+-      if (IS_ENABLED(CONFIG_64BIT)) {
++      if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) {
+               max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE;
+               memblock_cap_memory_range(phys_ram_base,
+                                         max_mapped_addr - phys_ram_base);
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-fix-toolchain-vector-detection.patch b/queue-6.6/riscv-fix-toolchain-vector-detection.patch
new file mode 100644 (file)
index 0000000..47a194c
--- /dev/null
@@ -0,0 +1,44 @@
+From c33dc3fb77fb63f1ee00cb422132365e1b0f0654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 00:11:31 +0000
+Subject: riscv: Fix toolchain vector detection
+
+From: Anton Blanchard <antonb@tenstorrent.com>
+
+[ Upstream commit 5ba7a75a53dffbf727e842b5847859bb482ac4aa ]
+
+A recent change to gcc flags rv64iv as no longer valid:
+
+   cc1: sorry, unimplemented: Currently the 'V' implementation
+   requires the 'M' extension
+
+and as a result vector support is disabled. Fix this by adding m
+to our toolchain vector detection code.
+
+Signed-off-by: Anton Blanchard <antonb@tenstorrent.com>
+Fixes: fa8e7cce55da ("riscv: Enable Vector code to be built")
+Link: https://lore.kernel.org/r/20240819001131.1738806-1-antonb@tenstorrent.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index c785a0200573..d5d70dc5656e 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -489,8 +489,8 @@ config RISCV_ISA_SVPBMT
+ config TOOLCHAIN_HAS_V
+       bool
+       default y
+-      depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv)
+-      depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv)
++      depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64imv)
++      depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv)
+       depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
+       depends on AS_HAS_OPTION_ARCH
+-- 
+2.43.0
+
index 49072c8f7390d850a277f53a160b5bb3fca8df9f..f01fd0e9715f96c11c680b8361a68ac90c5a105f 100644 (file)
@@ -224,3 +224,39 @@ uprobes-use-kzalloc-to-allocate-xol-area.patch
 perf-aux-fix-aux-buffer-serialization.patch
 mm-vmscan-use-folio_migratetype-instead-of-get_pageb.patch
 revert-mm-skip-cma-pages-when-they-are-not-available.patch
+workqueue-wq_watchdog_touch-is-always-called-with-va.patch
+workqueue-improve-scalability-of-workqueue-watchdog-.patch
+acpi-processor-return-an-error-if-acpi_processor_get.patch
+acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch
+arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch
+arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch
+can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch
+can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch
+can-mcp251xfd-clarify-the-meaning-of-timestamp.patch
+can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch
+drm-amd-add-gfx12-swizzle-mode-defs.patch
+drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch
+ata-libata-scsi-remove-redundant-sense_buffer-memset.patch
+ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch
+crypto-starfive-align-rsa-input-data-to-32-bit.patch
+crypto-starfive-fix-nent-assignment-in-rsa-dec.patch
+clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch
+powerpc-64e-remove-unused-ibm-htw-code.patch
+powerpc-64e-split-out-nohash-book3e-64-bit-code.patch
+powerpc-64e-define-mmu_pte_psize-static.patch
+powerpc-vdso-don-t-discard-rela-sections.patch
+asoc-tegra-fix-cbb-error-during-probe.patch
+nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch
+nvme-pci-allocate-tagset-on-reset-if-necessary.patch
+asoc-sof-topology-clear-sof-link-platform-name-upon-.patch
+asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch
+clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch
+clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch
+drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch
+drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch
+gpio-rockchip-fix-of-node-leak-in-probe.patch
+gpio-modepin-enable-module-autoloading.patch
+smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch
+riscv-fix-toolchain-vector-detection.patch
+riscv-do-not-restrict-memory-size-because-of-linear-.patch
+ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch
diff --git a/queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch b/queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch
new file mode 100644 (file)
index 0000000..7353fb0
--- /dev/null
@@ -0,0 +1,39 @@
+From fb34dd92610955be3490c50f64fdf446df4a0130 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Sep 2024 10:53:23 -0300
+Subject: smb: client: fix double put of @cfile in smb2_rename_path()
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 3523a3df03c6f04f7ea9c2e7050102657e331a4f ]
+
+If smb2_set_path_attr() is called with a valid @cfile and returned
+-EINVAL, we need to call cifs_get_writable_path() again as the
+reference of @cfile was already dropped by previous smb2_compound_op()
+call.
+
+Fixes: 71f15c90e785 ("smb: client: retry compound request without reusing lease")
+Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Cc: David Howells <dhowells@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2inode.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
+index fc82d5ebf923..dd8acd207752 100644
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -1106,6 +1106,8 @@ int smb2_rename_path(const unsigned int xid,
+                                 co, DELETE, SMB2_OP_RENAME, cfile, source_dentry);
+       if (rc == -EINVAL) {
+               cifs_dbg(FYI, "invalid lease key, resending request without lease");
++              cifs_get_writable_path(tcon, from_name,
++                                     FIND_WR_WITH_DELETE, &cfile);
+               rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb,
+                                 co, DELETE, SMB2_OP_RENAME, cfile, NULL);
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch b/queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch
new file mode 100644 (file)
index 0000000..f786ad2
--- /dev/null
@@ -0,0 +1,69 @@
+From be71ecd2d4eef6adad8b09abefe0dcb03542d774 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 11:13:48 +0800
+Subject: ublk_drv: fix NULL pointer dereference in ublk_ctrl_start_recovery()
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit e58f5142f88320a5b1449f96a146f2f24615c5c7 ]
+
+When two UBLK_CMD_START_USER_RECOVERY commands are submitted, the
+first one sets 'ubq->ubq_daemon' to NULL, and the second one triggers
+WARN in ublk_queue_reinit() and subsequently a NULL pointer dereference
+issue.
+
+Fix it by adding the check in ublk_ctrl_start_recovery() and return
+immediately in case of zero 'ub->nr_queues_ready'.
+
+  BUG: kernel NULL pointer dereference, address: 0000000000000028
+  RIP: 0010:ublk_ctrl_start_recovery.constprop.0+0x82/0x180
+  Call Trace:
+   <TASK>
+   ? __die+0x20/0x70
+   ? page_fault_oops+0x75/0x170
+   ? exc_page_fault+0x64/0x140
+   ? asm_exc_page_fault+0x22/0x30
+   ? ublk_ctrl_start_recovery.constprop.0+0x82/0x180
+   ublk_ctrl_uring_cmd+0x4f7/0x6c0
+   ? pick_next_task_idle+0x26/0x40
+   io_uring_cmd+0x9a/0x1b0
+   io_issue_sqe+0x193/0x3f0
+   io_wq_submit_work+0x9b/0x390
+   io_worker_handle_work+0x165/0x360
+   io_wq_worker+0xcb/0x2f0
+   ? finish_task_switch.isra.0+0x203/0x290
+   ? finish_task_switch.isra.0+0x203/0x290
+   ? __pfx_io_wq_worker+0x10/0x10
+   ret_from_fork+0x2d/0x50
+   ? __pfx_io_wq_worker+0x10/0x10
+   ret_from_fork_asm+0x1a/0x30
+   </TASK>
+
+Fixes: c732a852b419 ("ublk_drv: add START_USER_RECOVERY and END_USER_RECOVERY support")
+Reported-and-tested-by: Changhui Zhong <czhong@redhat.com>
+Closes: https://lore.kernel.org/all/CAGVVp+UvLiS+bhNXV-h2icwX1dyybbYHeQUuH7RYqUvMQf6N3w@mail.gmail.com
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Li Nan <linan122@huawei.com>
+Link: https://lore.kernel.org/r/20240904031348.4139545-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ublk_drv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index f4e0573c4711..bf7f68e90953 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -2603,6 +2603,8 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub,
+       mutex_lock(&ub->mutex);
+       if (!ublk_can_use_recovery(ub))
+               goto out_unlock;
++      if (!ub->nr_queues_ready)
++              goto out_unlock;
+       /*
+        * START_RECOVERY is only allowd after:
+        *
+-- 
+2.43.0
+
diff --git a/queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch b/queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch
new file mode 100644 (file)
index 0000000..da1b07e
--- /dev/null
@@ -0,0 +1,77 @@
+From d1f93f72f0cd3e8694b3b9b6f5a2c44cefefc893 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jun 2024 21:42:45 +1000
+Subject: workqueue: Improve scalability of workqueue watchdog touch
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 98f887f820c993e05a12e8aa816c80b8661d4c87 ]
+
+On a ~2000 CPU powerpc system, hard lockups have been observed in the
+workqueue code when stop_machine runs (in this case due to CPU hotplug).
+This is due to lots of CPUs spinning in multi_cpu_stop, calling
+touch_nmi_watchdog() which ends up calling wq_watchdog_touch().
+wq_watchdog_touch() writes to the global variable wq_watchdog_touched,
+and that can find itself in the same cacheline as other important
+workqueue data, which slows down operations to the point of lockups.
+
+In the case of the following abridged trace, worker_pool_idr was in
+the hot line, causing the lockups to always appear at idr_find.
+
+  watchdog: CPU 1125 self-detected hard LOCKUP @ idr_find
+  Call Trace:
+  get_work_pool
+  __queue_work
+  call_timer_fn
+  run_timer_softirq
+  __do_softirq
+  do_softirq_own_stack
+  irq_exit
+  timer_interrupt
+  decrementer_common_virt
+  * interrupt: 900 (timer) at multi_cpu_stop
+  multi_cpu_stop
+  cpu_stopper_thread
+  smpboot_thread_fn
+  kthread
+
+Fix this by having wq_watchdog_touch() only write to the line if the
+last time a touch was recorded exceeds 1/4 of the watchdog threshold.
+
+Reported-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/workqueue.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index a1665c2e04b4..7fa1c7c9151a 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -6456,12 +6456,18 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
+ notrace void wq_watchdog_touch(int cpu)
+ {
++      unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ;
++      unsigned long touch_ts = READ_ONCE(wq_watchdog_touched);
++      unsigned long now = jiffies;
++
+       if (cpu >= 0)
+-              per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies;
++              per_cpu(wq_watchdog_touched_cpu, cpu) = now;
+       else
+               WARN_ONCE(1, "%s should be called with valid CPU", __func__);
+-      wq_watchdog_touched = jiffies;
++      /* Don't unnecessarily store to global cacheline */
++      if (time_after(now, touch_ts + thresh / 4))
++              WRITE_ONCE(wq_watchdog_touched, jiffies);
+ }
+ static void wq_watchdog_set_thresh(unsigned long thresh)
+-- 
+2.43.0
+
diff --git a/queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch b/queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch
new file mode 100644 (file)
index 0000000..d1634b4
--- /dev/null
@@ -0,0 +1,36 @@
+From 2c2744a833641a616f33ca086b64971a690a880d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jun 2024 21:42:44 +1000
+Subject: workqueue: wq_watchdog_touch is always called with valid CPU
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 18e24deb1cc92f2068ce7434a94233741fbd7771 ]
+
+Warn in the case it is called with cpu == -1. This does not appear
+to happen anywhere.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/workqueue.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 8c7bafbee1b1..a1665c2e04b4 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -6458,6 +6458,8 @@ notrace void wq_watchdog_touch(int cpu)
+ {
+       if (cpu >= 0)
+               per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies;
++      else
++              WARN_ONCE(1, "%s should be called with valid CPU", __func__);
+       wq_watchdog_touched = jiffies;
+ }
+-- 
+2.43.0
+