]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Thu, 6 Apr 2023 11:22:44 +0000 (07:22 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 6 Apr 2023 11:22:44 +0000 (07:22 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
25 files changed:
queue-5.15/arm64-dts-imx8mp-correct-usb-clocks.patch [new file with mode: 0644]
queue-5.15/bpf-hash-map-avoid-deadlock-with-suitable-hash-mask.patch [new file with mode: 0644]
queue-5.15/drm-amdgpu-fix-amdgpu_job_free_resources-v2.patch [new file with mode: 0644]
queue-5.15/drm-amdgpu-prevent-race-between-late-signaled-fences.patch [new file with mode: 0644]
queue-5.15/iavf-iavf_main-actually-log-src-mask-when-talking-ab.patch [new file with mode: 0644]
queue-5.15/iavf-return-errno-code-instead-of-status-code.patch [new file with mode: 0644]
queue-5.15/kvm-arm64-pmu-fix-get_one_reg-for-vpmc-regs-to-retur.patch [new file with mode: 0644]
queue-5.15/nfsd-fix-sparse-warning.patch [new file with mode: 0644]
queue-5.15/nfsd-pass-range-end-to-vfs_fsync_range-instead-of-co.patch [new file with mode: 0644]
queue-5.15/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch [new file with mode: 0644]
queue-5.15/ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch [new file with mode: 0644]
queue-5.15/ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch [new file with mode: 0644]
queue-5.15/platform-x86-int3472-discrete-ensure-the-clk-power-e.patch [new file with mode: 0644]
queue-5.15/platform-x86-int3472-split-into-2-drivers.patch [new file with mode: 0644]
queue-5.15/rdma-irdma-do-not-request-2-level-pbles-for-cq-alloc.patch [new file with mode: 0644]
queue-5.15/serial-8250_exar-derive-nr_ports-from-pci-id-for-acc.patch [new file with mode: 0644]
queue-5.15/serial-exar-add-support-for-sealevel-7xxxc-serial-ca.patch [new file with mode: 0644]
queue-5.15/series [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-determine-the-cache-level-from-dts.patch [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-fix-missing-free_irq-in-error-path.patch [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-fix-missing-iounmap-in-error-path-.patch [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-fix-missing-of_node_put-in-sifive_.patch [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-reduce-printing-on-init.patch [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-rename-sifive-l2-cache-to-composab.patch [new file with mode: 0644]
queue-5.15/soc-sifive-ccache-use-pr_fmt-to-remove-ccache-prefix.patch [new file with mode: 0644]

diff --git a/queue-5.15/arm64-dts-imx8mp-correct-usb-clocks.patch b/queue-5.15/arm64-dts-imx8mp-correct-usb-clocks.patch
new file mode 100644 (file)
index 0000000..7a9b148
--- /dev/null
@@ -0,0 +1,74 @@
+From de4dcce44501a59369374ea4bc8a5e3c42b5d7c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Sep 2022 22:54:23 +0800
+Subject: arm64: dts: imx8mp: correct usb clocks
+
+From: Li Jun <jun.li@nxp.com>
+
+[ Upstream commit 8a1ed98fe0f2e7669f0409de0f46f317b275f8be ]
+
+After commit cf7f3f4fa9e5 ("clk: imx8mp: fix usb_root_clk parent"),
+usb_root_clk is no longer for suspend clock so update dts accordingly
+to use right bus clock and suspend clock.
+
+Fixes: fb8587a2c165 ("arm64: dtsi: imx8mp: add usb nodes")
+Cc: stable@vger.kernel.org # ed1f4ccfe947: clk: imx: imx8mp: add shared clk gate for usb suspend clk
+Cc: stable@vger.kernel.org # v5.19+
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mp.dtsi | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index ab670b5d641b1..7f338c28a5173 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -890,7 +890,7 @@
+                       compatible = "fsl,imx8mp-dwc3";
+                       reg = <0x32f10100 0x8>;
+                       clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+-                               <&clk IMX8MP_CLK_USB_ROOT>;
++                               <&clk IMX8MP_CLK_USB_SUSP>;
+                       clock-names = "hsio", "suspend";
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+@@ -902,9 +902,9 @@
+                       usb_dwc3_0: usb@38100000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x38100000 0x10000>;
+-                              clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
++                              clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+                                        <&clk IMX8MP_CLK_USB_CORE_REF>,
+-                                       <&clk IMX8MP_CLK_USB_ROOT>;
++                                       <&clk IMX8MP_CLK_USB_SUSP>;
+                               clock-names = "bus_early", "ref", "suspend";
+                               assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+                               assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+@@ -931,7 +931,7 @@
+                       compatible = "fsl,imx8mp-dwc3";
+                       reg = <0x32f10108 0x8>;
+                       clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+-                               <&clk IMX8MP_CLK_USB_ROOT>;
++                               <&clk IMX8MP_CLK_USB_SUSP>;
+                       clock-names = "hsio", "suspend";
+                       interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+@@ -943,9 +943,9 @@
+                       usb_dwc3_1: usb@38200000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x38200000 0x10000>;
+-                              clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
++                              clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+                                        <&clk IMX8MP_CLK_USB_CORE_REF>,
+-                                       <&clk IMX8MP_CLK_USB_ROOT>;
++                                       <&clk IMX8MP_CLK_USB_SUSP>;
+                               clock-names = "bus_early", "ref", "suspend";
+                               assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+                               assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+-- 
+2.39.2
+
diff --git a/queue-5.15/bpf-hash-map-avoid-deadlock-with-suitable-hash-mask.patch b/queue-5.15/bpf-hash-map-avoid-deadlock-with-suitable-hash-mask.patch
new file mode 100644 (file)
index 0000000..b918031
--- /dev/null
@@ -0,0 +1,68 @@
+From 9f4e0fe1857fa8c855ae8faa4d075cca2740fcd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 17:29:01 +0800
+Subject: bpf: hash map, avoid deadlock with suitable hash mask
+
+From: Tonghao Zhang <tong@infragraf.org>
+
+[ Upstream commit 9f907439dc80e4a2fcfb949927b36c036468dbb3 ]
+
+The deadlock still may occur while accessed in NMI and non-NMI
+context. Because in NMI, we still may access the same bucket but with
+different map_locked index.
+
+For example, on the same CPU, .max_entries = 2, we update the hash map,
+with key = 4, while running bpf prog in NMI nmi_handle(), to update
+hash map with key = 20, so it will have the same bucket index but have
+different map_locked index.
+
+To fix this issue, using min mask to hash again.
+
+Fixes: 20b6cc34ea74 ("bpf: Avoid hashtab deadlock with map_locked")
+Signed-off-by: Tonghao Zhang <tong@infragraf.org>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yhs@fb.com>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: KP Singh <kpsingh@kernel.org>
+Cc: Stanislav Fomichev <sdf@google.com>
+Cc: Hao Luo <haoluo@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Hou Tao <houtao1@huawei.com>
+Acked-by: Yonghong Song <yhs@fb.com>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20230111092903.92389-1-tong@infragraf.org
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/hashtab.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index e7f45a966e6b5..10b37773d9e47 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -163,7 +163,7 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab,
+       unsigned long flags;
+       bool use_raw_lock;
+-      hash = hash & HASHTAB_MAP_LOCK_MASK;
++      hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1);
+       use_raw_lock = htab_use_raw_lock(htab);
+       if (use_raw_lock)
+@@ -194,7 +194,7 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab,
+ {
+       bool use_raw_lock = htab_use_raw_lock(htab);
+-      hash = hash & HASHTAB_MAP_LOCK_MASK;
++      hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1);
+       if (use_raw_lock)
+               raw_spin_unlock_irqrestore(&b->raw_lock, flags);
+       else
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-amdgpu-fix-amdgpu_job_free_resources-v2.patch b/queue-5.15/drm-amdgpu-fix-amdgpu_job_free_resources-v2.patch
new file mode 100644 (file)
index 0000000..3896863
--- /dev/null
@@ -0,0 +1,50 @@
+From e92b352cf7fc95f802a0b5a710069af4daa04e40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 14:46:00 +0100
+Subject: drm/amdgpu: fix amdgpu_job_free_resources v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+[ Upstream commit 1427a720273976a81d13d9d9fa60d53ce881cbd7 ]
+
+It can be that neither fence were initialized when we run out of UVD
+streams for example.
+
+v2: fix typo breaking compile
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2324
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-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_job.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+index de29518673dd3..90a83aaa9908c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -135,8 +135,14 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
+       else
+               hw_fence = &job->hw_fence;
+-      /* use sched fence if available */
+-      f = job->base.s_fence ? &job->base.s_fence->finished : hw_fence;
++      /* Check if any fences where initialized */
++      if (job->base.s_fence && job->base.s_fence->finished.ops)
++              f = &job->base.s_fence->finished;
++      else if (job->hw_fence.ops)
++              f = &job->hw_fence;
++      else
++              f = NULL;
++
+       for (i = 0; i < job->num_ibs; ++i)
+               amdgpu_ib_free(ring->adev, &job->ibs[i], f);
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-amdgpu-prevent-race-between-late-signaled-fences.patch b/queue-5.15/drm-amdgpu-prevent-race-between-late-signaled-fences.patch
new file mode 100644 (file)
index 0000000..308fc44
--- /dev/null
@@ -0,0 +1,102 @@
+From 99466fc2f9a85035bbdad1a89e942297b5d042c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 00:28:50 -0400
+Subject: drm/amdgpu: Prevent race between late signaled fences and GPU reset.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
+
+[ Upstream commit 9e225fb9e636b31b97e9d35324c2f9e43ee0aab4 ]
+
+Problem:
+After we start handling timed out jobs we assume there fences won't be
+signaled but we cannot be sure and sometimes they fire late. We need
+to prevent concurrent accesses to fence array from
+amdgpu_fence_driver_clear_job_fences during GPU reset and amdgpu_fence_process
+from a late EOP interrupt.
+
+Fix:
+Before accessing fence array in GPU disable EOP interrupt and flush
+all pending interrupt handlers for amdgpu device's interrupt line.
+
+v2: Switch from irq_get/put to full enable/disable_irq for amdgpu
+
+Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
+Acked-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 1427a7202739 ("drm/amdgpu: fix amdgpu_job_free_resources v2")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  4 ++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  | 18 ++++++++++++++++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h   |  1 +
+ 3 files changed, 23 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 2f51789d98181..8711d39fc2f71 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4609,6 +4609,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
+               amdgpu_virt_fini_data_exchange(adev);
+       }
++      amdgpu_fence_driver_isr_toggle(adev, true);
++
+       /* block all schedulers and reset given job's ring */
+       for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
+               struct amdgpu_ring *ring = adev->rings[i];
+@@ -4631,6 +4633,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
+               amdgpu_fence_driver_force_completion(ring);
+       }
++      amdgpu_fence_driver_isr_toggle(adev, false);
++
+       if (job && job->vm)
+               drm_sched_increase_karma(&job->base);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+index bbd6f7a123033..f3d7094184530 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+@@ -569,6 +569,24 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev)
+       }
+ }
++/* Will either stop and flush handlers for amdgpu interrupt or reanble it */
++void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop)
++{
++      int i;
++
++      for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
++              struct amdgpu_ring *ring = adev->rings[i];
++
++              if (!ring || !ring->fence_drv.initialized || !ring->fence_drv.irq_src)
++                      continue;
++
++              if (stop)
++                      disable_irq(adev->irq.irq);
++              else
++                      enable_irq(adev->irq.irq);
++      }
++}
++
+ void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev)
+ {
+       unsigned int i, j;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+index e713d31619fe7..fc87a1fea8b44 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+@@ -131,6 +131,7 @@ signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring,
+                                     uint32_t wait_seq,
+                                     signed long timeout);
+ unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);
++void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop);
+ /*
+  * Rings.
+-- 
+2.39.2
+
diff --git a/queue-5.15/iavf-iavf_main-actually-log-src-mask-when-talking-ab.patch b/queue-5.15/iavf-iavf_main-actually-log-src-mask-when-talking-ab.patch
new file mode 100644 (file)
index 0000000..e96ddb0
--- /dev/null
@@ -0,0 +1,40 @@
+From 174e76a5e4e1a6a995eb186593b92108efb5ad35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 09:32:46 +0300
+Subject: iavf/iavf_main: actually log ->src mask when talking about it
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit 6650c8e906ce58404bfdfceceeba7bd10d397d40 ]
+
+This fixes a copy-paste issue where dev_err would log the dst mask even
+though it is clearly talking about src.
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE
+static analysis tool.
+
+Fixes: 0075fa0fadd0 ("i40evf: Add support to apply cloud filters")
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index bafccf61c654f..3b62f37b3cf14 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3181,7 +3181,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                               field_flags |= IAVF_CLOUD_FIELD_IIP;
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad ip src mask 0x%08x\n",
+-                                      be32_to_cpu(match.mask->dst));
++                                      be32_to_cpu(match.mask->src));
+                               return -EINVAL;
+                       }
+               }
+-- 
+2.39.2
+
diff --git a/queue-5.15/iavf-return-errno-code-instead-of-status-code.patch b/queue-5.15/iavf-return-errno-code-instead-of-status-code.patch
new file mode 100644 (file)
index 0000000..e7680ba
--- /dev/null
@@ -0,0 +1,119 @@
+From abfb95c92f14be1021b3e31ba4e62c6ec4708ed2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 09:53:34 -0700
+Subject: iavf: return errno code instead of status code
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 9f4651ea3e07339b460d403ff01b7cc2178fef7b ]
+
+The iavf_parse_cls_flower function returns an integer error code, and
+not an iavf_status enumeration.
+
+Fix the function to use the standard errno value EINVAL as its return
+instead of using IAVF_ERR_CONFIG.
+
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 6650c8e906ce ("iavf/iavf_main: actually log ->src mask when talking about it")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index f5e6ae2c683f4..bafccf61c654f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3103,7 +3103,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad ether dest mask %pM\n",
+                                       match.mask->dst);
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+@@ -3113,7 +3113,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad ether src mask %pM\n",
+                                       match.mask->src);
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+@@ -3148,7 +3148,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad vlan mask %u\n",
+                                       match.mask->vlan_id);
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+               vf->mask.tcp_spec.vlan_id |= cpu_to_be16(0xffff);
+@@ -3172,7 +3172,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad ip dst mask 0x%08x\n",
+                                       be32_to_cpu(match.mask->dst));
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+@@ -3182,13 +3182,13 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad ip src mask 0x%08x\n",
+                                       be32_to_cpu(match.mask->dst));
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+               if (field_flags & IAVF_CLOUD_FIELD_TEN_ID) {
+                       dev_info(&adapter->pdev->dev, "Tenant id not allowed for ip filter\n");
+-                      return IAVF_ERR_CONFIG;
++                      return -EINVAL;
+               }
+               if (match.key->dst) {
+                       vf->mask.tcp_spec.dst_ip[0] |= cpu_to_be32(0xffffffff);
+@@ -3209,7 +3209,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+               if (ipv6_addr_any(&match.mask->dst)) {
+                       dev_err(&adapter->pdev->dev, "Bad ipv6 dst mask 0x%02x\n",
+                               IPV6_ADDR_ANY);
+-                      return IAVF_ERR_CONFIG;
++                      return -EINVAL;
+               }
+               /* src and dest IPv6 address should not be LOOPBACK
+@@ -3219,7 +3219,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                   ipv6_addr_loopback(&match.key->src)) {
+                       dev_err(&adapter->pdev->dev,
+                               "ipv6 addr should not be loopback\n");
+-                      return IAVF_ERR_CONFIG;
++                      return -EINVAL;
+               }
+               if (!ipv6_addr_any(&match.mask->dst) ||
+                   !ipv6_addr_any(&match.mask->src))
+@@ -3244,7 +3244,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad src port mask %u\n",
+                                       be16_to_cpu(match.mask->src));
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+@@ -3254,7 +3254,7 @@ static int iavf_parse_cls_flower(struct iavf_adapter *adapter,
+                       } else {
+                               dev_err(&adapter->pdev->dev, "Bad dst port mask %u\n",
+                                       be16_to_cpu(match.mask->dst));
+-                              return IAVF_ERR_CONFIG;
++                              return -EINVAL;
+                       }
+               }
+               if (match.key->dst) {
+-- 
+2.39.2
+
diff --git a/queue-5.15/kvm-arm64-pmu-fix-get_one_reg-for-vpmc-regs-to-retur.patch b/queue-5.15/kvm-arm64-pmu-fix-get_one_reg-for-vpmc-regs-to-retur.patch
new file mode 100644 (file)
index 0000000..ac4174c
--- /dev/null
@@ -0,0 +1,84 @@
+From 9fbc81f2e30dcfa51e1e617ccf2f17ccf0cfceac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Mar 2023 20:32:08 -0700
+Subject: KVM: arm64: PMU: Fix GET_ONE_REG for vPMC regs to return the current
+ value
+
+From: Reiji Watanabe <reijiw@google.com>
+
+[ Upstream commit 9228b26194d1cc00449f12f306f53ef2e234a55b ]
+
+Have KVM_GET_ONE_REG for vPMU counter (vPMC) registers (PMCCNTR_EL0
+and PMEVCNTR<n>_EL0) return the sum of the register value in the sysreg
+file and the current perf event counter value.
+
+Values of vPMC registers are saved in sysreg files on certain occasions.
+These saved values don't represent the current values of the vPMC
+registers if the perf events for the vPMCs count events after the save.
+The current values of those registers are the sum of the sysreg file
+value and the current perf event counter value.  But, when userspace
+reads those registers (using KVM_GET_ONE_REG), KVM returns the sysreg
+file value to userspace (not the sum value).
+
+Fix this to return the sum value for KVM_GET_ONE_REG.
+
+Fixes: 051ff581ce70 ("arm64: KVM: Add access handler for event counter register")
+Cc: stable@vger.kernel.org
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Reiji Watanabe <reijiw@google.com>
+Link: https://lore.kernel.org/r/20230313033208.1475499-1-reijiw@google.com
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kvm/sys_regs.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
+index c11612db4a371..c211f719c2474 100644
+--- a/arch/arm64/kvm/sys_regs.c
++++ b/arch/arm64/kvm/sys_regs.c
+@@ -764,6 +764,22 @@ static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx)
+       return true;
+ }
++static int get_pmu_evcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
++                        u64 *val)
++{
++      u64 idx;
++
++      if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 0)
++              /* PMCCNTR_EL0 */
++              idx = ARMV8_PMU_CYCLE_IDX;
++      else
++              /* PMEVCNTRn_EL0 */
++              idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
++
++      *val = kvm_pmu_get_counter_value(vcpu, idx);
++      return 0;
++}
++
+ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
+                             struct sys_reg_params *p,
+                             const struct sys_reg_desc *r)
+@@ -980,7 +996,7 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ /* Macro to expand the PMEVCNTRn_EL0 register */
+ #define PMU_PMEVCNTR_EL0(n)                                           \
+       { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)),                            \
+-        .reset = reset_pmevcntr,                                      \
++        .reset = reset_pmevcntr, .get_user = get_pmu_evcntr,          \
+         .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
+ /* Macro to expand the PMEVTYPERn_EL0 register */
+@@ -1651,7 +1667,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
+       { PMU_SYS_REG(SYS_PMCEID1_EL0),
+         .access = access_pmceid, .reset = NULL },
+       { PMU_SYS_REG(SYS_PMCCNTR_EL0),
+-        .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 },
++        .access = access_pmu_evcntr, .reset = reset_unknown,
++        .reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr},
+       { PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
+         .access = access_pmu_evtyper, .reset = NULL },
+       { PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
+-- 
+2.39.2
+
diff --git a/queue-5.15/nfsd-fix-sparse-warning.patch b/queue-5.15/nfsd-fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..b5f7779
--- /dev/null
@@ -0,0 +1,36 @@
+From 43a4883be61317fdc87147170c432e940bdbd49e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Oct 2021 16:44:20 -0400
+Subject: NFSD: Fix sparse warning
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit c2f1c4bd20621175c581f298b4943df0cffbd841 ]
+
+/home/cel/src/linux/linux/fs/nfsd/nfs4proc.c:1539:24: warning: incorrect type in assignment (different base types)
+/home/cel/src/linux/linux/fs/nfsd/nfs4proc.c:1539:24:    expected restricted __be32 [usertype] status
+/home/cel/src/linux/linux/fs/nfsd/nfs4proc.c:1539:24:    got int
+
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Stable-dep-of: 79a1d88a36f7 ("NFSD: pass range end to vfs_fsync_range() instead of count")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index b817d24d25a60..c91da7bce17ea 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1513,7 +1513,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
+       u64 bytes_total = copy->cp_count;
+       u64 src_pos = copy->cp_src_pos;
+       u64 dst_pos = copy->cp_dst_pos;
+-      __be32 status;
++      int status;
+       /* See RFC 7862 p.67: */
+       if (bytes_total == 0)
+-- 
+2.39.2
+
diff --git a/queue-5.15/nfsd-pass-range-end-to-vfs_fsync_range-instead-of-co.patch b/queue-5.15/nfsd-pass-range-end-to-vfs_fsync_range-instead-of-co.patch
new file mode 100644 (file)
index 0000000..a6275e0
--- /dev/null
@@ -0,0 +1,48 @@
+From b4a7f861a9c3d5083116baefce41d3b4928dcc7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 10:28:36 -0500
+Subject: NFSD: pass range end to vfs_fsync_range() instead of count
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit 79a1d88a36f77374c77fd41a4386d8c2736b8704 ]
+
+_nfsd_copy_file_range() calls vfs_fsync_range() with an offset and
+count (bytes written), but the former wants the start and end bytes
+of the range to sync. Fix it up.
+
+Fixes: eac0b17a77fb ("NFSD add vfs_fsync after async copy is done")
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Tested-by: Dai Ngo <dai.ngo@oracle.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index c91da7bce17ea..3eb500adcda2e 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1514,6 +1514,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
+       u64 src_pos = copy->cp_src_pos;
+       u64 dst_pos = copy->cp_dst_pos;
+       int status;
++      loff_t end;
+       /* See RFC 7862 p.67: */
+       if (bytes_total == 0)
+@@ -1533,8 +1534,8 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
+       /* for a non-zero asynchronous copy do a commit of data */
+       if (!copy->cp_synchronous && copy->cp_res.wr_bytes_written > 0) {
+               since = READ_ONCE(dst->f_wb_err);
+-              status = vfs_fsync_range(dst, copy->cp_dst_pos,
+-                                       copy->cp_res.wr_bytes_written, 0);
++              end = copy->cp_dst_pos + copy->cp_res.wr_bytes_written - 1;
++              status = vfs_fsync_range(dst, copy->cp_dst_pos, end, 0);
+               if (!status)
+                       status = filemap_check_wb_err(dst->f_mapping, since);
+               if (!status)
+-- 
+2.39.2
+
diff --git a/queue-5.15/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch b/queue-5.15/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch
new file mode 100644 (file)
index 0000000..3c89e25
--- /dev/null
@@ -0,0 +1,121 @@
+From 215fea60023294149e33ea98c8d1ef814b053f68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 15:46:27 +0800
+Subject: ocfs2: fix memory leak in ocfs2_mount_volume()
+
+From: Li Zetao <ocfs2-devel@oss.oracle.com>
+
+[ Upstream commit ce2fcf1516d674a174d9b34d1e1024d64de9fba3 ]
+
+There is a memory leak reported by kmemleak:
+
+  unreferenced object 0xffff88810cc65e60 (size 32):
+    comm "mount.ocfs2", pid 23753, jiffies 4302528942 (age 34735.105s)
+    hex dump (first 32 bytes):
+      10 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01  ................
+      01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00  ................
+    backtrace:
+      [<ffffffff8170f73d>] __kmalloc+0x4d/0x150
+      [<ffffffffa0ac3f51>] ocfs2_compute_replay_slots+0x121/0x330 [ocfs2]
+      [<ffffffffa0b65165>] ocfs2_check_volume+0x485/0x900 [ocfs2]
+      [<ffffffffa0b68129>] ocfs2_mount_volume.isra.0+0x1e9/0x650 [ocfs2]
+      [<ffffffffa0b7160b>] ocfs2_fill_super+0xe0b/0x1740 [ocfs2]
+      [<ffffffff818e1fe2>] mount_bdev+0x312/0x400
+      [<ffffffff819a086d>] legacy_get_tree+0xed/0x1d0
+      [<ffffffff818de82d>] vfs_get_tree+0x7d/0x230
+      [<ffffffff81957f92>] path_mount+0xd62/0x1760
+      [<ffffffff81958a5a>] do_mount+0xca/0xe0
+      [<ffffffff81958d3c>] __x64_sys_mount+0x12c/0x1a0
+      [<ffffffff82f26f15>] do_syscall_64+0x35/0x80
+      [<ffffffff8300006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+This call stack is related to two problems.  Firstly, the ocfs2 super uses
+"replay_map" to trace online/offline slots, in order to recover offline
+slots during recovery and mount.  But when ocfs2_truncate_log_init()
+returns an error in ocfs2_mount_volume(), the memory of "replay_map" will
+not be freed in error handling path.  Secondly, the memory of "replay_map"
+will not be freed if d_make_root() returns an error in ocfs2_fill_super().
+But the memory of "replay_map" will be freed normally when completing
+recovery and mount in ocfs2_complete_mount_recovery().
+
+Fix the first problem by adding error handling path to free "replay_map"
+when ocfs2_truncate_log_init() fails.  And fix the second problem by
+calling ocfs2_free_replay_slots(osb) in the error handling path
+"out_dismount".  In addition, since ocfs2_free_replay_slots() is static,
+it is necessary to remove its static attribute and declare it in header
+file.
+
+Link: https://lkml.kernel.org/r/20221109074627.2303950-1-lizetao1@huawei.com
+Fixes: 9140db04ef18 ("ocfs2: recover orphans in offline slots during recovery and mount")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/journal.c | 2 +-
+ fs/ocfs2/journal.h | 1 +
+ fs/ocfs2/super.c   | 5 ++++-
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
+index 4f15750aac5d5..86864a90de2cd 100644
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -157,7 +157,7 @@ static void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
+       replay_map->rm_state = REPLAY_DONE;
+ }
+-static void ocfs2_free_replay_slots(struct ocfs2_super *osb)
++void ocfs2_free_replay_slots(struct ocfs2_super *osb)
+ {
+       struct ocfs2_replay_map *replay_map = osb->replay_map;
+diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
+index d158acb8b38a8..a54f20bce9fef 100644
+--- a/fs/ocfs2/journal.h
++++ b/fs/ocfs2/journal.h
+@@ -150,6 +150,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb);
+ void ocfs2_recovery_exit(struct ocfs2_super *osb);
+ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
++void ocfs2_free_replay_slots(struct ocfs2_super *osb);
+ /*
+  *  Journal Control:
+  *  Initialize, Load, Shutdown, Wipe a journal.
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index 64795f836550f..db38b424f7a1a 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1160,6 +1160,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+ out_dismount:
+       atomic_set(&osb->vol_state, VOLUME_DISABLED);
+       wake_up(&osb->osb_mount_event);
++      ocfs2_free_replay_slots(osb);
+       ocfs2_dismount_volume(sb, 1);
+       goto out;
+@@ -1825,12 +1826,14 @@ static int ocfs2_mount_volume(struct super_block *sb)
+       status = ocfs2_truncate_log_init(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto out_system_inodes;
++              goto out_check_volume;
+       }
+       ocfs2_super_unlock(osb, 1);
+       return 0;
++out_check_volume:
++      ocfs2_free_replay_slots(osb);
+ out_system_inodes:
+       if (osb->local_alloc_state == OCFS2_LA_ENABLED)
+               ocfs2_shutdown_local_alloc(osb);
+-- 
+2.39.2
+
diff --git a/queue-5.15/ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch b/queue-5.15/ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch
new file mode 100644 (file)
index 0000000..f06e5f6
--- /dev/null
@@ -0,0 +1,115 @@
+From 4c70d518fcf8c49e7fd47d26e6ff1fb4335dbaca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 14:37:58 -0700
+Subject: ocfs2: ocfs2_mount_volume does cleanup job before return error
+
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+
+[ Upstream commit 0737e01de9c411e4db87dcedf4a9789d41b1c5c1 ]
+
+After this patch, when error, ocfs2_fill_super doesn't take care to
+release resources which are allocated in ocfs2_mount_volume.
+
+Link: https://lkml.kernel.org/r/20220424130952.2436-5-heming.zhao@suse.com
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: ce2fcf1516d6 ("ocfs2: fix memory leak in ocfs2_mount_volume()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/super.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index a03f0cabff0bf..017f809e54401 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1783,11 +1783,10 @@ static int ocfs2_get_sector(struct super_block *sb,
+ static int ocfs2_mount_volume(struct super_block *sb)
+ {
+       int status = 0;
+-      int unlock_super = 0;
+       struct ocfs2_super *osb = OCFS2_SB(sb);
+       if (ocfs2_is_hard_readonly(osb))
+-              goto leave;
++              goto out;
+       mutex_init(&osb->obs_trim_fs_mutex);
+@@ -1797,44 +1796,56 @@ static int ocfs2_mount_volume(struct super_block *sb)
+               if (status == -EBADR && ocfs2_userspace_stack(osb))
+                       mlog(ML_ERROR, "couldn't mount because cluster name on"
+                       " disk does not match the running cluster name.\n");
+-              goto leave;
++              goto out;
+       }
+       status = ocfs2_super_lock(osb, 1);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_dlm;
+       }
+-      unlock_super = 1;
+       /* This will load up the node map and add ourselves to it. */
+       status = ocfs2_find_slot(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_super_lock;
+       }
+       /* load all node-local system inodes */
+       status = ocfs2_init_local_system_inodes(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_super_lock;
+       }
+       status = ocfs2_check_volume(osb);
+       if (status < 0) {
+               mlog_errno(status);
+-              goto leave;
++              goto out_system_inodes;
+       }
+       status = ocfs2_truncate_log_init(osb);
+-      if (status < 0)
++      if (status < 0) {
+               mlog_errno(status);
++              goto out_system_inodes;
++      }
+-leave:
+-      if (unlock_super)
+-              ocfs2_super_unlock(osb, 1);
++      ocfs2_super_unlock(osb, 1);
++      return 0;
++out_system_inodes:
++      if (osb->local_alloc_state == OCFS2_LA_ENABLED)
++              ocfs2_shutdown_local_alloc(osb);
++      ocfs2_release_system_inodes(osb);
++      /* before journal shutdown, we should release slot_info */
++      ocfs2_free_slot_info(osb);
++      ocfs2_journal_shutdown(osb);
++out_super_lock:
++      ocfs2_super_unlock(osb, 1);
++out_dlm:
++      ocfs2_dlm_shutdown(osb, 0);
++out:
+       return status;
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch b/queue-5.15/ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch
new file mode 100644 (file)
index 0000000..b391ebb
--- /dev/null
@@ -0,0 +1,200 @@
+From af03f1c727ba1f189f757ea70e50b476a151903d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 14:37:58 -0700
+Subject: ocfs2: rewrite error handling of ocfs2_fill_super
+
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+
+[ Upstream commit f1e75d128b46e3b066e7b2e7cfca10491109d44d ]
+
+Current ocfs2_fill_super() uses one goto label "read_super_error" to
+handle all error cases.  And with previous serial patches, the error
+handling should fork more branches to handle different error cases.  This
+patch rewrite the error handling of ocfs2_fill_super.
+
+Link: https://lkml.kernel.org/r/20220424130952.2436-6-heming.zhao@suse.com
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: ce2fcf1516d6 ("ocfs2: fix memory leak in ocfs2_mount_volume()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/super.c | 67 +++++++++++++++++++++++-------------------------
+ 1 file changed, 32 insertions(+), 35 deletions(-)
+
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index 017f809e54401..64795f836550f 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -980,28 +980,27 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
+               status = -EINVAL;
+-              goto read_super_error;
++              goto out;
+       }
+       /* probe for superblock */
+       status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats);
+       if (status < 0) {
+               mlog(ML_ERROR, "superblock probe failed!\n");
+-              goto read_super_error;
++              goto out;
+       }
+       status = ocfs2_initialize_super(sb, bh, sector_size, &stats);
+-      osb = OCFS2_SB(sb);
+-      if (status < 0) {
+-              mlog_errno(status);
+-              goto read_super_error;
+-      }
+       brelse(bh);
+       bh = NULL;
++      if (status < 0)
++              goto out;
++
++      osb = OCFS2_SB(sb);
+       if (!ocfs2_check_set_options(sb, &parsed_options)) {
+               status = -EINVAL;
+-              goto read_super_error;
++              goto out_super;
+       }
+       osb->s_mount_opt = parsed_options.mount_opt;
+       osb->s_atime_quantum = parsed_options.atime_quantum;
+@@ -1018,7 +1017,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       status = ocfs2_verify_userspace_stack(osb, &parsed_options);
+       if (status)
+-              goto read_super_error;
++              goto out_super;
+       sb->s_magic = OCFS2_SUPER_MAGIC;
+@@ -1032,7 +1031,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+                       status = -EACCES;
+                       mlog(ML_ERROR, "Readonly device detected but readonly "
+                            "mount was not specified.\n");
+-                      goto read_super_error;
++                      goto out_super;
+               }
+               /* You should not be able to start a local heartbeat
+@@ -1041,7 +1040,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+                       status = -EROFS;
+                       mlog(ML_ERROR, "Local heartbeat specified on readonly "
+                            "device.\n");
+-                      goto read_super_error;
++                      goto out_super;
+               }
+               status = ocfs2_check_journals_nolocks(osb);
+@@ -1050,9 +1049,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+                               mlog(ML_ERROR, "Recovery required on readonly "
+                                    "file system, but write access is "
+                                    "unavailable.\n");
+-                      else
+-                              mlog_errno(status);
+-                      goto read_super_error;
++                      goto out_super;
+               }
+               ocfs2_set_ro_flag(osb, 1);
+@@ -1068,10 +1065,8 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       }
+       status = ocfs2_verify_heartbeat(osb);
+-      if (status < 0) {
+-              mlog_errno(status);
+-              goto read_super_error;
+-      }
++      if (status < 0)
++              goto out_super;
+       osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
+                                                ocfs2_debugfs_root);
+@@ -1085,15 +1080,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       status = ocfs2_mount_volume(sb);
+       if (status < 0)
+-              goto read_super_error;
++              goto out_debugfs;
+       if (osb->root_inode)
+               inode = igrab(osb->root_inode);
+       if (!inode) {
+               status = -EIO;
+-              mlog_errno(status);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
+@@ -1101,7 +1095,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       if (!osb->osb_dev_kset) {
+               status = -ENOMEM;
+               mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       /* Create filecheck sysfs related directories/files at
+@@ -1110,14 +1104,13 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+               status = -ENOMEM;
+               mlog(ML_ERROR, "Unable to create filecheck sysfs directory at "
+                       "/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       root = d_make_root(inode);
+       if (!root) {
+               status = -ENOMEM;
+-              mlog_errno(status);
+-              goto read_super_error;
++              goto out_dismount;
+       }
+       sb->s_root = root;
+@@ -1164,17 +1157,21 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+       return status;
+-read_super_error:
+-      brelse(bh);
+-
+-      if (status)
+-              mlog_errno(status);
++out_dismount:
++      atomic_set(&osb->vol_state, VOLUME_DISABLED);
++      wake_up(&osb->osb_mount_event);
++      ocfs2_dismount_volume(sb, 1);
++      goto out;
+-      if (osb) {
+-              atomic_set(&osb->vol_state, VOLUME_DISABLED);
+-              wake_up(&osb->osb_mount_event);
+-              ocfs2_dismount_volume(sb, 1);
+-      }
++out_debugfs:
++      debugfs_remove_recursive(osb->osb_debug_root);
++out_super:
++      ocfs2_release_system_inodes(osb);
++      kfree(osb->recovery_map);
++      ocfs2_delete_osb(osb);
++      kfree(osb);
++out:
++      mlog_errno(status);
+       return status;
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/platform-x86-int3472-discrete-ensure-the-clk-power-e.patch b/queue-5.15/platform-x86-int3472-discrete-ensure-the-clk-power-e.patch
new file mode 100644 (file)
index 0000000..7f79635
--- /dev/null
@@ -0,0 +1,74 @@
+From 75dffdd864ba13f8b175e561969f87605bb45635 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 21:14:26 +0100
+Subject: platform/x86: int3472/discrete: Ensure the clk/power enable pins are
+ in output mode
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit cf5ac2d45f6e4d11ad78e7b10ae9a4121ba5e995 ]
+
+acpi_get_and_request_gpiod() does not take a gpio_lookup_flags argument
+specifying that the pins direction should be initialized to a specific
+value.
+
+This means that in some cases the pins might be left in input mode, causing
+the gpiod_set() calls made to enable the clk / regulator to not work.
+
+One example of this problem is the clk-enable GPIO for the ov01a1s sensor
+on a Dell Latitude 9420 being left in input mode causing the clk to
+never get enabled.
+
+Explicitly set the direction of the pins to output to fix this.
+
+Fixes: 5de691bffe57 ("platform/x86: Add intel_skl_int3472 driver")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Daniel Scally <djrscally@gmail.com>
+Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Link: https://lore.kernel.org/r/20230111201426.947853-1-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/int3472/clk_and_regulator.c | 3 +++
+ drivers/platform/x86/intel/int3472/discrete.c          | 4 ++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/platform/x86/intel/int3472/clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+index 1cf958983e868..28353addffa7f 100644
+--- a/drivers/platform/x86/intel/int3472/clk_and_regulator.c
++++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+@@ -181,6 +181,9 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
+               return PTR_ERR(int3472->regulator.gpio);
+       }
++      /* Ensure the pin is in output mode and non-active state */
++      gpiod_direction_output(int3472->regulator.gpio, 0);
++
+       cfg.dev = &int3472->adev->dev;
+       cfg.init_data = &init_data;
+       cfg.ena_gpiod = int3472->regulator.gpio;
+diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
+index d2e8a87a077e7..401fa8f223d62 100644
+--- a/drivers/platform/x86/intel/int3472/discrete.c
++++ b/drivers/platform/x86/intel/int3472/discrete.c
+@@ -169,6 +169,8 @@ static int skl_int3472_map_gpio_to_clk(struct int3472_discrete_device *int3472,
+                       return (PTR_ERR(gpio));
+               int3472->clock.ena_gpio = gpio;
++              /* Ensure the pin is in output mode and non-active state */
++              gpiod_direction_output(int3472->clock.ena_gpio, 0);
+               break;
+       case INT3472_GPIO_TYPE_PRIVACY_LED:
+               gpio = acpi_get_and_request_gpiod(path, pin, "int3472,privacy-led");
+@@ -176,6 +178,8 @@ static int skl_int3472_map_gpio_to_clk(struct int3472_discrete_device *int3472,
+                       return (PTR_ERR(gpio));
+               int3472->clock.led_gpio = gpio;
++              /* Ensure the pin is in output mode and non-active state */
++              gpiod_direction_output(int3472->clock.led_gpio, 0);
+               break;
+       default:
+               dev_err(int3472->dev, "Invalid GPIO type 0x%02x for clock\n", type);
+-- 
+2.39.2
+
diff --git a/queue-5.15/platform-x86-int3472-split-into-2-drivers.patch b/queue-5.15/platform-x86-int3472-split-into-2-drivers.patch
new file mode 100644 (file)
index 0000000..56ec4fe
--- /dev/null
@@ -0,0 +1,380 @@
+From ebeedb3be543d94138bf8d2eb52e4a38b5a83095 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Dec 2021 11:28:50 +0100
+Subject: platform/x86: int3472: Split into 2 drivers
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit a2f9fbc247eea0ad1b0b59bc29bec144c5ead03c ]
+
+The intel_skl_int3472.ko module contains 2 separate drivers,
+the int3472_discrete platform driver and the int3472_tps68470
+I2C-driver.
+
+These 2 drivers contain very little shared code, only
+skl_int3472_get_acpi_buffer() and skl_int3472_fill_cldb() are
+shared.
+
+Split the module into 2 drivers, linking the little shared code
+directly into both.
+
+This will allow us to add soft-module dependencies for the
+tps68470 clk, gpio and regulator drivers to the new
+intel_skl_int3472_tps68470.ko to help with probe ordering issues
+without causing these modules to get loaded on boards which only
+use the int3472_discrete platform driver.
+
+While at it also rename the .c and .h files to remove the
+cumbersome intel_skl_int3472_ prefix.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20211203102857.44539-8-hdegoede@redhat.com
+Stable-dep-of: cf5ac2d45f6e ("platform/x86: int3472/discrete: Ensure the clk/power enable pins are in output mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/int3472/Makefile   |   9 +-
+ ...lk_and_regulator.c => clk_and_regulator.c} |   2 +-
+ drivers/platform/x86/intel/int3472/common.c   |  54 +++++++++
+ .../{intel_skl_int3472_common.h => common.h}  |   3 -
+ ...ntel_skl_int3472_discrete.c => discrete.c} |  28 ++++-
+ .../intel/int3472/intel_skl_int3472_common.c  | 106 ------------------
+ ...ntel_skl_int3472_tps68470.c => tps68470.c} |  23 +++-
+ 7 files changed, 105 insertions(+), 120 deletions(-)
+ rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_clk_and_regulator.c => clk_and_regulator.c} (99%)
+ create mode 100644 drivers/platform/x86/intel/int3472/common.c
+ rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_common.h => common.h} (94%)
+ rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_discrete.c => discrete.c} (93%)
+ delete mode 100644 drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
+ rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_tps68470.c => tps68470.c} (85%)
+
+diff --git a/drivers/platform/x86/intel/int3472/Makefile b/drivers/platform/x86/intel/int3472/Makefile
+index 2362e04db18d5..771e720528a06 100644
+--- a/drivers/platform/x86/intel/int3472/Makefile
++++ b/drivers/platform/x86/intel/int3472/Makefile
+@@ -1,5 +1,4 @@
+-obj-$(CONFIG_INTEL_SKL_INT3472)               += intel_skl_int3472.o
+-intel_skl_int3472-y                   := intel_skl_int3472_common.o \
+-                                         intel_skl_int3472_discrete.o \
+-                                         intel_skl_int3472_tps68470.o \
+-                                         intel_skl_int3472_clk_and_regulator.o
++obj-$(CONFIG_INTEL_SKL_INT3472)               += intel_skl_int3472_discrete.o \
++                                         intel_skl_int3472_tps68470.o
++intel_skl_int3472_discrete-y          := discrete.o clk_and_regulator.o common.o
++intel_skl_int3472_tps68470-y          := tps68470.o common.o
+diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+similarity index 99%
+rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c
+rename to drivers/platform/x86/intel/int3472/clk_and_regulator.c
+index 1700e7557a824..1cf958983e868 100644
+--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c
++++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+@@ -9,7 +9,7 @@
+ #include <linux/regulator/driver.h>
+ #include <linux/slab.h>
+-#include "intel_skl_int3472_common.h"
++#include "common.h"
+ /*
+  * The regulators have to have .ops to be valid, but the only ops we actually
+diff --git a/drivers/platform/x86/intel/int3472/common.c b/drivers/platform/x86/intel/int3472/common.c
+new file mode 100644
+index 0000000000000..350655a9515b1
+--- /dev/null
++++ b/drivers/platform/x86/intel/int3472/common.c
+@@ -0,0 +1,54 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Author: Dan Scally <djrscally@gmail.com> */
++
++#include <linux/acpi.h>
++#include <linux/slab.h>
++
++#include "common.h"
++
++union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
++{
++      struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
++      acpi_handle handle = adev->handle;
++      union acpi_object *obj;
++      acpi_status status;
++
++      status = acpi_evaluate_object(handle, id, NULL, &buffer);
++      if (ACPI_FAILURE(status))
++              return ERR_PTR(-ENODEV);
++
++      obj = buffer.pointer;
++      if (!obj)
++              return ERR_PTR(-ENODEV);
++
++      if (obj->type != ACPI_TYPE_BUFFER) {
++              acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
++              kfree(obj);
++              return ERR_PTR(-EINVAL);
++      }
++
++      return obj;
++}
++
++int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
++{
++      union acpi_object *obj;
++      int ret;
++
++      obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
++      if (IS_ERR(obj))
++              return PTR_ERR(obj);
++
++      if (obj->buffer.length > sizeof(*cldb)) {
++              acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
++              ret = -EINVAL;
++              goto out_free_obj;
++      }
++
++      memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
++      ret = 0;
++
++out_free_obj:
++      kfree(obj);
++      return ret;
++}
+diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel/int3472/common.h
+similarity index 94%
+rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h
+rename to drivers/platform/x86/intel/int3472/common.h
+index 714fde73b5247..d14944ee85861 100644
+--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h
++++ b/drivers/platform/x86/intel/int3472/common.h
+@@ -105,9 +105,6 @@ struct int3472_discrete_device {
+       struct gpiod_lookup_table gpios;
+ };
+-int skl_int3472_discrete_probe(struct platform_device *pdev);
+-int skl_int3472_discrete_remove(struct platform_device *pdev);
+-int skl_int3472_tps68470_probe(struct i2c_client *client);
+ union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
+                                              char *id);
+ int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
+diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
+similarity index 93%
+rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c
+rename to drivers/platform/x86/intel/int3472/discrete.c
+index e59d79c7e82f8..d2e8a87a077e7 100644
+--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c
++++ b/drivers/platform/x86/intel/int3472/discrete.c
+@@ -14,7 +14,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/uuid.h>
+-#include "intel_skl_int3472_common.h"
++#include "common.h"
+ /*
+  * 79234640-9e10-4fea-a5c1-b5aa8b19756f
+@@ -332,7 +332,9 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
+       return 0;
+ }
+-int skl_int3472_discrete_probe(struct platform_device *pdev)
++static int skl_int3472_discrete_remove(struct platform_device *pdev);
++
++static int skl_int3472_discrete_probe(struct platform_device *pdev)
+ {
+       struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+       struct int3472_discrete_device *int3472;
+@@ -395,7 +397,7 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
+       return ret;
+ }
+-int skl_int3472_discrete_remove(struct platform_device *pdev)
++static int skl_int3472_discrete_remove(struct platform_device *pdev)
+ {
+       struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
+@@ -411,3 +413,23 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
+       return 0;
+ }
++
++static const struct acpi_device_id int3472_device_id[] = {
++      { "INT3472", 0 },
++      { }
++};
++MODULE_DEVICE_TABLE(acpi, int3472_device_id);
++
++static struct platform_driver int3472_discrete = {
++      .driver = {
++              .name = "int3472-discrete",
++              .acpi_match_table = int3472_device_id,
++      },
++      .probe = skl_int3472_discrete_probe,
++      .remove = skl_int3472_discrete_remove,
++};
++module_platform_driver(int3472_discrete);
++
++MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Discrete Device Driver");
++MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c b/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
+deleted file mode 100644
+index 497e74fba75fb..0000000000000
+--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
++++ /dev/null
+@@ -1,106 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/* Author: Dan Scally <djrscally@gmail.com> */
+-
+-#include <linux/acpi.h>
+-#include <linux/i2c.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-
+-#include "intel_skl_int3472_common.h"
+-
+-union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
+-{
+-      struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+-      acpi_handle handle = adev->handle;
+-      union acpi_object *obj;
+-      acpi_status status;
+-
+-      status = acpi_evaluate_object(handle, id, NULL, &buffer);
+-      if (ACPI_FAILURE(status))
+-              return ERR_PTR(-ENODEV);
+-
+-      obj = buffer.pointer;
+-      if (!obj)
+-              return ERR_PTR(-ENODEV);
+-
+-      if (obj->type != ACPI_TYPE_BUFFER) {
+-              acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
+-              kfree(obj);
+-              return ERR_PTR(-EINVAL);
+-      }
+-
+-      return obj;
+-}
+-
+-int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
+-{
+-      union acpi_object *obj;
+-      int ret;
+-
+-      obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
+-      if (IS_ERR(obj))
+-              return PTR_ERR(obj);
+-
+-      if (obj->buffer.length > sizeof(*cldb)) {
+-              acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
+-              ret = -EINVAL;
+-              goto out_free_obj;
+-      }
+-
+-      memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
+-      ret = 0;
+-
+-out_free_obj:
+-      kfree(obj);
+-      return ret;
+-}
+-
+-static const struct acpi_device_id int3472_device_id[] = {
+-      { "INT3472", 0 },
+-      { }
+-};
+-MODULE_DEVICE_TABLE(acpi, int3472_device_id);
+-
+-static struct platform_driver int3472_discrete = {
+-      .driver = {
+-              .name = "int3472-discrete",
+-              .acpi_match_table = int3472_device_id,
+-      },
+-      .probe = skl_int3472_discrete_probe,
+-      .remove = skl_int3472_discrete_remove,
+-};
+-
+-static struct i2c_driver int3472_tps68470 = {
+-      .driver = {
+-              .name = "int3472-tps68470",
+-              .acpi_match_table = int3472_device_id,
+-      },
+-      .probe_new = skl_int3472_tps68470_probe,
+-};
+-
+-static int skl_int3472_init(void)
+-{
+-      int ret;
+-
+-      ret = platform_driver_register(&int3472_discrete);
+-      if (ret)
+-              return ret;
+-
+-      ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470);
+-      if (ret)
+-              platform_driver_unregister(&int3472_discrete);
+-
+-      return ret;
+-}
+-module_init(skl_int3472_init);
+-
+-static void skl_int3472_exit(void)
+-{
+-      platform_driver_unregister(&int3472_discrete);
+-      i2c_del_driver(&int3472_tps68470);
+-}
+-module_exit(skl_int3472_exit);
+-
+-MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
+-MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
+-MODULE_LICENSE("GPL v2");
+diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
+similarity index 85%
+rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
+rename to drivers/platform/x86/intel/int3472/tps68470.c
+index c05b4cf502fef..fd3bef449137c 100644
+--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
++++ b/drivers/platform/x86/intel/int3472/tps68470.c
+@@ -7,7 +7,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+-#include "intel_skl_int3472_common.h"
++#include "common.h"
+ #define DESIGNED_FOR_CHROMEOS         1
+ #define DESIGNED_FOR_WINDOWS          2
+@@ -95,7 +95,7 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
+       return DESIGNED_FOR_WINDOWS;
+ }
+-int skl_int3472_tps68470_probe(struct i2c_client *client)
++static int skl_int3472_tps68470_probe(struct i2c_client *client)
+ {
+       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+       struct regmap *regmap;
+@@ -135,3 +135,22 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
+       return ret;
+ }
++
++static const struct acpi_device_id int3472_device_id[] = {
++      { "INT3472", 0 },
++      { }
++};
++MODULE_DEVICE_TABLE(acpi, int3472_device_id);
++
++static struct i2c_driver int3472_tps68470 = {
++      .driver = {
++              .name = "int3472-tps68470",
++              .acpi_match_table = int3472_device_id,
++      },
++      .probe_new = skl_int3472_tps68470_probe,
++};
++module_i2c_driver(int3472_tps68470);
++
++MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
++MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+2.39.2
+
diff --git a/queue-5.15/rdma-irdma-do-not-request-2-level-pbles-for-cq-alloc.patch b/queue-5.15/rdma-irdma-do-not-request-2-level-pbles-for-cq-alloc.patch
new file mode 100644 (file)
index 0000000..d895aac
--- /dev/null
@@ -0,0 +1,79 @@
+From bb82e63a205ac69d6327fc78f093c84e50a59c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 19:17:01 -0600
+Subject: RDMA/irdma: Do not request 2-level PBLEs for CQ alloc
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 8f7e2daa6336f9f4b6f8a4715a809674606df16b ]
+
+When allocating PBLE's for a large CQ, it is possible
+that a 2-level PBLE is returned which would cause the
+CQ allocation to fail since 1-level is assumed and checked for.
+Fix this by requesting a level one PBLE only.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20221115011701.1379-4-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index c5971a840b876..27f22d595a5dc 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2272,9 +2272,10 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+  * @rf: RDMA PCI function
+  * @iwmr: mr pointer for this memory registration
+  * @use_pbles: flag if to use pble's
++ * @lvl_1_only: request only level 1 pble if true
+  */
+ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr,
+-                           bool use_pbles)
++                           bool use_pbles, bool lvl_1_only)
+ {
+       struct irdma_pbl *iwpbl = &iwmr->iwpbl;
+       struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc;
+@@ -2285,7 +2286,7 @@ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr,
+       if (use_pbles) {
+               status = irdma_get_pble(rf->pble_rsrc, palloc, iwmr->page_cnt,
+-                                      false);
++                                      lvl_1_only);
+               if (status)
+                       return -ENOMEM;
+@@ -2328,16 +2329,10 @@ static int irdma_handle_q_mem(struct irdma_device *iwdev,
+       bool ret = true;
+       pg_size = iwmr->page_size;
+-      err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles);
++      err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, true);
+       if (err)
+               return err;
+-      if (use_pbles && palloc->level != PBLE_LEVEL_1) {
+-              irdma_free_pble(iwdev->rf->pble_rsrc, palloc);
+-              iwpbl->pbl_allocated = false;
+-              return -ENOMEM;
+-      }
+-
+       if (use_pbles)
+               arr = palloc->level1.addr;
+@@ -2808,7 +2803,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+       case IRDMA_MEMREG_TYPE_MEM:
+               use_pbles = (iwmr->page_cnt != 1);
+-              err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles);
++              err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, false);
+               if (err)
+                       goto error;
+-- 
+2.39.2
+
diff --git a/queue-5.15/serial-8250_exar-derive-nr_ports-from-pci-id-for-acc.patch b/queue-5.15/serial-8250_exar-derive-nr_ports-from-pci-id-for-acc.patch
new file mode 100644 (file)
index 0000000..fc95d37
--- /dev/null
@@ -0,0 +1,86 @@
+From eb0555d4a2678c6c6cbdc38cf9aa1551aff7bef1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 20:06:08 +0200
+Subject: serial: 8250_exar: derive nr_ports from PCI ID for Acces I/O cards
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 8e4413aaf6a2e3a46e99a0718ca54c0cf8609cb2 ]
+
+In the similar way how it's done in 8250_pericom, derive the number of
+the UART ports from PCI ID for Acces I/O cards.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20220127180608.71509-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 14ee78d5932a ("serial: exar: Add support for Sealevel 7xxxC serial cards")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_exar.c | 37 ++++++++++-------------------
+ 1 file changed, 13 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
+index d502240bbcf23..7292917ac8784 100644
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -623,7 +623,12 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
+       maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3);
+-      nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
++      if (pcidev->vendor == PCI_VENDOR_ID_ACCESSIO)
++              nr_ports = BIT(((pcidev->device & 0x38) >> 3) - 1);
++      else if (board->num_ports)
++              nr_ports = board->num_ports;
++      else
++              nr_ports = pcidev->device & 0x0f;
+       priv = devm_kzalloc(&pcidev->dev, struct_size(priv, line, nr_ports), GFP_KERNEL);
+       if (!priv)
+@@ -722,22 +727,6 @@ static int __maybe_unused exar_resume(struct device *dev)
+ static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume);
+-static const struct exar8250_board acces_com_2x = {
+-      .num_ports      = 2,
+-      .setup          = pci_xr17c154_setup,
+-};
+-
+-static const struct exar8250_board acces_com_4x = {
+-      .num_ports      = 4,
+-      .setup          = pci_xr17c154_setup,
+-};
+-
+-static const struct exar8250_board acces_com_8x = {
+-      .num_ports      = 8,
+-      .setup          = pci_xr17c154_setup,
+-};
+-
+-
+ static const struct exar8250_board pbn_fastcom335_2 = {
+       .num_ports      = 2,
+       .setup          = pci_fastcom335_setup,
+@@ -822,13 +811,13 @@ static const struct exar8250_board pbn_exar_XR17V8358 = {
+       }
+ static const struct pci_device_id exar_pci_tbl[] = {
+-      EXAR_DEVICE(ACCESSIO, COM_2S, acces_com_2x),
+-      EXAR_DEVICE(ACCESSIO, COM_4S, acces_com_4x),
+-      EXAR_DEVICE(ACCESSIO, COM_8S, acces_com_8x),
+-      EXAR_DEVICE(ACCESSIO, COM232_8, acces_com_8x),
+-      EXAR_DEVICE(ACCESSIO, COM_2SM, acces_com_2x),
+-      EXAR_DEVICE(ACCESSIO, COM_4SM, acces_com_4x),
+-      EXAR_DEVICE(ACCESSIO, COM_8SM, acces_com_8x),
++      EXAR_DEVICE(ACCESSIO, COM_2S, pbn_exar_XR17C15x),
++      EXAR_DEVICE(ACCESSIO, COM_4S, pbn_exar_XR17C15x),
++      EXAR_DEVICE(ACCESSIO, COM_8S, pbn_exar_XR17C15x),
++      EXAR_DEVICE(ACCESSIO, COM232_8, pbn_exar_XR17C15x),
++      EXAR_DEVICE(ACCESSIO, COM_2SM, pbn_exar_XR17C15x),
++      EXAR_DEVICE(ACCESSIO, COM_4SM, pbn_exar_XR17C15x),
++      EXAR_DEVICE(ACCESSIO, COM_8SM, pbn_exar_XR17C15x),
+       CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
+       CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
+-- 
+2.39.2
+
diff --git a/queue-5.15/serial-exar-add-support-for-sealevel-7xxxc-serial-ca.patch b/queue-5.15/serial-exar-add-support-for-sealevel-7xxxc-serial-ca.patch
new file mode 100644 (file)
index 0000000..6325e3c
--- /dev/null
@@ -0,0 +1,67 @@
+From b9ac329250f72461909c2542d08e1877adc7d513 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 14:40:29 -0500
+Subject: serial: exar: Add support for Sealevel 7xxxC serial cards
+
+From: Matthew Howell <matthew.howell@sealevel.com>
+
+[ Upstream commit 14ee78d5932afeb710c8305196a676a715bfdea8 ]
+
+Add support for Sealevel 7xxxC serial cards.
+
+This patch:
+* Adds IDs to recognize 7xxxC cards from Sealevel Systems.
+* Updates exar_pci_probe() to set nr_ports to last two bytes of primary
+  dev ID for these cards.
+
+Signed-off-by: Matthew Howell <matthew.howell@sealevel.com>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/alpine.DEB.2.21.2301191440010.22558@tstest-VirtualBox
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_exar.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
+index 7292917ac8784..c767636d9bb0f 100644
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -43,6 +43,12 @@
+ #define PCI_DEVICE_ID_EXAR_XR17V4358          0x4358
+ #define PCI_DEVICE_ID_EXAR_XR17V8358          0x8358
++#define PCI_DEVICE_ID_SEALEVEL_710xC          0x1001
++#define PCI_DEVICE_ID_SEALEVEL_720xC          0x1002
++#define PCI_DEVICE_ID_SEALEVEL_740xC          0x1004
++#define PCI_DEVICE_ID_SEALEVEL_780xC          0x1008
++#define PCI_DEVICE_ID_SEALEVEL_716xC          0x1010
++
+ #define UART_EXAR_INT0                0x80
+ #define UART_EXAR_8XMODE      0x88    /* 8X sampling rate select */
+ #define UART_EXAR_SLEEP               0x8b    /* Sleep mode */
+@@ -627,6 +633,8 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
+               nr_ports = BIT(((pcidev->device & 0x38) >> 3) - 1);
+       else if (board->num_ports)
+               nr_ports = board->num_ports;
++      else if (pcidev->vendor == PCI_VENDOR_ID_SEALEVEL)
++              nr_ports = pcidev->device & 0xff;
+       else
+               nr_ports = pcidev->device & 0x0f;
+@@ -853,6 +861,12 @@ static const struct pci_device_id exar_pci_tbl[] = {
+       EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4),
+       EXAR_DEVICE(COMMTECH, 2324PCI335, pbn_fastcom335_4),
+       EXAR_DEVICE(COMMTECH, 2328PCI335, pbn_fastcom335_8),
++
++      EXAR_DEVICE(SEALEVEL, 710xC, pbn_exar_XR17V35x),
++      EXAR_DEVICE(SEALEVEL, 720xC, pbn_exar_XR17V35x),
++      EXAR_DEVICE(SEALEVEL, 740xC, pbn_exar_XR17V35x),
++      EXAR_DEVICE(SEALEVEL, 780xC, pbn_exar_XR17V35x),
++      EXAR_DEVICE(SEALEVEL, 716xC, pbn_exar_XR17V35x),
+       { 0, }
+ };
+ MODULE_DEVICE_TABLE(pci, exar_pci_tbl);
+-- 
+2.39.2
+
diff --git a/queue-5.15/series b/queue-5.15/series
new file mode 100644 (file)
index 0000000..3999fc1
--- /dev/null
@@ -0,0 +1,24 @@
+kvm-arm64-pmu-fix-get_one_reg-for-vpmc-regs-to-retur.patch
+soc-sifive-ccache-rename-sifive-l2-cache-to-composab.patch
+soc-sifive-ccache-determine-the-cache-level-from-dts.patch
+soc-sifive-ccache-reduce-printing-on-init.patch
+soc-sifive-ccache-use-pr_fmt-to-remove-ccache-prefix.patch
+soc-sifive-ccache-fix-missing-iounmap-in-error-path-.patch
+soc-sifive-ccache-fix-missing-free_irq-in-error-path.patch
+soc-sifive-ccache-fix-missing-of_node_put-in-sifive_.patch
+ocfs2-ocfs2_mount_volume-does-cleanup-job-before-ret.patch
+ocfs2-rewrite-error-handling-of-ocfs2_fill_super.patch
+ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch
+nfsd-fix-sparse-warning.patch
+nfsd-pass-range-end-to-vfs_fsync_range-instead-of-co.patch
+rdma-irdma-do-not-request-2-level-pbles-for-cq-alloc.patch
+platform-x86-int3472-split-into-2-drivers.patch
+platform-x86-int3472-discrete-ensure-the-clk-power-e.patch
+iavf-return-errno-code-instead-of-status-code.patch
+iavf-iavf_main-actually-log-src-mask-when-talking-ab.patch
+arm64-dts-imx8mp-correct-usb-clocks.patch
+serial-8250_exar-derive-nr_ports-from-pci-id-for-acc.patch
+serial-exar-add-support-for-sealevel-7xxxc-serial-ca.patch
+drm-amdgpu-prevent-race-between-late-signaled-fences.patch
+drm-amdgpu-fix-amdgpu_job_free_resources-v2.patch
+bpf-hash-map-avoid-deadlock-with-suitable-hash-mask.patch
diff --git a/queue-5.15/soc-sifive-ccache-determine-the-cache-level-from-dts.patch b/queue-5.15/soc-sifive-ccache-determine-the-cache-level-from-dts.patch
new file mode 100644 (file)
index 0000000..8c87f53
--- /dev/null
@@ -0,0 +1,56 @@
+From 30e750852bcb00d0ec038ae35846966131870d11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 06:18:13 +0000
+Subject: soc: sifive: ccache: determine the cache level from dts
+
+From: Zong Li <zong.li@sifive.com>
+
+[ Upstream commit 95f196f3212bbc258611c22865aef12b98304e1d ]
+
+Composable cache could be L2 or L3 cache, use 'cache-level' property of
+device node to determine the level.
+
+Signed-off-by: Zong Li <zong.li@sifive.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20220913061817.22564-4-zong.li@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: 73e770f08502 ("soc: sifive: ccache: fix missing iounmap() in error path in sifive_ccache_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sifive/sifive_ccache.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index 949b824e89adf..b361b661ea09a 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -38,6 +38,7 @@
+ static void __iomem *ccache_base;
+ static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
+ static struct riscv_cacheinfo_ops ccache_cache_ops;
++static int level;
+ enum {
+       DIR_CORR = 0,
+@@ -144,7 +145,7 @@ static const struct attribute_group *ccache_get_priv_group(struct cacheinfo
+                                                          *this_leaf)
+ {
+       /* We want to use private group for composable cache only */
+-      if (this_leaf->level == 2)
++      if (this_leaf->level == level)
+               return &priv_attr_group;
+       else
+               return NULL;
+@@ -215,6 +216,9 @@ static int __init sifive_ccache_init(void)
+       if (!ccache_base)
+               return -ENOMEM;
++      if (of_property_read_u32(np, "cache-level", &level))
++              return -ENOENT;
++
+       intr_num = of_property_count_u32_elems(np, "interrupts");
+       if (!intr_num) {
+               pr_err("CCACHE: no interrupts property\n");
+-- 
+2.39.2
+
diff --git a/queue-5.15/soc-sifive-ccache-fix-missing-free_irq-in-error-path.patch b/queue-5.15/soc-sifive-ccache-fix-missing-free_irq-in-error-path.patch
new file mode 100644 (file)
index 0000000..ff446b4
--- /dev/null
@@ -0,0 +1,47 @@
+From 42f02719f423d4256dcefc34c23b324bd5b57a0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 10:31:48 +0800
+Subject: soc: sifive: ccache: fix missing free_irq() in error path in
+ sifive_ccache_init()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 756344e7cb1afbb87da8705c20384dddd0dea233 ]
+
+Add missing free_irq() before return error from sifive_ccache_init().
+
+Fixes: a967a289f169 ("RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sifive/sifive_ccache.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index 335e4303fb928..4b9d0a656a979 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -234,7 +234,7 @@ static int __init sifive_ccache_init(void)
+                                NULL);
+               if (rc) {
+                       pr_err("Could not request IRQ %d\n", g_irq[i]);
+-                      goto err_unmap;
++                      goto err_free_irq;
+               }
+       }
+@@ -248,6 +248,9 @@ static int __init sifive_ccache_init(void)
+ #endif
+       return 0;
++err_free_irq:
++      while (--i >= 0)
++              free_irq(g_irq[i], NULL);
+ err_unmap:
+       iounmap(ccache_base);
+       return rc;
+-- 
+2.39.2
+
diff --git a/queue-5.15/soc-sifive-ccache-fix-missing-iounmap-in-error-path-.patch b/queue-5.15/soc-sifive-ccache-fix-missing-iounmap-in-error-path-.patch
new file mode 100644 (file)
index 0000000..ac48ad3
--- /dev/null
@@ -0,0 +1,68 @@
+From 5b332dee87d3c4dfea42bd7e78baee82b8b7f571 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 10:31:47 +0800
+Subject: soc: sifive: ccache: fix missing iounmap() in error path in
+ sifive_ccache_init()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 73e770f085023da327dc9ffeb6cd96b0bb22d97e ]
+
+Add missing iounmap() before return error from sifive_ccache_init().
+
+Fixes: a967a289f169 ("RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sifive/sifive_ccache.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index 91f0c2b32ea2b..335e4303fb928 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -216,13 +216,16 @@ static int __init sifive_ccache_init(void)
+       if (!ccache_base)
+               return -ENOMEM;
+-      if (of_property_read_u32(np, "cache-level", &level))
+-              return -ENOENT;
++      if (of_property_read_u32(np, "cache-level", &level)) {
++              rc = -ENOENT;
++              goto err_unmap;
++      }
+       intr_num = of_property_count_u32_elems(np, "interrupts");
+       if (!intr_num) {
+               pr_err("No interrupts property\n");
+-              return -ENODEV;
++              rc = -ENODEV;
++              goto err_unmap;
+       }
+       for (i = 0; i < intr_num; i++) {
+@@ -231,7 +234,7 @@ static int __init sifive_ccache_init(void)
+                                NULL);
+               if (rc) {
+                       pr_err("Could not request IRQ %d\n", g_irq[i]);
+-                      return rc;
++                      goto err_unmap;
+               }
+       }
+@@ -244,6 +247,10 @@ static int __init sifive_ccache_init(void)
+       setup_sifive_debug();
+ #endif
+       return 0;
++
++err_unmap:
++      iounmap(ccache_base);
++      return rc;
+ }
+ device_initcall(sifive_ccache_init);
+-- 
+2.39.2
+
diff --git a/queue-5.15/soc-sifive-ccache-fix-missing-of_node_put-in-sifive_.patch b/queue-5.15/soc-sifive-ccache-fix-missing-of_node_put-in-sifive_.patch
new file mode 100644 (file)
index 0000000..ded5d53
--- /dev/null
@@ -0,0 +1,68 @@
+From 248910f3f21104746a7d140474645ed10409b383 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 10:31:49 +0800
+Subject: soc: sifive: ccache: fix missing of_node_put() in
+ sifive_ccache_init()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 8fbf94fea0b4e187ca9100936c5429f96b8a4e44 ]
+
+The device_node pointer returned by of_find_matching_node() with
+refcount incremented, when finish using it, the refcount need be
+decreased.
+
+Fixes: a967a289f169 ("RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sifive/sifive_ccache.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index 4b9d0a656a979..09914cb4f0284 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -209,12 +209,16 @@ static int __init sifive_ccache_init(void)
+       if (!np)
+               return -ENODEV;
+-      if (of_address_to_resource(np, 0, &res))
+-              return -ENODEV;
++      if (of_address_to_resource(np, 0, &res)) {
++              rc = -ENODEV;
++              goto err_node_put;
++      }
+       ccache_base = ioremap(res.start, resource_size(&res));
+-      if (!ccache_base)
+-              return -ENOMEM;
++      if (!ccache_base) {
++              rc = -ENOMEM;
++              goto err_node_put;
++      }
+       if (of_property_read_u32(np, "cache-level", &level)) {
+               rc = -ENOENT;
+@@ -237,6 +241,7 @@ static int __init sifive_ccache_init(void)
+                       goto err_free_irq;
+               }
+       }
++      of_node_put(np);
+       ccache_config_read();
+@@ -253,6 +258,8 @@ static int __init sifive_ccache_init(void)
+               free_irq(g_irq[i], NULL);
+ err_unmap:
+       iounmap(ccache_base);
++err_node_put:
++      of_node_put(np);
+       return rc;
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/soc-sifive-ccache-reduce-printing-on-init.patch b/queue-5.15/soc-sifive-ccache-reduce-printing-on-init.patch
new file mode 100644 (file)
index 0000000..e86a469
--- /dev/null
@@ -0,0 +1,66 @@
+From bf335099c9ba5205a878d54645790175661333d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 06:18:14 +0000
+Subject: soc: sifive: ccache: reduce printing on init
+
+From: Ben Dooks <ben.dooks@sifive.com>
+
+[ Upstream commit 3fb787e5bad50687a65ded7f3bb805cab70dff59 ]
+
+The driver prints out 6 lines on startup, which can easily be redcued
+to two lines without losing any information.
+
+Note, to make the types work better, uint64_t has been replaced with
+ULL to make the unsigned long long match the format in the print
+statement.
+
+Signed-off-by: Ben Dooks <ben.dooks@sifive.com>
+Signed-off-by: Zong Li <zong.li@sifive.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20220913061817.22564-5-zong.li@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: 73e770f08502 ("soc: sifive: ccache: fix missing iounmap() in error path in sifive_ccache_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sifive/sifive_ccache.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index b361b661ea09a..17080af7dfa00 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -81,20 +81,17 @@ static void setup_sifive_debug(void)
+ static void ccache_config_read(void)
+ {
+-      u32 regval, val;
+-
+-      regval = readl(ccache_base + SIFIVE_CCACHE_CONFIG);
+-      val = regval & 0xFF;
+-      pr_info("CCACHE: No. of Banks in the cache: %d\n", val);
+-      val = (regval & 0xFF00) >> 8;
+-      pr_info("CCACHE: No. of ways per bank: %d\n", val);
+-      val = (regval & 0xFF0000) >> 16;
+-      pr_info("CCACHE: Sets per bank: %llu\n", (uint64_t)1 << val);
+-      val = (regval & 0xFF000000) >> 24;
+-      pr_info("CCACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val);
+-
+-      regval = readl(ccache_base + SIFIVE_CCACHE_WAYENABLE);
+-      pr_info("CCACHE: Index of the largest way enabled: %d\n", regval);
++      u32 cfg;
++
++      cfg = readl(ccache_base + SIFIVE_CCACHE_CONFIG);
++
++      pr_info("CCACHE: %u banks, %u ways, sets/bank=%llu, bytes/block=%llu\n",
++              (cfg & 0xff), (cfg >> 8) & 0xff,
++              BIT_ULL((cfg >> 16) & 0xff),
++              BIT_ULL((cfg >> 24) & 0xff));
++
++      cfg = readl(ccache_base + SIFIVE_CCACHE_WAYENABLE);
++      pr_info("CCACHE: Index of the largest way enabled: %u\n", cfg);
+ }
+ static const struct of_device_id sifive_ccache_ids[] = {
+-- 
+2.39.2
+
diff --git a/queue-5.15/soc-sifive-ccache-rename-sifive-l2-cache-to-composab.patch b/queue-5.15/soc-sifive-ccache-rename-sifive-l2-cache-to-composab.patch
new file mode 100644 (file)
index 0000000..e3d9dec
--- /dev/null
@@ -0,0 +1,673 @@
+From 6f46e25b6cf3540adb412957ed3ee02d8be7bbff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 06:18:12 +0000
+Subject: soc: sifive: ccache: Rename SiFive L2 cache to Composable cache.
+
+From: Greentime Hu <greentime.hu@sifive.com>
+
+[ Upstream commit ca120a79cf5a3323172c82e77efd70ae10d120ef ]
+
+Since composable cache may be L3 cache if there is a L2 cache, we should
+use its original name composable cache to prevent confusion.
+
+There are some new lines were generated due to adding the compatible
+"sifive,ccache0" into ID table and indent requirement.
+
+The sifive L2 has been renamed to sifive CCACHE, EDAC driver needs to
+apply the change as well.
+
+Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
+Signed-off-by: Zong Li <zong.li@sifive.com>
+Co-developed-by: Zong Li <zong.li@sifive.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20220913061817.22564-3-zong.li@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: 73e770f08502 ("soc: sifive: ccache: fix missing iounmap() in error path in sifive_ccache_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/Kconfig                 |   2 +-
+ drivers/edac/sifive_edac.c           |  12 +-
+ drivers/soc/sifive/Kconfig           |   6 +-
+ drivers/soc/sifive/Makefile          |   2 +-
+ drivers/soc/sifive/sifive_ccache.c   | 245 +++++++++++++++++++++++++++
+ drivers/soc/sifive/sifive_l2_cache.c | 237 --------------------------
+ include/soc/sifive/sifive_ccache.h   |  16 ++
+ include/soc/sifive/sifive_l2_cache.h |  16 --
+ 8 files changed, 272 insertions(+), 264 deletions(-)
+ create mode 100644 drivers/soc/sifive/sifive_ccache.c
+ delete mode 100644 drivers/soc/sifive/sifive_l2_cache.c
+ create mode 100644 include/soc/sifive/sifive_ccache.h
+ delete mode 100644 include/soc/sifive/sifive_l2_cache.h
+
+diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
+index 2fc4c3f91fd54..0e1ed09ec5b72 100644
+--- a/drivers/edac/Kconfig
++++ b/drivers/edac/Kconfig
+@@ -471,7 +471,7 @@ config EDAC_ALTERA_SDMMC
+ config EDAC_SIFIVE
+       bool "Sifive platform EDAC driver"
+-      depends on EDAC=y && SIFIVE_L2
++      depends on EDAC=y && SIFIVE_CCACHE
+       help
+         Support for error detection and correction on the SiFive SoCs.
+diff --git a/drivers/edac/sifive_edac.c b/drivers/edac/sifive_edac.c
+index 3a3dcb14ed99d..a759a56ad34de 100644
+--- a/drivers/edac/sifive_edac.c
++++ b/drivers/edac/sifive_edac.c
+@@ -2,7 +2,7 @@
+ /*
+  * SiFive Platform EDAC Driver
+  *
+- * Copyright (C) 2018-2019 SiFive, Inc.
++ * Copyright (C) 2018-2022 SiFive, Inc.
+  *
+  * This driver is partially based on octeon_edac-pc.c
+  *
+@@ -10,7 +10,7 @@
+ #include <linux/edac.h>
+ #include <linux/platform_device.h>
+ #include "edac_module.h"
+-#include <soc/sifive/sifive_l2_cache.h>
++#include <soc/sifive/sifive_ccache.h>
+ #define DRVNAME "sifive_edac"
+@@ -32,9 +32,9 @@ int ecc_err_event(struct notifier_block *this, unsigned long event, void *ptr)
+       p = container_of(this, struct sifive_edac_priv, notifier);
+-      if (event == SIFIVE_L2_ERR_TYPE_UE)
++      if (event == SIFIVE_CCACHE_ERR_TYPE_UE)
+               edac_device_handle_ue(p->dci, 0, 0, msg);
+-      else if (event == SIFIVE_L2_ERR_TYPE_CE)
++      else if (event == SIFIVE_CCACHE_ERR_TYPE_CE)
+               edac_device_handle_ce(p->dci, 0, 0, msg);
+       return NOTIFY_OK;
+@@ -67,7 +67,7 @@ static int ecc_register(struct platform_device *pdev)
+               goto err;
+       }
+-      register_sifive_l2_error_notifier(&p->notifier);
++      register_sifive_ccache_error_notifier(&p->notifier);
+       return 0;
+@@ -81,7 +81,7 @@ static int ecc_unregister(struct platform_device *pdev)
+ {
+       struct sifive_edac_priv *p = platform_get_drvdata(pdev);
+-      unregister_sifive_l2_error_notifier(&p->notifier);
++      unregister_sifive_ccache_error_notifier(&p->notifier);
+       edac_device_del_device(&pdev->dev);
+       edac_device_free_ctl_info(p->dci);
+diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig
+index 58cf8c40d08d5..ed4c571f8771b 100644
+--- a/drivers/soc/sifive/Kconfig
++++ b/drivers/soc/sifive/Kconfig
+@@ -2,9 +2,9 @@
+ if SOC_SIFIVE
+-config SIFIVE_L2
+-      bool "Sifive L2 Cache controller"
++config SIFIVE_CCACHE
++      bool "Sifive Composable Cache controller"
+       help
+-        Support for the L2 cache controller on SiFive platforms.
++        Support for the composable cache controller on SiFive platforms.
+ endif
+diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile
+index b5caff77938f6..1f5dc339bf827 100644
+--- a/drivers/soc/sifive/Makefile
++++ b/drivers/soc/sifive/Makefile
+@@ -1,3 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0
+-obj-$(CONFIG_SIFIVE_L2)       += sifive_l2_cache.o
++obj-$(CONFIG_SIFIVE_CCACHE)   += sifive_ccache.o
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+new file mode 100644
+index 0000000000000..949b824e89adf
+--- /dev/null
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -0,0 +1,245 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * SiFive composable cache controller Driver
++ *
++ * Copyright (C) 2018-2022 SiFive, Inc.
++ *
++ */
++#include <linux/debugfs.h>
++#include <linux/interrupt.h>
++#include <linux/of_irq.h>
++#include <linux/of_address.h>
++#include <linux/device.h>
++#include <asm/cacheinfo.h>
++#include <soc/sifive/sifive_ccache.h>
++
++#define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
++#define SIFIVE_CCACHE_DIRECCFIX_HIGH 0x104
++#define SIFIVE_CCACHE_DIRECCFIX_COUNT 0x108
++
++#define SIFIVE_CCACHE_DIRECCFAIL_LOW 0x120
++#define SIFIVE_CCACHE_DIRECCFAIL_HIGH 0x124
++#define SIFIVE_CCACHE_DIRECCFAIL_COUNT 0x128
++
++#define SIFIVE_CCACHE_DATECCFIX_LOW 0x140
++#define SIFIVE_CCACHE_DATECCFIX_HIGH 0x144
++#define SIFIVE_CCACHE_DATECCFIX_COUNT 0x148
++
++#define SIFIVE_CCACHE_DATECCFAIL_LOW 0x160
++#define SIFIVE_CCACHE_DATECCFAIL_HIGH 0x164
++#define SIFIVE_CCACHE_DATECCFAIL_COUNT 0x168
++
++#define SIFIVE_CCACHE_CONFIG 0x00
++#define SIFIVE_CCACHE_WAYENABLE 0x08
++#define SIFIVE_CCACHE_ECCINJECTERR 0x40
++
++#define SIFIVE_CCACHE_MAX_ECCINTR 4
++
++static void __iomem *ccache_base;
++static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
++static struct riscv_cacheinfo_ops ccache_cache_ops;
++
++enum {
++      DIR_CORR = 0,
++      DATA_CORR,
++      DATA_UNCORR,
++      DIR_UNCORR,
++};
++
++#ifdef CONFIG_DEBUG_FS
++static struct dentry *sifive_test;
++
++static ssize_t ccache_write(struct file *file, const char __user *data,
++                          size_t count, loff_t *ppos)
++{
++      unsigned int val;
++
++      if (kstrtouint_from_user(data, count, 0, &val))
++              return -EINVAL;
++      if ((val < 0xFF) || (val >= 0x10000 && val < 0x100FF))
++              writel(val, ccache_base + SIFIVE_CCACHE_ECCINJECTERR);
++      else
++              return -EINVAL;
++      return count;
++}
++
++static const struct file_operations ccache_fops = {
++      .owner = THIS_MODULE,
++      .open = simple_open,
++      .write = ccache_write
++};
++
++static void setup_sifive_debug(void)
++{
++      sifive_test = debugfs_create_dir("sifive_ccache_cache", NULL);
++
++      debugfs_create_file("sifive_debug_inject_error", 0200,
++                          sifive_test, NULL, &ccache_fops);
++}
++#endif
++
++static void ccache_config_read(void)
++{
++      u32 regval, val;
++
++      regval = readl(ccache_base + SIFIVE_CCACHE_CONFIG);
++      val = regval & 0xFF;
++      pr_info("CCACHE: No. of Banks in the cache: %d\n", val);
++      val = (regval & 0xFF00) >> 8;
++      pr_info("CCACHE: No. of ways per bank: %d\n", val);
++      val = (regval & 0xFF0000) >> 16;
++      pr_info("CCACHE: Sets per bank: %llu\n", (uint64_t)1 << val);
++      val = (regval & 0xFF000000) >> 24;
++      pr_info("CCACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val);
++
++      regval = readl(ccache_base + SIFIVE_CCACHE_WAYENABLE);
++      pr_info("CCACHE: Index of the largest way enabled: %d\n", regval);
++}
++
++static const struct of_device_id sifive_ccache_ids[] = {
++      { .compatible = "sifive,fu540-c000-ccache" },
++      { .compatible = "sifive,fu740-c000-ccache" },
++      { .compatible = "sifive,ccache0" },
++      { /* end of table */ }
++};
++
++static ATOMIC_NOTIFIER_HEAD(ccache_err_chain);
++
++int register_sifive_ccache_error_notifier(struct notifier_block *nb)
++{
++      return atomic_notifier_chain_register(&ccache_err_chain, nb);
++}
++EXPORT_SYMBOL_GPL(register_sifive_ccache_error_notifier);
++
++int unregister_sifive_ccache_error_notifier(struct notifier_block *nb)
++{
++      return atomic_notifier_chain_unregister(&ccache_err_chain, nb);
++}
++EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
++
++static int ccache_largest_wayenabled(void)
++{
++      return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
++}
++
++static ssize_t number_of_ways_enabled_show(struct device *dev,
++                                         struct device_attribute *attr,
++                                         char *buf)
++{
++      return sprintf(buf, "%u\n", ccache_largest_wayenabled());
++}
++
++static DEVICE_ATTR_RO(number_of_ways_enabled);
++
++static struct attribute *priv_attrs[] = {
++      &dev_attr_number_of_ways_enabled.attr,
++      NULL,
++};
++
++static const struct attribute_group priv_attr_group = {
++      .attrs = priv_attrs,
++};
++
++static const struct attribute_group *ccache_get_priv_group(struct cacheinfo
++                                                         *this_leaf)
++{
++      /* We want to use private group for composable cache only */
++      if (this_leaf->level == 2)
++              return &priv_attr_group;
++      else
++              return NULL;
++}
++
++static irqreturn_t ccache_int_handler(int irq, void *device)
++{
++      unsigned int add_h, add_l;
++
++      if (irq == g_irq[DIR_CORR]) {
++              add_h = readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_HIGH);
++              add_l = readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_LOW);
++              pr_err("CCACHE: DirError @ 0x%08X.%08X\n", add_h, add_l);
++              /* Reading this register clears the DirError interrupt sig */
++              readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_COUNT);
++              atomic_notifier_call_chain(&ccache_err_chain,
++                                         SIFIVE_CCACHE_ERR_TYPE_CE,
++                                         "DirECCFix");
++      }
++      if (irq == g_irq[DIR_UNCORR]) {
++              add_h = readl(ccache_base + SIFIVE_CCACHE_DIRECCFAIL_HIGH);
++              add_l = readl(ccache_base + SIFIVE_CCACHE_DIRECCFAIL_LOW);
++              /* Reading this register clears the DirFail interrupt sig */
++              readl(ccache_base + SIFIVE_CCACHE_DIRECCFAIL_COUNT);
++              atomic_notifier_call_chain(&ccache_err_chain,
++                                         SIFIVE_CCACHE_ERR_TYPE_UE,
++                                         "DirECCFail");
++              panic("CCACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l);
++      }
++      if (irq == g_irq[DATA_CORR]) {
++              add_h = readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_HIGH);
++              add_l = readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_LOW);
++              pr_err("CCACHE: DataError @ 0x%08X.%08X\n", add_h, add_l);
++              /* Reading this register clears the DataError interrupt sig */
++              readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_COUNT);
++              atomic_notifier_call_chain(&ccache_err_chain,
++                                         SIFIVE_CCACHE_ERR_TYPE_CE,
++                                         "DatECCFix");
++      }
++      if (irq == g_irq[DATA_UNCORR]) {
++              add_h = readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_HIGH);
++              add_l = readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_LOW);
++              pr_err("CCACHE: DataFail @ 0x%08X.%08X\n", add_h, add_l);
++              /* Reading this register clears the DataFail interrupt sig */
++              readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_COUNT);
++              atomic_notifier_call_chain(&ccache_err_chain,
++                                         SIFIVE_CCACHE_ERR_TYPE_UE,
++                                         "DatECCFail");
++      }
++
++      return IRQ_HANDLED;
++}
++
++static int __init sifive_ccache_init(void)
++{
++      struct device_node *np;
++      struct resource res;
++      int i, rc, intr_num;
++
++      np = of_find_matching_node(NULL, sifive_ccache_ids);
++      if (!np)
++              return -ENODEV;
++
++      if (of_address_to_resource(np, 0, &res))
++              return -ENODEV;
++
++      ccache_base = ioremap(res.start, resource_size(&res));
++      if (!ccache_base)
++              return -ENOMEM;
++
++      intr_num = of_property_count_u32_elems(np, "interrupts");
++      if (!intr_num) {
++              pr_err("CCACHE: no interrupts property\n");
++              return -ENODEV;
++      }
++
++      for (i = 0; i < intr_num; i++) {
++              g_irq[i] = irq_of_parse_and_map(np, i);
++              rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
++                               NULL);
++              if (rc) {
++                      pr_err("CCACHE: Could not request IRQ %d\n", g_irq[i]);
++                      return rc;
++              }
++      }
++
++      ccache_config_read();
++
++      ccache_cache_ops.get_priv_group = ccache_get_priv_group;
++      riscv_set_cacheinfo_ops(&ccache_cache_ops);
++
++#ifdef CONFIG_DEBUG_FS
++      setup_sifive_debug();
++#endif
++      return 0;
++}
++
++device_initcall(sifive_ccache_init);
+diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
+deleted file mode 100644
+index 59640a1d0b28a..0000000000000
+--- a/drivers/soc/sifive/sifive_l2_cache.c
++++ /dev/null
+@@ -1,237 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/*
+- * SiFive L2 cache controller Driver
+- *
+- * Copyright (C) 2018-2019 SiFive, Inc.
+- *
+- */
+-#include <linux/debugfs.h>
+-#include <linux/interrupt.h>
+-#include <linux/of_irq.h>
+-#include <linux/of_address.h>
+-#include <linux/device.h>
+-#include <asm/cacheinfo.h>
+-#include <soc/sifive/sifive_l2_cache.h>
+-
+-#define SIFIVE_L2_DIRECCFIX_LOW 0x100
+-#define SIFIVE_L2_DIRECCFIX_HIGH 0x104
+-#define SIFIVE_L2_DIRECCFIX_COUNT 0x108
+-
+-#define SIFIVE_L2_DIRECCFAIL_LOW 0x120
+-#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124
+-#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128
+-
+-#define SIFIVE_L2_DATECCFIX_LOW 0x140
+-#define SIFIVE_L2_DATECCFIX_HIGH 0x144
+-#define SIFIVE_L2_DATECCFIX_COUNT 0x148
+-
+-#define SIFIVE_L2_DATECCFAIL_LOW 0x160
+-#define SIFIVE_L2_DATECCFAIL_HIGH 0x164
+-#define SIFIVE_L2_DATECCFAIL_COUNT 0x168
+-
+-#define SIFIVE_L2_CONFIG 0x00
+-#define SIFIVE_L2_WAYENABLE 0x08
+-#define SIFIVE_L2_ECCINJECTERR 0x40
+-
+-#define SIFIVE_L2_MAX_ECCINTR 4
+-
+-static void __iomem *l2_base;
+-static int g_irq[SIFIVE_L2_MAX_ECCINTR];
+-static struct riscv_cacheinfo_ops l2_cache_ops;
+-
+-enum {
+-      DIR_CORR = 0,
+-      DATA_CORR,
+-      DATA_UNCORR,
+-      DIR_UNCORR,
+-};
+-
+-#ifdef CONFIG_DEBUG_FS
+-static struct dentry *sifive_test;
+-
+-static ssize_t l2_write(struct file *file, const char __user *data,
+-                      size_t count, loff_t *ppos)
+-{
+-      unsigned int val;
+-
+-      if (kstrtouint_from_user(data, count, 0, &val))
+-              return -EINVAL;
+-      if ((val < 0xFF) || (val >= 0x10000 && val < 0x100FF))
+-              writel(val, l2_base + SIFIVE_L2_ECCINJECTERR);
+-      else
+-              return -EINVAL;
+-      return count;
+-}
+-
+-static const struct file_operations l2_fops = {
+-      .owner = THIS_MODULE,
+-      .open = simple_open,
+-      .write = l2_write
+-};
+-
+-static void setup_sifive_debug(void)
+-{
+-      sifive_test = debugfs_create_dir("sifive_l2_cache", NULL);
+-
+-      debugfs_create_file("sifive_debug_inject_error", 0200,
+-                          sifive_test, NULL, &l2_fops);
+-}
+-#endif
+-
+-static void l2_config_read(void)
+-{
+-      u32 regval, val;
+-
+-      regval = readl(l2_base + SIFIVE_L2_CONFIG);
+-      val = regval & 0xFF;
+-      pr_info("L2CACHE: No. of Banks in the cache: %d\n", val);
+-      val = (regval & 0xFF00) >> 8;
+-      pr_info("L2CACHE: No. of ways per bank: %d\n", val);
+-      val = (regval & 0xFF0000) >> 16;
+-      pr_info("L2CACHE: Sets per bank: %llu\n", (uint64_t)1 << val);
+-      val = (regval & 0xFF000000) >> 24;
+-      pr_info("L2CACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val);
+-
+-      regval = readl(l2_base + SIFIVE_L2_WAYENABLE);
+-      pr_info("L2CACHE: Index of the largest way enabled: %d\n", regval);
+-}
+-
+-static const struct of_device_id sifive_l2_ids[] = {
+-      { .compatible = "sifive,fu540-c000-ccache" },
+-      { .compatible = "sifive,fu740-c000-ccache" },
+-      { /* end of table */ },
+-};
+-
+-static ATOMIC_NOTIFIER_HEAD(l2_err_chain);
+-
+-int register_sifive_l2_error_notifier(struct notifier_block *nb)
+-{
+-      return atomic_notifier_chain_register(&l2_err_chain, nb);
+-}
+-EXPORT_SYMBOL_GPL(register_sifive_l2_error_notifier);
+-
+-int unregister_sifive_l2_error_notifier(struct notifier_block *nb)
+-{
+-      return atomic_notifier_chain_unregister(&l2_err_chain, nb);
+-}
+-EXPORT_SYMBOL_GPL(unregister_sifive_l2_error_notifier);
+-
+-static int l2_largest_wayenabled(void)
+-{
+-      return readl(l2_base + SIFIVE_L2_WAYENABLE) & 0xFF;
+-}
+-
+-static ssize_t number_of_ways_enabled_show(struct device *dev,
+-                                         struct device_attribute *attr,
+-                                         char *buf)
+-{
+-      return sprintf(buf, "%u\n", l2_largest_wayenabled());
+-}
+-
+-static DEVICE_ATTR_RO(number_of_ways_enabled);
+-
+-static struct attribute *priv_attrs[] = {
+-      &dev_attr_number_of_ways_enabled.attr,
+-      NULL,
+-};
+-
+-static const struct attribute_group priv_attr_group = {
+-      .attrs = priv_attrs,
+-};
+-
+-static const struct attribute_group *l2_get_priv_group(struct cacheinfo *this_leaf)
+-{
+-      /* We want to use private group for L2 cache only */
+-      if (this_leaf->level == 2)
+-              return &priv_attr_group;
+-      else
+-              return NULL;
+-}
+-
+-static irqreturn_t l2_int_handler(int irq, void *device)
+-{
+-      unsigned int add_h, add_l;
+-
+-      if (irq == g_irq[DIR_CORR]) {
+-              add_h = readl(l2_base + SIFIVE_L2_DIRECCFIX_HIGH);
+-              add_l = readl(l2_base + SIFIVE_L2_DIRECCFIX_LOW);
+-              pr_err("L2CACHE: DirError @ 0x%08X.%08X\n", add_h, add_l);
+-              /* Reading this register clears the DirError interrupt sig */
+-              readl(l2_base + SIFIVE_L2_DIRECCFIX_COUNT);
+-              atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE,
+-                                         "DirECCFix");
+-      }
+-      if (irq == g_irq[DIR_UNCORR]) {
+-              add_h = readl(l2_base + SIFIVE_L2_DIRECCFAIL_HIGH);
+-              add_l = readl(l2_base + SIFIVE_L2_DIRECCFAIL_LOW);
+-              /* Reading this register clears the DirFail interrupt sig */
+-              readl(l2_base + SIFIVE_L2_DIRECCFAIL_COUNT);
+-              atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE,
+-                                         "DirECCFail");
+-              panic("L2CACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l);
+-      }
+-      if (irq == g_irq[DATA_CORR]) {
+-              add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH);
+-              add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW);
+-              pr_err("L2CACHE: DataError @ 0x%08X.%08X\n", add_h, add_l);
+-              /* Reading this register clears the DataError interrupt sig */
+-              readl(l2_base + SIFIVE_L2_DATECCFIX_COUNT);
+-              atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE,
+-                                         "DatECCFix");
+-      }
+-      if (irq == g_irq[DATA_UNCORR]) {
+-              add_h = readl(l2_base + SIFIVE_L2_DATECCFAIL_HIGH);
+-              add_l = readl(l2_base + SIFIVE_L2_DATECCFAIL_LOW);
+-              pr_err("L2CACHE: DataFail @ 0x%08X.%08X\n", add_h, add_l);
+-              /* Reading this register clears the DataFail interrupt sig */
+-              readl(l2_base + SIFIVE_L2_DATECCFAIL_COUNT);
+-              atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE,
+-                                         "DatECCFail");
+-      }
+-
+-      return IRQ_HANDLED;
+-}
+-
+-static int __init sifive_l2_init(void)
+-{
+-      struct device_node *np;
+-      struct resource res;
+-      int i, rc, intr_num;
+-
+-      np = of_find_matching_node(NULL, sifive_l2_ids);
+-      if (!np)
+-              return -ENODEV;
+-
+-      if (of_address_to_resource(np, 0, &res))
+-              return -ENODEV;
+-
+-      l2_base = ioremap(res.start, resource_size(&res));
+-      if (!l2_base)
+-              return -ENOMEM;
+-
+-      intr_num = of_property_count_u32_elems(np, "interrupts");
+-      if (!intr_num) {
+-              pr_err("L2CACHE: no interrupts property\n");
+-              return -ENODEV;
+-      }
+-
+-      for (i = 0; i < intr_num; i++) {
+-              g_irq[i] = irq_of_parse_and_map(np, i);
+-              rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL);
+-              if (rc) {
+-                      pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[i]);
+-                      return rc;
+-              }
+-      }
+-
+-      l2_config_read();
+-
+-      l2_cache_ops.get_priv_group = l2_get_priv_group;
+-      riscv_set_cacheinfo_ops(&l2_cache_ops);
+-
+-#ifdef CONFIG_DEBUG_FS
+-      setup_sifive_debug();
+-#endif
+-      return 0;
+-}
+-device_initcall(sifive_l2_init);
+diff --git a/include/soc/sifive/sifive_ccache.h b/include/soc/sifive/sifive_ccache.h
+new file mode 100644
+index 0000000000000..4d4ed49388a0a
+--- /dev/null
++++ b/include/soc/sifive/sifive_ccache.h
+@@ -0,0 +1,16 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * SiFive Composable Cache Controller header file
++ *
++ */
++
++#ifndef __SOC_SIFIVE_CCACHE_H
++#define __SOC_SIFIVE_CCACHE_H
++
++extern int register_sifive_ccache_error_notifier(struct notifier_block *nb);
++extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb);
++
++#define SIFIVE_CCACHE_ERR_TYPE_CE 0
++#define SIFIVE_CCACHE_ERR_TYPE_UE 1
++
++#endif /* __SOC_SIFIVE_CCACHE_H */
+diff --git a/include/soc/sifive/sifive_l2_cache.h b/include/soc/sifive/sifive_l2_cache.h
+deleted file mode 100644
+index 92ade10ed67e9..0000000000000
+--- a/include/soc/sifive/sifive_l2_cache.h
++++ /dev/null
+@@ -1,16 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
+-/*
+- * SiFive L2 Cache Controller header file
+- *
+- */
+-
+-#ifndef __SOC_SIFIVE_L2_CACHE_H
+-#define __SOC_SIFIVE_L2_CACHE_H
+-
+-extern int register_sifive_l2_error_notifier(struct notifier_block *nb);
+-extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb);
+-
+-#define SIFIVE_L2_ERR_TYPE_CE 0
+-#define SIFIVE_L2_ERR_TYPE_UE 1
+-
+-#endif /* __SOC_SIFIVE_L2_CACHE_H */
+-- 
+2.39.2
+
diff --git a/queue-5.15/soc-sifive-ccache-use-pr_fmt-to-remove-ccache-prefix.patch b/queue-5.15/soc-sifive-ccache-use-pr_fmt-to-remove-ccache-prefix.patch
new file mode 100644 (file)
index 0000000..bc519a9
--- /dev/null
@@ -0,0 +1,102 @@
+From a4eaebec7992c50b11bfa97a7976cf7e92bdc913 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 06:18:15 +0000
+Subject: soc: sifive: ccache: use pr_fmt() to remove CCACHE: prefixes
+
+From: Ben Dooks <ben.dooks@sifive.com>
+
+[ Upstream commit 696ab9bda22a770d079dc3a23bac9aaa553d98f4 ]
+
+Use the pr_fmt() macro to prefix all the output with "CCACHE:"
+to avoid having to write it out each time, or make a large diff
+when the next change comes along.
+
+Signed-off-by: Ben Dooks <ben.dooks@sifive.com>
+Signed-off-by: Zong Li <zong.li@sifive.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20220913061817.22564-6-zong.li@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: 73e770f08502 ("soc: sifive: ccache: fix missing iounmap() in error path in sifive_ccache_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sifive/sifive_ccache.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
+index 17080af7dfa00..91f0c2b32ea2b 100644
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -5,6 +5,9 @@
+  * Copyright (C) 2018-2022 SiFive, Inc.
+  *
+  */
++
++#define pr_fmt(fmt) "CCACHE: " fmt
++
+ #include <linux/debugfs.h>
+ #include <linux/interrupt.h>
+ #include <linux/of_irq.h>
+@@ -85,13 +88,13 @@ static void ccache_config_read(void)
+       cfg = readl(ccache_base + SIFIVE_CCACHE_CONFIG);
+-      pr_info("CCACHE: %u banks, %u ways, sets/bank=%llu, bytes/block=%llu\n",
++      pr_info("%u banks, %u ways, sets/bank=%llu, bytes/block=%llu\n",
+               (cfg & 0xff), (cfg >> 8) & 0xff,
+               BIT_ULL((cfg >> 16) & 0xff),
+               BIT_ULL((cfg >> 24) & 0xff));
+       cfg = readl(ccache_base + SIFIVE_CCACHE_WAYENABLE);
+-      pr_info("CCACHE: Index of the largest way enabled: %u\n", cfg);
++      pr_info("Index of the largest way enabled: %u\n", cfg);
+ }
+ static const struct of_device_id sifive_ccache_ids[] = {
+@@ -155,7 +158,7 @@ static irqreturn_t ccache_int_handler(int irq, void *device)
+       if (irq == g_irq[DIR_CORR]) {
+               add_h = readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_HIGH);
+               add_l = readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_LOW);
+-              pr_err("CCACHE: DirError @ 0x%08X.%08X\n", add_h, add_l);
++              pr_err("DirError @ 0x%08X.%08X\n", add_h, add_l);
+               /* Reading this register clears the DirError interrupt sig */
+               readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_COUNT);
+               atomic_notifier_call_chain(&ccache_err_chain,
+@@ -175,7 +178,7 @@ static irqreturn_t ccache_int_handler(int irq, void *device)
+       if (irq == g_irq[DATA_CORR]) {
+               add_h = readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_HIGH);
+               add_l = readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_LOW);
+-              pr_err("CCACHE: DataError @ 0x%08X.%08X\n", add_h, add_l);
++              pr_err("DataError @ 0x%08X.%08X\n", add_h, add_l);
+               /* Reading this register clears the DataError interrupt sig */
+               readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_COUNT);
+               atomic_notifier_call_chain(&ccache_err_chain,
+@@ -185,7 +188,7 @@ static irqreturn_t ccache_int_handler(int irq, void *device)
+       if (irq == g_irq[DATA_UNCORR]) {
+               add_h = readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_HIGH);
+               add_l = readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_LOW);
+-              pr_err("CCACHE: DataFail @ 0x%08X.%08X\n", add_h, add_l);
++              pr_err("DataFail @ 0x%08X.%08X\n", add_h, add_l);
+               /* Reading this register clears the DataFail interrupt sig */
+               readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_COUNT);
+               atomic_notifier_call_chain(&ccache_err_chain,
+@@ -218,7 +221,7 @@ static int __init sifive_ccache_init(void)
+       intr_num = of_property_count_u32_elems(np, "interrupts");
+       if (!intr_num) {
+-              pr_err("CCACHE: no interrupts property\n");
++              pr_err("No interrupts property\n");
+               return -ENODEV;
+       }
+@@ -227,7 +230,7 @@ static int __init sifive_ccache_init(void)
+               rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
+                                NULL);
+               if (rc) {
+-                      pr_err("CCACHE: Could not request IRQ %d\n", g_irq[i]);
++                      pr_err("Could not request IRQ %d\n", g_irq[i]);
+                       return rc;
+               }
+       }
+-- 
+2.39.2
+