]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Wed, 9 Aug 2023 01:44:05 +0000 (21:44 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 9 Aug 2023 01:44:05 +0000 (21:44 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
18 files changed:
queue-5.10/arm-dts-imx-add-usb-alias.patch [new file with mode: 0644]
queue-5.10/arm-dts-imx6sll-fixup-of-operating-points.patch [new file with mode: 0644]
queue-5.10/arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch [new file with mode: 0644]
queue-5.10/exfat-check-if-filename-entries-exceeds-max-filename.patch [new file with mode: 0644]
queue-5.10/exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch [new file with mode: 0644]
queue-5.10/exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch [new file with mode: 0644]
queue-5.10/exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch [new file with mode: 0644]
queue-5.10/mt76-move-band-capabilities-in-mt76_phy.patch [new file with mode: 0644]
queue-5.10/mt76-mt7615-fix-fall-through-warnings-for-clang.patch [new file with mode: 0644]
queue-5.10/pm-sleep-wakeirq-fix-wake-irq-arming.patch [new file with mode: 0644]
queue-5.10/pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch [new file with mode: 0644]
queue-5.10/selftests-rseq-check-if-libc-rseq-support-is-registe.patch [new file with mode: 0644]
queue-5.10/selftests-rseq-play-nice-with-binaries-statically-li.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch [new file with mode: 0644]
queue-5.10/soundwire-bus-pm_runtime_request_resume-on-periphera.patch [new file with mode: 0644]
queue-5.10/soundwire-fix-enumeration-completion.patch [new file with mode: 0644]
queue-5.10/wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch [new file with mode: 0644]

diff --git a/queue-5.10/arm-dts-imx-add-usb-alias.patch b/queue-5.10/arm-dts-imx-add-usb-alias.patch
new file mode 100644 (file)
index 0000000..69b40ab
--- /dev/null
@@ -0,0 +1,127 @@
+From 9323bb3d03760f9c66c052430966b23aec4442dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Nov 2020 19:29:53 +0800
+Subject: ARM: dts: imx: add usb alias
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 5c8b3b8a182cbc1ccdfcdeea9b25dd2c12a8148f ]
+
+Add usb alias for bootloader searching the controller in correct order.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: ee70b908f77a ("ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6qdl.dtsi | 4 ++++
+ arch/arm/boot/dts/imx6sl.dtsi  | 3 +++
+ arch/arm/boot/dts/imx6sll.dtsi | 2 ++
+ arch/arm/boot/dts/imx6sx.dtsi  | 3 +++
+ arch/arm/boot/dts/imx6ul.dtsi  | 2 ++
+ arch/arm/boot/dts/imx7d.dtsi   | 6 ++++++
+ arch/arm/boot/dts/imx7s.dtsi   | 2 ++
+ 7 files changed, 22 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
+index 7858ae5d39df7..7d81992dfafc6 100644
+--- a/arch/arm/boot/dts/imx6qdl.dtsi
++++ b/arch/arm/boot/dts/imx6qdl.dtsi
+@@ -45,6 +45,10 @@ aliases {
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
++              usb0 = &usbotg;
++              usb1 = &usbh1;
++              usb2 = &usbh2;
++              usb3 = &usbh3;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
+       };
+diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
+index c184a6d5bc420..5b4dfc62030e8 100644
+--- a/arch/arm/boot/dts/imx6sl.dtsi
++++ b/arch/arm/boot/dts/imx6sl.dtsi
+@@ -39,6 +39,9 @@ aliases {
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
++              usb0 = &usbotg1;
++              usb1 = &usbotg2;
++              usb2 = &usbh;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
+       };
+diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
+index bf5b262b91f91..eecb2f68a1c32 100644
+--- a/arch/arm/boot/dts/imx6sll.dtsi
++++ b/arch/arm/boot/dts/imx6sll.dtsi
+@@ -36,6 +36,8 @@ aliases {
+               spi1 = &ecspi2;
+               spi3 = &ecspi3;
+               spi4 = &ecspi4;
++              usb0 = &usbotg1;
++              usb1 = &usbotg2;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
+       };
+diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
+index c399919943c34..629c6a7432d9b 100644
+--- a/arch/arm/boot/dts/imx6sx.dtsi
++++ b/arch/arm/boot/dts/imx6sx.dtsi
+@@ -49,6 +49,9 @@ aliases {
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
+               spi4 = &ecspi5;
++              usb0 = &usbotg1;
++              usb1 = &usbotg2;
++              usb2 = &usbh;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
+       };
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index c40684ad11b8e..b40dd0c198028 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -47,6 +47,8 @@ aliases {
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
++              usb0 = &usbotg1;
++              usb1 = &usbotg2;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
+       };
+diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
+index cff875b80b60e..b0bcfa9094a30 100644
+--- a/arch/arm/boot/dts/imx7d.dtsi
++++ b/arch/arm/boot/dts/imx7d.dtsi
+@@ -7,6 +7,12 @@
+ #include <dt-bindings/reset/imx7-reset.h>
+ / {
++      aliases {
++              usb0 = &usbotg1;
++              usb1 = &usbotg2;
++              usb2 = &usbh;
++      };
++
+       cpus {
+               cpu0: cpu@0 {
+                       clock-frequency = <996000000>;
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 43b39ad9ddcee..334e781663cc2 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -47,6 +47,8 @@ aliases {
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
++              usb0 = &usbotg1;
++              usb1 = &usbh;
+       };
+       cpus {
+-- 
+2.40.1
+
diff --git a/queue-5.10/arm-dts-imx6sll-fixup-of-operating-points.patch b/queue-5.10/arm-dts-imx6sll-fixup-of-operating-points.patch
new file mode 100644 (file)
index 0000000..223141a
--- /dev/null
@@ -0,0 +1,59 @@
+From a7f2ed0b27730bad07085a112189e37e56a3cd8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Sep 2021 11:14:37 +0200
+Subject: ARM: dts: imx6sll: fixup of operating points
+
+From: Andreas Kemnade <andreas@kemnade.info>
+
+[ Upstream commit 1875903019ea6e32e6e544c1631b119e4fd60b20 ]
+
+Make operating point definitions comply with binding
+specifications.
+
+Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: ee70b908f77a ("ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6sll.dtsi | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
+index eecb2f68a1c32..2873369a57c02 100644
+--- a/arch/arm/boot/dts/imx6sll.dtsi
++++ b/arch/arm/boot/dts/imx6sll.dtsi
+@@ -51,20 +51,18 @@ cpu0: cpu@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+-                      operating-points = <
++                      operating-points =
+                               /* kHz    uV */
+-                              996000  1275000
+-                              792000  1175000
+-                              396000  1075000
+-                              198000  975000
+-                      >;
+-                      fsl,soc-operating-points = <
++                              <996000  1275000>,
++                              <792000  1175000>,
++                              <396000  1075000>,
++                              <198000   975000>;
++                      fsl,soc-operating-points =
+                               /* ARM kHz      SOC-PU uV */
+-                              996000          1175000
+-                              792000          1175000
+-                              396000          1175000
+-                              198000          1175000
+-                      >;
++                              <996000         1175000>,
++                              <792000         1175000>,
++                              <396000         1175000>,
++                              <198000         1175000>;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
+                       clocks = <&clks IMX6SLL_CLK_ARM>,
+-- 
+2.40.1
+
diff --git a/queue-5.10/arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch b/queue-5.10/arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch
new file mode 100644 (file)
index 0000000..5d0ca3a
--- /dev/null
@@ -0,0 +1,36 @@
+From 005a79aa9afc6ad9731333a74c217d7f4b27f379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 10:28:33 +0800
+Subject: ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit ee70b908f77a9d8f689dea986f09e6d7dc481934 ]
+
+Property name "phy-3p0-supply" is used instead of "phy-reg_3p0-supply".
+
+Fixes: 9f30b6b1a957 ("ARM: dts: imx: Add basic dtsi file for imx6sll")
+cc: <stable@vger.kernel.org>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6sll.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
+index 2873369a57c02..3659fd5ecfa62 100644
+--- a/arch/arm/boot/dts/imx6sll.dtsi
++++ b/arch/arm/boot/dts/imx6sll.dtsi
+@@ -552,7 +552,7 @@ usbphy2: usb-phy@20ca000 {
+                               reg = <0x020ca000 0x1000>;
+                               interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USBPHY2>;
+-                              phy-reg_3p0-supply = <&reg_3p0>;
++                              phy-3p0-supply = <&reg_3p0>;
+                               fsl,anatop = <&anatop>;
+                       };
+-- 
+2.40.1
+
diff --git a/queue-5.10/exfat-check-if-filename-entries-exceeds-max-filename.patch b/queue-5.10/exfat-check-if-filename-entries-exceeds-max-filename.patch
new file mode 100644 (file)
index 0000000..4935920
--- /dev/null
@@ -0,0 +1,65 @@
+From fbfa24459c36e49bc4fd8d9db9c2efeea9f5abae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 21:59:37 +0900
+Subject: exfat: check if filename entries exceeds max filename length
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit d42334578eba1390859012ebb91e1e556d51db49 ]
+
+exfat_extract_uni_name copies characters from a given file name entry into
+the 'uniname' variable. This variable is actually defined on the stack of
+the exfat_readdir() function. According to the definition of
+the 'exfat_uni_name' type, the file name should be limited 255 characters
+(+ null teminator space), but the exfat_get_uniname_from_ext_entry()
+function can write more characters because there is no check if filename
+entries exceeds max filename length. This patch add the check not to copy
+filename characters when exceeding max filename length.
+
+Cc: stable@vger.kernel.org
+Cc: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Reported-by: Maxim Suhanov <dfirblog@gmail.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exfat/dir.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
+index d2be36ddc18a5..4e9b85d35d938 100644
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -33,6 +33,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
+ {
+       int i;
+       struct exfat_entry_set_cache es;
++      unsigned int uni_len = 0, len;
+       if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES))
+               return;
+@@ -50,7 +51,10 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
+               if (exfat_get_entry_type(ep) != TYPE_EXTEND)
+                       break;
+-              exfat_extract_uni_name(ep, uniname);
++              len = exfat_extract_uni_name(ep, uniname);
++              uni_len += len;
++              if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH)
++                      break;
+               uniname += EXFAT_FILE_NAME_LEN;
+       }
+@@ -1037,7 +1041,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
+                       if (entry_type == TYPE_EXTEND) {
+                               unsigned short entry_uniname[16], unichar;
+-                              if (step != DIRENT_STEP_NAME) {
++                              if (step != DIRENT_STEP_NAME ||
++                                  name_len >= MAX_NAME_LENGTH) {
+                                       step = DIRENT_STEP_FILE;
+                                       continue;
+                               }
+-- 
+2.40.1
+
diff --git a/queue-5.10/exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch b/queue-5.10/exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch
new file mode 100644 (file)
index 0000000..79bf596
--- /dev/null
@@ -0,0 +1,239 @@
+From 6c290ca5ee81f3322bcc3c5a7879a0e100405040 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 11:37:13 +0800
+Subject: exfat: move exfat_entry_set_cache from heap to stack
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+[ Upstream commit 20914ff6dd56dd6b548bf5dd90bff09ef89999e4 ]
+
+The size of struct exfat_entry_set_cache is only 56 bytes on
+64-bit system, and allocating from stack is more efficient than
+allocating from heap.
+
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Reviewed-by: Andy Wu <Andy.Wu@sony.com>
+Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exfat/dir.c      | 35 +++++++++++++++--------------------
+ fs/exfat/exfat_fs.h |  5 +++--
+ fs/exfat/inode.c    | 13 ++++++-------
+ fs/exfat/namei.c    | 11 +++++------
+ 4 files changed, 29 insertions(+), 35 deletions(-)
+
+diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
+index 185aa13945d3d..d2be36ddc18a5 100644
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -32,10 +32,9 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
+               struct exfat_chain *p_dir, int entry, unsigned short *uniname)
+ {
+       int i;
+-      struct exfat_entry_set_cache *es;
++      struct exfat_entry_set_cache es;
+-      es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES);
+-      if (!es)
++      if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES))
+               return;
+       /*
+@@ -44,8 +43,8 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
+        * Third entry  : first file-name entry
+        * So, the index of first file-name dentry should start from 2.
+        */
+-      for (i = 2; i < es->num_entries; i++) {
+-              struct exfat_dentry *ep = exfat_get_dentry_cached(es, i);
++      for (i = 2; i < es.num_entries; i++) {
++              struct exfat_dentry *ep = exfat_get_dentry_cached(&es, i);
+               /* end of name entry */
+               if (exfat_get_entry_type(ep) != TYPE_EXTEND)
+@@ -55,7 +54,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
+               uniname += EXFAT_FILE_NAME_LEN;
+       }
+-      exfat_free_dentry_set(es, false);
++      exfat_free_dentry_set(&es, false);
+ }
+ /* read a directory entry from the opened directory */
+@@ -613,7 +612,6 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
+       if (IS_DYNAMIC_ES(es))
+               kfree(es->bh);
+-      kfree(es);
+       return err;
+ }
+@@ -813,14 +811,14 @@ struct exfat_dentry *exfat_get_dentry_cached(
+  *   pointer of entry set on success,
+  *   NULL on failure.
+  */
+-struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+-              struct exfat_chain *p_dir, int entry, unsigned int type)
++int exfat_get_dentry_set(struct exfat_entry_set_cache *es,
++              struct super_block *sb, struct exfat_chain *p_dir, int entry,
++              unsigned int type)
+ {
+       int ret, i, num_bh;
+       unsigned int off, byte_offset, clu = 0;
+       sector_t sec;
+       struct exfat_sb_info *sbi = EXFAT_SB(sb);
+-      struct exfat_entry_set_cache *es;
+       struct exfat_dentry *ep;
+       int num_entries;
+       enum exfat_validate_dentry_mode mode = ES_MODE_STARTED;
+@@ -828,17 +826,15 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+       if (p_dir->dir == DIR_DELETED) {
+               exfat_err(sb, "access to deleted dentry");
+-              return NULL;
++              return -EIO;
+       }
+       byte_offset = EXFAT_DEN_TO_B(entry);
+       ret = exfat_walk_fat_chain(sb, p_dir, byte_offset, &clu);
+       if (ret)
+-              return NULL;
++              return ret;
+-      es = kzalloc(sizeof(*es), GFP_KERNEL);
+-      if (!es)
+-              return NULL;
++      memset(es, 0, sizeof(*es));
+       es->sb = sb;
+       es->modified = false;
+@@ -856,7 +852,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+       bh = sb_bread(sb, sec);
+       if (!bh)
+-              goto free_es;
++              return -EIO;
+       es->bh[es->num_bh++] = bh;
+       ep = exfat_get_dentry_cached(es, 0);
+@@ -872,8 +868,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+               es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL);
+               if (!es->bh) {
+                       brelse(bh);
+-                      kfree(es);
+-                      return NULL;
++                      return -ENOMEM;
+               }
+               es->bh[0] = bh;
+       }
+@@ -902,11 +897,11 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+               if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode))
+                       goto free_es;
+       }
+-      return es;
++      return 0;
+ free_es:
+       exfat_free_dentry_set(es, false);
+-      return NULL;
++      return -EIO;
+ }
+ enum {
+diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
+index 11e579a2598d8..6ecc7a51b4d18 100644
+--- a/fs/exfat/exfat_fs.h
++++ b/fs/exfat/exfat_fs.h
+@@ -470,8 +470,9 @@ struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
+               sector_t *sector);
+ struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es,
+               int num);
+-struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+-              struct exfat_chain *p_dir, int entry, unsigned int type);
++int exfat_get_dentry_set(struct exfat_entry_set_cache *es,
++              struct super_block *sb, struct exfat_chain *p_dir, int entry,
++              unsigned int type);
+ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync);
+ int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir);
+diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c
+index 4bd73820a4ac0..7f70284da530f 100644
+--- a/fs/exfat/inode.c
++++ b/fs/exfat/inode.c
+@@ -21,7 +21,7 @@ static int __exfat_write_inode(struct inode *inode, int sync)
+ {
+       unsigned long long on_disk_size;
+       struct exfat_dentry *ep, *ep2;
+-      struct exfat_entry_set_cache *es = NULL;
++      struct exfat_entry_set_cache es;
+       struct super_block *sb = inode->i_sb;
+       struct exfat_sb_info *sbi = EXFAT_SB(sb);
+       struct exfat_inode_info *ei = EXFAT_I(inode);
+@@ -42,11 +42,10 @@ static int __exfat_write_inode(struct inode *inode, int sync)
+       exfat_set_volume_dirty(sb);
+       /* get the directory entry of given file or directory */
+-      es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES);
+-      if (!es)
++      if (exfat_get_dentry_set(&es, sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES))
+               return -EIO;
+-      ep = exfat_get_dentry_cached(es, 0);
+-      ep2 = exfat_get_dentry_cached(es, 1);
++      ep = exfat_get_dentry_cached(&es, 0);
++      ep2 = exfat_get_dentry_cached(&es, 1);
+       ep->dentry.file.attr = cpu_to_le16(exfat_make_attr(inode));
+@@ -76,8 +75,8 @@ static int __exfat_write_inode(struct inode *inode, int sync)
+       ep2->dentry.stream.valid_size = cpu_to_le64(on_disk_size);
+       ep2->dentry.stream.size = ep2->dentry.stream.valid_size;
+-      exfat_update_dir_chksum_with_entry_set(es);
+-      return exfat_free_dentry_set(es, sync);
++      exfat_update_dir_chksum_with_entry_set(&es);
++      return exfat_free_dentry_set(&es, sync);
+ }
+ int exfat_write_inode(struct inode *inode, struct writeback_control *wbc)
+diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
+index bd00afc5e4c16..10062b5282bd0 100644
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -595,7 +595,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
+       struct exfat_sb_info *sbi = EXFAT_SB(sb);
+       struct exfat_inode_info *ei = EXFAT_I(dir);
+       struct exfat_dentry *ep, *ep2;
+-      struct exfat_entry_set_cache *es;
++      struct exfat_entry_set_cache es;
+       /* for optimized dir & entry to prevent long traverse of cluster chain */
+       struct exfat_hint hint_opt;
+@@ -635,11 +635,10 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
+       if (cdir.flags & ALLOC_NO_FAT_CHAIN)
+               cdir.size -= dentry / sbi->dentries_per_clu;
+       dentry = hint_opt.eidx;
+-      es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES);
+-      if (!es)
++      if (exfat_get_dentry_set(&es, sb, &cdir, dentry, ES_2_ENTRIES))
+               return -EIO;
+-      ep = exfat_get_dentry_cached(es, 0);
+-      ep2 = exfat_get_dentry_cached(es, 1);
++      ep = exfat_get_dentry_cached(&es, 0);
++      ep2 = exfat_get_dentry_cached(&es, 1);
+       info->type = exfat_get_entry_type(ep);
+       info->attr = le16_to_cpu(ep->dentry.file.attr);
+@@ -668,7 +667,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
+                            ep->dentry.file.access_time,
+                            ep->dentry.file.access_date,
+                            0);
+-      exfat_free_dentry_set(es, false);
++      exfat_free_dentry_set(&es, false);
+       if (ei->start_clu == EXFAT_FREE_CLUSTER) {
+               exfat_fs_error(sb,
+-- 
+2.40.1
+
diff --git a/queue-5.10/exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch b/queue-5.10/exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch
new file mode 100644 (file)
index 0000000..eb12825
--- /dev/null
@@ -0,0 +1,131 @@
+From 13ced2ee70174024313b574b2bbc769be56b2baf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 12:53:36 +0900
+Subject: exfat: speed up iterate/lookup by fixing start point of traversing
+ cluster chain
+
+From: Hyeongseok Kim <hyeongseok@gmail.com>
+
+[ Upstream commit c6e2f52e3051e8d898d38840104638ca8bbcdec2 ]
+
+When directory iterate and lookup is called, there's a buggy rewinding
+of start point for traversing cluster chain to the parent directory
+entry's first cluster. This caused repeated cluster chain traversing
+from the first entry of the parent directory that would show worse
+performance if huge amounts of files exist under the parent directory.
+Fix not to rewind, make continue from currently referenced cluster and
+dir entry.
+
+Tested with 50,000 files under single directory / 256GB sdcard,
+with command "time ls -l > /dev/null",
+Before :     0m08.69s real     0m00.27s user     0m05.91s system
+After  :     0m07.01s real     0m00.25s user     0m04.34s system
+
+Signed-off-by: Hyeongseok Kim <hyeongseok@gmail.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exfat/dir.c      | 19 +++++++++++++------
+ fs/exfat/exfat_fs.h |  2 +-
+ fs/exfat/namei.c    |  9 ++++++++-
+ 3 files changed, 22 insertions(+), 8 deletions(-)
+
+diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
+index 093f79ae3c671..0e1886f9a6241 100644
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -148,7 +148,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
+                                       0);
+                       *uni_name.name = 0x0;
+-                      exfat_get_uniname_from_ext_entry(sb, &dir, dentry,
++                      exfat_get_uniname_from_ext_entry(sb, &clu, i,
+                               uni_name.name);
+                       exfat_utf16_to_nls(sb, &uni_name,
+                               dir_entry->namebuf.lfn,
+@@ -902,14 +902,19 @@ enum {
+ };
+ /*
+- * return values:
+- *   >= 0     : return dir entiry position with the name in dir
+- *   -ENOENT  : entry with the name does not exist
+- *   -EIO     : I/O error
++ * @ei:         inode info of parent directory
++ * @p_dir:      directory structure of parent directory
++ * @num_entries:entry size of p_uniname
++ * @hint_opt:   If p_uniname is found, filled with optimized dir/entry
++ *              for traversing cluster chain.
++ * @return:
++ *   >= 0:      file directory entry position where the name exists
++ *   -ENOENT:   entry with the name does not exist
++ *   -EIO:      I/O error
+  */
+ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
+               struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
+-              int num_entries, unsigned int type)
++              int num_entries, unsigned int type, struct exfat_hint *hint_opt)
+ {
+       int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
+       int order, step, name_len = 0;
+@@ -986,6 +991,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
+                       if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) {
+                               step = DIRENT_STEP_FILE;
++                              hint_opt->clu = clu.dir;
++                              hint_opt->eidx = i;
+                               if (type == TYPE_ALL || type == entry_type) {
+                                       num_ext = ep->dentry.file.num_ext;
+                                       step = DIRENT_STEP_STRM;
+diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
+index 07b09af57436f..436683da2515c 100644
+--- a/fs/exfat/exfat_fs.h
++++ b/fs/exfat/exfat_fs.h
+@@ -458,7 +458,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es);
+ int exfat_calc_num_entries(struct exfat_uni_name *p_uniname);
+ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
+               struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
+-              int num_entries, unsigned int type);
++              int num_entries, unsigned int type, struct exfat_hint *hint_opt);
+ int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu);
+ int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
+               int entry, sector_t *sector, int *offset);
+diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
+index 1382d816912c8..bd00afc5e4c16 100644
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -596,6 +596,8 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
+       struct exfat_inode_info *ei = EXFAT_I(dir);
+       struct exfat_dentry *ep, *ep2;
+       struct exfat_entry_set_cache *es;
++      /* for optimized dir & entry to prevent long traverse of cluster chain */
++      struct exfat_hint hint_opt;
+       if (qname->len == 0)
+               return -ENOENT;
+@@ -619,7 +621,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
+       /* search the file name for directories */
+       dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name,
+-                      num_entries, TYPE_ALL);
++                      num_entries, TYPE_ALL, &hint_opt);
+       if (dentry < 0)
+               return dentry; /* -error value */
+@@ -628,6 +630,11 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
+       info->entry = dentry;
+       info->num_subdirs = 0;
++      /* adjust cdir to the optimized value */
++      cdir.dir = hint_opt.clu;
++      if (cdir.flags & ALLOC_NO_FAT_CHAIN)
++              cdir.size -= dentry / sbi->dentries_per_clu;
++      dentry = hint_opt.eidx;
+       es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES);
+       if (!es)
+               return -EIO;
+-- 
+2.40.1
+
diff --git a/queue-5.10/exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch b/queue-5.10/exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch
new file mode 100644 (file)
index 0000000..745cb40
--- /dev/null
@@ -0,0 +1,91 @@
+From 1471114981b32b5b4deb18990e261e67e5ef6ddf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 13:50:22 +0800
+Subject: exfat: support dynamic allocate bh for exfat_entry_set_cache
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+[ Upstream commit a3ff29a95fde16906304455aa8c0bd84eb770258 ]
+
+In special cases, a file or a directory may occupied more than 19
+directory entries, pre-allocating 3 bh is not enough. Such as
+  - Support vendor secondary directory entry in the future.
+  - Since file directory entry is damaged, the SecondaryCount
+    field is bigger than 18.
+
+So this commit supports dynamic allocation of bh.
+
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Reviewed-by: Andy Wu <Andy.Wu@sony.com>
+Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exfat/dir.c      | 15 +++++++++++++++
+ fs/exfat/exfat_fs.h |  5 ++++-
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
+index 0e1886f9a6241..185aa13945d3d 100644
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -609,6 +609,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
+                       bforget(es->bh[i]);
+               else
+                       brelse(es->bh[i]);
++
++      if (IS_DYNAMIC_ES(es))
++              kfree(es->bh);
++
+       kfree(es);
+       return err;
+ }
+@@ -844,6 +848,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+       /* byte offset in sector */
+       off = EXFAT_BLK_OFFSET(byte_offset, sb);
+       es->start_off = off;
++      es->bh = es->__bh;
+       /* sector offset in cluster */
+       sec = EXFAT_B_TO_BLK(byte_offset, sb);
+@@ -863,6 +868,16 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
+       es->num_entries = num_entries;
+       num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb);
++      if (num_bh > ARRAY_SIZE(es->__bh)) {
++              es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL);
++              if (!es->bh) {
++                      brelse(bh);
++                      kfree(es);
++                      return NULL;
++              }
++              es->bh[0] = bh;
++      }
++
+       for (i = 1; i < num_bh; i++) {
+               /* get the next sector */
+               if (exfat_is_last_sector_in_cluster(sbi, sec)) {
+diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
+index 436683da2515c..11e579a2598d8 100644
+--- a/fs/exfat/exfat_fs.h
++++ b/fs/exfat/exfat_fs.h
+@@ -170,10 +170,13 @@ struct exfat_entry_set_cache {
+       bool modified;
+       unsigned int start_off;
+       int num_bh;
+-      struct buffer_head *bh[DIR_CACHE_SIZE];
++      struct buffer_head *__bh[DIR_CACHE_SIZE];
++      struct buffer_head **bh;
+       unsigned int num_entries;
+ };
++#define IS_DYNAMIC_ES(es)     ((es)->__bh != (es)->bh)
++
+ struct exfat_dir_entry {
+       struct exfat_chain dir;
+       int entry;
+-- 
+2.40.1
+
diff --git a/queue-5.10/mt76-move-band-capabilities-in-mt76_phy.patch b/queue-5.10/mt76-move-band-capabilities-in-mt76_phy.patch
new file mode 100644 (file)
index 0000000..d1404ee
--- /dev/null
@@ -0,0 +1,295 @@
+From 961b846f4b586328bcb83c59be949312f4dbacca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Nov 2020 10:56:56 +0100
+Subject: mt76: move band capabilities in mt76_phy
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 48dbce5cb1ba3ce5b2ed3e997bcb1e4697d41b71 ]
+
+This is a preliminary patch to move properly support mt7915 dbdc
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Stable-dep-of: 421033deb915 ("wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mac80211.c    |  8 ++++----
+ drivers/net/wireless/mediatek/mt76/mt76.h        |  2 +-
+ .../net/wireless/mediatek/mt76/mt7603/eeprom.c   |  2 +-
+ drivers/net/wireless/mediatek/mt76/mt7615/dma.c  |  2 +-
+ .../net/wireless/mediatek/mt76/mt7615/eeprom.c   | 16 ++++++++--------
+ .../net/wireless/mediatek/mt76/mt76x0/eeprom.c   |  6 +++---
+ drivers/net/wireless/mediatek/mt76/mt76x0/init.c |  4 ++--
+ drivers/net/wireless/mediatek/mt76/mt76x0/phy.c  |  4 ++--
+ .../net/wireless/mediatek/mt76/mt76x02_eeprom.c  |  8 ++++----
+ .../net/wireless/mediatek/mt76/mt7915/eeprom.c   |  8 ++++----
+ drivers/net/wireless/mediatek/mt76/mt7915/init.c |  5 ++---
+ 11 files changed, 32 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
+index 81ff3b4c6c1b3..dc1191aa0443e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -160,9 +160,9 @@ static void mt76_init_stream_cap(struct mt76_phy *phy,
+ void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
+ {
+-      if (phy->dev->cap.has_2ghz)
++      if (phy->cap.has_2ghz)
+               mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
+-      if (phy->dev->cap.has_5ghz)
++      if (phy->cap.has_5ghz)
+               mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
+ }
+ EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
+@@ -463,13 +463,13 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
+       dev_set_drvdata(dev->dev, dev);
+       mt76_phy_init(dev, hw);
+-      if (dev->cap.has_2ghz) {
++      if (phy->cap.has_2ghz) {
+               ret = mt76_init_sband_2g(dev, rates, n_rates);
+               if (ret)
+                       return ret;
+       }
+-      if (dev->cap.has_5ghz) {
++      if (phy->cap.has_5ghz) {
+               ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
+               if (ret)
+                       return ret;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 5a8060790a61f..16e65020a242d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -561,6 +561,7 @@ struct mt76_phy {
+       struct mt76_channel_state *chan_state;
+       ktime_t survey_time;
++      struct mt76_hw_cap cap;
+       struct mt76_sband sband_2g;
+       struct mt76_sband sband_5g;
+@@ -630,7 +631,6 @@ struct mt76_dev {
+       struct debugfs_blob_wrapper eeprom;
+       struct debugfs_blob_wrapper otp;
+-      struct mt76_hw_cap cap;
+       struct mt76_rate_power rate_power;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
+index 01f1e0da5ee1e..a6df733aca492 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
+@@ -170,7 +170,7 @@ int mt7603_eeprom_init(struct mt7603_dev *dev)
+       }
+       eeprom = (u8 *)dev->mt76.eeprom.data;
+-      dev->mt76.cap.has_2ghz = true;
++      dev->mphy.cap.has_2ghz = true;
+       memcpy(dev->mt76.macaddr, eeprom + MT_EE_MAC_ADDR, ETH_ALEN);
+       /* Check for 1SS devices */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+index bf8ae14121dba..637ef0882436c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+@@ -202,7 +202,7 @@ int mt7615_dma_init(struct mt7615_dev *dev)
+       int ret;
+       /* Increase buffer size to receive large VHT MPDUs */
+-      if (dev->mt76.cap.has_5ghz)
++      if (dev->mphy.cap.has_5ghz)
+               rx_buf_size *= 2;
+       mt76_dma_attach(&dev->mt76);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+index e9cdcdc54d5c3..714d1ff69c560 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+@@ -100,20 +100,20 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
+       if (is_mt7663(&dev->mt76)) {
+               /* dual band */
+-              dev->mt76.cap.has_2ghz = true;
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_2ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               return;
+       }
+       if (is_mt7622(&dev->mt76)) {
+               /* 2GHz only */
+-              dev->mt76.cap.has_2ghz = true;
++              dev->mphy.cap.has_2ghz = true;
+               return;
+       }
+       if (is_mt7611(&dev->mt76)) {
+               /* 5GHz only */
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               return;
+       }
+@@ -121,17 +121,17 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
+                       eeprom[MT_EE_WIFI_CONF]);
+       switch (val) {
+       case MT_EE_5GHZ:
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               break;
+       case MT_EE_2GHZ:
+-              dev->mt76.cap.has_2ghz = true;
++              dev->mphy.cap.has_2ghz = true;
+               break;
+       case MT_EE_DBDC:
+               dev->dbdc_support = true;
+               /* fall through */
+       default:
+-              dev->mt76.cap.has_2ghz = true;
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_2ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               break;
+       }
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
+index 9087607b621e8..ebf4c96532d31 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
+@@ -52,15 +52,15 @@ static void mt76x0_set_chip_cap(struct mt76x02_dev *dev)
+       mt76x02_eeprom_parse_hw_cap(dev);
+       dev_dbg(dev->mt76.dev, "2GHz %d 5GHz %d\n",
+-              dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz);
++              dev->mphy.cap.has_2ghz, dev->mphy.cap.has_5ghz);
+       if (dev->no_2ghz) {
+-              dev->mt76.cap.has_2ghz = false;
++              dev->mphy.cap.has_2ghz = false;
+               dev_dbg(dev->mt76.dev, "mask out 2GHz support\n");
+       }
+       if (is_mt7630(dev)) {
+-              dev->mt76.cap.has_5ghz = false;
++              dev->mphy.cap.has_5ghz = false;
+               dev_dbg(dev->mt76.dev, "mask out 5GHz support\n");
+       }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+index d78866bf41ba3..0bac39bf3b66d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+@@ -245,7 +245,7 @@ int mt76x0_register_device(struct mt76x02_dev *dev)
+       if (ret)
+               return ret;
+-      if (dev->mt76.cap.has_5ghz) {
++      if (dev->mphy.cap.has_5ghz) {
+               struct ieee80211_supported_band *sband;
+               sband = &dev->mphy.sband_5g.sband;
+@@ -253,7 +253,7 @@ int mt76x0_register_device(struct mt76x02_dev *dev)
+               mt76x0_init_txpower(dev, sband);
+       }
+-      if (dev->mt76.cap.has_2ghz)
++      if (dev->mphy.cap.has_2ghz)
+               mt76x0_init_txpower(dev, &dev->mphy.sband_2g.sband);
+       mt76x02_init_debugfs(dev);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+index 3de33aadf7941..e91c314cdfac5 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+@@ -447,11 +447,11 @@ static void mt76x0_phy_ant_select(struct mt76x02_dev *dev)
+               else
+                       coex3 |= BIT(4);
+               coex3 |= BIT(3);
+-              if (dev->mt76.cap.has_2ghz)
++              if (dev->mphy.cap.has_2ghz)
+                       wlan |= BIT(6);
+       } else {
+               /* sigle antenna mode */
+-              if (dev->mt76.cap.has_5ghz) {
++              if (dev->mphy.cap.has_5ghz) {
+                       coex3 |= BIT(3) | BIT(4);
+               } else {
+                       wlan |= BIT(6);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
+index c54c50fd639a9..0acabba2d1a50 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
+@@ -75,14 +75,14 @@ void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev)
+       switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) {
+       case BOARD_TYPE_5GHZ:
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               break;
+       case BOARD_TYPE_2GHZ:
+-              dev->mt76.cap.has_2ghz = true;
++              dev->mphy.cap.has_2ghz = true;
+               break;
+       default:
+-              dev->mt76.cap.has_2ghz = true;
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_2ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               break;
+       }
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+index e4c5f968f706d..5f6c527611f20 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+@@ -57,14 +57,14 @@ static void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev)
+       val = FIELD_GET(MT_EE_WIFI_CONF_BAND_SEL, val);
+       switch (val) {
+       case MT_EE_5GHZ:
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               break;
+       case MT_EE_2GHZ:
+-              dev->mt76.cap.has_2ghz = true;
++              dev->mphy.cap.has_2ghz = true;
+               break;
+       default:
+-              dev->mt76.cap.has_2ghz = true;
+-              dev->mt76.cap.has_5ghz = true;
++              dev->mphy.cap.has_2ghz = true;
++              dev->mphy.cap.has_5ghz = true;
+               break;
+       }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index 8f01ca1694bca..99683688a8363 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -528,10 +528,9 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+ {
+       struct ieee80211_sband_iftype_data *data;
+       struct ieee80211_supported_band *band;
+-      struct mt76_dev *mdev = &phy->dev->mt76;
+       int n;
+-      if (mdev->cap.has_2ghz) {
++      if (phy->mt76->cap.has_2ghz) {
+               data = phy->iftype[NL80211_BAND_2GHZ];
+               n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
+@@ -540,7 +539,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+               band->n_iftype_data = n;
+       }
+-      if (mdev->cap.has_5ghz) {
++      if (phy->mt76->cap.has_5ghz) {
+               data = phy->iftype[NL80211_BAND_5GHZ];
+               n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
+-- 
+2.40.1
+
diff --git a/queue-5.10/mt76-mt7615-fix-fall-through-warnings-for-clang.patch b/queue-5.10/mt76-mt7615-fix-fall-through-warnings-for-clang.patch
new file mode 100644 (file)
index 0000000..2ef9121
--- /dev/null
@@ -0,0 +1,42 @@
+From dfd012be3e12f57e4560c60120630906b1a4e39c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Nov 2020 12:37:18 -0600
+Subject: mt76: mt7615: Fix fall-through warnings for Clang
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit f12758f6f929dbcd37abdb1d91d245539eca48f8 ]
+
+In preparation to enable -Wimplicit-fallthrough for Clang, fix a
+warning by replacing a /* fall through */ comment with the new
+pseudo-keyword macro fallthrough; instead of letting the code fall
+through to the next case.
+
+Notice that Clang doesn't recognize /* fall through */ comments as
+implicit fall-through markings.
+
+Link: https://github.com/KSPP/linux/issues/115
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Stable-dep-of: 421033deb915 ("wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+index 714d1ff69c560..48ce24f0f77b7 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+@@ -128,7 +128,7 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
+               break;
+       case MT_EE_DBDC:
+               dev->dbdc_support = true;
+-              /* fall through */
++              fallthrough;
+       default:
+               dev->mphy.cap.has_2ghz = true;
+               dev->mphy.cap.has_5ghz = true;
+-- 
+2.40.1
+
diff --git a/queue-5.10/pm-sleep-wakeirq-fix-wake-irq-arming.patch b/queue-5.10/pm-sleep-wakeirq-fix-wake-irq-arming.patch
new file mode 100644 (file)
index 0000000..2435fc9
--- /dev/null
@@ -0,0 +1,95 @@
+From 19ecf8b860166f21bf563792f7dc0e775d3648f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 16:57:39 +0200
+Subject: PM: sleep: wakeirq: fix wake irq arming
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 8527beb12087238d4387607597b4020bc393c4b4 ]
+
+The decision whether to enable a wake irq during suspend can not be done
+based on the runtime PM state directly as a driver may use wake irqs
+without implementing runtime PM. Such drivers specifically leave the
+state set to the default 'suspended' and the wake irq is thus never
+enabled at suspend.
+
+Add a new wake irq flag to track whether a dedicated wake irq has been
+enabled at runtime suspend and therefore must not be enabled at system
+suspend.
+
+Note that pm_runtime_enabled() can not be used as runtime PM is always
+disabled during late suspend.
+
+Fixes: 69728051f5bf ("PM / wakeirq: Fix unbalanced IRQ enable for wakeirq")
+Cc: 4.16+ <stable@vger.kernel.org> # 4.16+
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Tested-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/power.h   |  1 +
+ drivers/base/power/wakeirq.c | 12 ++++++++----
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
+index 0eb7f02b3ad59..922ed457db191 100644
+--- a/drivers/base/power/power.h
++++ b/drivers/base/power/power.h
+@@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct device *dev);
+ #define WAKE_IRQ_DEDICATED_MASK               (WAKE_IRQ_DEDICATED_ALLOCATED | \
+                                        WAKE_IRQ_DEDICATED_MANAGED | \
+                                        WAKE_IRQ_DEDICATED_REVERSE)
++#define WAKE_IRQ_DEDICATED_ENABLED    BIT(3)
+ struct wake_irq {
+       struct device *dev;
+diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
+index a6d53f0173d35..aea690c64e394 100644
+--- a/drivers/base/power/wakeirq.c
++++ b/drivers/base/power/wakeirq.c
+@@ -317,8 +317,10 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
+       return;
+ enable:
+-      if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
++      if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
+               enable_irq(wirq->irq);
++              wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
++      }
+ }
+ /**
+@@ -339,8 +341,10 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
+       if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
+               return;
+-      if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
++      if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
++              wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
+               disable_irq_nosync(wirq->irq);
++      }
+ }
+ /**
+@@ -379,7 +383,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq)
+       if (device_may_wakeup(wirq->dev)) {
+               if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
+-                  !pm_runtime_status_suspended(wirq->dev))
++                  !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
+                       enable_irq(wirq->irq);
+               enable_irq_wake(wirq->irq);
+@@ -402,7 +406,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
+               disable_irq_wake(wirq->irq);
+               if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
+-                  !pm_runtime_status_suspended(wirq->dev))
++                  !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
+                       disable_irq_nosync(wirq->irq);
+       }
+ }
+-- 
+2.40.1
+
diff --git a/queue-5.10/pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch b/queue-5.10/pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch
new file mode 100644 (file)
index 0000000..3abe7ab
--- /dev/null
@@ -0,0 +1,290 @@
+From 3f52d790fa0341c0dde5210361bba6b1153d215b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 15:01:53 +0800
+Subject: PM / wakeirq: support enabling wake-up irq after runtime_suspend
+ called
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+[ Upstream commit 259714100d98b50bf04d36a21bf50ca8b829fc11 ]
+
+When the dedicated wake IRQ is level trigger, and it uses the
+device's low-power status as the wakeup source, that means if the
+device is not in low-power state, the wake IRQ will be triggered
+if enabled; For this case, need enable the wake IRQ after running
+the device's ->runtime_suspend() which make it enter low-power state.
+
+e.g.
+Assume the wake IRQ is a low level trigger type, and the wakeup
+signal comes from the low-power status of the device.
+The wakeup signal is low level at running time (0), and becomes
+high level when the device enters low-power state (runtime_suspend
+(1) is called), a wakeup event at (2) make the device exit low-power
+state, then the wakeup signal also becomes low level.
+
+                ------------------
+               |           ^     ^|
+----------------           |     | --------------
+ |<---(0)--->|<--(1)--|   (3)   (2)    (4)
+
+if enable the wake IRQ before running runtime_suspend during (0),
+a wake IRQ will arise, it causes resume immediately;
+it works if enable wake IRQ ( e.g. at (3) or (4)) after running
+->runtime_suspend().
+
+This patch introduces a new status WAKE_IRQ_DEDICATED_REVERSE to
+optionally support enabling wake IRQ after running ->runtime_suspend().
+
+Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 8527beb12087 ("PM: sleep: wakeirq: fix wake irq arming")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/power.h   |   7 ++-
+ drivers/base/power/runtime.c |   6 ++-
+ drivers/base/power/wakeirq.c | 101 +++++++++++++++++++++++++++--------
+ include/linux/pm_wakeirq.h   |   9 +++-
+ 4 files changed, 96 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
+index 54292cdd7808b..0eb7f02b3ad59 100644
+--- a/drivers/base/power/power.h
++++ b/drivers/base/power/power.h
+@@ -25,8 +25,10 @@ extern u64 pm_runtime_active_time(struct device *dev);
+ #define WAKE_IRQ_DEDICATED_ALLOCATED  BIT(0)
+ #define WAKE_IRQ_DEDICATED_MANAGED    BIT(1)
++#define WAKE_IRQ_DEDICATED_REVERSE    BIT(2)
+ #define WAKE_IRQ_DEDICATED_MASK               (WAKE_IRQ_DEDICATED_ALLOCATED | \
+-                                       WAKE_IRQ_DEDICATED_MANAGED)
++                                       WAKE_IRQ_DEDICATED_MANAGED | \
++                                       WAKE_IRQ_DEDICATED_REVERSE)
+ struct wake_irq {
+       struct device *dev;
+@@ -39,7 +41,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq);
+ extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq);
+ extern void dev_pm_enable_wake_irq_check(struct device *dev,
+                                        bool can_change_status);
+-extern void dev_pm_disable_wake_irq_check(struct device *dev);
++extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable);
++extern void dev_pm_enable_wake_irq_complete(struct device *dev);
+ #ifdef CONFIG_PM_SLEEP
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 360094692d29e..fbbc3ed143f27 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -675,6 +675,8 @@ static int rpm_suspend(struct device *dev, int rpmflags)
+       if (retval)
+               goto fail;
++      dev_pm_enable_wake_irq_complete(dev);
++
+  no_callback:
+       __update_runtime_status(dev, RPM_SUSPENDED);
+       pm_runtime_deactivate_timer(dev);
+@@ -720,7 +722,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
+       return retval;
+  fail:
+-      dev_pm_disable_wake_irq_check(dev);
++      dev_pm_disable_wake_irq_check(dev, true);
+       __update_runtime_status(dev, RPM_ACTIVE);
+       dev->power.deferred_resume = false;
+       wake_up_all(&dev->power.wait_queue);
+@@ -903,7 +905,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
+       callback = RPM_GET_CALLBACK(dev, runtime_resume);
+-      dev_pm_disable_wake_irq_check(dev);
++      dev_pm_disable_wake_irq_check(dev, false);
+       retval = rpm_callback(callback, dev);
+       if (retval) {
+               __update_runtime_status(dev, RPM_SUSPENDED);
+diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
+index 8e021082dba8c..a6d53f0173d35 100644
+--- a/drivers/base/power/wakeirq.c
++++ b/drivers/base/power/wakeirq.c
+@@ -145,24 +145,7 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq)
+       return IRQ_HANDLED;
+ }
+-/**
+- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
+- * @dev: Device entry
+- * @irq: Device wake-up interrupt
+- *
+- * Unless your hardware has separate wake-up interrupts in addition
+- * to the device IO interrupts, you don't need this.
+- *
+- * Sets up a threaded interrupt handler for a device that has
+- * a dedicated wake-up interrupt in addition to the device IO
+- * interrupt.
+- *
+- * The interrupt starts disabled, and needs to be managed for
+- * the device by the bus code or the device driver using
+- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq()
+- * functions.
+- */
+-int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
++static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag)
+ {
+       struct wake_irq *wirq;
+       int err;
+@@ -200,7 +183,7 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
+       if (err)
+               goto err_free_irq;
+-      wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED;
++      wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag;
+       return err;
+@@ -213,8 +196,57 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
+       return err;
+ }
++
++
++/**
++ * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
++ * @dev: Device entry
++ * @irq: Device wake-up interrupt
++ *
++ * Unless your hardware has separate wake-up interrupts in addition
++ * to the device IO interrupts, you don't need this.
++ *
++ * Sets up a threaded interrupt handler for a device that has
++ * a dedicated wake-up interrupt in addition to the device IO
++ * interrupt.
++ *
++ * The interrupt starts disabled, and needs to be managed for
++ * the device by the bus code or the device driver using
++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
++ * functions.
++ */
++int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
++{
++      return __dev_pm_set_dedicated_wake_irq(dev, irq, 0);
++}
+ EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
++/**
++ * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt
++ *                                         with reverse enable ordering
++ * @dev: Device entry
++ * @irq: Device wake-up interrupt
++ *
++ * Unless your hardware has separate wake-up interrupts in addition
++ * to the device IO interrupts, you don't need this.
++ *
++ * Sets up a threaded interrupt handler for a device that has a dedicated
++ * wake-up interrupt in addition to the device IO interrupt. It sets
++ * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend()
++ * to enable dedicated wake-up interrupt after running the runtime suspend
++ * callback for @dev.
++ *
++ * The interrupt starts disabled, and needs to be managed for
++ * the device by the bus code or the device driver using
++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
++ * functions.
++ */
++int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
++{
++      return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE);
++}
++EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse);
++
+ /**
+  * dev_pm_enable_wake_irq - Enable device wake-up interrupt
+  * @dev: Device
+@@ -285,27 +317,54 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
+       return;
+ enable:
+-      enable_irq(wirq->irq);
++      if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
++              enable_irq(wirq->irq);
+ }
+ /**
+  * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
+  * @dev: Device
++ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE
+  *
+  * Disables wake-up interrupt conditionally based on status.
+  * Should be only called from rpm_suspend() and rpm_resume() path.
+  */
+-void dev_pm_disable_wake_irq_check(struct device *dev)
++void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
+ {
+       struct wake_irq *wirq = dev->power.wakeirq;
+       if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
+               return;
++      if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
++              return;
++
+       if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
+               disable_irq_nosync(wirq->irq);
+ }
++/**
++ * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before
++ * @dev: Device using the wake IRQ
++ *
++ * Enable wake IRQ conditionally based on status, mainly used if want to
++ * enable wake IRQ after running ->runtime_suspend() which depends on
++ * WAKE_IRQ_DEDICATED_REVERSE.
++ *
++ * Should be only called from rpm_suspend() path.
++ */
++void dev_pm_enable_wake_irq_complete(struct device *dev)
++{
++      struct wake_irq *wirq = dev->power.wakeirq;
++
++      if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
++              return;
++
++      if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
++          wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
++              enable_irq(wirq->irq);
++}
++
+ /**
+  * dev_pm_arm_wake_irq - Arm device wake-up
+  * @wirq: Device wake-up interrupt
+diff --git a/include/linux/pm_wakeirq.h b/include/linux/pm_wakeirq.h
+index cd5b62db90845..e63a63aa47a37 100644
+--- a/include/linux/pm_wakeirq.h
++++ b/include/linux/pm_wakeirq.h
+@@ -17,8 +17,8 @@
+ #ifdef CONFIG_PM
+ extern int dev_pm_set_wake_irq(struct device *dev, int irq);
+-extern int dev_pm_set_dedicated_wake_irq(struct device *dev,
+-                                       int irq);
++extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq);
++extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq);
+ extern void dev_pm_clear_wake_irq(struct device *dev);
+ extern void dev_pm_enable_wake_irq(struct device *dev);
+ extern void dev_pm_disable_wake_irq(struct device *dev);
+@@ -35,6 +35,11 @@ static inline int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
+       return 0;
+ }
++static inline int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
++{
++      return 0;
++}
++
+ static inline void dev_pm_clear_wake_irq(struct device *dev)
+ {
+ }
+-- 
+2.40.1
+
diff --git a/queue-5.10/selftests-rseq-check-if-libc-rseq-support-is-registe.patch b/queue-5.10/selftests-rseq-check-if-libc-rseq-support-is-registe.patch
new file mode 100644 (file)
index 0000000..cf90392
--- /dev/null
@@ -0,0 +1,44 @@
+From 945041e91c00299bf5298d73776ca3ce500fb85f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 11:48:30 -0400
+Subject: selftests/rseq: check if libc rseq support is registered
+
+From: Michael Jeanson <mjeanson@efficios.com>
+
+[ Upstream commit d1a997ba4c1bf65497d956aea90de42a6398f73a ]
+
+When checking for libc rseq support in the library constructor, don't
+only depend on the symbols presence, check that the registration was
+completed.
+
+This targets a scenario where the libc has rseq support but it is not
+wired for the current architecture in 'bits/rseq.h', we want to fallback
+to our internal registration mechanism.
+
+Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/r/20220614154830.1367382-4-mjeanson@efficios.com
+Stable-dep-of: 3bcbc20942db ("selftests/rseq: Play nice with binaries statically linked against glibc 2.35+")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/rseq/rseq.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c
+index 986b9458efb26..4177f9507bbee 100644
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -111,7 +111,8 @@ void rseq_init(void)
+       libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
+       libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
+       libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
+-      if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) {
++      if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p &&
++                      *libc_rseq_size_p != 0) {
+               /* rseq registration owned by glibc */
+               rseq_offset = *libc_rseq_offset_p;
+               rseq_size = *libc_rseq_size_p;
+-- 
+2.40.1
+
diff --git a/queue-5.10/selftests-rseq-play-nice-with-binaries-statically-li.patch b/queue-5.10/selftests-rseq-play-nice-with-binaries-statically-li.patch
new file mode 100644 (file)
index 0000000..115a892
--- /dev/null
@@ -0,0 +1,84 @@
+From be2e644ce622bb85699da2eab45fe0b43cf7b8d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 15:33:52 -0700
+Subject: selftests/rseq: Play nice with binaries statically linked against
+ glibc 2.35+
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 3bcbc20942db5d738221cca31a928efc09827069 ]
+
+To allow running rseq and KVM's rseq selftests as statically linked
+binaries, initialize the various "trampoline" pointers to point directly
+at the expect glibc symbols, and skip the dlysm() lookups if the rseq
+size is non-zero, i.e. the binary is statically linked *and* the libc
+registered its own rseq.
+
+Define weak versions of the symbols so as not to break linking against
+libc versions that don't support rseq in any capacity.
+
+The KVM selftests in particular are often statically linked so that they
+can be run on targets with very limited runtime environments, i.e. test
+machines.
+
+Fixes: 233e667e1ae3 ("selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35")
+Cc: Aaron Lewis <aaronlewis@google.com>
+Cc: kvm@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20230721223352.2333911-1-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/rseq/rseq.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c
+index 4177f9507bbee..b736a5169aad0 100644
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -32,9 +32,17 @@
+ #include "../kselftest.h"
+ #include "rseq.h"
+-static const ptrdiff_t *libc_rseq_offset_p;
+-static const unsigned int *libc_rseq_size_p;
+-static const unsigned int *libc_rseq_flags_p;
++/*
++ * Define weak versions to play nice with binaries that are statically linked
++ * against a libc that doesn't support registering its own rseq.
++ */
++__weak ptrdiff_t __rseq_offset;
++__weak unsigned int __rseq_size;
++__weak unsigned int __rseq_flags;
++
++static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset;
++static const unsigned int *libc_rseq_size_p = &__rseq_size;
++static const unsigned int *libc_rseq_flags_p = &__rseq_flags;
+ /* Offset from the thread pointer to the rseq area.  */
+ ptrdiff_t rseq_offset;
+@@ -108,9 +116,17 @@ int rseq_unregister_current_thread(void)
+ static __attribute__((constructor))
+ void rseq_init(void)
+ {
+-      libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
+-      libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
+-      libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
++      /*
++       * If the libc's registered rseq size isn't already valid, it may be
++       * because the binary is dynamically linked and not necessarily due to
++       * libc not having registered a restartable sequence.  Try to find the
++       * symbols if that's the case.
++       */
++      if (!*libc_rseq_size_p) {
++              libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
++              libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
++              libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
++      }
+       if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p &&
+                       *libc_rseq_size_p != 0) {
+               /* rseq registration owned by glibc */
+-- 
+2.40.1
+
index cb5b627da8875b97e0f9280b7698947284c590fc..b1a968473f165bf4dc2674ae94de3ff1133f85ce 100644 (file)
@@ -183,3 +183,20 @@ ext2-drop-fragment-support.patch
 mtd-rawnand-omap_elm-fix-incorrect-type-in-assignmen.patch
 mtd-rawnand-fsl_upm-fix-an-off-by-one-test-in-fun_ex.patch
 powerpc-mm-altmap-fix-altmap-boundary-check.patch
+selftests-rseq-check-if-libc-rseq-support-is-registe.patch
+selftests-rseq-play-nice-with-binaries-statically-li.patch
+soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch
+soundwire-bus-pm_runtime_request_resume-on-periphera.patch
+soundwire-fix-enumeration-completion.patch
+pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch
+pm-sleep-wakeirq-fix-wake-irq-arming.patch
+exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch
+exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch
+exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch
+exfat-check-if-filename-entries-exceeds-max-filename.patch
+mt76-move-band-capabilities-in-mt76_phy.patch
+mt76-mt7615-fix-fall-through-warnings-for-clang.patch
+wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch
+arm-dts-imx-add-usb-alias.patch
+arm-dts-imx6sll-fixup-of-operating-points.patch
+arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch
diff --git a/queue-5.10/soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch b/queue-5.10/soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch
new file mode 100644 (file)
index 0000000..7570233
--- /dev/null
@@ -0,0 +1,64 @@
+From 45c65ae606247cb635ae0300f98b651bce8da65b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jan 2021 16:54:02 +0800
+Subject: soundwire: bus: add better dev_dbg to track complete() calls
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit f1b690261247c9895f7a4b05d14a4026739134eb ]
+
+Add a dev_dbg() log for both enumeration and initialization completion
+to better track suspend-resume issues.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Reviewed-by: Chao Song <chao.song@intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20210126085402.4264-1-yung-chuan.liao@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: c40d6b3249b1 ("soundwire: fix enumeration completion")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 3317a02bcc170..9c7c8fa7f53e4 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -797,7 +797,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
+       if (status == SDW_SLAVE_UNATTACHED) {
+               dev_dbg(&slave->dev,
+-                      "%s: initializing completion for Slave %d\n",
++                      "%s: initializing enumeration and init completion for Slave %d\n",
+                       __func__, slave->dev_num);
+               init_completion(&slave->enumeration_complete);
+@@ -806,7 +806,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
+       } else if ((status == SDW_SLAVE_ATTACHED) &&
+                  (slave->status == SDW_SLAVE_UNATTACHED)) {
+               dev_dbg(&slave->dev,
+-                      "%s: signaling completion for Slave %d\n",
++                      "%s: signaling enumeration completion for Slave %d\n",
+                       __func__, slave->dev_num);
+               complete(&slave->enumeration_complete);
+@@ -1734,8 +1734,13 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
+               if (ret)
+                       dev_err(slave->bus->dev,
+                               "Update Slave status failed:%d\n", ret);
+-              if (attached_initializing)
++              if (attached_initializing) {
++                      dev_dbg(&slave->dev,
++                              "%s: signaling initialization completion for Slave %d\n",
++                              __func__, slave->dev_num);
++
+                       complete(&slave->initialization_complete);
++              }
+       }
+       return ret;
+-- 
+2.40.1
+
diff --git a/queue-5.10/soundwire-bus-pm_runtime_request_resume-on-periphera.patch b/queue-5.10/soundwire-bus-pm_runtime_request_resume-on-periphera.patch
new file mode 100644 (file)
index 0000000..d7c35e8
--- /dev/null
@@ -0,0 +1,68 @@
+From 5ffae591a68f43d3eb9e9d356ca00f0d5913a430 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Apr 2022 10:32:41 +0800
+Subject: soundwire: bus: pm_runtime_request_resume on peripheral attachment
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit e557bca49b812908f380c56b5b4b2f273848b676 ]
+
+In typical use cases, the peripheral becomes pm_runtime active as a
+result of the ALSA/ASoC framework starting up a DAI. The parent/child
+hierarchy guarantees that the manager device will be fully resumed
+beforehand.
+
+There is however a corner case where the manager device may become
+pm_runtime active, but without ALSA/ASoC requesting any functionality
+from the peripherals. In this case, the hardware peripheral device
+will report as ATTACHED and its initialization routine will be
+executed. If this initialization routine initiates any sort of
+deferred processing, there is a possibility that the manager could
+suspend without the peripheral suspend sequence being invoked: from
+the pm_runtime framework perspective, the peripheral is *already*
+suspended.
+
+To avoid such disconnects between hardware state and pm_runtime state,
+this patch adds an asynchronous pm_request_resume() upon successful
+attach/initialization which will result in the proper resume/suspend
+sequence to be followed on the peripheral side.
+
+BugLink: https://github.com/thesofproject/linux/issues/3459
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20220420023241.14335-4-yung-chuan.liao@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: c40d6b3249b1 ("soundwire: fix enumeration completion")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 9c7c8fa7f53e4..831d2d751d5de 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -1740,6 +1740,18 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
+                               __func__, slave->dev_num);
+                       complete(&slave->initialization_complete);
++
++                      /*
++                       * If the manager became pm_runtime active, the peripherals will be
++                       * restarted and attach, but their pm_runtime status may remain
++                       * suspended. If the 'update_slave_status' callback initiates
++                       * any sort of deferred processing, this processing would not be
++                       * cancelled on pm_runtime suspend.
++                       * To avoid such zombie states, we queue a request to resume.
++                       * This would be a no-op in case the peripheral was being resumed
++                       * by e.g. the ALSA/ASoC framework.
++                       */
++                      pm_request_resume(&slave->dev);
+               }
+       }
+-- 
+2.40.1
+
diff --git a/queue-5.10/soundwire-fix-enumeration-completion.patch b/queue-5.10/soundwire-fix-enumeration-completion.patch
new file mode 100644 (file)
index 0000000..1bc3319
--- /dev/null
@@ -0,0 +1,75 @@
+From ac0a9a3463f50897e4f926073b4aa0cc9e473401 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 14:30:11 +0200
+Subject: soundwire: fix enumeration completion
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit c40d6b3249b11d60e09d81530588f56233d9aa44 ]
+
+The soundwire subsystem uses two completion structures that allow
+drivers to wait for soundwire device to become enumerated on the bus and
+initialised by their drivers, respectively.
+
+The code implementing the signalling is currently broken as it does not
+signal all current and future waiters and also uses the wrong
+reinitialisation function, which can potentially lead to memory
+corruption if there are still waiters on the queue.
+
+Not signalling future waiters specifically breaks sound card probe
+deferrals as codec drivers can not tell that the soundwire device is
+already attached when being reprobed. Some codec runtime PM
+implementations suffer from similar problems as waiting for enumeration
+during resume can also timeout despite the device already having been
+enumerated.
+
+Fixes: fb9469e54fa7 ("soundwire: bus: fix race condition with enumeration_complete signaling")
+Fixes: a90def068127 ("soundwire: bus: fix race condition with initialization_complete signaling")
+Cc: stable@vger.kernel.org      # 5.7
+Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Cc: Rander Wang <rander.wang@linux.intel.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230705123018.30903-2-johan+linaro@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 831d2d751d5de..0e0a19030c35b 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -800,8 +800,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
+                       "%s: initializing enumeration and init completion for Slave %d\n",
+                       __func__, slave->dev_num);
+-              init_completion(&slave->enumeration_complete);
+-              init_completion(&slave->initialization_complete);
++              reinit_completion(&slave->enumeration_complete);
++              reinit_completion(&slave->initialization_complete);
+       } else if ((status == SDW_SLAVE_ATTACHED) &&
+                  (slave->status == SDW_SLAVE_UNATTACHED)) {
+@@ -809,7 +809,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
+                       "%s: signaling enumeration completion for Slave %d\n",
+                       __func__, slave->dev_num);
+-              complete(&slave->enumeration_complete);
++              complete_all(&slave->enumeration_complete);
+       }
+       slave->status = status;
+       mutex_unlock(&slave->bus->bus_lock);
+@@ -1739,7 +1739,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
+                               "%s: signaling initialization completion for Slave %d\n",
+                               __func__, slave->dev_num);
+-                      complete(&slave->initialization_complete);
++                      complete_all(&slave->initialization_complete);
+                       /*
+                        * If the manager became pm_runtime active, the peripherals will be
+-- 
+2.40.1
+
diff --git a/queue-5.10/wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch b/queue-5.10/wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch
new file mode 100644 (file)
index 0000000..6e48d1b
--- /dev/null
@@ -0,0 +1,51 @@
+From 89c58c4fe58d72c8530f29e1853d59b3c17750c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 10:34:07 +0300
+Subject: wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D
+ (DBDC)
+
+From: Paul Fertser <fercerpav@gmail.com>
+
+[ Upstream commit 421033deb91521aa6a9255e495cb106741a52275 ]
+
+On DBDC devices the first (internal) phy is only capable of using
+2.4 GHz band, and the 5 GHz band is exposed via a separate phy object,
+so avoid the false advertising.
+
+Reported-by: Rani Hod <rani.hod@gmail.com>
+Closes: https://github.com/openwrt/openwrt/pull/12361
+Fixes: 7660a1bd0c22 ("mt76: mt7615: register ext_phy if DBDC is detected")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Fertser <fercerpav@gmail.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Acked-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230605073408.8699-1-fercerpav@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+index 48ce24f0f77b7..85f56487feff2 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+@@ -123,12 +123,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
+       case MT_EE_5GHZ:
+               dev->mphy.cap.has_5ghz = true;
+               break;
+-      case MT_EE_2GHZ:
+-              dev->mphy.cap.has_2ghz = true;
+-              break;
+       case MT_EE_DBDC:
+               dev->dbdc_support = true;
+               fallthrough;
++      case MT_EE_2GHZ:
++              dev->mphy.cap.has_2ghz = true;
++              break;
+       default:
+               dev->mphy.cap.has_2ghz = true;
+               dev->mphy.cap.has_5ghz = true;
+-- 
+2.40.1
+