--- /dev/null
+From stable+bounces-273267-greg=kroah.com@vger.kernel.org Fri Jul 10 17:49:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:42:05 -0400
+Subject: ACPI: NFIT: core: Fix acpi_nfit_init() error cleanup
+To: stable@vger.kernel.org
+Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, Dave Jiang <dave.jiang@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260710154205.284338-1-sashal@kernel.org>
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 38bf27511ef41bffebd157ec3eba41fc89ba59cd ]
+
+If acpi_nfit_init() fails after adding the acpi_desc object to the
+acpi_descs list, that object is never removed from that list because
+the acpi_nfit_shutdown() devm action is not added for the NFIT device
+in that case. Next, the acpi_nfit_init() failure causes
+acpi_nfit_probe() to fail, the acpi_desc object is freed, and a
+dangling pointer is left behind in the acpi_descs. Any subsequent
+ACPI Machine Check Exception will trigger nfit_handle_mce() which
+iterates over acpi_descs and so a use-after-free will occur.
+
+Moreover, if acpi_nfit_probe() returns 0 after installing a notify
+handler for the NFIT device and without allocating the acpi_desc
+object and setting the NFIT device's driver data pointer, the
+acpi_desc object will be allocated by acpi_nfit_update_notify()
+and acpi_nfit_init() will be called to initialize it. Regardless
+of whether or not acpi_nfit_init() fails in that case, the
+acpi_nfit_shutdown() devm action is not added for the NFIT device
+and acpi_desc is never removed from the acpi_descs list. If the
+acpi_desc object is freed subsequently on driver removal, any
+subsequent ACPI MCE will lead to a use-after-free like in the
+previous case.
+
+To address the first issue mentioned above, make acpi_nfit_probe()
+call acpi_nfit_shutdown() directly on acpi_nfit_init() failures and
+to address the other one, add a remove callback to the driver and
+make it call acpi_nfit_shutdown(). Also, since it is now possible to
+pass NULL to acpi_nfit_shutdown() or the acpi_desc object passed to it
+may not have been initialized, add checks against NULL for acpi_desc and
+its nvdimm_bus field to that function and make acpi_nfit_unregister()
+clear the latter after unregistering the NVDIMM bus.
+
+Fixes: a61fe6f7902e ("nfit, tools/testing/nvdimm: unify common init for acpi_nfit_desc")
+Fixes: fbabd829fe76 ("acpi, nfit: fix module unload vs workqueue shutdown race")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: All applicable <stable@vger.kernel.org>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://patch.msgid.link/1963615.tdWV9SEqCh@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/acpi/nfit/core.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -3456,6 +3456,8 @@ static void acpi_nfit_unregister(void *d
+ struct acpi_nfit_desc *acpi_desc = data;
+
+ nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
++ /* The nvdimm_bus object may have been freed, so clear the pointer. */
++ acpi_desc->nvdimm_bus = NULL;
+ }
+
+ int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *data, acpi_size sz)
+@@ -3680,7 +3682,10 @@ static void acpi_nfit_put_table(void *ta
+ void acpi_nfit_shutdown(void *data)
+ {
+ struct acpi_nfit_desc *acpi_desc = data;
+- struct device *bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus);
++ struct device *bus_dev;
++
++ if (!acpi_desc || !acpi_desc->nvdimm_bus)
++ return;
+
+ /*
+ * Destruct under acpi_desc_lock so that nfit_handle_mce does not
+@@ -3695,6 +3700,7 @@ void acpi_nfit_shutdown(void *data)
+ mutex_unlock(&acpi_desc->init_mutex);
+ cancel_delayed_work_sync(&acpi_desc->dwork);
+
++ bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus);
+ /*
+ * Bounce the nvdimm bus lock to make sure any in-flight
+ * acpi_nfit_ars_rescan() submissions have had a chance to
+@@ -3762,13 +3768,14 @@ static int acpi_nfit_add(struct acpi_dev
+ sz - sizeof(struct acpi_table_nfit));
+
+ if (rc)
+- return rc;
+- return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
++ acpi_nfit_shutdown(acpi_desc);
++
++ return rc;
+ }
+
+ static int acpi_nfit_remove(struct acpi_device *adev)
+ {
+- /* see acpi_nfit_unregister */
++ acpi_nfit_shutdown(dev_get_drvdata(&adev->dev));
+ return 0;
+ }
+
--- /dev/null
+From stable+bounces-274100-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:53 -0400
+Subject: ALSA: aoa: check snd_ctl_new1() return value
+To: stable@vger.kernel.org
+Cc: Zhao Dongdong <zhaodongdong@kylinos.cn>, Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030453.2382650-1-sashal@kernel.org>
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 8df560fefe6fed6a20b7e06720eeaeccec349ac0 ]
+
+snd_ctl_new1() can return NULL when memory allocation fails. In
+layout.c, the function does not check the return value before
+dereferencing ctl->id.name or passing to aoa_snd_ctl_add(), which can
+lead to a NULL pointer dereference.
+
+Add NULL checks after snd_ctl_new1() calls and return early if any
+fails.
+
+Assisted-by: Opencode:DeepSeek-V4-Flash
+Cc: stable@vger.kernel.org
+Fixes: f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Link: https://patch.msgid.link/tencent_35F3A25FEEBF190A2E15ED787754C57E3708@qq.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/aoa/fabrics/layout.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/sound/aoa/fabrics/layout.c
++++ b/sound/aoa/fabrics/layout.c
+@@ -947,6 +947,8 @@ static void layout_attached_codec(struct
+ if (lineout == 1)
+ ldev->gpio.methods->set_lineout(codec->gpio, 1);
+ ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
++ if (!ctl)
++ return;
+ if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+ strlcpy(ctl->id.name,
+ "Headphone Switch", sizeof(ctl->id.name));
+@@ -961,6 +963,8 @@ static void layout_attached_codec(struct
+ if (ldev->have_lineout_detect) {
+ ctl = snd_ctl_new1(&lineout_detect_choice,
+ ldev);
++ if (!ctl)
++ return;
+ if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+ strlcpy(ctl->id.name,
+ "Headphone Detect Autoswitch",
+@@ -968,6 +972,8 @@ static void layout_attached_codec(struct
+ aoa_snd_ctl_add(ctl);
+ ctl = snd_ctl_new1(&lineout_detected,
+ ldev);
++ if (!ctl)
++ return;
+ if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+ strlcpy(ctl->id.name,
+ "Headphone Detected",
--- /dev/null
+From stable+bounces-278575-greg=kroah.com@vger.kernel.org Tue Jul 21 14:02:36 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 07:56:41 -0400
+Subject: audit: add audit_log_nf_skb helper function
+To: stable@vger.kernel.org
+Cc: Ricardo Robaina <rrobaina@redhat.com>, Florian Westphal <fw@strlen.de>, Paul Moore <paul@paul-moore.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721115642.3699441-1-sashal@kernel.org>
+
+From: Ricardo Robaina <rrobaina@redhat.com>
+
+[ Upstream commit f19590b07cb620be1fcd5474c49515e21a05d406 ]
+
+Netfilter code (net/netfilter/nft_log.c and net/netfilter/xt_AUDIT.c)
+have to be kept in sync. Both source files had duplicated versions of
+audit_ip4() and audit_ip6() functions, which can result in lack of
+consistency and/or duplicated work.
+
+This patch adds a helper function in audit.c that can be called by
+netfilter code commonly, aiming to improve maintainability and
+consistency.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Suggested-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Stable-dep-of: 65dfde57d1e2 ("audit: fix potential integer overflow in audit_log_n_hex()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/audit.h | 8 +++++
+ kernel/audit.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
+ net/netfilter/nft_log.c | 58 ------------------------------------------
+ net/netfilter/xt_AUDIT.c | 58 ------------------------------------------
+ 4 files changed, 74 insertions(+), 114 deletions(-)
+
+--- a/include/linux/audit.h
++++ b/include/linux/audit.h
+@@ -186,6 +186,8 @@ extern void audit_log_lost(const ch
+
+ extern int audit_log_task_context(struct audit_buffer *ab);
+ extern void audit_log_task_info(struct audit_buffer *ab);
++extern int audit_log_nf_skb(struct audit_buffer *ab,
++ const struct sk_buff *skb, u8 nfproto);
+
+ extern int audit_update_lsm_rules(void);
+
+@@ -251,6 +253,12 @@ static inline int audit_log_task_context
+ static inline void audit_log_task_info(struct audit_buffer *ab)
+ { }
+
++static inline int audit_log_nf_skb(struct audit_buffer *ab,
++ const struct sk_buff *skb, u8 nfproto)
++{
++ return 0;
++}
++
+ static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
+ {
+ return INVALID_UID;
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -59,6 +59,8 @@
+ #include <linux/freezer.h>
+ #include <linux/pid_namespace.h>
+ #include <net/netns/generic.h>
++#include <net/ip.h>
++#include <net/ipv6.h>
+
+ #include "audit.h"
+
+@@ -2304,6 +2306,68 @@ void audit_log_path_denied(int type, con
+ audit_log_end(ab);
+ }
+
++int audit_log_nf_skb(struct audit_buffer *ab,
++ const struct sk_buff *skb, u8 nfproto)
++{
++ /* find the IP protocol in the case of NFPROTO_BRIDGE */
++ if (nfproto == NFPROTO_BRIDGE) {
++ switch (eth_hdr(skb)->h_proto) {
++ case htons(ETH_P_IP):
++ nfproto = NFPROTO_IPV4;
++ break;
++ case htons(ETH_P_IPV6):
++ nfproto = NFPROTO_IPV6;
++ break;
++ default:
++ goto unknown_proto;
++ }
++ }
++
++ switch (nfproto) {
++ case NFPROTO_IPV4: {
++ struct iphdr iph;
++ const struct iphdr *ih;
++
++ ih = skb_header_pointer(skb, skb_network_offset(skb),
++ sizeof(iph), &iph);
++ if (!ih)
++ return -ENOMEM;
++
++ audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
++ &ih->saddr, &ih->daddr, ih->protocol);
++ break;
++ }
++ case NFPROTO_IPV6: {
++ struct ipv6hdr iph;
++ const struct ipv6hdr *ih;
++ u8 nexthdr;
++ __be16 frag_off;
++
++ ih = skb_header_pointer(skb, skb_network_offset(skb),
++ sizeof(iph), &iph);
++ if (!ih)
++ return -ENOMEM;
++
++ nexthdr = ih->nexthdr;
++ ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(iph),
++ &nexthdr, &frag_off);
++
++ audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
++ &ih->saddr, &ih->daddr, nexthdr);
++ break;
++ }
++ default:
++ goto unknown_proto;
++ }
++
++ return 0;
++
++unknown_proto:
++ audit_log_format(ab, " saddr=? daddr=? proto=?");
++ return -EPFNOSUPPORT;
++}
++EXPORT_SYMBOL(audit_log_nf_skb);
++
+ /* global counter which is incremented every time something logs in */
+ static atomic_t session_id = ATOMIC_INIT(0);
+
+--- a/net/netfilter/nft_log.c
++++ b/net/netfilter/nft_log.c
+@@ -26,46 +26,10 @@ struct nft_log {
+ char *prefix;
+ };
+
+-static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+- struct iphdr _iph;
+- const struct iphdr *ih;
+-
+- ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
+- if (!ih)
+- return false;
+-
+- audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
+- &ih->saddr, &ih->daddr, ih->protocol);
+-
+- return true;
+-}
+-
+-static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+- struct ipv6hdr _ip6h;
+- const struct ipv6hdr *ih;
+- u8 nexthdr;
+- __be16 frag_off;
+-
+- ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
+- if (!ih)
+- return false;
+-
+- nexthdr = ih->nexthdr;
+- ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
+-
+- audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
+- &ih->saddr, &ih->daddr, nexthdr);
+-
+- return true;
+-}
+-
+ static void nft_log_eval_audit(const struct nft_pktinfo *pkt)
+ {
+ struct sk_buff *skb = pkt->skb;
+ struct audit_buffer *ab;
+- int fam = -1;
+
+ if (!audit_enabled)
+ return;
+@@ -76,27 +40,7 @@ static void nft_log_eval_audit(const str
+
+ audit_log_format(ab, "mark=%#x", skb->mark);
+
+- switch (nft_pf(pkt)) {
+- case NFPROTO_BRIDGE:
+- switch (eth_hdr(skb)->h_proto) {
+- case htons(ETH_P_IP):
+- fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+- break;
+- case htons(ETH_P_IPV6):
+- fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+- break;
+- }
+- break;
+- case NFPROTO_IPV4:
+- fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+- break;
+- case NFPROTO_IPV6:
+- fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+- break;
+- }
+-
+- if (fam == -1)
+- audit_log_format(ab, " saddr=? daddr=? proto=-1");
++ audit_log_nf_skb(ab, skb, nft_pf(pkt));
+
+ audit_log_end(ab);
+ }
+--- a/net/netfilter/xt_AUDIT.c
++++ b/net/netfilter/xt_AUDIT.c
+@@ -28,46 +28,10 @@ MODULE_ALIAS("ip6t_AUDIT");
+ MODULE_ALIAS("ebt_AUDIT");
+ MODULE_ALIAS("arpt_AUDIT");
+
+-static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+- struct iphdr _iph;
+- const struct iphdr *ih;
+-
+- ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
+- if (!ih)
+- return false;
+-
+- audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
+- &ih->saddr, &ih->daddr, ih->protocol);
+-
+- return true;
+-}
+-
+-static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+- struct ipv6hdr _ip6h;
+- const struct ipv6hdr *ih;
+- u8 nexthdr;
+- __be16 frag_off;
+-
+- ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
+- if (!ih)
+- return false;
+-
+- nexthdr = ih->nexthdr;
+- ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
+-
+- audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
+- &ih->saddr, &ih->daddr, nexthdr);
+-
+- return true;
+-}
+-
+ static unsigned int
+ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ {
+ struct audit_buffer *ab;
+- int fam = -1;
+
+ if (audit_enabled == AUDIT_OFF)
+ goto errout;
+@@ -77,27 +41,7 @@ audit_tg(struct sk_buff *skb, const stru
+
+ audit_log_format(ab, "mark=%#x", skb->mark);
+
+- switch (xt_family(par)) {
+- case NFPROTO_BRIDGE:
+- switch (eth_hdr(skb)->h_proto) {
+- case htons(ETH_P_IP):
+- fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+- break;
+- case htons(ETH_P_IPV6):
+- fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+- break;
+- }
+- break;
+- case NFPROTO_IPV4:
+- fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+- break;
+- case NFPROTO_IPV6:
+- fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+- break;
+- }
+-
+- if (fam == -1)
+- audit_log_format(ab, " saddr=? daddr=? proto=-1");
++ audit_log_nf_skb(ab, skb, xt_family(par));
+
+ audit_log_end(ab);
+
--- /dev/null
+From stable+bounces-278576-greg=kroah.com@vger.kernel.org Tue Jul 21 13:56:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 07:56:42 -0400
+Subject: audit: fix potential integer overflow in audit_log_n_hex()
+To: stable@vger.kernel.org
+Cc: Ricardo Robaina <rrobaina@redhat.com>, Richard Guy Briggs <rgb@redhat.com>, Paul Moore <paul@paul-moore.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721115642.3699441-2-sashal@kernel.org>
+
+From: Ricardo Robaina <rrobaina@redhat.com>
+
+[ Upstream commit 65dfde57d1e29ce2b76fc23dd565eccd5c0bc0f0 ]
+
+The function calculates new_len as len << 1 for hex encoding. This
+has two overflow risks: the shift itself can overflow when len is
+large, and the result can be truncated when assigned to new_len
+(declared as int) from the size_t calculation.
+
+Fix by using check_shl_overflow() to catch shift overflow and
+changing new_len and loop counter i to size_t to prevent truncation.
+
+Cc: stable@vger.kernel.org
+Fixes: 168b7173959f ("AUDIT: Clean up logging of untrusted strings")
+Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
+Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
+[PM: remove vertical whitspace noise]
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/audit.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -61,6 +61,7 @@
+ #include <net/netns/generic.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
++#include <linux/overflow.h>
+
+ #include "audit.h"
+
+@@ -2034,7 +2035,8 @@ void audit_log_format(struct audit_buffe
+ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
+ size_t len)
+ {
+- int i, avail, new_len;
++ int avail;
++ size_t i, new_len;
+ unsigned char *ptr;
+ struct sk_buff *skb;
+
+@@ -2044,7 +2046,12 @@ void audit_log_n_hex(struct audit_buffer
+ BUG_ON(!ab->skb);
+ skb = ab->skb;
+ avail = skb_tailroom(skb);
+- new_len = len<<1;
++
++ if (check_shl_overflow(len, 1, &new_len)) {
++ audit_log_format(ab, "?");
++ return;
++ }
++
+ if (new_len >= avail) {
+ /* Round the buffer request up to the next multiple */
+ new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
--- /dev/null
+From sashal@kernel.org Tue Jul 14 16:06:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 10:06:12 -0400
+Subject: binder: fix UAF in binder_free_transaction()
+To: stable@vger.kernel.org
+Cc: Carlos Llamas <cmllamas@google.com>, stable <stable@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714140612.2729754-2-sashal@kernel.org>
+
+From: Carlos Llamas <cmllamas@google.com>
+
+[ Upstream commit f223d27a546c1e1f48d38fd67760e78f068fe8c4 ]
+
+In binder_free_transaction(), the t->to_proc is read under the t->lock.
+However, once the t->lock is dropped, the to_proc can die in parallel.
+This leads to a use-after-free error when we attempt to acquire its
+inner lock right afterwards:
+
+ ==================================================================
+ BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xe4/0x1a0
+ Write of size 4 at addr ffff00001125da70 by task B/672
+
+ CPU: 20 UID: 0 PID: 672 Comm: B Not tainted 7.1.0-rc6-00284-g8e65320d91cd #4 PREEMPT
+ Hardware name: linux,dummy-virt (DT)
+ Call trace:
+ _raw_spin_lock+0xe4/0x1a0
+ binder_free_transaction+0x8c/0x320
+ binder_send_failed_reply+0x21c/0x2f8
+ binder_thread_release+0x488/0x7e0
+ binder_ioctl+0x12c0/0x29a0
+ [...]
+
+ Allocated by task 675:
+ __kmalloc_cache_noprof+0x174/0x444
+ binder_open+0x118/0xb70
+ do_dentry_open+0x374/0x1040
+ vfs_open+0x58/0x3bc
+ [...]
+
+ Freed by task 212:
+ __kasan_slab_free+0x58/0x80
+ kfree+0x1a0/0x4a4
+ binder_proc_dec_tmpref+0x32c/0x5e0
+ binder_deferred_func+0xc48/0x104c
+ process_one_work+0x53c/0xbc0
+ [...]
+ ==================================================================
+
+To prevent this, pin the target thread (t->to_thread) to guarantee the
+target process remains alive. Undelivered transactions without a target
+thread are already safe, as the target process can only be the current
+context in those paths.
+
+Cc: stable <stable@kernel.org>
+Reported-by: Alice Ryhl <aliceryhl@google.com>
+Closes: https://lore.kernel.org/all/aikJKVuny_eOivwN@google.com/
+Fixes: a370003cc301 ("binder: fix possible UAF when freeing buffer")
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://patch.msgid.link/20260619185233.2194678-2-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -1909,10 +1909,19 @@ static void binder_free_txn_fixups(struc
+
+ static void binder_free_transaction(struct binder_transaction *t)
+ {
++ struct binder_thread *target_thread;
+ struct binder_proc *target_proc;
+
+ spin_lock(&t->lock);
+ target_proc = t->to_proc;
++ target_thread = t->to_thread;
++ /*
++ * Pin target_thread to keep target_proc alive. Undelivered
++ * transactions with !target_thread are safe, as target_proc
++ * can only be the current context there.
++ */
++ if (target_thread)
++ atomic_inc(&target_thread->tmp_ref);
+ spin_unlock(&t->lock);
+
+ if (target_proc) {
+@@ -1921,6 +1930,10 @@ static void binder_free_transaction(stru
+ t->buffer->transaction = NULL;
+ binder_inner_proc_unlock(target_proc);
+ }
++
++ if (target_thread)
++ binder_thread_dec_tmpref(target_thread);
++
+ /*
+ * If the transaction has no target_proc, then
+ * t->buffer->transaction has already been cleared.
--- /dev/null
+From stable+bounces-274097-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:47 -0400
+Subject: bitops: make BYTES_TO_BITS() treewide-available
+To: stable@vger.kernel.org
+Cc: Alexander Lobakin <aleksander.lobakin@intel.com>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Przemek Kitszel <przemyslaw.kitszel@intel.com>, Yury Norov <yury.norov@gmail.com>, "David S. Miller" <davem@davemloft.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030448.2382602-1-sashal@kernel.org>
+
+From: Alexander Lobakin <aleksander.lobakin@intel.com>
+
+[ Upstream commit 7d8296b250f2eed73f1758607926d4d258dea5d4 ]
+
+Avoid open-coding that simple expression each time by moving
+BYTES_TO_BITS() from the probes code to <linux/bitops.h> to export
+it to the rest of the kernel.
+Simplify the macro while at it. `BITS_PER_LONG / sizeof(long)` always
+equals to %BITS_PER_BYTE, regardless of the target architecture.
+Do the same for the tools ecosystem as well (incl. its version of
+bitops.h). The previous implementation had its implicit type of long,
+while the new one is int, so adjust the format literal accordingly in
+the perf code.
+
+Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Acked-by: Yury Norov <yury.norov@gmail.com>
+Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 55052184ac90 ("iio: common: st_sensors: honour channel endianness in read_axis_data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/bitops.h | 2 ++
+ kernel/trace/trace_probe.c | 2 --
+ tools/include/linux/bitops.h | 2 ++
+ tools/perf/util/probe-finder.c | 4 +---
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -17,6 +17,8 @@
+ #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
+ #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
+
++#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_BYTE)
++
+ extern unsigned int __sw_hweight8(unsigned int w);
+ extern unsigned int __sw_hweight16(unsigned int w);
+ extern unsigned int __sw_hweight32(unsigned int w);
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -503,8 +503,6 @@ parse_probe_arg(char *arg, const struct
+ return ret;
+ }
+
+-#define BYTES_TO_BITS(nb) ((BITS_PER_LONG * (nb)) / sizeof(long))
+-
+ /* Bitfield type needs to be parsed into a fetch function */
+ static int __parse_bitfield_probe_arg(const char *bf,
+ const struct fetch_type *t,
+--- a/tools/include/linux/bitops.h
++++ b/tools/include/linux/bitops.h
+@@ -20,6 +20,8 @@
+ #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
+ #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
+
++#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_BYTE)
++
+ extern unsigned int __sw_hweight8(unsigned int w);
+ extern unsigned int __sw_hweight16(unsigned int w);
+ extern unsigned int __sw_hweight32(unsigned int w);
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -299,8 +299,6 @@ static_var:
+ return ret2;
+ }
+
+-#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long))
+-
+ static int convert_variable_type(Dwarf_Die *vr_die,
+ struct probe_trace_arg *tvar,
+ const char *cast, bool user_access)
+@@ -330,7 +328,7 @@ static int convert_variable_type(Dwarf_D
+ total = dwarf_bytesize(vr_die);
+ if (boffs < 0 || total < 0)
+ return -ENOENT;
+- ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs,
++ ret = snprintf(buf, 16, "b%d@%d/%d", bsize, boffs,
+ BYTES_TO_BITS(total));
+ goto formatted;
+ }
--- /dev/null
+From stable+bounces-274238-greg=kroah.com@vger.kernel.org Tue Jul 14 15:31:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:48 -0400
+Subject: Bluetooth: btintel: Check firmware version before download
+To: stable@vger.kernel.org
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Tedd Ho-Jeong An <tedd.an@intel.com>, Marcel Holtmann <marcel@holtmann.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132650.2663656-2-sashal@kernel.org>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit ac0565462e330a2b762ca5849a4140b29d725786 ]
+
+This checks the firmware build number, week and year against the
+repective loaded version. If details are a match, skip the download
+process.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btintel.c | 106 +++++++++++++++++++++++++++++++++---------
+ drivers/bluetooth/btintel.h | 5 +
+ drivers/bluetooth/btusb.c | 9 +++
+ drivers/bluetooth/hci_intel.c | 7 +-
+ 4 files changed, 101 insertions(+), 26 deletions(-)
+
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -24,6 +24,14 @@
+ #define ECDSA_OFFSET 644
+ #define ECDSA_HEADER_LEN 320
+
++#define CMD_WRITE_BOOT_PARAMS 0xfc0e
++struct cmd_write_boot_params {
++ u32 boot_addr;
++ u8 fw_build_num;
++ u8 fw_build_ww;
++ u8 fw_build_yy;
++} __packed;
++
+ int btintel_check_bdaddr(struct hci_dev *hdev)
+ {
+ struct hci_rp_read_bd_addr *bda;
+@@ -841,7 +849,7 @@ static int btintel_sfi_ecdsa_header_secu
+
+ static int btintel_download_firmware_payload(struct hci_dev *hdev,
+ const struct firmware *fw,
+- u32 *boot_param, size_t offset)
++ size_t offset)
+ {
+ int err;
+ const u8 *fw_ptr;
+@@ -854,21 +862,6 @@ static int btintel_download_firmware_pay
+ while (fw_ptr - fw->data < fw->size) {
+ struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
+
+- /* Each SKU has a different reset parameter to use in the
+- * HCI_Intel_Reset command and it is embedded in the firmware
+- * data. So, instead of using static value per SKU, check
+- * the firmware data and save it for later use.
+- */
+- if (le16_to_cpu(cmd->opcode) == 0xfc0e) {
+- /* The boot parameter is the first 32-bit value
+- * and rest of 3 octets are reserved.
+- */
+- *boot_param = get_unaligned_le32(fw_ptr + frag_len +
+- sizeof(*cmd));
+-
+- bt_dev_dbg(hdev, "boot_param=0x%x", *boot_param);
+- }
+-
+ frag_len += sizeof(*cmd) + cmd->plen;
+
+ /* The parameter length of the secure send command requires
+@@ -897,28 +890,101 @@ done:
+ return err;
+ }
+
++static bool btintel_firmware_version(struct hci_dev *hdev,
++ u8 num, u8 ww, u8 yy,
++ const struct firmware *fw,
++ u32 *boot_addr)
++{
++ const u8 *fw_ptr;
++
++ fw_ptr = fw->data;
++
++ while (fw_ptr - fw->data < fw->size) {
++ struct hci_command_hdr *cmd = (void *)(fw_ptr);
++
++ /* Each SKU has a different reset parameter to use in the
++ * HCI_Intel_Reset command and it is embedded in the firmware
++ * data. So, instead of using static value per SKU, check
++ * the firmware data and save it for later use.
++ */
++ if (le16_to_cpu(cmd->opcode) == CMD_WRITE_BOOT_PARAMS) {
++ struct cmd_write_boot_params *params;
++
++ params = (void *)(fw_ptr + sizeof(*cmd));
++
++ bt_dev_info(hdev, "Boot Address: 0x%x",
++ le32_to_cpu(params->boot_addr));
++
++ bt_dev_info(hdev, "Firmware Version: %u-%u.%u",
++ params->fw_build_num, params->fw_build_ww,
++ params->fw_build_yy);
++
++ return (num == params->fw_build_num &&
++ ww == params->fw_build_ww &&
++ yy == params->fw_build_yy);
++ }
++
++ fw_ptr += sizeof(*cmd) + cmd->plen;
++ }
++
++ return false;
++}
++
+ int btintel_download_firmware(struct hci_dev *hdev,
++ struct intel_version *ver,
+ const struct firmware *fw,
+ u32 *boot_param)
+ {
+ int err;
+
++ /* SfP and WsP don't seem to update the firmware version on file
++ * so version checking is currently not possible.
++ */
++ switch (ver->hw_variant) {
++ case 0x0b: /* SfP */
++ case 0x0c: /* WsP */
++ /* Skip version checking */
++ break;
++ default:
++ /* Skip download if firmware has the same version */
++ if (btintel_firmware_version(hdev, ver->fw_build_num,
++ ver->fw_build_ww, ver->fw_build_yy,
++ fw, boot_param)) {
++ bt_dev_info(hdev, "Firmware already loaded");
++ /* Return -EALREADY to indicate that the firmware has
++ * already been loaded.
++ */
++ return -EALREADY;
++ }
++ }
++
+ err = btintel_sfi_rsa_header_secure_send(hdev, fw);
+ if (err)
+ return err;
+
+- return btintel_download_firmware_payload(hdev, fw, boot_param,
+- RSA_HEADER_LEN);
++ return btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
+ }
+ EXPORT_SYMBOL_GPL(btintel_download_firmware);
+
+ int btintel_download_firmware_newgen(struct hci_dev *hdev,
++ struct intel_version_tlv *ver,
+ const struct firmware *fw, u32 *boot_param,
+ u8 hw_variant, u8 sbe_type)
+ {
+ int err;
+ u32 css_header_ver;
+
++ /* Skip download if firmware has the same version */
++ if (btintel_firmware_version(hdev, ver->min_fw_build_nn,
++ ver->min_fw_build_cw, ver->min_fw_build_yy,
++ fw, boot_param)) {
++ bt_dev_info(hdev, "Firmware already loaded");
++ /* Return -EALREADY to indicate that firmware has already been
++ * loaded.
++ */
++ return -EALREADY;
++ }
++
+ /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
+ * only RSA secure boot engine. Hence, the corresponding sfi file will
+ * have RSA header of 644 bytes followed by Command Buffer.
+@@ -948,7 +1014,7 @@ int btintel_download_firmware_newgen(str
+ if (err)
+ return err;
+
+- err = btintel_download_firmware_payload(hdev, fw, boot_param, RSA_HEADER_LEN);
++ err = btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
+ if (err)
+ return err;
+ } else if (hw_variant >= 0x17) {
+@@ -969,7 +1035,6 @@ int btintel_download_firmware_newgen(str
+ return err;
+
+ err = btintel_download_firmware_payload(hdev, fw,
+- boot_param,
+ RSA_HEADER_LEN + ECDSA_HEADER_LEN);
+ if (err)
+ return err;
+@@ -979,7 +1044,6 @@ int btintel_download_firmware_newgen(str
+ return err;
+
+ err = btintel_download_firmware_payload(hdev, fw,
+- boot_param,
+ RSA_HEADER_LEN + ECDSA_HEADER_LEN);
+ if (err)
+ return err;
+--- a/drivers/bluetooth/btintel.h
++++ b/drivers/bluetooth/btintel.h
+@@ -157,9 +157,10 @@ struct regmap *btintel_regmap_init(struc
+ int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param);
+ int btintel_read_boot_params(struct hci_dev *hdev,
+ struct intel_boot_params *params);
+-int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw,
+- u32 *boot_param);
++int btintel_download_firmware(struct hci_dev *dev, struct intel_version *ver,
++ const struct firmware *fw, u32 *boot_param);
+ int btintel_download_firmware_newgen(struct hci_dev *hdev,
++ struct intel_version_tlv *ver,
+ const struct firmware *fw,
+ u32 *boot_param, u8 hw_variant,
+ u8 sbe_type);
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2602,8 +2602,15 @@ static int btusb_intel_download_firmware
+ set_bit(BTUSB_DOWNLOADING, &data->flags);
+
+ /* Start firmware downloading and get boot parameter */
+- err = btintel_download_firmware(hdev, fw, boot_param);
++ err = btintel_download_firmware(hdev, ver, fw, boot_param);
+ if (err < 0) {
++ if (err == -EALREADY) {
++ /* Firmware has already been loaded */
++ set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
++ err = 0;
++ goto done;
++ }
++
+ /* When FW download fails, send Intel Reset to retry
+ * FW download.
+ */
+--- a/drivers/bluetooth/hci_intel.c
++++ b/drivers/bluetooth/hci_intel.c
+@@ -735,7 +735,7 @@ static int intel_setup(struct hci_uart *
+ set_bit(STATE_DOWNLOADING, &intel->flags);
+
+ /* Start firmware downloading and get boot parameter */
+- err = btintel_download_firmware(hdev, fw, &boot_param);
++ err = btintel_download_firmware(hdev, &ver, fw, &boot_param);
+ if (err < 0)
+ goto done;
+
+@@ -784,7 +784,10 @@ static int intel_setup(struct hci_uart *
+ done:
+ release_firmware(fw);
+
+- if (err < 0)
++ /* Check if there was an error and if is not -EALREADY which means the
++ * firmware has already been loaded.
++ */
++ if (err < 0 && err != -EALREADY)
+ return err;
+
+ /* We need to restore the default speed before Intel reset */
--- /dev/null
+From stable+bounces-274237-greg=kroah.com@vger.kernel.org Tue Jul 14 15:35:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:47 -0400
+Subject: Bluetooth: btintel: Fix offset calculation boot address parameter
+To: stable@vger.kernel.org
+Cc: Kiran K <kiran.k@intel.com>, Marcel Holtmann <marcel@holtmann.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132650.2663656-1-sashal@kernel.org>
+
+From: Kiran K <kiran.k@intel.com>
+
+[ Upstream commit d00745da644d42c2f97293eb3fe19cfd5c0b073c ]
+
+Boot address parameter was not getting updated properly
+due to wrong offset
+
+Signed-off-by: Kiran K <kiran.k@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btintel.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -863,7 +863,8 @@ static int btintel_download_firmware_pay
+ /* The boot parameter is the first 32-bit value
+ * and rest of 3 octets are reserved.
+ */
+- *boot_param = get_unaligned_le32(fw_ptr + sizeof(*cmd));
++ *boot_param = get_unaligned_le32(fw_ptr + frag_len +
++ sizeof(*cmd));
+
+ bt_dev_dbg(hdev, "boot_param=0x%x", *boot_param);
+ }
--- /dev/null
+From stable+bounces-274240-greg=kroah.com@vger.kernel.org Tue Jul 14 15:31:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:50 -0400
+Subject: Bluetooth: btusb: fix use-after-free on marvell probe failure
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Rajat Jain <rajatja@google.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132650.2663656-4-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 ]
+
+Make sure to stop any TX URBs submitted during Marvell OOB wakeup
+configuration on later probe failures to avoid use-after-free in the
+completion callback.
+
+This issue was reported by Sashiko while reviewing a fix for a wakeup
+source leak in the btusb probe errors paths.
+
+Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org
+Fixes: a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup")
+Cc: stable@vger.kernel.org # 4.11
+Cc: Rajat Jain <rajatja@google.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btusb.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4352,7 +4352,7 @@ static int btusb_probe(struct usb_interf
+ err = usb_set_interface(data->udev, 0, 0);
+ if (err < 0) {
+ BT_ERR("failed to set interface 0, alt 0 %d", err);
+- goto out_free_dev;
++ goto err_kill_tx_urbs;
+ }
+ }
+
+@@ -4360,7 +4360,7 @@ static int btusb_probe(struct usb_interf
+ err = usb_driver_claim_interface(&btusb_driver,
+ data->isoc, data);
+ if (err < 0)
+- goto out_free_dev;
++ goto err_kill_tx_urbs;
+ }
+
+ if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) {
+@@ -4391,6 +4391,8 @@ err_release_siblings:
+ usb_set_intfdata(data->isoc, NULL);
+ usb_driver_release_interface(&btusb_driver, data->isoc);
+ }
++err_kill_tx_urbs:
++ usb_kill_anchored_urbs(&data->tx_anchor);
+ out_free_dev:
+ if (data->reset_gpio)
+ gpiod_put(data->reset_gpio);
--- /dev/null
+From stable+bounces-274245-greg=kroah.com@vger.kernel.org Tue Jul 14 15:27:22 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:57 -0400
+Subject: Bluetooth: btusb: fix wakeup source leak on probe failure
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Rajat Jain <rajatja@google.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132657.2663805-5-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 3d93e1bb0fb881fe3ef961d1120556658e9cac4d ]
+
+Make sure to disable wakeup on probe failure to avoid leaking the wakeup
+source.
+
+Fixes: fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Cc: stable@vger.kernel.org # 4.11
+Cc: Rajat Jain <rajatja@google.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btusb.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -3501,6 +3501,11 @@ static int marvell_config_oob_wake(struc
+
+ return 0;
+ }
++#else
++static inline int marvell_config_oob_wake(struct hci_dev *hdev)
++{
++ return 0;
++}
+ #endif
+
+ static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
+@@ -4011,6 +4016,11 @@ static int btusb_config_oob_wake(struct
+ bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq);
+ return 0;
+ }
++#else
++static inline int btusb_config_oob_wake(struct hci_dev *hdev)
++{
++ return 0;
++}
+ #endif
+
+ static void btusb_check_needs_reset_resume(struct usb_interface *intf)
+@@ -4164,7 +4174,6 @@ static int btusb_probe(struct usb_interf
+ hdev->notify = btusb_notify;
+ hdev->prevent_wake = btusb_prevent_wake;
+
+-#ifdef CONFIG_PM
+ err = btusb_config_oob_wake(hdev);
+ if (err)
+ goto out_free_dev;
+@@ -4173,9 +4182,9 @@ static int btusb_probe(struct usb_interf
+ if (id->driver_info & BTUSB_MARVELL && data->oob_wake_irq) {
+ err = marvell_config_oob_wake(hdev);
+ if (err)
+- goto out_free_dev;
++ goto err_disable_wakeup;
+ }
+-#endif
++
+ if (id->driver_info & BTUSB_CW6622)
+ set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+
+@@ -4393,6 +4402,9 @@ err_release_siblings:
+ }
+ err_kill_tx_urbs:
+ usb_kill_anchored_urbs(&data->tx_anchor);
++err_disable_wakeup:
++ if (data->oob_wake_irq)
++ device_init_wakeup(&data->udev->dev, false);
+ out_free_dev:
+ if (data->reset_gpio)
+ gpiod_put(data->reset_gpio);
--- /dev/null
+From stable+bounces-275107-greg=kroah.com@vger.kernel.org Thu Jul 16 02:17:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 20:16:50 -0400
+Subject: Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock
+To: stable@vger.kernel.org
+Cc: Runyu Xiao <runyu.xiao@seu.edu.cn>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716001650.589781-3-sashal@kernel.org>
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2641a9e0a1dd4af2e21995470a21d55dd35e5203 ]
+
+l2cap_conn_del() takes conn->lock and then calls cancel_work_sync() for
+pending_rx_work. process_pending_rx() takes the same mutex, so teardown
+can deadlock against the worker it is flushing.
+
+This issue was found by our static analysis tool and then manually
+reviewed against the current tree.
+
+The grounded PoC kept the l2cap_conn_ready() -> queue_work(...,
+&conn->pending_rx_work) submit path, the l2cap_conn_del() ->
+cancel_work_sync(&conn->pending_rx_work) teardown path, and the
+process_pending_rx() -> mutex_lock(&conn->lock) worker edge. Lockdep
+reported:
+
+ WARNING: possible circular locking dependency detected
+ process_pending_rx+0x21/0x2a [vuln_msv]
+ l2cap_conn_del.constprop.0+0x3f/0x4e [vuln_msv]
+ *** DEADLOCK ***
+
+Cancel pending_rx_work before taking conn->lock, matching the existing
+lock-before-drain ordering used for the two delayed works in the same
+teardown path. The pending_rx queue is still purged after the work has
+been cancelled and conn->lock has been acquired.
+
+Fixes: 7ab56c3a6ecc ("Bluetooth: Fix deadlock in l2cap_conn_del()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1901,17 +1901,11 @@ static void l2cap_conn_del(struct hci_co
+ cancel_delayed_work_sync(&conn->info_timer);
+ cancel_work_sync(&conn->id_addr_update_work);
+
++ cancel_work_sync(&conn->pending_rx_work);
++
+ kfree_skb(conn->rx_skb);
+
+ skb_queue_purge(&conn->pending_rx);
+-
+- /* We can not call flush_work(&conn->pending_rx_work) here since we
+- * might block if we are running on a worker from the same workqueue
+- * pending_rx_work is waiting on.
+- */
+- if (work_pending(&conn->pending_rx_work))
+- cancel_work_sync(&conn->pending_rx_work);
+-
+ ida_destroy(&conn->tx_ida);
+
+ l2cap_unregister_all_users(conn);
--- /dev/null
+From stable+bounces-275106-greg=kroah.com@vger.kernel.org Thu Jul 16 02:16:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 20:16:49 -0400
+Subject: Bluetooth: L2CAP: Fix deadlock in l2cap_conn_del()
+To: stable@vger.kernel.org
+Cc: Hyunwoo Kim <imv4bel@gmail.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716001650.589781-2-sashal@kernel.org>
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+[ Upstream commit 00fdebbbc557a2fc21321ff2eaa22fd70c078608 ]
+
+l2cap_conn_del() calls cancel_delayed_work_sync() for both info_timer
+and id_addr_timer while holding conn->lock. However, the work functions
+l2cap_info_timeout() and l2cap_conn_update_id_addr() both acquire
+conn->lock, creating a potential AB-BA deadlock if the work is already
+executing when l2cap_conn_del() takes the lock.
+
+Move the work cancellations before acquiring conn->lock and use
+disable_delayed_work_sync() to additionally prevent the works from
+being rearmed after cancellation, consistent with the pattern used in
+hci_conn_del().
+
+Fixes: ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in hci_chan_del")
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2641a9e0a1dd ("Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1898,6 +1898,9 @@ static void l2cap_conn_del(struct hci_co
+
+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+
++ cancel_delayed_work_sync(&conn->info_timer);
++ cancel_work_sync(&conn->id_addr_update_work);
++
+ kfree_skb(conn->rx_skb);
+
+ skb_queue_purge(&conn->pending_rx);
+@@ -1911,9 +1914,6 @@ static void l2cap_conn_del(struct hci_co
+
+ ida_destroy(&conn->tx_ida);
+
+- if (work_pending(&conn->id_addr_update_work))
+- cancel_work_sync(&conn->id_addr_update_work);
+-
+ l2cap_unregister_all_users(conn);
+
+ /* Force the connection to be immediately dropped */
+@@ -1938,9 +1938,6 @@ static void l2cap_conn_del(struct hci_co
+
+ hci_chan_del(conn->hchan);
+
+- if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
+- cancel_delayed_work_sync(&conn->info_timer);
+-
+ hcon->l2cap_data = NULL;
+ conn->hchan = NULL;
+ l2cap_conn_put(conn);
--- /dev/null
+From stable+bounces-275105-greg=kroah.com@vger.kernel.org Thu Jul 16 02:16:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 20:16:48 -0400
+Subject: Bluetooth: L2CAP: Fix not tracking outstanding TX ident
+To: stable@vger.kernel.org
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Paul Menzel <pmenzel@molgen.mpg.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716001650.589781-1-sashal@kernel.org>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 6c3ea155e5ee3e56606233acde8309afda66d483 ]
+
+This attempts to proper track outstanding request by using struct ida
+and allocating from it in l2cap_get_ident using ida_alloc_range which
+would reuse ids as they are free, then upon completion release
+the id using ida_free.
+
+This fixes the qualification test case L2CAP/COS/CED/BI-29-C which
+attempts to check if the host stack is able to work after 256 attempts
+to connect which requires Ident field to use the full range of possible
+values in order to pass the test.
+
+Link: https://github.com/bluez/bluez/issues/1829
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Stable-dep-of: 2641a9e0a1dd ("Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/l2cap.h | 3 --
+ net/bluetooth/l2cap_core.c | 53 ++++++++++++++++++++++++++++++------------
+ 2 files changed, 40 insertions(+), 16 deletions(-)
+
+--- a/include/net/bluetooth/l2cap.h
++++ b/include/net/bluetooth/l2cap.h
+@@ -690,8 +690,7 @@ struct l2cap_conn {
+
+ struct sk_buff *rx_skb;
+ __u32 rx_len;
+- __u8 tx_ident;
+- struct mutex ident_lock;
++ struct ida tx_ida;
+
+ struct sk_buff_head pending_rx;
+ struct work_struct pending_rx_work;
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -939,26 +939,18 @@ int l2cap_chan_check_security(struct l2c
+ initiator);
+ }
+
+-static u8 l2cap_get_ident(struct l2cap_conn *conn)
++static int l2cap_get_ident(struct l2cap_conn *conn)
+ {
+- u8 id;
++ /* LE link does not support tools like l2ping so use the full range */
++ if (conn->hcon->type == LE_LINK)
++ return ida_alloc_range(&conn->tx_ida, 1, 255, GFP_ATOMIC);
+
+ /* Get next available identificator.
+ * 1 - 128 are used by kernel.
+ * 129 - 199 are reserved.
+ * 200 - 254 are used by utilities like l2ping, etc.
+ */
+-
+- mutex_lock(&conn->ident_lock);
+-
+- if (++conn->tx_ident > 128)
+- conn->tx_ident = 1;
+-
+- id = conn->tx_ident;
+-
+- mutex_unlock(&conn->ident_lock);
+-
+- return id;
++ return ida_alloc_range(&conn->tx_ida, 1, 128, GFP_ATOMIC);
+ }
+
+ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
+@@ -1917,6 +1909,8 @@ static void l2cap_conn_del(struct hci_co
+ if (work_pending(&conn->pending_rx_work))
+ cancel_work_sync(&conn->pending_rx_work);
+
++ ida_destroy(&conn->tx_ida);
++
+ if (work_pending(&conn->id_addr_update_work))
+ cancel_work_sync(&conn->id_addr_update_work);
+
+@@ -5788,12 +5782,41 @@ unlock:
+ return err;
+ }
+
++static void l2cap_put_ident(struct l2cap_conn *conn, u8 code, u8 id)
++{
++ int ret;
++
++ switch (code) {
++ case L2CAP_COMMAND_REJ:
++ case L2CAP_CONN_RSP:
++ case L2CAP_CONF_RSP:
++ case L2CAP_DISCONN_RSP:
++ case L2CAP_ECHO_RSP:
++ case L2CAP_INFO_RSP:
++ case L2CAP_CONN_PARAM_UPDATE_RSP:
++ case L2CAP_ECRED_CONN_RSP:
++ case L2CAP_ECRED_RECONF_RSP:
++ /* The remote may send bogus ids that would make ida_free
++ * generate warnings, so only free ids that are actually
++ * allocated: probing the exact id returns -ENOSPC when it
++ * is in use, otherwise the probe allocated it and freeing
++ * is safe either way. Only on -ENOMEM is the id known to
++ * be unallocated and the free must be skipped.
++ */
++ ret = ida_alloc_range(&conn->tx_ida, id, id, GFP_ATOMIC);
++ if (ret >= 0 || ret == -ENOSPC)
++ ida_free(&conn->tx_ida, id);
++ }
++}
++
+ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
+ {
+ int err = 0;
+
++ l2cap_put_ident(conn, cmd->code, cmd->ident);
++
+ switch (cmd->code) {
+ case L2CAP_COMMAND_REJ:
+ l2cap_command_rej(conn, cmd, cmd_len, data);
+@@ -6532,6 +6555,8 @@ static inline int l2cap_le_sig_cmd(struc
+ {
+ int err = 0;
+
++ l2cap_put_ident(conn, cmd->code, cmd->ident);
++
+ switch (cmd->code) {
+ case L2CAP_COMMAND_REJ:
+ l2cap_le_command_rej(conn, cmd, cmd_len, data);
+@@ -8085,13 +8110,13 @@ static struct l2cap_conn *l2cap_conn_add
+ hci_dev_test_flag(hcon->hdev, HCI_FORCE_BREDR_SMP)))
+ conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR;
+
+- mutex_init(&conn->ident_lock);
+ mutex_init(&conn->chan_lock);
+
+ INIT_LIST_HEAD(&conn->chan_l);
+ INIT_LIST_HEAD(&conn->users);
+
+ INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
++ ida_init(&conn->tx_ida);
+
+ skb_queue_head_init(&conn->pending_rx);
+ INIT_WORK(&conn->pending_rx_work, process_pending_rx);
--- /dev/null
+From stable+bounces-278192-greg=kroah.com@vger.kernel.org Mon Jul 20 20:38:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 14:38:37 -0400
+Subject: btrfs: do not trim a device which is not writeable
+To: stable@vger.kernel.org
+Cc: Qu Wenruo <wqu@suse.com>, Su Yue <glass.su@suse.com>, Filipe Manana <fdmanana@suse.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720183837.3080301-1-sashal@kernel.org>
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit 1b1937eb08f51319bf71575484cde2b8c517aedc ]
+
+[BUG]
+There is a bug report that btrfs/242 can randomly fail with the
+following NULL pointer dereference:
+
+ run fstests btrfs/242 at 2026-06-01 10:25:08
+ BTRFS: device fsid d4d7f234-487c-4787-88e4-47a8b68c9874 devid 1 transid 9 /dev/sdc (8:32) scanned by mount (122609)
+ BTRFS info (device sdc): first mount of filesystem d4d7f234-487c-4787-88e4-47a8b68c9874
+ BTRFS info (device sdc): using crc32c checksum algorithm
+ BTRFS warning (device sdc): devid 2 uuid fbe72d72-3272-482d-80fb-ab88ed398192 is missing
+ BTRFS warning (device sdc): devid 2 uuid fbe72d72-3272-482d-80fb-ab88ed398192 is missing
+ BTRFS info (device sdc): allowing degraded mounts
+ BTRFS info (device sdc): turning on async discard
+ BTRFS info (device sdc): enabling free space tree
+ Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
+ user pgtable: 4k pages, 48-bit VAs, pgdp=000000013fd6b000
+ CPU: 4 UID: 0 PID: 122625 Comm: fstrim Not tainted 7.0.10-2-default #1 PREEMPT(full) openSUSE Tumbleweed e9a5f6b24978fba3bf015a992f865837fdfff3dd
+ Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20250812-19.fc42 08/12/2025
+ pstate: 01400005 (nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+ pc : btrfs_trim_fs+0x34c/0xa00 [btrfs]
+ lr : btrfs_trim_fs+0x1f0/0xa00 [btrfs]
+ Call trace:
+ btrfs_trim_fs+0x34c/0xa00 [btrfs f02c1d570ceea621c69d302ba75dd61868083840] (P)
+ btrfs_ioctl_fitrim+0xe8/0x178 [btrfs f02c1d570ceea621c69d302ba75dd61868083840]
+ btrfs_ioctl+0xdd4/0x2bd8 [btrfs f02c1d570ceea621c69d302ba75dd61868083840]
+ __arm64_sys_ioctl+0xac/0x108
+ invoke_syscall.constprop.0+0x5c/0xd0
+ el0_svc_common.constprop.0+0x40/0xf0
+ do_el0_svc+0x24/0x40
+ el0_svc+0x40/0x1d0
+ el0t_64_sync_handler+0xa0/0xe8
+ el0t_64_sync+0x1b0/0x1b8
+ Code: 17ffff83 f94017e0 f9002be0 f9402ea0 (f9400c00)
+ ---[ end trace 0000000000000000 ]---
+
+Also the reporter is very kind to test the following ASSERT() added to
+btrfs_trim_free_extents_throttle():
+
+ ASSERT(device->bdev,
+ "devid=%llu path=%s dev_state=0x%lx\n",
+ device->devid, btrfs_dev_name(device), device->dev_state);
+
+And it shows the following output:
+
+ assertion failed: device->bdev, in extent-tree.c:6630 (devid=2 path=/dev/sdd dev_state=0x82)
+
+Which means the device->bdev is NULL, and the dev_state is
+BTRFS_DEV_STATE_IN_FS_METADATA | BTRFS_DEV_STATE_ITEM_FOUND, without
+BTRFS_DEV_STATE_WRITEABLE flag set.
+
+[CAUSE]
+The pc points to the following call chain:
+
+ btrfs_trim_fs()
+ |- btrfs_trim_free_extents()
+ |- btrfs_trim_free_extents_throttle()
+ |- bdev_max_discard_sectors(device->bdev)
+
+So the NULL pointer dereference is caused by device->bdev being NULL.
+
+This looks impossible by a quick glance, as just before calling
+btrfs_trim_free_extents_throttle(), we have skipped any device that has
+BTRFS_DEV_STATE_MISSING flag set.
+
+However in this particular case, there is a window where the missing
+device is later re-scanned, causing btrfs to remove the
+BTRFS_DEV_STATE_MISSING flag:
+
+ btrfs_control_ioctl()
+ |- btrfs_scan_one_device()
+ |- device_list_add()
+ |- rcu_assign_pointer(device->name, name);
+ | This updates the missing device's path to the new good path.
+ |
+ |- clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)
+ This removes the BTRFS_DEV_STATE_MISSING flag.
+
+This allows the missing device to re-appear and clear the
+BTRFS_DEV_STATE_MISSING flag. However the device still does not have
+the BTRFS_DEV_STATE_WRITEABLE flag set, nor is its bdev pointer updated.
+
+The bdev pointer remains NULL, triggering the crash later.
+
+[FIX]
+This is a big de-synchronization between BTRFS_DEV_STATE_MISSING and
+device->bdev pointer, and shows a gap in btrfs's re-appearing-device
+handling.
+
+The proper handling of re-appearing device will need quite some extra
+work, which is out of the context of this small fix.
+
+Thankfully the regular bbio submission path has already handled it well
+by checking if the device->bdev is NULL before submitting.
+
+So here we just fix the crash by checking if the device is writeable and
+has a bdev pointer before calling bdev_max_discard_sectors().
+
+Reported-by: Su Yue <glass.su@suse.com>
+Link: https://lore.kernel.org/linux-btrfs/wlwir19t.fsf@damenly.org/
+Fixes: 499f377f49f0 ("btrfs: iterate over unused chunk space in FITRIM")
+CC: stable@vger.kernel.org # 5.10+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent-tree.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -5762,12 +5762,16 @@ static int btrfs_trim_free_extents(struc
+
+ *trimmed = 0;
+
+- /* Discard not supported = nothing to do. */
+- if (!blk_queue_discard(bdev_get_queue(device->bdev)))
++ /*
++ * The caller only filters out MISSING devices, but a device that was
++ * missing at mount and later rescanned has MISSING cleared while bdev
++ * is still NULL and WRITEABLE is still unset. Skip those here.
++ */
++ if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) || !device->bdev)
+ return 0;
+
+- /* Not writable = nothing to do. */
+- if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
++ /* Discard not supported = nothing to do. */
++ if (!blk_queue_discard(bdev_get_queue(device->bdev)))
+ return 0;
+
+ /* No free space = nothing to do. */
--- /dev/null
+From stable+bounces-274571-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:01 -0400
+Subject: cifs: Create a new shared file holding smb2 pdu definitions
+To: stable@vger.kernel.org
+Cc: Ronnie Sahlberg <lsahlber@redhat.com>, Namjae Jeon <linkinjeon@kernel.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-1-sashal@kernel.org>
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+[ Upstream commit 0d35e382e4e96a4fd97a1438bc1b11a91d2d85a6 ]
+
+This file will contain all the definitions we need for SMB2 packets
+and will follow the naming convention of MS-SMB2.PDF as closely
+as possible to make it easier to cross-reference beween the definitions
+and the standard.
+
+The content of this file will mostly consist of migration of existing
+definitions in the cifs/smb2.pdu.h and ksmbd/smb2pdu.h files
+with some additional tweaks as the two files have diverged.
+
+This patch introduces the new smbfs_common/smb2pdu.h file
+and migrates the SMB2 header as well as TREE_CONNECT and TREE_DISCONNECT
+to the shared file.
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifsfs.c | 1
+ fs/cifs/cifsglob.h | 3
+ fs/cifs/connect.c | 4
+ fs/cifs/misc.c | 2
+ fs/cifs/smb2maperror.c | 16 +-
+ fs/cifs/smb2misc.c | 43 ++---
+ fs/cifs/smb2ops.c | 61 +++----
+ fs/cifs/smb2pdu.c | 106 ++++++-------
+ fs/cifs/smb2pdu.h | 365 ++++------------------------------------------
+ fs/cifs/smb2proto.h | 2
+ fs/cifs/smb2transport.c | 36 ++--
+ fs/smbfs_common/smb2pdu.h | 318 ++++++++++++++++++++++++++++++++++++++++
+ 12 files changed, 491 insertions(+), 466 deletions(-)
+ create mode 100644 fs/smbfs_common/smb2pdu.h
+
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -51,7 +51,6 @@
+ #include <linux/key-type.h>
+ #include "cifs_spnego.h"
+ #include "fscache.h"
+-#include "smb2pdu.h"
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ #include "dfs_cache.h"
+ #endif
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -32,6 +32,7 @@
+ #include <crypto/internal/hash.h>
+ #include <linux/scatterlist.h>
+ #include <uapi/linux/cifs/cifs_mount.h>
++#include "../smbfs_common/smb2pdu.h"
+ #include "smb2pdu.h"
+ #include "smb2glob.h"
+
+@@ -866,7 +867,7 @@ revert_current_mid(struct TCP_Server_Inf
+
+ static inline void
+ revert_current_mid_from_hdr(struct TCP_Server_Info *server,
+- const struct smb2_sync_hdr *shdr)
++ const struct smb2_hdr *shdr)
+ {
+ unsigned int num = le16_to_cpu(shdr->CreditCharge);
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -848,7 +848,7 @@ dequeue_mid(struct mid_q_entry *mid, boo
+ static unsigned int
+ smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
+
+ /*
+ * SMB1 does not use credits.
+@@ -1048,7 +1048,7 @@ cifs_handle_standard(struct TCP_Server_I
+ static void
+ smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
+
+ /*
+ * SMB1 does not use credits.
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -164,7 +164,7 @@ cifs_buf_get(void)
+ * SMB2 header is bigger than CIFS one - no problems to clean some
+ * more bytes for CIFS.
+ */
+- size_t buf_size = sizeof(struct smb2_sync_hdr);
++ size_t buf_size = sizeof(struct smb2_hdr);
+
+ /*
+ * We could use negotiated size instead of max_msgsize -
+--- a/fs/cifs/smb2maperror.c
++++ b/fs/cifs/smb2maperror.c
+@@ -2452,14 +2452,16 @@ smb2_print_status(__le32 status)
+ int
+ map_smb2_to_linux_error(char *buf, bool log_err)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+ unsigned int i;
+ int rc = -EIO;
+ __le32 smb2err = shdr->Status;
+
+ if (smb2err == 0) {
+- trace_smb3_cmd_done(shdr->TreeId, shdr->SessionId,
+- le16_to_cpu(shdr->Command), le64_to_cpu(shdr->MessageId));
++ trace_smb3_cmd_done(le32_to_cpu(shdr->Id.SyncId.TreeId),
++ le64_to_cpu(shdr->SessionId),
++ le16_to_cpu(shdr->Command),
++ le64_to_cpu(shdr->MessageId));
+ return 0;
+ }
+
+@@ -2483,8 +2485,10 @@ map_smb2_to_linux_error(char *buf, bool
+ cifs_dbg(FYI, "Mapping SMB2 status code 0x%08x to POSIX err %d\n",
+ __le32_to_cpu(smb2err), rc);
+
+- trace_smb3_cmd_err(shdr->TreeId, shdr->SessionId,
+- le16_to_cpu(shdr->Command),
+- le64_to_cpu(shdr->MessageId), le32_to_cpu(smb2err), rc);
++ trace_smb3_cmd_err(le32_to_cpu(shdr->Id.SyncId.TreeId),
++ le64_to_cpu(shdr->SessionId),
++ le16_to_cpu(shdr->Command),
++ le64_to_cpu(shdr->MessageId),
++ le32_to_cpu(smb2err), rc);
+ return rc;
+ }
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -21,7 +21,6 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+ #include <linux/ctype.h>
+-#include "smb2pdu.h"
+ #include "cifsglob.h"
+ #include "cifsproto.h"
+ #include "smb2proto.h"
+@@ -32,7 +31,7 @@
+ #include "nterr.h"
+
+ static int
+-check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
++check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
+ {
+ __u64 wire_mid = le64_to_cpu(shdr->MessageId);
+
+@@ -94,9 +93,9 @@ static const __le16 smb2_rsp_struct_size
+ /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
+ };
+
+-#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_sync_hdr) + sizeof(struct smb2_negotiate_rsp))
++#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_hdr) + sizeof(struct smb2_negotiate_rsp))
+
+-static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
++static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
+ __u32 non_ctxlen)
+ {
+ __u16 neg_count;
+@@ -139,13 +138,13 @@ static __u32 get_neg_ctxt_len(struct smb
+ int
+ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
+- struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)shdr;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
++ struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
+ __u64 mid;
+ __u32 clc_len; /* calculated length */
+ int command;
+- int pdu_size = sizeof(struct smb2_sync_pdu);
+- int hdr_size = sizeof(struct smb2_sync_hdr);
++ int pdu_size = sizeof(struct smb2_pdu);
++ int hdr_size = sizeof(struct smb2_hdr);
+
+ /*
+ * Add function to do table lookup of StructureSize by command
+@@ -161,7 +160,7 @@ smb2_check_message(char *buf, unsigned i
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &srvr->smb_ses_list) {
+ ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+- if (ses->Suid == thdr->SessionId)
++ if (ses->Suid == le64_to_cpu(thdr->SessionId))
+ break;
+
+ ses = NULL;
+@@ -303,7 +302,7 @@ static const bool has_smb2_data_area[NUM
+ * area and the offset to it (from the beginning of the smb are also returned.
+ */
+ char *
+-smb2_get_data_area_len(int *off, int *len, struct smb2_sync_hdr *shdr)
++smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr)
+ {
+ const int max_off = 4096;
+ const int max_len = 128 * 1024;
+@@ -402,8 +401,8 @@ smb2_get_data_area_len(int *off, int *le
+ unsigned int
+ smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
+ {
+- struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)buf;
+- struct smb2_sync_hdr *shdr = &pdu->sync_hdr;
++ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
++ struct smb2_hdr *shdr = &pdu->hdr;
+ int offset; /* the offset from the beginning of SMB to data area */
+ int data_length; /* the length of the variable length data area */
+ /* Structure Size has already been checked to make sure it is 64 */
+@@ -679,7 +678,7 @@ smb2_is_valid_oplock_break(char *buffer,
+
+ cifs_dbg(FYI, "Checking for oplock break\n");
+
+- if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
++ if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
+ return false;
+
+ if (rsp->StructureSize !=
+@@ -832,23 +831,23 @@ smb2_handle_cancelled_close(struct cifs_
+ int
+ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server)
+ {
+- struct smb2_sync_hdr *sync_hdr = mid->resp_buf;
++ struct smb2_hdr *hdr = mid->resp_buf;
+ struct smb2_create_rsp *rsp = mid->resp_buf;
+ struct cifs_tcon *tcon;
+ int rc;
+
+- if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE ||
+- sync_hdr->Status != STATUS_SUCCESS)
++ if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || hdr->Command != SMB2_CREATE ||
++ hdr->Status != STATUS_SUCCESS)
+ return 0;
+
+- tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
+- sync_hdr->TreeId);
++ tcon = smb2_find_smb_tcon(server, le64_to_cpu(hdr->SessionId),
++ le32_to_cpu(hdr->Id.SyncId.TreeId));
+ if (!tcon)
+ return -ENOENT;
+
+ rc = __smb2_handle_cancelled_cmd(tcon,
+- le16_to_cpu(sync_hdr->Command),
+- le64_to_cpu(sync_hdr->MessageId),
++ le16_to_cpu(hdr->Command),
++ le64_to_cpu(hdr->MessageId),
+ rsp->PersistentFileId,
+ rsp->VolatileFileId);
+ if (rc)
+@@ -868,10 +867,10 @@ smb311_update_preauth_hash(struct cifs_s
+ {
+ int i, rc;
+ struct sdesc *d;
+- struct smb2_sync_hdr *hdr;
++ struct smb2_hdr *hdr;
+ struct TCP_Server_Info *server = cifs_ses_server(ses);
+
+- hdr = (struct smb2_sync_hdr *)iov[0].iov_base;
++ hdr = (struct smb2_hdr *)iov[0].iov_base;
+ /* neg prot are always taken */
+ if (hdr->Command == SMB2_NEGOTIATE)
+ goto ok;
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -268,7 +268,7 @@ static struct mid_q_entry *
+ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
+ {
+ struct mid_q_entry *mid;
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+ __u64 wire_mid = le64_to_cpu(shdr->MessageId);
+
+ if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+@@ -310,11 +310,11 @@ static void
+ smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
+ {
+ #ifdef CONFIG_CIFS_DEBUG2
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+
+ cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
+ shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
+- shdr->ProcessId);
++ shdr->Id.SyncId.ProcessId);
+ cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
+ server->ops->calc_smb_size(buf, server));
+ #endif
+@@ -817,7 +817,7 @@ int open_shroot(unsigned int xid, struct
+ oparms.fid->persistent_fid = o_rsp->PersistentFileId;
+ oparms.fid->volatile_fid = o_rsp->VolatileFileId;
+ #ifdef CONFIG_CIFS_DEBUG2
+- oparms.fid->mid = le64_to_cpu(o_rsp->sync_hdr.MessageId);
++ oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
+ #endif /* CIFS_DEBUG2 */
+
+ memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid));
+@@ -2318,7 +2318,7 @@ smb2_query_dir_first(const unsigned int
+
+ /* If the open failed there is nothing to do */
+ op_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+- if (op_rsp == NULL || op_rsp->sync_hdr.Status != STATUS_SUCCESS) {
++ if (op_rsp == NULL || op_rsp->hdr.Status != STATUS_SUCCESS) {
+ cifs_dbg(FYI, "query_dir_first: open failed rc=%d\n", rc);
+ goto qdf_free;
+ }
+@@ -2337,7 +2337,7 @@ smb2_query_dir_first(const unsigned int
+ atomic_inc(&tcon->num_remote_opens);
+
+ qd_rsp = (struct smb2_query_directory_rsp *)rsp_iov[1].iov_base;
+- if (qd_rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
++ if (qd_rsp->hdr.Status == STATUS_NO_MORE_FILES) {
+ trace_smb3_query_dir_done(xid, fid->persistent_fid,
+ tcon->tid, tcon->ses->Suid, 0, 0);
+ srch_inf->endOfSearch = true;
+@@ -2389,7 +2389,7 @@ smb2_close_dir(const unsigned int xid, s
+ static bool
+ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+
+ if (shdr->Status != STATUS_PENDING)
+ return false;
+@@ -2407,13 +2407,14 @@ smb2_is_status_pending(char *buf, struct
+ static bool
+ smb2_is_session_expired(char *buf)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+
+ if (shdr->Status != STATUS_NETWORK_SESSION_EXPIRED &&
+ shdr->Status != STATUS_USER_SESSION_DELETED)
+ return false;
+
+- trace_smb3_ses_expired(shdr->TreeId, shdr->SessionId,
++ trace_smb3_ses_expired(le32_to_cpu(shdr->Id.SyncId.TreeId),
++ le64_to_cpu(shdr->SessionId),
+ le16_to_cpu(shdr->Command),
+ le64_to_cpu(shdr->MessageId));
+ cifs_dbg(FYI, "Session expired or deleted\n");
+@@ -2424,7 +2425,7 @@ smb2_is_session_expired(char *buf)
+ static bool
+ smb2_is_status_io_timeout(char *buf)
+ {
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+
+ if (shdr->Status == STATUS_IO_TIMEOUT)
+ return true;
+@@ -2448,9 +2449,9 @@ smb2_oplock_response(struct cifs_tcon *t
+ void
+ smb2_set_related(struct smb_rqst *rqst)
+ {
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+
+- shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
++ shdr = (struct smb2_hdr *)(rqst->rq_iov[0].iov_base);
+ if (shdr == NULL) {
+ cifs_dbg(FYI, "shdr NULL in smb2_set_related\n");
+ return;
+@@ -2463,13 +2464,13 @@ char smb2_padding[7] = {0, 0, 0, 0, 0, 0
+ void
+ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
+ {
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+ struct cifs_ses *ses = tcon->ses;
+ struct TCP_Server_Info *server = ses->server;
+ unsigned long len = smb_rqst_len(server, rqst);
+ int i, num_padding;
+
+- shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
++ shdr = (struct smb2_hdr *)(rqst->rq_iov[0].iov_base);
+ if (shdr == NULL) {
+ cifs_dbg(FYI, "shdr NULL in smb2_set_next_command\n");
+ return;
+@@ -3018,7 +3019,7 @@ smb2_query_symlink(const unsigned int xi
+ resp_buftype, rsp_iov);
+
+ create_rsp = rsp_iov[0].iov_base;
+- if (create_rsp && create_rsp->sync_hdr.Status)
++ if (create_rsp && create_rsp->hdr.Status)
+ err_iov = rsp_iov[0];
+ ioctl_rsp = rsp_iov[1].iov_base;
+
+@@ -4183,8 +4184,8 @@ static void
+ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
+ struct smb_rqst *old_rq, __le16 cipher_type)
+ {
+- struct smb2_sync_hdr *shdr =
+- (struct smb2_sync_hdr *)old_rq->rq_iov[0].iov_base;
++ struct smb2_hdr *shdr =
++ (struct smb2_hdr *)old_rq->rq_iov[0].iov_base;
+
+ memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
+ tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
+@@ -4322,7 +4323,7 @@ crypt_message(struct TCP_Server_Info *se
+ unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
+ void *creq;
+
+- rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
++ rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key);
+ if (rc) {
+ cifs_server_dbg(VFS, "%s: Could not get %scryption key\n", __func__,
+ enc ? "en" : "de");
+@@ -4608,7 +4609,7 @@ handle_read_data(struct TCP_Server_Info
+ unsigned int cur_page_idx;
+ unsigned int pad_len;
+ struct cifs_readdata *rdata = mid->callback_data;
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+ struct bio_vec *bvec = NULL;
+ struct iov_iter iter;
+ struct kvec iov;
+@@ -4927,7 +4928,7 @@ receive_encrypted_standard(struct TCP_Se
+ {
+ int ret, length;
+ char *buf = server->smallbuf;
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+ unsigned int pdu_length = server->pdu_size;
+ unsigned int buf_size;
+ unsigned int next_cmd;
+@@ -4958,7 +4959,7 @@ receive_encrypted_standard(struct TCP_Se
+
+ next_is_large = server->large_buf;
+ one_more:
+- shdr = (struct smb2_sync_hdr *)buf;
++ shdr = (struct smb2_hdr *)buf;
+ next_cmd = le32_to_cpu(shdr->NextCommand);
+ if (next_cmd) {
+ if (WARN_ON_ONCE(next_cmd > pdu_length))
+@@ -5029,7 +5030,7 @@ smb3_receive_transform(struct TCP_Server
+ unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
+
+ if (pdu_length < sizeof(struct smb2_transform_hdr) +
+- sizeof(struct smb2_sync_hdr)) {
++ sizeof(struct smb2_hdr)) {
+ cifs_server_dbg(VFS, "Transform message is too small (%u)\n",
+ pdu_length);
+ cifs_reconnect(server);
+@@ -5062,7 +5063,7 @@ smb3_handle_read_data(struct TCP_Server_
+ static int
+ smb2_next_header(char *buf)
+ {
+- struct smb2_sync_hdr *hdr = (struct smb2_sync_hdr *)buf;
++ struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
+ struct smb2_transform_hdr *t_hdr = (struct smb2_transform_hdr *)buf;
+
+ if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM)
+@@ -5602,7 +5603,7 @@ struct smb_version_values smb20_values =
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5624,7 +5625,7 @@ struct smb_version_values smb21_values =
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5645,7 +5646,7 @@ struct smb_version_values smb3any_values
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5666,7 +5667,7 @@ struct smb_version_values smbdefault_val
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5687,7 +5688,7 @@ struct smb_version_values smb30_values =
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5708,7 +5709,7 @@ struct smb_version_values smb302_values
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5729,7 +5730,7 @@ struct smb_version_values smb311_values
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+ .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+- .header_size = sizeof(struct smb2_sync_hdr),
++ .header_size = sizeof(struct smb2_hdr),
+ .header_preamble_size = 0,
+ .max_header_size = MAX_SMB2_HDR_SIZE,
+ .read_rsp_size = sizeof(struct smb2_read_rsp),
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -36,7 +36,6 @@
+ #include <linux/uuid.h>
+ #include <linux/pagemap.h>
+ #include <linux/xattr.h>
+-#include "smb2pdu.h"
+ #include "cifsglob.h"
+ #include "cifsacl.h"
+ #include "cifsproto.h"
+@@ -97,7 +96,7 @@ int smb3_encryption_required(const struc
+ }
+
+ static void
+-smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd,
++smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd,
+ const struct cifs_tcon *tcon,
+ struct TCP_Server_Info *server)
+ {
+@@ -117,7 +116,7 @@ smb2_hdr_assemble(struct smb2_sync_hdr *
+ } else {
+ shdr->CreditRequest = cpu_to_le16(2);
+ }
+- shdr->ProcessId = cpu_to_le32((__u16)current->tgid);
++ shdr->Id.SyncId.ProcessId = cpu_to_le32((__u16)current->tgid);
+
+ if (!tcon)
+ goto out;
+@@ -128,10 +127,10 @@ smb2_hdr_assemble(struct smb2_sync_hdr *
+ shdr->CreditCharge = cpu_to_le16(1);
+ /* else CreditCharge MBZ */
+
+- shdr->TreeId = tcon->tid;
++ shdr->Id.SyncId.TreeId = cpu_to_le32(tcon->tid);
+ /* Uid is not converted */
+ if (tcon->ses)
+- shdr->SessionId = tcon->ses->Suid;
++ shdr->SessionId = cpu_to_le64(tcon->ses->Suid);
+
+ /*
+ * If we would set SMB2_FLAGS_DFS_OPERATIONS on open we also would have
+@@ -347,7 +346,7 @@ fill_small_buf(__le16 smb2_command, stru
+ void *buf,
+ unsigned int *total_len)
+ {
+- struct smb2_sync_pdu *spdu = (struct smb2_sync_pdu *)buf;
++ struct smb2_pdu *spdu = (struct smb2_pdu *)buf;
+ /* lookup word count ie StructureSize from table */
+ __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_command)];
+
+@@ -357,10 +356,10 @@ fill_small_buf(__le16 smb2_command, stru
+ */
+ memset(buf, 0, 256);
+
+- smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon, server);
++ smb2_hdr_assemble(&spdu->hdr, smb2_command, tcon, server);
+ spdu->StructureSize2 = cpu_to_le16(parmsize);
+
+- *total_len = parmsize + sizeof(struct smb2_sync_hdr);
++ *total_len = parmsize + sizeof(struct smb2_hdr);
+ }
+
+ /*
+@@ -388,7 +387,7 @@ static int __smb2_plain_req_init(__le16
+ }
+
+ fill_small_buf(smb2_command, tcon, server,
+- (struct smb2_sync_hdr *)(*request_buf),
++ (struct smb2_hdr *)(*request_buf),
+ total_len);
+
+ if (tcon != NULL) {
+@@ -813,7 +812,7 @@ SMB2_negotiate(const unsigned int xid, s
+ if (rc)
+ return rc;
+
+- req->sync_hdr.SessionId = 0;
++ req->hdr.SessionId = 0;
+
+ memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
+ memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
+@@ -969,7 +968,7 @@ SMB2_negotiate(const unsigned int xid, s
+ server->cipher_type = SMB2_ENCRYPTION_AES128_CCM;
+
+ security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
+- (struct smb2_sync_hdr *)rsp);
++ (struct smb2_hdr *)rsp);
+ /*
+ * See MS-SMB2 section 2.2.4: if no blob, client picks default which
+ * for us will be
+@@ -1206,13 +1205,13 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_
+ return rc;
+
+ if (sess_data->ses->binding) {
+- req->sync_hdr.SessionId = sess_data->ses->Suid;
+- req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++ req->hdr.SessionId = cpu_to_le64(sess_data->ses->Suid);
++ req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+ req->PreviousSessionId = 0;
+ req->Flags = SMB2_SESSION_REQ_FLAG_BINDING;
+ } else {
+ /* First session, not a reauthenticate */
+- req->sync_hdr.SessionId = 0;
++ req->hdr.SessionId = 0;
+ /*
+ * if reconnect, we need to send previous sess id
+ * otherwise it is 0
+@@ -1222,7 +1221,7 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_
+ }
+
+ /* enough to enable echos and oplocks and one max size write */
+- req->sync_hdr.CreditRequest = cpu_to_le16(130);
++ req->hdr.CreditRequest = cpu_to_le16(130);
+
+ /* only one of SMB2 signing flags may be set in SMB2 request */
+ if (server->sign)
+@@ -1381,7 +1380,7 @@ SMB2_auth_kerberos(struct SMB2_sess_data
+ rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
+ /* keep session id and flags if binding */
+ if (!ses->binding) {
+- ses->Suid = rsp->sync_hdr.SessionId;
++ ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
+ ses->session_flags = le16_to_cpu(rsp->SessionFlags);
+ }
+
+@@ -1457,7 +1456,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(stru
+
+ /* If true, rc here is expected and not an error */
+ if (sess_data->buf0_type != CIFS_NO_BUFFER &&
+- rsp->sync_hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
++ rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
+ rc = 0;
+
+ if (rc)
+@@ -1479,7 +1478,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(stru
+
+ /* keep existing ses id and flags if binding */
+ if (!ses->binding) {
+- ses->Suid = rsp->sync_hdr.SessionId;
++ ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
+ ses->session_flags = le16_to_cpu(rsp->SessionFlags);
+ }
+
+@@ -1514,7 +1513,7 @@ SMB2_sess_auth_rawntlmssp_authenticate(s
+ goto out;
+
+ req = (struct smb2_sess_setup_req *) sess_data->iov[0].iov_base;
+- req->sync_hdr.SessionId = ses->Suid;
++ req->hdr.SessionId = cpu_to_le64(ses->Suid);
+
+ rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length, ses,
+ sess_data->nls_cp);
+@@ -1540,7 +1539,7 @@ SMB2_sess_auth_rawntlmssp_authenticate(s
+
+ /* keep existing ses id and flags if binding */
+ if (!ses->binding) {
+- ses->Suid = rsp->sync_hdr.SessionId;
++ ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
+ ses->session_flags = le16_to_cpu(rsp->SessionFlags);
+ }
+
+@@ -1671,12 +1670,12 @@ SMB2_logoff(const unsigned int xid, stru
+ return rc;
+
+ /* since no tcon, smb2_init can not do this, so do here */
+- req->sync_hdr.SessionId = ses->Suid;
++ req->hdr.SessionId = cpu_to_le64(ses->Suid);
+
+ if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
+ flags |= CIFS_TRANSFORM_REQ;
+ else if (server->sign)
+- req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++ req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+
+ flags |= CIFS_NO_RSP_BUF;
+
+@@ -1783,14 +1782,14 @@ SMB2_tcon(const unsigned int xid, struct
+ !(ses->session_flags &
+ (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) &&
+ ((ses->user_name != NULL) || (ses->sectype == Kerberos)))
+- req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++ req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+
+ memset(&rqst, 0, sizeof(struct smb_rqst));
+ rqst.rq_iov = iov;
+ rqst.rq_nvec = 2;
+
+ /* Need 64 for max size write so ask for more in case not there yet */
+- req->sync_hdr.CreditRequest = cpu_to_le16(64);
++ req->hdr.CreditRequest = cpu_to_le16(64);
+
+ rc = cifs_send_recv(xid, ses, server,
+ &rqst, &resp_buftype, flags, &rsp_iov);
+@@ -1828,7 +1827,7 @@ SMB2_tcon(const unsigned int xid, struct
+ tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess);
+ tcon->tidStatus = CifsGood;
+ tcon->need_reconnect = false;
+- tcon->tid = rsp->sync_hdr.TreeId;
++ tcon->tid = le32_to_cpu(rsp->hdr.Id.SyncId.TreeId);
+ strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
+
+ if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
+@@ -1849,9 +1848,8 @@ tcon_exit:
+ return rc;
+
+ tcon_error_exit:
+- if (rsp && rsp->sync_hdr.Status == STATUS_BAD_NETWORK_NAME) {
++ if (rsp && rsp->hdr.Status == STATUS_BAD_NETWORK_NAME)
+ cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
+- }
+ goto tcon_exit;
+ }
+
+@@ -2585,7 +2583,7 @@ int smb311_posix_mkdir(const unsigned in
+ if (tcon->share_flags & SHI1005_FLAGS_DFS) {
+ int name_len;
+
+- req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
++ req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
+ rc = alloc_path_with_tree_prefix(©_path, ©_size,
+ &name_len,
+ tcon->treeName, utf16_path);
+@@ -2717,7 +2715,7 @@ SMB2_open_init(struct cifs_tcon *tcon, s
+ if (tcon->share_flags & SHI1005_FLAGS_DFS) {
+ int name_len;
+
+- req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
++ req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
+ rc = alloc_path_with_tree_prefix(©_path, ©_size,
+ &name_len,
+ tcon->treeName, path);
+@@ -2929,7 +2927,7 @@ SMB2_open(const unsigned int xid, struct
+ oparms->fid->volatile_fid = rsp->VolatileFileId;
+ oparms->fid->access = oparms->desired_access;
+ #ifdef CONFIG_CIFS_DEBUG2
+- oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId);
++ oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId);
+ #endif /* CIFS_DEBUG2 */
+
+ if (buf) {
+@@ -3035,7 +3033,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon,
+ * response size smaller.
+ */
+ req->MaxOutputResponse = cpu_to_le32(max_response_size);
+- req->sync_hdr.CreditCharge =
++ req->hdr.CreditCharge =
+ cpu_to_le16(DIV_ROUND_UP(max(indatalen, max_response_size),
+ SMB2_MAX_BUFFER_SIZE));
+ /* always an FSCTL (for now) */
+@@ -3043,7 +3041,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon,
+
+ /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+ if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+- req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++ req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+
+ return 0;
+ }
+@@ -3668,7 +3666,7 @@ smb2_echo_callback(struct mid_q_entry *m
+
+ if (mid->mid_state == MID_RESPONSE_RECEIVED
+ || mid->mid_state == MID_RESPONSE_MALFORMED) {
+- credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
++ credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
+ credits.instance = server->reconnect_instance;
+ }
+
+@@ -3768,7 +3766,7 @@ SMB2_echo(struct TCP_Server_Info *server
+ if (rc)
+ return rc;
+
+- req->sync_hdr.CreditRequest = cpu_to_le16(1);
++ req->hdr.CreditRequest = cpu_to_le16(1);
+
+ iov[0].iov_len = total_len;
+ iov[0].iov_base = (char *)req;
+@@ -3872,7 +3870,7 @@ smb2_new_read_req(void **buf, unsigned i
+ {
+ int rc = -EACCES;
+ struct smb2_read_plain_req *req = NULL;
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+ struct TCP_Server_Info *server = io_parms->server;
+
+ rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server,
+@@ -3883,8 +3881,8 @@ smb2_new_read_req(void **buf, unsigned i
+ if (server == NULL)
+ return -ECONNABORTED;
+
+- shdr = &req->sync_hdr;
+- shdr->ProcessId = cpu_to_le32(io_parms->pid);
++ shdr = &req->hdr;
++ shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
+
+ req->PersistentFileId = io_parms->persistent_fid;
+ req->VolatileFileId = io_parms->volatile_fid;
+@@ -3945,8 +3943,8 @@ smb2_new_read_req(void **buf, unsigned i
+ * Related requests use info from previous read request
+ * in chain.
+ */
+- shdr->SessionId = 0xFFFFFFFFFFFFFFFF;
+- shdr->TreeId = 0xFFFFFFFF;
++ shdr->SessionId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
++ shdr->Id.SyncId.TreeId = cpu_to_le32(0xFFFFFFFF);
+ req->PersistentFileId = 0xFFFFFFFFFFFFFFFF;
+ req->VolatileFileId = 0xFFFFFFFFFFFFFFFF;
+ }
+@@ -3966,8 +3964,8 @@ smb2_readv_callback(struct mid_q_entry *
+ struct cifs_readdata *rdata = mid->callback_data;
+ struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
+ struct TCP_Server_Info *server = rdata->server;
+- struct smb2_sync_hdr *shdr =
+- (struct smb2_sync_hdr *)rdata->iov[0].iov_base;
++ struct smb2_hdr *shdr =
++ (struct smb2_hdr *)rdata->iov[0].iov_base;
+ struct cifs_credits credits = { .value = 0, .instance = 0 };
+ struct smb_rqst rqst = { .rq_iov = &rdata->iov[1],
+ .rq_nvec = 1, };
+@@ -4056,7 +4054,7 @@ smb2_async_readv(struct cifs_readdata *r
+ {
+ int rc, flags = 0;
+ char *buf;
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+ struct cifs_io_parms io_parms;
+ struct smb_rqst rqst = { .rq_iov = rdata->iov,
+ .rq_nvec = 1 };
+@@ -4089,7 +4087,7 @@ smb2_async_readv(struct cifs_readdata *r
+ rdata->iov[0].iov_base = buf;
+ rdata->iov[0].iov_len = total_len;
+
+- shdr = (struct smb2_sync_hdr *)buf;
++ shdr = (struct smb2_hdr *)buf;
+
+ if (rdata->credits.value > 0) {
+ shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
+@@ -4222,7 +4220,7 @@ smb2_writev_callback(struct mid_q_entry
+
+ switch (mid->mid_state) {
+ case MID_RESPONSE_RECEIVED:
+- credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
++ credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
+ credits.instance = server->reconnect_instance;
+ wdata->result = smb2_check_receive(mid, server, 0);
+ if (wdata->result != 0)
+@@ -4248,7 +4246,7 @@ smb2_writev_callback(struct mid_q_entry
+ wdata->result = -EAGAIN;
+ break;
+ case MID_RESPONSE_MALFORMED:
+- credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
++ credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
+ credits.instance = server->reconnect_instance;
+ fallthrough;
+ default:
+@@ -4295,7 +4293,7 @@ smb2_async_writev(struct cifs_writedata
+ {
+ int rc = -EACCES, flags = 0;
+ struct smb2_write_req *req = NULL;
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+ struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+ struct TCP_Server_Info *server = wdata->server;
+ struct kvec iov[1];
+@@ -4313,8 +4311,8 @@ smb2_async_writev(struct cifs_writedata
+ if (smb3_encryption_required(tcon))
+ flags |= CIFS_TRANSFORM_REQ;
+
+- shdr = (struct smb2_sync_hdr *)req;
+- shdr->ProcessId = cpu_to_le32(wdata->cfile->pid);
++ shdr = (struct smb2_hdr *)req;
++ shdr->Id.SyncId.ProcessId = cpu_to_le32(wdata->cfile->pid);
+
+ req->PersistentFileId = wdata->cfile->fid.persistent_fid;
+ req->VolatileFileId = wdata->cfile->fid.volatile_fid;
+@@ -4465,7 +4463,7 @@ SMB2_write(const unsigned int xid, struc
+ if (smb3_encryption_required(io_parms->tcon))
+ flags |= CIFS_TRANSFORM_REQ;
+
+- req->sync_hdr.ProcessId = cpu_to_le32(io_parms->pid);
++ req->hdr.Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
+
+ req->PersistentFileId = io_parms->persistent_fid;
+ req->VolatileFileId = io_parms->volatile_fid;
+@@ -4852,7 +4850,7 @@ SMB2_query_directory(const unsigned int
+
+ if (rc) {
+ if (rc == -ENODATA &&
+- rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
++ rsp->hdr.Status == STATUS_NO_MORE_FILES) {
+ trace_smb3_query_dir_done(xid, persistent_fid,
+ tcon->tid, tcon->ses->Suid, index, 0);
+ srch_inf->endOfSearch = true;
+@@ -4900,7 +4898,7 @@ SMB2_set_info_init(struct cifs_tcon *tco
+ if (rc)
+ return rc;
+
+- req->sync_hdr.ProcessId = cpu_to_le32(pid);
++ req->hdr.Id.SyncId.ProcessId = cpu_to_le32(pid);
+ req->InfoType = info_type;
+ req->FileInfoClass = info_class;
+ req->PersistentFileId = persistent_fid;
+@@ -5060,7 +5058,7 @@ SMB2_oplock_break(const unsigned int xid
+ req->VolatileFid = volatile_fid;
+ req->PersistentFid = persistent_fid;
+ req->OplockLevel = oplock_level;
+- req->sync_hdr.CreditRequest = cpu_to_le16(1);
++ req->hdr.CreditRequest = cpu_to_le16(1);
+
+ flags |= CIFS_NO_RSP_BUF;
+
+@@ -5367,7 +5365,7 @@ smb2_lockv(const unsigned int xid, struc
+ if (smb3_encryption_required(tcon))
+ flags |= CIFS_TRANSFORM_REQ;
+
+- req->sync_hdr.ProcessId = cpu_to_le32(pid);
++ req->hdr.Id.SyncId.ProcessId = cpu_to_le32(pid);
+ req->LockCount = cpu_to_le16(num_lock);
+
+ req->PersistentFileId = persist_fid;
+@@ -5443,7 +5441,7 @@ SMB2_lease_break(const unsigned int xid,
+ if (smb3_encryption_required(tcon))
+ flags |= CIFS_TRANSFORM_REQ;
+
+- req->sync_hdr.CreditRequest = cpu_to_le16(1);
++ req->hdr.CreditRequest = cpu_to_le16(1);
+ req->StructureSize = cpu_to_le16(36);
+ total_len += 12;
+
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -27,149 +27,12 @@
+ #include <net/sock.h>
+ #include <cifsacl.h>
+
+-/*
+- * Note that, due to trying to use names similar to the protocol specifications,
+- * there are many mixed case field names in the structures below. Although
+- * this does not match typical Linux kernel style, it is necessary to be
+- * able to match against the protocol specfication.
+- *
+- * SMB2 commands
+- * Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
+- * (ie no useful data other than the SMB error code itself) and are marked such.
+- * Knowing this helps avoid response buffer allocations and copy in some cases.
+- */
+-
+-/* List of commands in host endian */
+-#define SMB2_NEGOTIATE_HE 0x0000
+-#define SMB2_SESSION_SETUP_HE 0x0001
+-#define SMB2_LOGOFF_HE 0x0002 /* trivial request/resp */
+-#define SMB2_TREE_CONNECT_HE 0x0003
+-#define SMB2_TREE_DISCONNECT_HE 0x0004 /* trivial req/resp */
+-#define SMB2_CREATE_HE 0x0005
+-#define SMB2_CLOSE_HE 0x0006
+-#define SMB2_FLUSH_HE 0x0007 /* trivial resp */
+-#define SMB2_READ_HE 0x0008
+-#define SMB2_WRITE_HE 0x0009
+-#define SMB2_LOCK_HE 0x000A
+-#define SMB2_IOCTL_HE 0x000B
+-#define SMB2_CANCEL_HE 0x000C
+-#define SMB2_ECHO_HE 0x000D
+-#define SMB2_QUERY_DIRECTORY_HE 0x000E
+-#define SMB2_CHANGE_NOTIFY_HE 0x000F
+-#define SMB2_QUERY_INFO_HE 0x0010
+-#define SMB2_SET_INFO_HE 0x0011
+-#define SMB2_OPLOCK_BREAK_HE 0x0012
+-
+-/* The same list in little endian */
+-#define SMB2_NEGOTIATE cpu_to_le16(SMB2_NEGOTIATE_HE)
+-#define SMB2_SESSION_SETUP cpu_to_le16(SMB2_SESSION_SETUP_HE)
+-#define SMB2_LOGOFF cpu_to_le16(SMB2_LOGOFF_HE)
+-#define SMB2_TREE_CONNECT cpu_to_le16(SMB2_TREE_CONNECT_HE)
+-#define SMB2_TREE_DISCONNECT cpu_to_le16(SMB2_TREE_DISCONNECT_HE)
+-#define SMB2_CREATE cpu_to_le16(SMB2_CREATE_HE)
+-#define SMB2_CLOSE cpu_to_le16(SMB2_CLOSE_HE)
+-#define SMB2_FLUSH cpu_to_le16(SMB2_FLUSH_HE)
+-#define SMB2_READ cpu_to_le16(SMB2_READ_HE)
+-#define SMB2_WRITE cpu_to_le16(SMB2_WRITE_HE)
+-#define SMB2_LOCK cpu_to_le16(SMB2_LOCK_HE)
+-#define SMB2_IOCTL cpu_to_le16(SMB2_IOCTL_HE)
+-#define SMB2_CANCEL cpu_to_le16(SMB2_CANCEL_HE)
+-#define SMB2_ECHO cpu_to_le16(SMB2_ECHO_HE)
+-#define SMB2_QUERY_DIRECTORY cpu_to_le16(SMB2_QUERY_DIRECTORY_HE)
+-#define SMB2_CHANGE_NOTIFY cpu_to_le16(SMB2_CHANGE_NOTIFY_HE)
+-#define SMB2_QUERY_INFO cpu_to_le16(SMB2_QUERY_INFO_HE)
+-#define SMB2_SET_INFO cpu_to_le16(SMB2_SET_INFO_HE)
+-#define SMB2_OPLOCK_BREAK cpu_to_le16(SMB2_OPLOCK_BREAK_HE)
+-
+-#define SMB2_INTERNAL_CMD cpu_to_le16(0xFFFF)
+-
+-#define NUMBER_OF_SMB2_COMMANDS 0x0013
+-
+ /* 52 transform hdr + 64 hdr + 88 create rsp */
+ #define SMB2_TRANSFORM_HEADER_SIZE 52
+ #define MAX_SMB2_HDR_SIZE 204
+
+-#define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
+-#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
+-#define SMB2_COMPRESSION_TRANSFORM_ID cpu_to_le32(0x424d53fc)
+-
+-/*
+- * SMB2 Header Definition
+- *
+- * "MBZ" : Must be Zero
+- * "BB" : BugBug, Something to check/review/analyze later
+- * "PDU" : "Protocol Data Unit" (ie a network "frame")
+- *
+- */
+-
+-#define SMB2_HEADER_STRUCTURE_SIZE cpu_to_le16(64)
+-
+-struct smb2_sync_hdr {
+- __le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */
+- __le16 StructureSize; /* 64 */
+- __le16 CreditCharge; /* MBZ */
+- __le32 Status; /* Error from server */
+- __le16 Command;
+- __le16 CreditRequest; /* CreditResponse */
+- __le32 Flags;
+- __le32 NextCommand;
+- __le64 MessageId;
+- __le32 ProcessId;
+- __u32 TreeId; /* opaque - so do not make little endian */
+- __u64 SessionId; /* opaque - so do not make little endian */
+- __u8 Signature[16];
+-} __packed;
+-
+ /* The total header size for SMB2 read and write */
+-#define SMB2_READWRITE_PDU_HEADER_SIZE (48 + sizeof(struct smb2_sync_hdr))
+-
+-struct smb2_sync_pdu {
+- struct smb2_sync_hdr sync_hdr;
+- __le16 StructureSize2; /* size of wct area (varies, request specific) */
+-} __packed;
+-
+-#define SMB3_AES_CCM_NONCE 11
+-#define SMB3_AES_GCM_NONCE 12
+-
+-/* Transform flags (for 3.0 dialect this flag indicates CCM */
+-#define TRANSFORM_FLAG_ENCRYPTED 0x0001
+-struct smb2_transform_hdr {
+- __le32 ProtocolId; /* 0xFD 'S' 'M' 'B' */
+- __u8 Signature[16];
+- __u8 Nonce[16];
+- __le32 OriginalMessageSize;
+- __u16 Reserved1;
+- __le16 Flags; /* EncryptionAlgorithm for 3.0, enc enabled for 3.1.1 */
+- __u64 SessionId;
+-} __packed;
+-
+-/* See MS-SMB2 2.2.42 */
+-struct smb2_compression_transform_hdr {
+- __le32 ProtocolId; /* 0xFC 'S' 'M' 'B' */
+- __le32 OriginalCompressedSegmentSize;
+- __le16 CompressionAlgorithm;
+- __le16 Flags;
+- __le16 Length; /* if chained it is length, else offset */
+-} __packed;
+-
+-/* See MS-SMB2 2.2.42.1 */
+-#define SMB2_COMPRESSION_FLAG_NONE 0x0000
+-#define SMB2_COMPRESSION_FLAG_CHAINED 0x0001
+-
+-struct compression_payload_header {
+- __le16 CompressionAlgorithm;
+- __le16 Flags;
+- __le32 Length; /* length of compressed playload including field below if present */
+- /* __le32 OriginalPayloadSize; */ /* optional */
+-} __packed;
+-
+-/* See MS-SMB2 2.2.42.2 */
+-struct compression_pattern_payload_v1 {
+- __le16 Pattern;
+- __le16 Reserved1;
+- __le16 Reserved2;
+- __le32 Repetitions;
+-} __packed;
++#define SMB2_READWRITE_PDU_HEADER_SIZE (48 + sizeof(struct smb2_hdr))
+
+ /* See MS-SMB2 2.2.43 */
+ struct smb2_rdma_transform {
+@@ -192,17 +55,6 @@ struct smb2_rdma_encryption_transform {
+ } __packed;
+
+ /*
+- * SMB2 flag definitions
+- */
+-#define SMB2_FLAGS_SERVER_TO_REDIR cpu_to_le32(0x00000001)
+-#define SMB2_FLAGS_ASYNC_COMMAND cpu_to_le32(0x00000002)
+-#define SMB2_FLAGS_RELATED_OPERATIONS cpu_to_le32(0x00000004)
+-#define SMB2_FLAGS_SIGNED cpu_to_le32(0x00000008)
+-#define SMB2_FLAGS_PRIORITY_MASK cpu_to_le32(0x00000070) /* SMB3.1.1 */
+-#define SMB2_FLAGS_DFS_OPERATIONS cpu_to_le32(0x10000000)
+-#define SMB2_FLAGS_REPLAY_OPERATION cpu_to_le32(0x20000000) /* SMB3 & up */
+-
+-/*
+ * Definitions for SMB2 Protocol Data Units (network frames)
+ *
+ * See MS-SMB2.PDF specification for protocol details.
+@@ -216,7 +68,7 @@ struct smb2_rdma_encryption_transform {
+ #define SMB2_ERROR_STRUCTURE_SIZE2 cpu_to_le16(9)
+
+ struct smb2_err_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize;
+ __le16 Reserved; /* MBZ */
+ __le32 ByteCount; /* even if zero, at least one byte follows */
+@@ -275,7 +127,7 @@ struct share_redirect_error_context_rsp
+ #define SMB2_CLIENT_GUID_SIZE 16
+
+ struct smb2_negotiate_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 36 */
+ __le16 DialectCount;
+ __le16 SecurityMode;
+@@ -449,7 +301,7 @@ struct smb2_posix_neg_context {
+ } __packed;
+
+ struct smb2_negotiate_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 65 */
+ __le16 SecurityMode;
+ __le16 DialectRevision;
+@@ -472,7 +324,7 @@ struct smb2_negotiate_rsp {
+ #define SMB2_SESSION_REQ_FLAG_ENCRYPT_DATA 0x04
+
+ struct smb2_sess_setup_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 25 */
+ __u8 Flags;
+ __u8 SecurityMode;
+@@ -489,7 +341,7 @@ struct smb2_sess_setup_req {
+ #define SMB2_SESSION_FLAG_IS_NULL 0x0002
+ #define SMB2_SESSION_FLAG_ENCRYPT_DATA 0x0004
+ struct smb2_sess_setup_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 SessionFlags;
+ __le16 SecurityBufferOffset;
+@@ -498,160 +350,13 @@ struct smb2_sess_setup_rsp {
+ } __packed;
+
+ struct smb2_logoff_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+ } __packed;
+
+ struct smb2_logoff_rsp {
+- struct smb2_sync_hdr sync_hdr;
+- __le16 StructureSize; /* Must be 4 */
+- __le16 Reserved;
+-} __packed;
+-
+-/* Flags/Reserved for SMB3.1.1 */
+-#define SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT cpu_to_le16(0x0001)
+-#define SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER cpu_to_le16(0x0002)
+-#define SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT cpu_to_le16(0x0004)
+-
+-struct smb2_tree_connect_req {
+- struct smb2_sync_hdr sync_hdr;
+- __le16 StructureSize; /* Must be 9 */
+- __le16 Flags; /* Reserved MBZ for dialects prior to SMB3.1.1 */
+- __le16 PathOffset;
+- __le16 PathLength;
+- __u8 Buffer[]; /* variable length */
+-} __packed;
+-
+-/* See MS-SMB2 section 2.2.9.2 */
+-/* Context Types */
+-#define SMB2_RESERVED_TREE_CONNECT_CONTEXT_ID 0x0000
+-#define SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID cpu_to_le16(0x0001)
+-
+-struct tree_connect_contexts {
+- __le16 ContextType;
+- __le16 DataLength;
+- __le32 Reserved;
+- __u8 Data[];
+-} __packed;
+-
+-/* Remoted identity tree connect context structures - see MS-SMB2 2.2.9.2.1 */
+-struct smb3_blob_data {
+- __le16 BlobSize;
+- __u8 BlobData[];
+-} __packed;
+-
+-/* Valid values for Attr */
+-#define SE_GROUP_MANDATORY 0x00000001
+-#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002
+-#define SE_GROUP_ENABLED 0x00000004
+-#define SE_GROUP_OWNER 0x00000008
+-#define SE_GROUP_USE_FOR_DENY_ONLY 0x00000010
+-#define SE_GROUP_INTEGRITY 0x00000020
+-#define SE_GROUP_INTEGRITY_ENABLED 0x00000040
+-#define SE_GROUP_RESOURCE 0x20000000
+-#define SE_GROUP_LOGON_ID 0xC0000000
+-
+-/* struct sid_attr_data is SidData array in BlobData format then le32 Attr */
+-
+-struct sid_array_data {
+- __le16 SidAttrCount;
+- /* SidAttrList - array of sid_attr_data structs */
+-} __packed;
+-
+-struct luid_attr_data {
+-
+-} __packed;
+-
+-/*
+- * struct privilege_data is the same as BLOB_DATA - see MS-SMB2 2.2.9.2.1.5
+- * but with size of LUID_ATTR_DATA struct and BlobData set to LUID_ATTR DATA
+- */
+-
+-struct privilege_array_data {
+- __le16 PrivilegeCount;
+- /* array of privilege_data structs */
+-} __packed;
+-
+-struct remoted_identity_tcon_context {
+- __le16 TicketType; /* must be 0x0001 */
+- __le16 TicketSize; /* total size of this struct */
+- __le16 User; /* offset to SID_ATTR_DATA struct with user info */
+- __le16 UserName; /* offset to null terminated Unicode username string */
+- __le16 Domain; /* offset to null terminated Unicode domain name */
+- __le16 Groups; /* offset to SID_ARRAY_DATA struct with group info */
+- __le16 RestrictedGroups; /* similar to above */
+- __le16 Privileges; /* offset to PRIVILEGE_ARRAY_DATA struct */
+- __le16 PrimaryGroup; /* offset to SID_ARRAY_DATA struct */
+- __le16 Owner; /* offset to BLOB_DATA struct */
+- __le16 DefaultDacl; /* offset to BLOB_DATA struct */
+- __le16 DeviceGroups; /* offset to SID_ARRAY_DATA struct */
+- __le16 UserClaims; /* offset to BLOB_DATA struct */
+- __le16 DeviceClaims; /* offset to BLOB_DATA struct */
+- __u8 TicketInfo[]; /* variable length buf - remoted identity data */
+-} __packed;
+-
+-struct smb2_tree_connect_req_extension {
+- __le32 TreeConnectContextOffset;
+- __le16 TreeConnectContextCount;
+- __u8 Reserved[10];
+- __u8 PathName[]; /* variable sized array */
+- /* followed by array of TreeConnectContexts */
+-} __packed;
+-
+-struct smb2_tree_connect_rsp {
+- struct smb2_sync_hdr sync_hdr;
+- __le16 StructureSize; /* Must be 16 */
+- __u8 ShareType; /* see below */
+- __u8 Reserved;
+- __le32 ShareFlags; /* see below */
+- __le32 Capabilities; /* see below */
+- __le32 MaximalAccess;
+-} __packed;
+-
+-/* Possible ShareType values */
+-#define SMB2_SHARE_TYPE_DISK 0x01
+-#define SMB2_SHARE_TYPE_PIPE 0x02
+-#define SMB2_SHARE_TYPE_PRINT 0x03
+-
+-/*
+- * Possible ShareFlags - exactly one and only one of the first 4 caching flags
+- * must be set (any of the remaining, SHI1005, flags may be set individually
+- * or in combination.
+- */
+-#define SMB2_SHAREFLAG_MANUAL_CACHING 0x00000000
+-#define SMB2_SHAREFLAG_AUTO_CACHING 0x00000010
+-#define SMB2_SHAREFLAG_VDO_CACHING 0x00000020
+-#define SMB2_SHAREFLAG_NO_CACHING 0x00000030
+-#define SHI1005_FLAGS_DFS 0x00000001
+-#define SHI1005_FLAGS_DFS_ROOT 0x00000002
+-#define SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS 0x00000100
+-#define SHI1005_FLAGS_FORCE_SHARED_DELETE 0x00000200
+-#define SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING 0x00000400
+-#define SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM 0x00000800
+-#define SHI1005_FLAGS_FORCE_LEVELII_OPLOCK 0x00001000
+-#define SHI1005_FLAGS_ENABLE_HASH_V1 0x00002000
+-#define SHI1005_FLAGS_ENABLE_HASH_V2 0x00004000
+-#define SHI1005_FLAGS_ENCRYPT_DATA 0x00008000
+-#define SMB2_SHAREFLAG_IDENTITY_REMOTING 0x00040000 /* 3.1.1 */
+-#define SHI1005_FLAGS_ALL 0x0004FF33
+-
+-/* Possible share capabilities */
+-#define SMB2_SHARE_CAP_DFS cpu_to_le32(0x00000008) /* all dialects */
+-#define SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY cpu_to_le32(0x00000010) /* 3.0 */
+-#define SMB2_SHARE_CAP_SCALEOUT cpu_to_le32(0x00000020) /* 3.0 */
+-#define SMB2_SHARE_CAP_CLUSTER cpu_to_le32(0x00000040) /* 3.0 */
+-#define SMB2_SHARE_CAP_ASYMMETRIC cpu_to_le32(0x00000080) /* 3.02 */
+-#define SMB2_SHARE_CAP_REDIRECT_TO_OWNER cpu_to_le32(0x00000100) /* 3.1.1 */
+-
+-struct smb2_tree_disconnect_req {
+- struct smb2_sync_hdr sync_hdr;
+- __le16 StructureSize; /* Must be 4 */
+- __le16 Reserved;
+-} __packed;
+-
+-struct smb2_tree_disconnect_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+ } __packed;
+@@ -784,7 +489,7 @@ struct smb2_tree_disconnect_rsp {
+ #define SMB2_CREATE_IOV_SIZE 8
+
+ struct smb2_create_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 57 */
+ __u8 SecurityFlags;
+ __u8 RequestedOplockLevel;
+@@ -811,7 +516,7 @@ struct smb2_create_req {
+ #define MAX_SMB2_CREATE_RESPONSE_SIZE 880
+
+ struct smb2_create_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 89 */
+ __u8 OplockLevel;
+ __u8 Flag; /* 0x01 if reparse point */
+@@ -1186,7 +891,7 @@ struct duplicate_extents_to_file {
+ #define SMB2_IOCTL_IOV_SIZE 2
+
+ struct smb2_ioctl_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 57 */
+ __u16 Reserved;
+ __le32 CtlCode;
+@@ -1204,7 +909,7 @@ struct smb2_ioctl_req {
+ } __packed;
+
+ struct smb2_ioctl_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 57 */
+ __u16 Reserved;
+ __le32 CtlCode;
+@@ -1222,7 +927,7 @@ struct smb2_ioctl_rsp {
+ /* Currently defined values for close flags */
+ #define SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB cpu_to_le16(0x0001)
+ struct smb2_close_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 24 */
+ __le16 Flags;
+ __le32 Reserved;
+@@ -1236,7 +941,7 @@ struct smb2_close_req {
+ #define MAX_SMB2_CLOSE_RESPONSE_SIZE 124
+
+ struct smb2_close_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* 60 */
+ __le16 Flags;
+ __le32 Reserved;
+@@ -1250,7 +955,7 @@ struct smb2_close_rsp {
+ } __packed;
+
+ struct smb2_flush_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 24 */
+ __le16 Reserved1;
+ __le32 Reserved2;
+@@ -1259,7 +964,7 @@ struct smb2_flush_req {
+ } __packed;
+
+ struct smb2_flush_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize;
+ __le16 Reserved;
+ } __packed;
+@@ -1276,7 +981,7 @@ struct smb2_flush_rsp {
+
+ /* SMB2 read request without RFC1001 length at the beginning */
+ struct smb2_read_plain_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 49 */
+ __u8 Padding; /* offset from start of SMB2 header to place read */
+ __u8 Flags; /* MBZ unless SMB3.02 or later */
+@@ -1297,7 +1002,7 @@ struct smb2_read_plain_req {
+ #define SMB2_READFLAG_RESPONSE_RDMA_TRANSFORM 0x00000001
+
+ struct smb2_read_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 17 */
+ __u8 DataOffset;
+ __u8 Reserved;
+@@ -1312,7 +1017,7 @@ struct smb2_read_rsp {
+ #define SMB2_WRITEFLAG_WRITE_UNBUFFERED 0x00000002 /* SMB3.02 or later */
+
+ struct smb2_write_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 49 */
+ __le16 DataOffset; /* offset from start of SMB2 header to write data */
+ __le32 Length;
+@@ -1328,7 +1033,7 @@ struct smb2_write_req {
+ } __packed;
+
+ struct smb2_write_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 17 */
+ __u8 DataOffset;
+ __u8 Reserved;
+@@ -1356,7 +1061,7 @@ struct smb2_write_rsp {
+ #define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800
+
+ struct smb2_change_notify_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize;
+ __le16 Flags;
+ __le32 OutputBufferLength;
+@@ -1367,7 +1072,7 @@ struct smb2_change_notify_req {
+ } __packed;
+
+ struct smb2_change_notify_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 OutputBufferOffset;
+ __le32 OutputBufferLength;
+@@ -1387,7 +1092,7 @@ struct smb2_lock_element {
+ } __packed;
+
+ struct smb2_lock_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 48 */
+ __le16 LockCount;
+ __le32 Reserved;
+@@ -1401,19 +1106,19 @@ struct smb2_lock_req {
+ } __packed;
+
+ struct smb2_lock_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+ } __packed;
+
+ struct smb2_echo_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __u16 Reserved;
+ } __packed;
+
+ struct smb2_echo_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __u16 Reserved;
+ } __packed;
+@@ -1427,7 +1132,7 @@ struct smb2_echo_rsp {
+ #define SMB2_QUERY_DIRECTORY_IOV_SIZE 2
+
+ struct smb2_query_directory_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 33 */
+ __u8 FileInformationClass;
+ __u8 Flags;
+@@ -1441,7 +1146,7 @@ struct smb2_query_directory_req {
+ } __packed;
+
+ struct smb2_query_directory_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 OutputBufferOffset;
+ __le32 OutputBufferLength;
+@@ -1474,7 +1179,7 @@ struct smb2_query_directory_rsp {
+ #define SL_INDEX_SPECIFIED 0x00000004
+
+ struct smb2_query_info_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 41 */
+ __u8 InfoType;
+ __u8 FileInfoClass;
+@@ -1490,7 +1195,7 @@ struct smb2_query_info_req {
+ } __packed;
+
+ struct smb2_query_info_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 OutputBufferOffset;
+ __le32 OutputBufferLength;
+@@ -1507,7 +1212,7 @@ struct smb2_query_info_rsp {
+ #define SMB2_SET_INFO_IOV_SIZE 3
+
+ struct smb2_set_info_req {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 33 */
+ __u8 InfoType;
+ __u8 FileInfoClass;
+@@ -1521,12 +1226,12 @@ struct smb2_set_info_req {
+ } __packed;
+
+ struct smb2_set_info_rsp {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 2 */
+ } __packed;
+
+ struct smb2_oplock_break {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 24 */
+ __u8 OplockLevel;
+ __u8 Reserved;
+@@ -1538,7 +1243,7 @@ struct smb2_oplock_break {
+ #define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)
+
+ struct smb2_lease_break {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 44 */
+ __le16 Epoch;
+ __le32 Flags;
+@@ -1551,7 +1256,7 @@ struct smb2_lease_break {
+ } __packed;
+
+ struct smb2_lease_ack {
+- struct smb2_sync_hdr sync_hdr;
++ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 36 */
+ __le16 Reserved;
+ __le32 Flags;
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -38,7 +38,7 @@ extern int smb2_check_message(char *buf,
+ struct TCP_Server_Info *server);
+ extern unsigned int smb2_calc_size(void *buf, struct TCP_Server_Info *server);
+ extern char *smb2_get_data_area_len(int *off, int *len,
+- struct smb2_sync_hdr *shdr);
++ struct smb2_hdr *shdr);
+ extern __le16 *cifs_convert_path_to_utf16(const char *from,
+ struct cifs_sb_info *cifs_sb);
+
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -33,7 +33,6 @@
+ #include <linux/highmem.h>
+ #include <crypto/algapi.h>
+ #include <crypto/aead.h>
+-#include "smb2pdu.h"
+ #include "cifsglob.h"
+ #include "cifsproto.h"
+ #include "smb2proto.h"
+@@ -227,14 +226,14 @@ smb2_calc_signature(struct smb_rqst *rqs
+ unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
+ unsigned char *sigptr = smb2_signature;
+ struct kvec *iov = rqst->rq_iov;
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
+ struct cifs_ses *ses;
+ struct shash_desc *shash;
+ struct crypto_shash *hash;
+ struct sdesc *sdesc = NULL;
+ struct smb_rqst drqst;
+
+- ses = smb2_find_smb_ses(server, shdr->SessionId);
++ ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
+ if (!ses) {
+ cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
+ return 0;
+@@ -563,14 +562,14 @@ smb3_calc_signature(struct smb_rqst *rqs
+ unsigned char smb3_signature[SMB2_CMACAES_SIZE];
+ unsigned char *sigptr = smb3_signature;
+ struct kvec *iov = rqst->rq_iov;
+- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
++ struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
+ struct shash_desc *shash;
+ struct crypto_shash *hash;
+ struct sdesc *sdesc = NULL;
+ struct smb_rqst drqst;
+ u8 key[SMB3_SIGN_KEY_SIZE];
+
+- rc = smb2_get_sign_key(shdr->SessionId, server, key);
++ rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
+ if (rc)
+ return 0;
+
+@@ -640,12 +639,12 @@ static int
+ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
+ {
+ int rc = 0;
+- struct smb2_sync_hdr *shdr;
++ struct smb2_hdr *shdr;
+ struct smb2_sess_setup_req *ssr;
+ bool is_binding;
+ bool is_signed;
+
+- shdr = (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++ shdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+ ssr = (struct smb2_sess_setup_req *)shdr;
+
+ is_binding = shdr->Command == SMB2_SESSION_SETUP &&
+@@ -671,8 +670,8 @@ smb2_verify_signature(struct smb_rqst *r
+ {
+ unsigned int rc;
+ char server_response_sig[SMB2_SIGNATURE_SIZE];
+- struct smb2_sync_hdr *shdr =
+- (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++ struct smb2_hdr *shdr =
++ (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+
+ if ((shdr->Command == SMB2_NEGOTIATE) ||
+ (shdr->Command == SMB2_SESSION_SETUP) ||
+@@ -719,7 +718,7 @@ smb2_verify_signature(struct smb_rqst *r
+ */
+ static inline void
+ smb2_seq_num_into_buf(struct TCP_Server_Info *server,
+- struct smb2_sync_hdr *shdr)
++ struct smb2_hdr *shdr)
+ {
+ unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
+
+@@ -730,7 +729,7 @@ smb2_seq_num_into_buf(struct TCP_Server_
+ }
+
+ static struct mid_q_entry *
+-smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
++smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
+ struct TCP_Server_Info *server)
+ {
+ struct mid_q_entry *temp;
+@@ -762,14 +761,15 @@ smb2_mid_entry_alloc(const struct smb2_s
+
+ atomic_inc(&midCount);
+ temp->mid_state = MID_REQUEST_ALLOCATED;
+- trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
+- le16_to_cpu(shdr->Command), temp->mid);
++ trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
++ le64_to_cpu(shdr->SessionId),
++ le16_to_cpu(shdr->Command), temp->mid);
+ return temp;
+ }
+
+ static int
+ smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
+- struct smb2_sync_hdr *shdr, struct mid_q_entry **mid)
++ struct smb2_hdr *shdr, struct mid_q_entry **mid)
+ {
+ if (server->tcpStatus == CifsExiting)
+ return -ENOENT;
+@@ -837,8 +837,8 @@ smb2_setup_request(struct cifs_ses *ses,
+ struct smb_rqst *rqst)
+ {
+ int rc;
+- struct smb2_sync_hdr *shdr =
+- (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++ struct smb2_hdr *shdr =
++ (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+ struct mid_q_entry *mid;
+
+ smb2_seq_num_into_buf(server, shdr);
+@@ -863,8 +863,8 @@ struct mid_q_entry *
+ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
+ {
+ int rc;
+- struct smb2_sync_hdr *shdr =
+- (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++ struct smb2_hdr *shdr =
++ (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+ struct mid_q_entry *mid;
+
+ if (server->tcpStatus == CifsNeedNegotiate &&
+--- /dev/null
++++ b/fs/smbfs_common/smb2pdu.h
+@@ -0,0 +1,318 @@
++/* SPDX-License-Identifier: LGPL-2.1 */
++#ifndef _COMMON_SMB2PDU_H
++#define _COMMON_SMB2PDU_H
++
++/*
++ * Note that, due to trying to use names similar to the protocol specifications,
++ * there are many mixed case field names in the structures below. Although
++ * this does not match typical Linux kernel style, it is necessary to be
++ * able to match against the protocol specfication.
++ *
++ * SMB2 commands
++ * Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
++ * (ie no useful data other than the SMB error code itself) and are marked such.
++ * Knowing this helps avoid response buffer allocations and copy in some cases.
++ */
++
++/* List of commands in host endian */
++#define SMB2_NEGOTIATE_HE 0x0000
++#define SMB2_SESSION_SETUP_HE 0x0001
++#define SMB2_LOGOFF_HE 0x0002 /* trivial request/resp */
++#define SMB2_TREE_CONNECT_HE 0x0003
++#define SMB2_TREE_DISCONNECT_HE 0x0004 /* trivial req/resp */
++#define SMB2_CREATE_HE 0x0005
++#define SMB2_CLOSE_HE 0x0006
++#define SMB2_FLUSH_HE 0x0007 /* trivial resp */
++#define SMB2_READ_HE 0x0008
++#define SMB2_WRITE_HE 0x0009
++#define SMB2_LOCK_HE 0x000A
++#define SMB2_IOCTL_HE 0x000B
++#define SMB2_CANCEL_HE 0x000C
++#define SMB2_ECHO_HE 0x000D
++#define SMB2_QUERY_DIRECTORY_HE 0x000E
++#define SMB2_CHANGE_NOTIFY_HE 0x000F
++#define SMB2_QUERY_INFO_HE 0x0010
++#define SMB2_SET_INFO_HE 0x0011
++#define SMB2_OPLOCK_BREAK_HE 0x0012
++
++/* The same list in little endian */
++#define SMB2_NEGOTIATE cpu_to_le16(SMB2_NEGOTIATE_HE)
++#define SMB2_SESSION_SETUP cpu_to_le16(SMB2_SESSION_SETUP_HE)
++#define SMB2_LOGOFF cpu_to_le16(SMB2_LOGOFF_HE)
++#define SMB2_TREE_CONNECT cpu_to_le16(SMB2_TREE_CONNECT_HE)
++#define SMB2_TREE_DISCONNECT cpu_to_le16(SMB2_TREE_DISCONNECT_HE)
++#define SMB2_CREATE cpu_to_le16(SMB2_CREATE_HE)
++#define SMB2_CLOSE cpu_to_le16(SMB2_CLOSE_HE)
++#define SMB2_FLUSH cpu_to_le16(SMB2_FLUSH_HE)
++#define SMB2_READ cpu_to_le16(SMB2_READ_HE)
++#define SMB2_WRITE cpu_to_le16(SMB2_WRITE_HE)
++#define SMB2_LOCK cpu_to_le16(SMB2_LOCK_HE)
++#define SMB2_IOCTL cpu_to_le16(SMB2_IOCTL_HE)
++#define SMB2_CANCEL cpu_to_le16(SMB2_CANCEL_HE)
++#define SMB2_ECHO cpu_to_le16(SMB2_ECHO_HE)
++#define SMB2_QUERY_DIRECTORY cpu_to_le16(SMB2_QUERY_DIRECTORY_HE)
++#define SMB2_CHANGE_NOTIFY cpu_to_le16(SMB2_CHANGE_NOTIFY_HE)
++#define SMB2_QUERY_INFO cpu_to_le16(SMB2_QUERY_INFO_HE)
++#define SMB2_SET_INFO cpu_to_le16(SMB2_SET_INFO_HE)
++#define SMB2_OPLOCK_BREAK cpu_to_le16(SMB2_OPLOCK_BREAK_HE)
++
++#define SMB2_INTERNAL_CMD cpu_to_le16(0xFFFF)
++
++#define NUMBER_OF_SMB2_COMMANDS 0x0013
++
++/*
++ * SMB2 Header Definition
++ *
++ * "MBZ" : Must be Zero
++ * "BB" : BugBug, Something to check/review/analyze later
++ * "PDU" : "Protocol Data Unit" (ie a network "frame")
++ *
++ */
++
++#define __SMB2_HEADER_STRUCTURE_SIZE 64
++#define SMB2_HEADER_STRUCTURE_SIZE \
++ cpu_to_le16(__SMB2_HEADER_STRUCTURE_SIZE)
++
++#define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
++#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
++#define SMB2_COMPRESSION_TRANSFORM_ID cpu_to_le32(0x424d53fc)
++
++/*
++ * SMB2 flag definitions
++ */
++#define SMB2_FLAGS_SERVER_TO_REDIR cpu_to_le32(0x00000001)
++#define SMB2_FLAGS_ASYNC_COMMAND cpu_to_le32(0x00000002)
++#define SMB2_FLAGS_RELATED_OPERATIONS cpu_to_le32(0x00000004)
++#define SMB2_FLAGS_SIGNED cpu_to_le32(0x00000008)
++#define SMB2_FLAGS_PRIORITY_MASK cpu_to_le32(0x00000070) /* SMB3.1.1 */
++#define SMB2_FLAGS_DFS_OPERATIONS cpu_to_le32(0x10000000)
++#define SMB2_FLAGS_REPLAY_OPERATION cpu_to_le32(0x20000000) /* SMB3 & up */
++
++/* See MS-SMB2 section 2.2.1 */
++struct smb2_hdr {
++ __le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */
++ __le16 StructureSize; /* 64 */
++ __le16 CreditCharge; /* MBZ */
++ __le32 Status; /* Error from server */
++ __le16 Command;
++ __le16 CreditRequest; /* CreditResponse */
++ __le32 Flags;
++ __le32 NextCommand;
++ __le64 MessageId;
++ union {
++ struct {
++ __le32 ProcessId;
++ __le32 TreeId;
++ } __packed SyncId;
++ __le64 AsyncId;
++ } __packed Id;
++ __le64 SessionId;
++ __u8 Signature[16];
++} __packed;
++
++struct smb2_pdu {
++ struct smb2_hdr hdr;
++ __le16 StructureSize2; /* size of wct area (varies, request specific) */
++} __packed;
++
++#define SMB3_AES_CCM_NONCE 11
++#define SMB3_AES_GCM_NONCE 12
++
++/* Transform flags (for 3.0 dialect this flag indicates CCM */
++#define TRANSFORM_FLAG_ENCRYPTED 0x0001
++struct smb2_transform_hdr {
++ __le32 ProtocolId; /* 0xFD 'S' 'M' 'B' */
++ __u8 Signature[16];
++ __u8 Nonce[16];
++ __le32 OriginalMessageSize;
++ __u16 Reserved1;
++ __le16 Flags; /* EncryptionAlgorithm for 3.0, enc enabled for 3.1.1 */
++ __le64 SessionId;
++} __packed;
++
++
++/* See MS-SMB2 2.2.42 */
++struct smb2_compression_transform_hdr_unchained {
++ __le32 ProtocolId; /* 0xFC 'S' 'M' 'B' */
++ __le32 OriginalCompressedSegmentSize;
++ __le16 CompressionAlgorithm;
++ __le16 Flags;
++ __le16 Length; /* if chained it is length, else offset */
++} __packed;
++
++/* See MS-SMB2 2.2.42.1 */
++#define SMB2_COMPRESSION_FLAG_NONE 0x0000
++#define SMB2_COMPRESSION_FLAG_CHAINED 0x0001
++
++struct compression_payload_header {
++ __le16 CompressionAlgorithm;
++ __le16 Flags;
++ __le32 Length; /* length of compressed playload including field below if present */
++ /* __le32 OriginalPayloadSize; */ /* optional, present when LZNT1, LZ77, LZ77+Huffman */
++} __packed;
++
++/* See MS-SMB2 2.2.42.2 */
++struct smb2_compression_transform_hdr_chained {
++ __le32 ProtocolId; /* 0xFC 'S' 'M' 'B' */
++ __le32 OriginalCompressedSegmentSize;
++ /* struct compression_payload_header[] */
++} __packed;
++
++/* See MS-SMB2 2.2.42.2.2 */
++struct compression_pattern_payload_v1 {
++ __le16 Pattern;
++ __le16 Reserved1;
++ __le16 Reserved2;
++ __le32 Repetitions;
++} __packed;
++
++/* See MS-SMB2 section 2.2.9.2 */
++/* Context Types */
++#define SMB2_RESERVED_TREE_CONNECT_CONTEXT_ID 0x0000
++#define SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID cpu_to_le16(0x0001)
++
++struct tree_connect_contexts {
++ __le16 ContextType;
++ __le16 DataLength;
++ __le32 Reserved;
++ __u8 Data[];
++} __packed;
++
++/* Remoted identity tree connect context structures - see MS-SMB2 2.2.9.2.1 */
++struct smb3_blob_data {
++ __le16 BlobSize;
++ __u8 BlobData[];
++} __packed;
++
++/* Valid values for Attr */
++#define SE_GROUP_MANDATORY 0x00000001
++#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002
++#define SE_GROUP_ENABLED 0x00000004
++#define SE_GROUP_OWNER 0x00000008
++#define SE_GROUP_USE_FOR_DENY_ONLY 0x00000010
++#define SE_GROUP_INTEGRITY 0x00000020
++#define SE_GROUP_INTEGRITY_ENABLED 0x00000040
++#define SE_GROUP_RESOURCE 0x20000000
++#define SE_GROUP_LOGON_ID 0xC0000000
++
++/* struct sid_attr_data is SidData array in BlobData format then le32 Attr */
++
++struct sid_array_data {
++ __le16 SidAttrCount;
++ /* SidAttrList - array of sid_attr_data structs */
++} __packed;
++
++struct luid_attr_data {
++
++} __packed;
++
++/*
++ * struct privilege_data is the same as BLOB_DATA - see MS-SMB2 2.2.9.2.1.5
++ * but with size of LUID_ATTR_DATA struct and BlobData set to LUID_ATTR DATA
++ */
++
++struct privilege_array_data {
++ __le16 PrivilegeCount;
++ /* array of privilege_data structs */
++} __packed;
++
++struct remoted_identity_tcon_context {
++ __le16 TicketType; /* must be 0x0001 */
++ __le16 TicketSize; /* total size of this struct */
++ __le16 User; /* offset to SID_ATTR_DATA struct with user info */
++ __le16 UserName; /* offset to null terminated Unicode username string */
++ __le16 Domain; /* offset to null terminated Unicode domain name */
++ __le16 Groups; /* offset to SID_ARRAY_DATA struct with group info */
++ __le16 RestrictedGroups; /* similar to above */
++ __le16 Privileges; /* offset to PRIVILEGE_ARRAY_DATA struct */
++ __le16 PrimaryGroup; /* offset to SID_ARRAY_DATA struct */
++ __le16 Owner; /* offset to BLOB_DATA struct */
++ __le16 DefaultDacl; /* offset to BLOB_DATA struct */
++ __le16 DeviceGroups; /* offset to SID_ARRAY_DATA struct */
++ __le16 UserClaims; /* offset to BLOB_DATA struct */
++ __le16 DeviceClaims; /* offset to BLOB_DATA struct */
++ __u8 TicketInfo[]; /* variable length buf - remoted identity data */
++} __packed;
++
++struct smb2_tree_connect_req_extension {
++ __le32 TreeConnectContextOffset;
++ __le16 TreeConnectContextCount;
++ __u8 Reserved[10];
++ __u8 PathName[]; /* variable sized array */
++ /* followed by array of TreeConnectContexts */
++} __packed;
++
++/* Flags/Reserved for SMB3.1.1 */
++#define SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT cpu_to_le16(0x0001)
++#define SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER cpu_to_le16(0x0002)
++#define SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT cpu_to_le16(0x0004)
++
++struct smb2_tree_connect_req {
++ struct smb2_hdr hdr;
++ __le16 StructureSize; /* Must be 9 */
++ __le16 Flags; /* Flags in SMB3.1.1 */
++ __le16 PathOffset;
++ __le16 PathLength;
++ __u8 Buffer[]; /* variable length */
++} __packed;
++
++/* Possible ShareType values */
++#define SMB2_SHARE_TYPE_DISK 0x01
++#define SMB2_SHARE_TYPE_PIPE 0x02
++#define SMB2_SHARE_TYPE_PRINT 0x03
++
++/*
++ * Possible ShareFlags - exactly one and only one of the first 4 caching flags
++ * must be set (any of the remaining, SHI1005, flags may be set individually
++ * or in combination.
++ */
++#define SMB2_SHAREFLAG_MANUAL_CACHING 0x00000000
++#define SMB2_SHAREFLAG_AUTO_CACHING 0x00000010
++#define SMB2_SHAREFLAG_VDO_CACHING 0x00000020
++#define SMB2_SHAREFLAG_NO_CACHING 0x00000030
++#define SHI1005_FLAGS_DFS 0x00000001
++#define SHI1005_FLAGS_DFS_ROOT 0x00000002
++#define SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS 0x00000100
++#define SHI1005_FLAGS_FORCE_SHARED_DELETE 0x00000200
++#define SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING 0x00000400
++#define SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM 0x00000800
++#define SHI1005_FLAGS_FORCE_LEVELII_OPLOCK 0x00001000
++#define SHI1005_FLAGS_ENABLE_HASH_V1 0x00002000
++#define SHI1005_FLAGS_ENABLE_HASH_V2 0x00004000
++#define SHI1005_FLAGS_ENCRYPT_DATA 0x00008000
++#define SMB2_SHAREFLAG_IDENTITY_REMOTING 0x00040000 /* 3.1.1 */
++#define SMB2_SHAREFLAG_COMPRESS_DATA 0x00100000 /* 3.1.1 */
++#define SHI1005_FLAGS_ALL 0x0014FF33
++
++/* Possible share capabilities */
++#define SMB2_SHARE_CAP_DFS cpu_to_le32(0x00000008) /* all dialects */
++#define SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY cpu_to_le32(0x00000010) /* 3.0 */
++#define SMB2_SHARE_CAP_SCALEOUT cpu_to_le32(0x00000020) /* 3.0 */
++#define SMB2_SHARE_CAP_CLUSTER cpu_to_le32(0x00000040) /* 3.0 */
++#define SMB2_SHARE_CAP_ASYMMETRIC cpu_to_le32(0x00000080) /* 3.02 */
++#define SMB2_SHARE_CAP_REDIRECT_TO_OWNER cpu_to_le32(0x00000100) /* 3.1.1 */
++
++struct smb2_tree_connect_rsp {
++ struct smb2_hdr hdr;
++ __le16 StructureSize; /* Must be 16 */
++ __u8 ShareType; /* see below */
++ __u8 Reserved;
++ __le32 ShareFlags; /* see below */
++ __le32 Capabilities; /* see below */
++ __le32 MaximalAccess;
++} __packed;
++
++struct smb2_tree_disconnect_req {
++ struct smb2_hdr hdr;
++ __le16 StructureSize; /* Must be 4 */
++ __le16 Reserved;
++} __packed;
++
++struct smb2_tree_disconnect_rsp {
++ struct smb2_hdr hdr;
++ __le16 StructureSize; /* Must be 4 */
++ __le16 Reserved;
++} __packed;
++
++
++#endif /* _COMMON_SMB2PDU_H */
--- /dev/null
+From stable+bounces-274568-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:02 -0400
+Subject: cifs: remove check of list iterator against head past the loop body
+To: stable@vger.kernel.org
+Cc: Jakob Koschel <jakobkoschel@gmail.com>, "Paulo Alcantara (SUSE)" <pc@cjr.nz>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-2-sashal@kernel.org>
+
+From: Jakob Koschel <jakobkoschel@gmail.com>
+
+[ Upstream commit 00c796eecba4898194ea549679797ee28f89a92f ]
+
+When list_for_each_entry() completes the iteration over the whole list
+without breaking the loop, the iterator value will be a bogus pointer
+computed based on the head element.
+
+While it is safe to use the pointer to determine if it was computed
+based on the head element, either with list_entry_is_head() or
+&pos->member == head, using the iterator variable after the loop should
+be avoided.
+
+In preparation to limit the scope of a list iterator to the list
+traversal loop, use a dedicated pointer to point to the found element [1].
+
+Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ [1]
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Jakob Koschel <jakobkoschel@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2misc.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -154,19 +154,18 @@ smb2_check_message(char *buf, unsigned i
+ struct smb2_transform_hdr *thdr =
+ (struct smb2_transform_hdr *)buf;
+ struct cifs_ses *ses = NULL;
+- struct list_head *tmp;
++ struct cifs_ses *iter;
+
+ /* decrypt frame now that it is completely read in */
+ spin_lock(&cifs_tcp_ses_lock);
+- list_for_each(tmp, &srvr->smb_ses_list) {
+- ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+- if (ses->Suid == le64_to_cpu(thdr->SessionId))
++ list_for_each_entry(iter, &srvr->smb_ses_list, smb_ses_list) {
++ if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
++ ses = iter;
+ break;
+-
+- ses = NULL;
++ }
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+- if (ses == NULL) {
++ if (!ses) {
+ cifs_dbg(VFS, "no decryption - session id not found\n");
+ return 1;
+ }
--- /dev/null
+From stable+bounces-274570-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:04 -0400
+Subject: cifs: remove unused server parameter from calc_smb_size()
+To: stable@vger.kernel.org
+Cc: Enzo Matsumiya <ematsumiya@suse.de>, "Paulo Alcantara (SUSE)" <pc@cjr.nz>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-4-sashal@kernel.org>
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+[ Upstream commit 68ed14496b032b0c9ef21b38ee45c6c8f3a18ff1 ]
+
+This parameter is unused by the called function
+
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifs_debug.c | 2 +-
+ fs/cifs/cifsglob.h | 2 +-
+ fs/cifs/cifsproto.h | 2 +-
+ fs/cifs/misc.c | 2 +-
+ fs/cifs/netmisc.c | 2 +-
+ fs/cifs/readdir.c | 6 ++----
+ fs/cifs/smb2misc.c | 4 ++--
+ fs/cifs/smb2ops.c | 2 +-
+ fs/cifs/smb2proto.h | 2 +-
+ 9 files changed, 11 insertions(+), 13 deletions(-)
+
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -41,7 +41,7 @@ void cifs_dump_detail(void *buf, struct
+ smb->Command, smb->Status.CifsError,
+ smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
+ cifs_dbg(VFS, "smb buf %p len %u\n", smb,
+- server->ops->calc_smb_size(smb, server));
++ server->ops->calc_smb_size(smb));
+ #endif /* CONFIG_CIFS_DEBUG2 */
+ }
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -397,7 +397,7 @@ struct smb_version_operations {
+ int (*close_dir)(const unsigned int, struct cifs_tcon *,
+ struct cifs_fid *);
+ /* calculate a size of SMB message */
+- unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi);
++ unsigned int (*calc_smb_size)(void *buf);
+ /* check for STATUS_PENDING and process the response if yes */
+ bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server);
+ /* check for STATUS_NETWORK_SESSION_EXPIRED */
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -148,7 +148,7 @@ extern int cifs_get_writable_path(struct
+ extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
+ extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
+ struct cifsFileInfo **ret_file);
+-extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
++extern unsigned int smbCalcSize(void *buf);
+ extern int decode_negTokenInit(unsigned char *security_blob, int length,
+ struct TCP_Server_Info *server);
+ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -370,7 +370,7 @@ checkSMB(char *buf, unsigned int total_r
+ /* otherwise, there is enough to get to the BCC */
+ if (check_smb_hdr(smb))
+ return -EIO;
+- clc_len = smbCalcSize(smb, server);
++ clc_len = smbCalcSize(smb);
+
+ if (4 + rfclen != total_read) {
+ cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n",
+--- a/fs/cifs/netmisc.c
++++ b/fs/cifs/netmisc.c
+@@ -913,7 +913,7 @@ map_and_check_smb_error(struct mid_q_ent
+ * portion, the number of word parameters and the data portion of the message
+ */
+ unsigned int
+-smbCalcSize(void *buf, struct TCP_Server_Info *server)
++smbCalcSize(void *buf)
+ {
+ struct smb_hdr *ptr = (struct smb_hdr *)buf;
+ return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -801,8 +801,7 @@ find_cifs_entry(const unsigned int xid,
+
+ end_of_smb = cfile->srch_inf.ntwrk_buf_start +
+ server->ops->calc_smb_size(
+- cfile->srch_inf.ntwrk_buf_start,
+- server);
++ cfile->srch_inf.ntwrk_buf_start);
+
+ cur_ent = cfile->srch_inf.srch_entries_start;
+ first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
+@@ -1000,8 +999,7 @@ int cifs_readdir(struct file *file, stru
+ cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
+ num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
+ max_len = tcon->ses->server->ops->calc_smb_size(
+- cifsFile->srch_inf.ntwrk_buf_start,
+- tcon->ses->server);
++ cifsFile->srch_inf.ntwrk_buf_start);
+ end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
+
+ tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -225,7 +225,7 @@ smb2_check_message(char *buf, unsigned i
+ }
+ }
+
+- calc_len = smb2_calc_size(buf, server);
++ calc_len = smb2_calc_size(buf);
+
+ /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
+ * be 0, and not a real miscalculation */
+@@ -407,7 +407,7 @@ smb2_get_data_area_len(int *off, int *le
+ * portion, the number of word parameters and the data portion of the message.
+ */
+ unsigned int
+-smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
++smb2_calc_size(void *buf)
+ {
+ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+ struct smb2_hdr *shdr = &pdu->hdr;
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -316,7 +316,7 @@ smb2_dump_detail(void *buf, struct TCP_S
+ shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
+ shdr->Id.SyncId.ProcessId);
+ cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
+- server->ops->calc_smb_size(buf, server));
++ server->ops->calc_smb_size(buf));
+ #endif
+ }
+
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -36,7 +36,7 @@ struct smb_rqst;
+ extern int map_smb2_to_linux_error(char *buf, bool log_err);
+ extern int smb2_check_message(char *buf, unsigned int length,
+ struct TCP_Server_Info *server);
+-extern unsigned int smb2_calc_size(void *buf, struct TCP_Server_Info *server);
++extern unsigned int smb2_calc_size(void *buf);
+ extern char *smb2_get_data_area_len(int *off, int *len,
+ struct smb2_hdr *shdr);
+ extern __le16 *cifs_convert_path_to_utf16(const char *from,
--- /dev/null
+From stable+bounces-275001-greg=kroah.com@vger.kernel.org Wed Jul 15 18:54:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:54:05 -0400
+Subject: coresight: etb10: restore atomic_t for shared reading state
+To: stable@vger.kernel.org
+Cc: Runyu Xiao <runyu.xiao@seu.edu.cn>, James Clark <james.clark@linaro.org>, Suzuki K Poulose <suzuki.poulose@arm.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715165405.963048-1-sashal@kernel.org>
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit fa09f08ede3db3050ae16ae1ed92c902d0cada23 ]
+
+The etb10 miscdevice uses drvdata->reading as a shared exclusivity gate
+for userspace buffer access. etb_open() claims that gate with
+local_cmpxchg(), and etb_release() clears it with local_set().
+
+That gate is shared per-device state rather than CPU-local state. A
+running system can reach it whenever /dev/<etb> is opened, closed, and
+reopened by different tasks while the device remains registered, so the
+same drvdata->reading variable may be claimed on one CPU and later
+cleared on another.
+
+This code used to use atomic_t for the same gate, but commit
+27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
+changed it to local_t even though the access pattern remained cross-task
+and cross-CPU. Restore atomic_t together with atomic_cmpxchg() and
+atomic_set() so the exclusivity gate again uses a primitive intended
+for shared state.
+
+The issue was found on Linux v6.18.21 by our static analysis tool while
+scanning surviving local_t-on-shared-state sites, and then manually
+reviewed against the live etb10 file-op path.
+
+It was runtime-validated with a reproducible QEMU no-device KCSAN PoC
+that kept the same report-local contract:
+
+ 1. use one shared struct etb_drvdata carrier and its
+ drvdata->reading gate;
+ 2. call etb_open() and etb_release() sequentially on that gate to
+ confirm the original claim/clear path;
+ 3. bind the open side to CPU0 and the release side to CPU1 for the
+ same gate to show cross-CPU ownership;
+ 4. run bound workers that repeatedly race etb_open() and
+ etb_release() on the same gate until KCSAN reports a target hit.
+
+The harness recorded:
+
+ L1 passed open=1 release=1
+ reading_after_open=1 reading_after_release=0
+ L2 passed open_cpu=0 release_cpu=1
+ cross_cpu_release=1 reading_after=0 open_ret=0
+
+Representative KCSAN excerpt from the no-device validation run:
+
+ BUG: KCSAN: data-race in etb_open.constprop.0.isra.0 [vuln_msv]
+
+ write to 0xffffffffc0003810 of 4 bytes by task 216 on cpu 1:
+ etb_open.constprop.0.isra.0+0x38/0x80 [vuln_msv]
+ l3_worker_thread_fn+0x4f/0xf0 [vuln_msv]
+ kthread+0x17e/0x1c0
+ ret_from_fork+0x22/0x30
+
+ read to 0xffffffffc0003810 of 4 bytes by task 215 on cpu 0:
+ etb_open.constprop.0.isra.0+0x18/0x80 [vuln_msv]
+ l3_worker_thread_fn+0x4f/0xf0 [vuln_msv]
+ kthread+0x17e/0x1c0
+ ret_from_fork+0x22/0x30
+
+ value changed: 0x00000000 -> 0x00000001
+
+ Reported by Kernel Concurrency Sanitizer on:
+ CPU: 0 PID: 215 Comm: etb10_l3_a Tainted: G O 6.1.66 #2
+
+This no-device harness is not a real ETB10 hardware end-to-end run, but
+it preserves the same shared drvdata->reading gate and the same
+etb_open()/etb_release() claim/clear contract. No real ETB10 hardware
+was available for runtime testing.
+
+Build-tested with:
+ make olddefconfig
+ make -j"$(nproc)" drivers/hwtracing/coresight/coresight-etb10.o
+
+Fixes: 27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20260528165201.319452-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwtracing/coresight/coresight-etb10.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/hwtracing/coresight/coresight-etb10.c
++++ b/drivers/hwtracing/coresight/coresight-etb10.c
+@@ -86,7 +86,7 @@ struct etb_drvdata {
+ struct coresight_device *csdev;
+ struct miscdevice miscdev;
+ spinlock_t spinlock;
+- local_t reading;
++ atomic_t reading;
+ pid_t pid;
+ u8 *buf;
+ u32 mode;
+@@ -603,7 +603,7 @@ static int etb_open(struct inode *inode,
+ struct etb_drvdata *drvdata = container_of(file->private_data,
+ struct etb_drvdata, miscdev);
+
+- if (local_cmpxchg(&drvdata->reading, 0, 1))
++ if (atomic_cmpxchg(&drvdata->reading, 0, 1))
+ return -EBUSY;
+
+ dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
+@@ -641,7 +641,7 @@ static int etb_release(struct inode *ino
+ {
+ struct etb_drvdata *drvdata = container_of(file->private_data,
+ struct etb_drvdata, miscdev);
+- local_set(&drvdata->reading, 0);
++ atomic_set(&drvdata->reading, 0);
+
+ dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
+ return 0;
--- /dev/null
+From stable+bounces-277188-greg=kroah.com@vger.kernel.org Fri Jul 17 21:23:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 15:23:48 -0400
+Subject: cpufreq: intel_pstate: Sync policy->cur during CPU offline
+To: stable@vger.kernel.org
+Cc: Fushuai Wang <wangfushuai@baidu.com>, Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>, "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717192348.2131400-1-sashal@kernel.org>
+
+From: Fushuai Wang <wangfushuai@baidu.com>
+
+[ Upstream commit bcbdaa1086c25a8a5d48e04e1b82fdfb0682b681 ]
+
+When a CPU goes offline with HWP disabled, intel_pstate_set_min_pstate()
+sets the MSR_IA32_PERF_CTL to minimum frequency to prevent SMT siblings
+from being restricted. However, the policy->cur value was not updated,
+leaving it at the previous value.
+
+When the CPU comes back online, governor->limits() checks if target_freq
+equals policy->cur and skips the frequency adjustment if they match. Since
+policy->cur still holds the previous value, the governor does not call
+cpufreq_driver->target to update MSR_IA32_PERF_CTL.
+
+Fix this by synchronizing policy->cur with the hardware state when setting
+minimum pstate during CPU offline.
+
+Fixes: bb18008f8086 ("intel_pstate: Set core to min P state during core offline")
+Cc: stable@vger.kernel.org # 3.15+
+Suggested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
+[ rjw: Subject refinement ]
+Link: https://patch.msgid.link/20260520032119.30615-1-fushuai.wang@linux.dev
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+[ replaced `cpu->pstate.min_freq` with `cpu->pstate.min_pstate * cpu->pstate.scaling` since 5.10 lacks the min_freq field ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cpufreq/intel_pstate.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -2355,10 +2355,12 @@ static int intel_pstate_cpu_offline(stru
+ * from getting to lower performance levels, so force the minimum
+ * performance on CPU offline to prevent that from happening.
+ */
+- if (hwp_active)
++ if (hwp_active) {
+ intel_pstate_hwp_offline(cpu);
+- else
++ } else {
+ intel_pstate_set_min_pstate(cpu);
++ policy->cur = cpu->pstate.min_pstate * cpu->pstate.scaling;
++ }
+
+ intel_pstate_exit_perf_limits(policy);
+
--- /dev/null
+From stable+bounces-278069-greg=kroah.com@vger.kernel.org Mon Jul 20 18:03:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:48:12 -0400
+Subject: crypto: atmel - Drop explicit initialization of struct i2c_device_id::driver_data to 0
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>, "Herbert Xu" <herbert@gondor.apana.org.au>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720154813.2319486-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+[ Upstream commit d86ad3911a5d4549297ed810ee450e5772fd665f ]
+
+These drivers don't use the driver_data member of struct i2c_device_id,
+so don't explicitly initialize this member.
+
+This prepares putting driver_data in an anonymous union which requires
+either no initialization or named designators. But it's also a nice
+cleanup on its own.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ea5e57cc9718 ("crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-ecc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/atmel-ecc.c
++++ b/drivers/crypto/atmel-ecc.c
+@@ -387,7 +387,7 @@ MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids
+ #endif
+
+ static const struct i2c_device_id atmel_ecc_id[] = {
+- { "atecc508a", 0 },
++ { "atecc508a" },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, atmel_ecc_id);
--- /dev/null
+From stable+bounces-278070-greg=kroah.com@vger.kernel.org Mon Jul 20 17:48:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:48:13 -0400
+Subject: crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Ard Biesheuvel <ardb@kernel.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720154813.2319486-3-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit ea5e57cc97185329dcc5ebdcaae7e1500bf0ad0b ]
+
+Commit 8006aff15516 ("crypto: atmel-sha204a - Set hwrng quality to
+lowest possible") reduced the hwrng quality to 1 based on a review by
+Bill Cox [1]. However, despite its title, the review only tested the
+ATSHA204, not the ATSHA204A.
+
+In the same thread, Atmel engineer Landon Cox wrote "this behavior has
+been eliminated entirely"[2] in the ATSHA204A and "this problem does not
+affect the ATECC108 or the ATECC108A (or the ATSHA204A)"[3].
+
+According to the official ATSHA204A datasheet [4], the device contains a
+high-quality hardware RNG that combines its output with an internal seed
+value stored in EEPROM or SRAM to generate random numbers. The device
+also implements all security functions using SHA-256, and the driver
+uses the chip's Random command in seed-update mode.
+
+Keep 'quality = 1' for ATSHA204, but drop the explicit hwrng quality
+reduction for ATSHA204A and fall back to the hwrng core default.
+
+[1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
+[2] https://www.metzdowd.com/pipermail/cryptography/2014-December/023852.html
+[3] https://www.metzdowd.com/pipermail/cryptography/2014-December/023886.html
+[4] https://ww1.microchip.com/downloads/en/DeviceDoc/ATSHA204A-Data-Sheet-40002025A.pdf
+
+Fixes: 8006aff15516 ("crypto: atmel-sha204a - Set hwrng quality to lowest possible")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-sha204a.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/crypto/atmel-sha204a.c
++++ b/drivers/crypto/atmel-sha204a.c
+@@ -18,6 +18,12 @@
+ #include <linux/workqueue.h>
+ #include "atmel-i2c.h"
+
++/*
++ * According to review by Bill Cox [1], the ATSHA204 has very low entropy.
++ * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
++ */
++static const unsigned short atsha204_quality = 1;
++
+ static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
+ void *areq, int status)
+ {
+@@ -96,6 +102,7 @@ static int atmel_sha204a_probe(struct i2
+ const struct i2c_device_id *id)
+ {
+ struct atmel_i2c_client_priv *i2c_priv;
++ const unsigned short *quality;
+ int ret;
+
+ ret = atmel_i2c_probe(client, id);
+@@ -109,11 +116,9 @@ static int atmel_sha204a_probe(struct i2
+ i2c_priv->hwrng.name = dev_name(&client->dev);
+ i2c_priv->hwrng.read = atmel_sha204a_rng_read;
+
+- /*
+- * According to review by Bill Cox [1], this HWRNG has very low entropy.
+- * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
+- */
+- i2c_priv->hwrng.quality = 1;
++ quality = i2c_get_match_data(client);
++ if (quality)
++ i2c_priv->hwrng.quality = *quality;
+
+ ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng);
+ if (ret)
+@@ -138,14 +143,14 @@ static int atmel_sha204a_remove(struct i
+ }
+
+ static const struct of_device_id atmel_sha204a_dt_ids[] __maybe_unused = {
+- { .compatible = "atmel,atsha204", },
++ { .compatible = "atmel,atsha204", .data = &atsha204_quality },
+ { .compatible = "atmel,atsha204a", },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, atmel_sha204a_dt_ids);
+
+ static const struct i2c_device_id atmel_sha204a_id[] = {
+- { "atsha204" },
++ { "atsha204", (kernel_ulong_t)&atsha204_quality },
+ { "atsha204a" },
+ { /* sentinel */ }
+ };
--- /dev/null
+From stable+bounces-278068-greg=kroah.com@vger.kernel.org Mon Jul 20 18:03:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:48:11 -0400
+Subject: crypto: atmel-sha204a - Mark OF related data as maybe unused
+To: stable@vger.kernel.org
+Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720154813.2319486-1-sashal@kernel.org>
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 75f3d950054389e2556277e42170e37dd97cd872 ]
+
+The driver can be compile tested with !CONFIG_OF making certain data
+unused:
+
+ drivers/crypto/atmel-sha204a.c:129:34: error: ‘atmel_sha204a_dt_ids’ defined but not used [-Werror=unused-const-variable=]
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ea5e57cc9718 ("crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-sha204a.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/atmel-sha204a.c
++++ b/drivers/crypto/atmel-sha204a.c
+@@ -137,14 +137,16 @@ static int atmel_sha204a_remove(struct i
+ return 0;
+ }
+
+-static const struct of_device_id atmel_sha204a_dt_ids[] = {
++static const struct of_device_id atmel_sha204a_dt_ids[] __maybe_unused = {
++ { .compatible = "atmel,atsha204", },
+ { .compatible = "atmel,atsha204a", },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, atmel_sha204a_dt_ids);
+
+ static const struct i2c_device_id atmel_sha204a_id[] = {
+- { "atsha204a", 0 },
++ { "atsha204" },
++ { "atsha204a" },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(i2c, atmel_sha204a_id);
--- /dev/null
+From stable+bounces-278234-greg=kroah.com@vger.kernel.org Mon Jul 20 22:46:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 16:44:29 -0400
+Subject: crypto: qat - fix restarting state leak on allocation failure
+To: stable@vger.kernel.org
+Cc: Ahsan Atta <ahsan.atta@intel.com>, Maksim Lukoshkov <maksim.lukoshkov@intel.com>, Giovanni Cabiddu <giovanni.cabiddu@intel.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720204429.3338926-1-sashal@kernel.org>
+
+From: Ahsan Atta <ahsan.atta@intel.com>
+
+[ Upstream commit 7d3ed20f7e46b3e991936fedd7a28f3ff4aec8d2 ]
+
+In adf_dev_aer_schedule_reset(), ADF_STATUS_RESTARTING is set before
+allocating reset_data. If the allocation fails, the function returns
+-ENOMEM without queuing reset work, so nothing ever clears the bit.
+This leaves the device permanently stuck in the restarting state,
+causing all subsequent reset attempts to be silently skipped.
+
+Fix this by using test_and_set_bit() to atomically claim the
+RESTARTING state, preventing duplicate reset scheduling races under
+concurrent fatal error reporting. If the subsequent allocation fails,
+clear the bit to restore clean state so future reset attempts can
+proceed.
+
+Cc: stable@vger.kernel.org
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
+Co-developed-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
+Signed-off-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/qat/qat_common/adf_aer.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/crypto/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/qat/qat_common/adf_aer.c
+@@ -116,13 +116,14 @@ static int adf_dev_aer_schedule_reset(st
+ struct adf_reset_dev_data *reset_data;
+
+ if (!adf_dev_started(accel_dev) ||
+- test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
++ test_and_set_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
+ return 0;
+
+- set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+ reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
+- if (!reset_data)
++ if (!reset_data) {
++ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+ return -ENOMEM;
++ }
+ reset_data->accel_dev = accel_dev;
+ init_completion(&reset_data->compl);
+ reset_data->mode = mode;
--- /dev/null
+From stable+bounces-274890-greg=kroah.com@vger.kernel.org Wed Jul 15 13:15:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 07:15:23 -0400
+Subject: crypto: qat - fix VF2PF work teardown race in adf_disable_sriov()
+To: stable@vger.kernel.org
+Cc: Giovanni Cabiddu <giovanni.cabiddu@intel.com>, Ahsan Atta <ahsan.atta@intel.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715111523.644545-1-sashal@kernel.org>
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit 277281c10c63791067d24d421f7c43a15faa9096 ]
+
+The VF2PF interrupt handler queues PF-side response work that stores a
+raw pointer to per-VF state (struct adf_accel_vf_info). Currently,
+adf_disable_sriov() destroys per-VF mutexes and frees vf_info without
+stopping new VF2PF work or waiting for in-flight workers to complete. A
+concurrently scheduled or already queued worker can then dereference
+freed memory.
+
+This manifests as a use-after-free when KASAN is enabled:
+
+ BUG: KASAN: null-ptr-deref in mutex_lock+0x76/0xe0
+ Write of size 8 at addr 0000000000000260 by task kworker/24:2/...
+ Workqueue: qat_pf2vf_resp_wq adf_iov_send_resp [intel_qat]
+ Call Trace:
+ kasan_report+0x119/0x140
+ mutex_lock+0x76/0xe0
+ adf_gen4_pfvf_send+0xd4/0x1f0 [intel_qat]
+ adf_recv_and_handle_vf2pf_msg+0x290/0x360 [intel_qat]
+ adf_iov_send_resp+0x8c/0xe0 [intel_qat]
+ process_one_work+0x6ac/0xfd0
+ worker_thread+0x4dd/0xd30
+ kthread+0x326/0x410
+ ret_from_fork+0x33b/0x670
+
+Add a PF-local flag, vf2pf_disabled, that gates work queueing, worker
+processing, and interrupt re-enabling during teardown. Set this flag
+atomically with the hardware interrupt mask inside
+adf_disable_all_vf2pf_interrupts(). After masking, synchronize the AE
+cluster MSI-X interrupt and flush the PF response workqueue before
+tearing down per-VF locks and state so all in-flight work completes
+before vf_info is destroyed.
+
+Introduce adf_enable_all_vf2pf_interrupts() to clear the flag and
+unmask all VF2PF interrupts under the same lock when SR-IOV is
+re-enabled. This ensures the software flag and hardware state transition
+atomically on both the enable and disable paths.
+
+Cc: stable@vger.kernel.org
+Fixes: ed8ccaef52fa ("crypto: qat - Add support for SRIOV")
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/qat/qat_common/adf_accel_devices.h | 2 +
+ drivers/crypto/qat/qat_common/adf_common_drv.h | 4 ++
+ drivers/crypto/qat/qat_common/adf_isr.c | 18 ++++++++++
+ drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 22 ++++++++++++
+ drivers/crypto/qat/qat_common/adf_sriov.c | 38 +++++++++++++++++-----
+ 5 files changed, 76 insertions(+), 8 deletions(-)
+
+--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
++++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
+@@ -191,6 +191,8 @@ struct adf_accel_dev {
+ struct adf_accel_pci accel_pci_dev;
+ union {
+ struct {
++ /* prevents VF2PF handling from racing with VF state teardown */
++ bool vf2pf_disabled;
+ /* vf_info is non-zero when SR-IOV is init'ed */
+ struct adf_accel_vf_info *vf_info;
+ } pf;
+--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
++++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
+@@ -125,6 +125,7 @@ void qat_asym_algs_unregister(void);
+
+ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+ void adf_isr_resource_free(struct adf_accel_dev *accel_dev);
++void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev);
+ int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev);
+
+@@ -189,6 +190,9 @@ void adf_disable_vf2pf_interrupts(struct
+ u32 vf_mask);
+ void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
+ u32 vf_mask);
++void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
++ u32 num_vfs);
++void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev);
+ void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
+ void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
+
+--- a/drivers/crypto/qat/qat_common/adf_isr.c
++++ b/drivers/crypto/qat/qat_common/adf_isr.c
+@@ -117,6 +117,24 @@ static irqreturn_t adf_msix_isr_ae(int i
+ return IRQ_NONE;
+ }
+
++void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev)
++{
++ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
++ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
++ struct msix_entry *msixe = pci_dev_info->msix_entries.entries;
++ u32 num_entries = pci_dev_info->msix_entries.num_entries;
++ u32 irq_idx;
++
++ if (!test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status) || !msixe)
++ return;
++
++ irq_idx = num_entries > 1 ? hw_data->num_banks : 0;
++ if (irq_idx >= num_entries)
++ return;
++
++ synchronize_irq(msixe[irq_idx].vector);
++}
++
+ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
+ {
+ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+--- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
++++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
+@@ -40,6 +40,9 @@ void adf_enable_vf2pf_interrupts(struct
+ void __iomem *pmisc_addr = pmisc->virt_addr;
+ u32 reg;
+
++ if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++ return;
++
+ /* Enable VF2PF Messaging Ints - VFs 1 through 16 per vf_mask[15:0] */
+ if (vf_mask & 0xFFFF) {
+ reg = ADF_CSR_RD(pmisc_addr, ADF_DH895XCC_ERRMSK3);
+@@ -55,6 +58,19 @@ void adf_enable_vf2pf_interrupts(struct
+ }
+ }
+
++void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
++ u32 num_vfs)
++{
++ u32 vf_mask;
++
++ vf_mask = BIT_ULL(num_vfs) - 1;
++ if (!vf_mask)
++ return;
++
++ WRITE_ONCE(accel_dev->pf.vf2pf_disabled, false);
++ adf_enable_vf2pf_interrupts(accel_dev, vf_mask);
++}
++
+ void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask)
+ {
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+@@ -78,6 +94,12 @@ void adf_disable_vf2pf_interrupts(struct
+ }
+ }
+
++void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev)
++{
++ WRITE_ONCE(accel_dev->pf.vf2pf_disabled, true);
++ adf_disable_vf2pf_interrupts(accel_dev, GENMASK(31, 0));
++}
++
+ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr)
+ {
+ struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
+--- a/drivers/crypto/qat/qat_common/adf_sriov.c
++++ b/drivers/crypto/qat/qat_common/adf_sriov.c
+@@ -44,16 +44,27 @@ static void adf_iov_send_resp(struct wor
+ {
+ struct adf_pf2vf_resp *pf2vf_resp =
+ container_of(work, struct adf_pf2vf_resp, pf2vf_resp_work);
++ struct adf_accel_vf_info *vf_info = pf2vf_resp->vf_info;
++ struct adf_accel_dev *accel_dev = vf_info->accel_dev;
+
+- adf_vf2pf_req_hndl(pf2vf_resp->vf_info);
++ if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++ goto out;
++
++ adf_vf2pf_req_hndl(vf_info);
++
++out:
+ kfree(pf2vf_resp);
+ }
+
+ static void adf_vf2pf_bh_handler(void *data)
+ {
+ struct adf_accel_vf_info *vf_info = (struct adf_accel_vf_info *)data;
++ struct adf_accel_dev *accel_dev = vf_info->accel_dev;
+ struct adf_pf2vf_resp *pf2vf_resp;
+
++ if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++ return;
++
+ pf2vf_resp = kzalloc(sizeof(*pf2vf_resp), GFP_ATOMIC);
+ if (!pf2vf_resp)
+ return;
+@@ -63,6 +74,12 @@ static void adf_vf2pf_bh_handler(void *d
+ queue_work(pf2vf_resp_wq, &pf2vf_resp->pf2vf_resp_work);
+ }
+
++static void adf_flush_pf2vf_resp_wq(void)
++{
++ if (pf2vf_resp_wq)
++ flush_workqueue(pf2vf_resp_wq);
++}
++
+ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)
+ {
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+@@ -105,7 +122,7 @@ static int adf_enable_sriov(struct adf_a
+ }
+
+ /* Enable VF to PF interrupts for all VFs */
+- adf_enable_vf2pf_interrupts(accel_dev, GENMASK_ULL(totalvfs - 1, 0));
++ adf_enable_all_vf2pf_interrupts(accel_dev, totalvfs);
+
+ /*
+ * Due to the hardware design, when SR-IOV and the ring arbiter
+@@ -142,8 +159,16 @@ void adf_disable_sriov(struct adf_accel_
+
+ pci_disable_sriov(accel_to_pci_dev(accel_dev));
+
+- /* Disable VF to PF interrupts */
+- adf_disable_vf2pf_interrupts(accel_dev, 0xFFFFFFFF);
++ /* Block VF2PF work and disable VF to PF interrupts */
++ adf_disable_all_vf2pf_interrupts(accel_dev);
++ adf_isr_sync_ae_cluster(accel_dev);
++
++ for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++) {
++ tasklet_disable(&vf->vf2pf_bh_tasklet);
++ tasklet_kill(&vf->vf2pf_bh_tasklet);
++ }
++
++ adf_flush_pf2vf_resp_wq();
+
+ /* Clear Valid bits in ME Thread to PCIe Function Mapping Group A */
+ for (i = 0; i < ME2FUNCTION_MAP_A_NUM_REGS; i++) {
+@@ -159,11 +184,8 @@ void adf_disable_sriov(struct adf_accel_
+ WRITE_CSR_ME2FUNCTION_MAP_B(pmisc_addr, i, reg);
+ }
+
+- for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++) {
+- tasklet_disable(&vf->vf2pf_bh_tasklet);
+- tasklet_kill(&vf->vf2pf_bh_tasklet);
++ for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++)
+ mutex_destroy(&vf->pf2vf_lock);
+- }
+
+ kfree(accel_dev->pf.vf_info);
+ accel_dev->pf.vf_info = NULL;
--- /dev/null
+From stable+bounces-278317-greg=kroah.com@vger.kernel.org Tue Jul 21 03:28:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 21:27:55 -0400
+Subject: crypto: qat - validate RSA CRT component lengths
+To: stable@vger.kernel.org
+Cc: Giovanni Cabiddu <giovanni.cabiddu@intel.com>, Ahsan Atta <ahsan.atta@intel.com>, Laurent M Coquerel <laurent.m.coquerel@intel.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721012755.3458522-1-sashal@kernel.org>
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit b3ac78756588059729b9195fcc9f4b37d54057a5 ]
+
+The generic RSA key parser (rsa_helper.c) bounds each CRT component (p,
+q, dp, dq, qinv) by the modulus size n_sz, but qat_rsa_setkey_crt()
+allocates half-size DMA buffers (key_sz / 2) and right-aligns each
+component with:
+
+ memcpy(dst + half_key_sz - len, src, len)
+
+When a CRT component is larger than half_key_sz the subtraction
+underflows and memcpy writes past the DMA buffer, causing memory
+corruption.
+
+Add a len > half_key_sz check next to the existing !len check for each
+of the five CRT components so the driver falls back to the non-CRT path
+instead of writing out of bounds.
+
+Fixes: 879f77e9071f ("crypto: qat - Add RSA CRT mode")
+Cc: stable@vger.kernel.org
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
+Reviewed-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
+Tested-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/qat/qat_common/qat_asym_algs.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -1030,7 +1030,7 @@ static void qat_rsa_setkey_crt(struct qa
+ ptr = rsa_key->p;
+ len = rsa_key->p_sz;
+ qat_rsa_drop_leading_zeros(&ptr, &len);
+- if (!len)
++ if (!len || len > half_key_sz)
+ goto err;
+ ctx->p = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_p, GFP_KERNEL);
+ if (!ctx->p)
+@@ -1041,7 +1041,7 @@ static void qat_rsa_setkey_crt(struct qa
+ ptr = rsa_key->q;
+ len = rsa_key->q_sz;
+ qat_rsa_drop_leading_zeros(&ptr, &len);
+- if (!len)
++ if (!len || len > half_key_sz)
+ goto free_p;
+ ctx->q = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_q, GFP_KERNEL);
+ if (!ctx->q)
+@@ -1052,7 +1052,7 @@ static void qat_rsa_setkey_crt(struct qa
+ ptr = rsa_key->dp;
+ len = rsa_key->dp_sz;
+ qat_rsa_drop_leading_zeros(&ptr, &len);
+- if (!len)
++ if (!len || len > half_key_sz)
+ goto free_q;
+ ctx->dp = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_dp,
+ GFP_KERNEL);
+@@ -1064,7 +1064,7 @@ static void qat_rsa_setkey_crt(struct qa
+ ptr = rsa_key->dq;
+ len = rsa_key->dq_sz;
+ qat_rsa_drop_leading_zeros(&ptr, &len);
+- if (!len)
++ if (!len || len > half_key_sz)
+ goto free_dp;
+ ctx->dq = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_dq,
+ GFP_KERNEL);
+@@ -1076,7 +1076,7 @@ static void qat_rsa_setkey_crt(struct qa
+ ptr = rsa_key->qinv;
+ len = rsa_key->qinv_sz;
+ qat_rsa_drop_leading_zeros(&ptr, &len);
+- if (!len)
++ if (!len || len > half_key_sz)
+ goto free_dq;
+ ctx->qinv = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_qinv,
+ GFP_KERNEL);
--- /dev/null
+From stable+bounces-277535-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:35 -0400
+Subject: drm/i2c/sil164: Drop no-op remove function
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit eb09882d64807c24228ed1d005dbbae70860ca3f ]
+
+A remove callback that just returns 0 is equivalent to no callback at all
+as can be seen in i2c_device_remove(). So simplify accordingly.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i2c/sil164_drv.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/drivers/gpu/drm/i2c/sil164_drv.c
++++ b/drivers/gpu/drm/i2c/sil164_drv.c
+@@ -370,12 +370,6 @@ sil164_probe(struct i2c_client *client,
+ return 0;
+ }
+
+-static int
+-sil164_remove(struct i2c_client *client)
+-{
+- return 0;
+-}
+-
+ static struct i2c_client *
+ sil164_detect_slave(struct i2c_client *client)
+ {
+@@ -427,7 +421,6 @@ MODULE_DEVICE_TABLE(i2c, sil164_ids);
+ static struct drm_i2c_encoder_driver sil164_driver = {
+ .i2c_driver = {
+ .probe = sil164_probe,
+- .remove = sil164_remove,
+ .driver = {
+ .name = "sil164",
+ },
--- /dev/null
+From stable+bounces-277538-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:38 -0400
+Subject: gpio: pca953x: Make platform teardown callback return void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Andy Shevchenko" <andy.shevchenko@gmail.com>, "Bartosz Golaszewski" <brgl@bgdev.pl>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-4-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 6a8f359c3132e4f51bdb263ad74ec632c65e55fd ]
+
+All platforms that provide a teardown callback return 0. New users are
+supposed to not make use of platform support, so there is no
+functionality lost.
+
+This patch is a preparation for making i2c remove callbacks return void.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-davinci/board-da850-evm.c | 12 ++++--------
+ drivers/gpio/gpio-pca953x.c | 11 +++--------
+ include/linux/platform_data/pca953x.h | 2 +-
+ 3 files changed, 8 insertions(+), 17 deletions(-)
+
+--- a/arch/arm/mach-davinci/board-da850-evm.c
++++ b/arch/arm/mach-davinci/board-da850-evm.c
+@@ -519,8 +519,8 @@ exp_setup_sela_fail:
+ return ret;
+ }
+
+-static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+- unsigned gpio, unsigned ngpio, void *c)
++static void da850_evm_ui_expander_teardown(struct i2c_client *client,
++ unsigned gpio, unsigned ngpio, void *c)
+ {
+ platform_device_unregister(&da850_evm_ui_keys_device);
+
+@@ -532,8 +532,6 @@ static int da850_evm_ui_expander_teardow
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
+-
+- return 0;
+ }
+
+ /* assign the baseboard expander's GPIOs after the UI board's */
+@@ -700,13 +698,11 @@ io_exp_setup_sw_fail:
+ return ret;
+ }
+
+-static int da850_evm_bb_expander_teardown(struct i2c_client *client,
+- unsigned gpio, unsigned ngpio, void *c)
++static void da850_evm_bb_expander_teardown(struct i2c_client *client,
++ unsigned gpio, unsigned ngpio, void *c)
+ {
+ platform_device_unregister(&da850_evm_bb_leds_device);
+ platform_device_unregister(&da850_evm_bb_keys_device);
+-
+- return 0;
+ }
+
+ static struct pca953x_platform_data da850_evm_ui_expander_info = {
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -1073,20 +1073,15 @@ static int pca953x_remove(struct i2c_cli
+ {
+ struct pca953x_platform_data *pdata = dev_get_platdata(&client->dev);
+ struct pca953x_chip *chip = i2c_get_clientdata(client);
+- int ret;
+
+ if (pdata && pdata->teardown) {
+- ret = pdata->teardown(client, chip->gpio_chip.base,
+- chip->gpio_chip.ngpio, pdata->context);
+- if (ret < 0)
+- dev_err(&client->dev, "teardown failed, %d\n", ret);
+- } else {
+- ret = 0;
++ pdata->teardown(client, chip->gpio_chip.base,
++ chip->gpio_chip.ngpio, pdata->context);
+ }
+
+ regulator_disable(chip->regulator);
+
+- return ret;
++ return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+--- a/include/linux/platform_data/pca953x.h
++++ b/include/linux/platform_data/pca953x.h
+@@ -22,7 +22,7 @@ struct pca953x_platform_data {
+ int (*setup)(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio,
+ void *context);
+- int (*teardown)(struct i2c_client *client,
++ void (*teardown)(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio,
+ void *context);
+ const char *const *names;
--- /dev/null
+From stable+bounces-277336-greg=kroah.com@vger.kernel.org Sat Jul 18 17:13:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 11:12:56 -0400
+Subject: hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length
+To: stable@vger.kernel.org
+Cc: Tristan Madani <tristan@talencesecurity.com>, syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com, syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com, Viacheslav Dubeyko <slava@dubeyko.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718151256.3269669-2-sashal@kernel.org>
+
+From: Tristan Madani <tristan@talencesecurity.com>
+
+[ Upstream commit 966cb76fb2857a4242cab6ea2ea17acf818a3da7 ]
+
+check_and_correct_requested_length() compares (off + len) against
+node_size using u32 arithmetic. When the caller passes a large len
+value (e.g. from an underflowed subtraction in hfs_brec_remove()),
+off + len can wrap past 2^32 and produce a small result, causing the
+bounds check to pass when it should fail.
+
+For example, with off=14 and len=0xFFFFFFF2 (underflowed from
+data_off - keyoffset - size in hfs_brec_remove), off + len wraps to 6,
+which is less than a typical node_size of 512, so the check passes and
+the subsequent memmove reads ~4GB past the node buffer.
+
+Fix this by widening the addition to u64 before comparing against
+node_size. This prevents the u32 wrap while keeping the logic
+straightforward.
+
+Reported-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6df204b70bf3261691c5
+Tested-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
+Reported-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e76bf3d19b85350571ac
+Tested-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
+Fixes: a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Link: https://lore.kernel.org/r/20260505111300.3592757-2-tristmd@gmail.com
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfs/bnode.c | 2 +-
+ fs/hfsplus/hfsplus_fs.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/hfs/bnode.c
++++ b/fs/hfs/bnode.c
+@@ -41,7 +41,7 @@ u32 check_and_correct_requested_length(s
+
+ node_size = node->tree->node_size;
+
+- if ((off + len) > node_size) {
++ if ((u64)off + len > node_size) {
+ u32 new_len = node_size - off;
+
+ pr_err("requested length has been corrected: "
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -614,7 +614,7 @@ u32 check_and_correct_requested_length(s
+
+ node_size = node->tree->node_size;
+
+- if ((off + len) > node_size) {
++ if ((u64)off + len > node_size) {
+ u32 new_len = node_size - off;
+
+ pr_err("requested length has been corrected: "
--- /dev/null
+From stable+bounces-277337-greg=kroah.com@vger.kernel.org Sat Jul 18 17:13:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 11:12:55 -0400
+Subject: hfs/hfsplus: prevent getting negative values of offset/length
+To: stable@vger.kernel.org
+Cc: Viacheslav Dubeyko <slava@dubeyko.com>, John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>, Yangtao Li <frank.li@vivo.com>, linux-fsdevel@vger.kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718151256.3269669-1-sashal@kernel.org>
+
+From: Viacheslav Dubeyko <slava@dubeyko.com>
+
+[ Upstream commit 00c14a09a70e10ae18eb3707d0059291425c04bd ]
+
+The syzbot reported KASAN out-of-bounds issue in
+hfs_bnode_move():
+
+[ 45.588165][ T9821] hfs: dst 14, src 65536, len -65536
+[ 45.588895][ T9821] ==================================================================
+[ 45.590114][ T9821] BUG: KASAN: out-of-bounds in hfs_bnode_move+0xfd/0x140
+[ 45.591127][ T9821] Read of size 18446744073709486080 at addr ffff888035935400 by task repro/9821
+[ 45.592207][ T9821]
+[ 45.592420][ T9821] CPU: 0 UID: 0 PID: 9821 Comm: repro Not tainted 6.16.0-rc7-dirty #42 PREEMPT(full)
+[ 45.592428][ T9821] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 45.592431][ T9821] Call Trace:
+[ 45.592434][ T9821] <TASK>
+[ 45.592437][ T9821] dump_stack_lvl+0x1c1/0x2a0
+[ 45.592446][ T9821] ? __virt_addr_valid+0x1c8/0x5c0
+[ 45.592454][ T9821] ? __pfx_dump_stack_lvl+0x10/0x10
+[ 45.592461][ T9821] ? rcu_is_watching+0x15/0xb0
+[ 45.592469][ T9821] ? lock_release+0x4b/0x3e0
+[ 45.592476][ T9821] ? __virt_addr_valid+0x1c8/0x5c0
+[ 45.592483][ T9821] ? __virt_addr_valid+0x4a5/0x5c0
+[ 45.592491][ T9821] print_report+0x17e/0x7c0
+[ 45.592497][ T9821] ? __virt_addr_valid+0x1c8/0x5c0
+[ 45.592504][ T9821] ? __virt_addr_valid+0x4a5/0x5c0
+[ 45.592511][ T9821] ? __phys_addr+0xd3/0x180
+[ 45.592519][ T9821] ? hfs_bnode_move+0xfd/0x140
+[ 45.592526][ T9821] kasan_report+0x147/0x180
+[ 45.592531][ T9821] ? _printk+0xcf/0x120
+[ 45.592537][ T9821] ? hfs_bnode_move+0xfd/0x140
+[ 45.592544][ T9821] ? hfs_bnode_move+0xfd/0x140
+[ 45.592552][ T9821] kasan_check_range+0x2b0/0x2c0
+[ 45.592557][ T9821] ? hfs_bnode_move+0xfd/0x140
+[ 45.592565][ T9821] __asan_memmove+0x29/0x70
+[ 45.592572][ T9821] hfs_bnode_move+0xfd/0x140
+[ 45.592580][ T9821] hfs_brec_remove+0x473/0x560
+[ 45.592589][ T9821] hfs_cat_move+0x6fb/0x960
+[ 45.592598][ T9821] ? __pfx_hfs_cat_move+0x10/0x10
+[ 45.592607][ T9821] ? seqcount_lockdep_reader_access+0x122/0x1c0
+[ 45.592614][ T9821] ? lockdep_hardirqs_on+0x9c/0x150
+[ 45.592631][ T9821] ? __lock_acquire+0xaec/0xd80
+[ 45.592641][ T9821] hfs_rename+0x1dc/0x2d0
+[ 45.592649][ T9821] ? __pfx_hfs_rename+0x10/0x10
+[ 45.592657][ T9821] vfs_rename+0xac6/0xed0
+[ 45.592664][ T9821] ? __pfx_vfs_rename+0x10/0x10
+[ 45.592670][ T9821] ? d_alloc+0x144/0x190
+[ 45.592677][ T9821] ? bpf_lsm_path_rename+0x9/0x20
+[ 45.592683][ T9821] ? security_path_rename+0x17d/0x490
+[ 45.592691][ T9821] do_renameat2+0x890/0xc50
+[ 45.592699][ T9821] ? __pfx_do_renameat2+0x10/0x10
+[ 45.592707][ T9821] ? getname_flags+0x1e5/0x540
+[ 45.592714][ T9821] __x64_sys_rename+0x82/0x90
+[ 45.592720][ T9821] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[ 45.592725][ T9821] do_syscall_64+0xf3/0x3a0
+[ 45.592741][ T9821] ? exc_page_fault+0x9f/0xf0
+[ 45.592748][ T9821] entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[ 45.592754][ T9821] RIP: 0033:0x7f7f73fe3fc9
+[ 45.592760][ T9821] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 48
+[ 45.592765][ T9821] RSP: 002b:00007ffc7e116cf8 EFLAGS: 00000283 ORIG_RAX: 0000000000000052
+[ 45.592772][ T9821] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7f73fe3fc9
+[ 45.592776][ T9821] RDX: 0000200000000871 RSI: 0000200000000780 RDI: 00002000000003c0
+[ 45.592781][ T9821] RBP: 00007ffc7e116d00 R08: 0000000000000000 R09: 00007ffc7e116d30
+[ 45.592784][ T9821] R10: fffffffffffffff0 R11: 0000000000000283 R12: 00005557e81f8250
+[ 45.592788][ T9821] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+[ 45.592795][ T9821] </TASK>
+[ 45.592797][ T9821]
+[ 45.619721][ T9821] The buggy address belongs to the physical page:
+[ 45.620300][ T9821] page: refcount:1 mapcount:1 mapping:0000000000000000 index:0x559a88174 pfn:0x35935
+[ 45.621150][ T9821] memcg:ffff88810a1d5b00
+[ 45.621531][ T9821] anon flags: 0xfff60000020838(uptodate|dirty|lru|owner_2|swapbacked|node=0|zone=1|lastcpupid=0x7ff)
+[ 45.622496][ T9821] raw: 00fff60000020838 ffffea0000d64d88 ffff888021753e10 ffff888029da0771
+[ 45.623260][ T9821] raw: 0000000559a88174 0000000000000000 0000000100000000 ffff88810a1d5b00
+[ 45.624030][ T9821] page dumped because: kasan: bad access detected
+[ 45.624602][ T9821] page_owner tracks the page as allocated
+[ 45.625115][ T9821] page last allocated via order 0, migratetype Movable, gfp_mask 0x140dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO0
+[ 45.626685][ T9821] post_alloc_hook+0x240/0x2a0
+[ 45.627127][ T9821] get_page_from_freelist+0x2101/0x21e0
+[ 45.627628][ T9821] __alloc_frozen_pages_noprof+0x274/0x380
+[ 45.628154][ T9821] alloc_pages_mpol+0x241/0x4b0
+[ 45.628593][ T9821] vma_alloc_folio_noprof+0xe4/0x210
+[ 45.629066][ T9821] folio_prealloc+0x30/0x180
+[ 45.629487][ T9821] __handle_mm_fault+0x34bd/0x5640
+[ 45.629957][ T9821] handle_mm_fault+0x40e/0x8e0
+[ 45.630392][ T9821] do_user_addr_fault+0xa81/0x1390
+[ 45.630862][ T9821] exc_page_fault+0x76/0xf0
+[ 45.631273][ T9821] asm_exc_page_fault+0x26/0x30
+[ 45.631712][ T9821] page last free pid 5269 tgid 5269 stack trace:
+[ 45.632281][ T9821] free_unref_folios+0xc73/0x14c0
+[ 45.632740][ T9821] folios_put_refs+0x55b/0x640
+[ 45.633177][ T9821] free_pages_and_swap_cache+0x26d/0x510
+[ 45.633685][ T9821] tlb_flush_mmu+0x3a0/0x680
+[ 45.634105][ T9821] tlb_finish_mmu+0xd4/0x200
+[ 45.634525][ T9821] exit_mmap+0x44c/0xb70
+[ 45.634914][ T9821] __mmput+0x118/0x420
+[ 45.635286][ T9821] exit_mm+0x1da/0x2c0
+[ 45.635659][ T9821] do_exit+0x652/0x2330
+[ 45.636039][ T9821] do_group_exit+0x21c/0x2d0
+[ 45.636457][ T9821] __x64_sys_exit_group+0x3f/0x40
+[ 45.636915][ T9821] x64_sys_call+0x21ba/0x21c0
+[ 45.637342][ T9821] do_syscall_64+0xf3/0x3a0
+[ 45.637756][ T9821] entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[ 45.638290][ T9821] page has been migrated, last migrate reason: numa_misplaced
+[ 45.638956][ T9821]
+[ 45.639173][ T9821] Memory state around the buggy address:
+[ 45.639677][ T9821] ffff888035935300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 45.640397][ T9821] ffff888035935380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 45.641117][ T9821] >ffff888035935400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 45.641837][ T9821] ^
+[ 45.642207][ T9821] ffff888035935480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 45.642929][ T9821] ffff888035935500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 45.643650][ T9821] ==================================================================
+
+This commit [1] fixes the issue if an offset inside of b-tree node
+or length of the request is bigger than b-tree node. However,
+this fix is still not ready for negative values
+of the offset or length. Moreover, negative values of
+the offset or length doesn't make sense for b-tree's
+operations. Because we could try to access the memory address
+outside of the beginning of memory page's addresses range.
+Also, using of negative values make logic very complicated,
+unpredictable, and we could access the wrong item(s)
+in the b-tree node.
+
+This patch changes b-tree interface by means of converting
+signed integer arguments of offset and length on u32 type.
+Such conversion has goal to prevent of using negative values
+unintentionally or by mistake in b-tree operations.
+
+[1] 'commit a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")'
+
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+cc: Yangtao Li <frank.li@vivo.com>
+cc: linux-fsdevel@vger.kernel.org
+Link: https://lore.kernel.org/r/20251002200020.2578311-1-slava@dubeyko.com
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Stable-dep-of: 966cb76fb285 ("hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfs/bfind.c | 2 -
+ fs/hfs/bnode.c | 52 +++++++++++++++---------------
+ fs/hfs/brec.c | 2 -
+ fs/hfs/btree.c | 2 -
+ fs/hfs/btree.h | 71 ++++++++++++++++++++---------------------
+ fs/hfs/hfs_fs.h | 83 ++++++++++++++++++++++++++++--------------------
+ fs/hfs/inode.c | 2 -
+ fs/hfsplus/bfind.c | 2 -
+ fs/hfsplus/bnode.c | 60 +++++++++++++++++-----------------
+ fs/hfsplus/brec.c | 2 -
+ fs/hfsplus/btree.c | 2 -
+ fs/hfsplus/hfsplus_fs.h | 38 ++++++++++-----------
+ 12 files changed, 167 insertions(+), 151 deletions(-)
+
+--- a/fs/hfs/bfind.c
++++ b/fs/hfs/bfind.c
+@@ -164,7 +164,7 @@ release:
+ return res;
+ }
+
+-int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len)
++int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len)
+ {
+ int res;
+
+--- a/fs/hfs/bnode.c
++++ b/fs/hfs/bnode.c
+@@ -16,14 +16,14 @@
+ #include "btree.h"
+
+ static inline
+-bool is_bnode_offset_valid(struct hfs_bnode *node, int off)
++bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off)
+ {
+ bool is_valid = off < node->tree->node_size;
+
+ if (!is_valid) {
+ pr_err("requested invalid offset: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d\n",
++ "node_size %u, offset %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off);
+ }
+@@ -32,7 +32,7 @@ bool is_bnode_offset_valid(struct hfs_bn
+ }
+
+ static inline
+-int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len)
++u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len)
+ {
+ unsigned int node_size;
+
+@@ -42,12 +42,12 @@ int check_and_correct_requested_length(s
+ node_size = node->tree->node_size;
+
+ if ((off + len) > node_size) {
+- int new_len = (int)node_size - off;
++ u32 new_len = node_size - off;
+
+ pr_err("requested length has been corrected: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, "
+- "requested_len %d, corrected_len %d\n",
++ "node_size %u, offset %u, "
++ "requested_len %u, corrected_len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len, new_len);
+
+@@ -57,12 +57,12 @@ int check_and_correct_requested_length(s
+ return len;
+ }
+
+-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+ struct page *page;
+- int pagenum;
+- int bytes_read;
+- int bytes_to_read;
++ u32 pagenum;
++ u32 bytes_read;
++ u32 bytes_to_read;
+ void *vaddr;
+
+ memset(buf, 0, len);
+@@ -73,7 +73,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+ if (len == 0) {
+ pr_err("requested zero length: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, len %d\n",
++ "node_size %u, offset %u, len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len);
+ return;
+@@ -89,7 +89,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+ if (pagenum >= node->tree->pages_per_bnode)
+ break;
+ page = node->page[pagenum];
+- bytes_to_read = min_t(int, len - bytes_read, PAGE_SIZE - off);
++ bytes_to_read = min_t(u32, len - bytes_read, PAGE_SIZE - off);
+
+ vaddr = kmap_atomic(page);
+ memcpy(buf + bytes_read, vaddr + off, bytes_to_read);
+@@ -100,7 +100,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+ }
+ }
+
+-u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
++u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off)
+ {
+ __be16 data;
+ // optimize later...
+@@ -108,7 +108,7 @@ u16 hfs_bnode_read_u16(struct hfs_bnode
+ return be16_to_cpu(data);
+ }
+
+-u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off)
++u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off)
+ {
+ u8 data;
+ // optimize later...
+@@ -116,10 +116,10 @@ u8 hfs_bnode_read_u8(struct hfs_bnode *n
+ return data;
+ }
+
+-void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
++void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off)
+ {
+ struct hfs_btree *tree;
+- int key_len;
++ u32 key_len;
+
+ tree = node->tree;
+ if (node->type == HFS_NODE_LEAF ||
+@@ -130,14 +130,14 @@ void hfs_bnode_read_key(struct hfs_bnode
+
+ if (key_len > sizeof(hfs_btree_key) || key_len < 1) {
+ memset(key, 0, sizeof(hfs_btree_key));
+- pr_err("hfs: Invalid key length: %d\n", key_len);
++ pr_err("hfs: Invalid key length: %u\n", key_len);
+ return;
+ }
+
+ hfs_bnode_read(node, key, off, key_len);
+ }
+
+-void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+ struct page *page;
+
+@@ -147,7 +147,7 @@ void hfs_bnode_write(struct hfs_bnode *n
+ if (len == 0) {
+ pr_err("requested zero length: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, len %d\n",
++ "node_size %u, offset %u, len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len);
+ return;
+@@ -163,20 +163,20 @@ void hfs_bnode_write(struct hfs_bnode *n
+ set_page_dirty(page);
+ }
+
+-void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data)
++void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data)
+ {
+ __be16 v = cpu_to_be16(data);
+ // optimize later...
+ hfs_bnode_write(node, &v, off, 2);
+ }
+
+-void hfs_bnode_write_u8(struct hfs_bnode *node, int off, u8 data)
++void hfs_bnode_write_u8(struct hfs_bnode *node, u32 off, u8 data)
+ {
+ // optimize later...
+ hfs_bnode_write(node, &data, off, 1);
+ }
+
+-void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
++void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len)
+ {
+ struct page *page;
+
+@@ -186,7 +186,7 @@ void hfs_bnode_clear(struct hfs_bnode *n
+ if (len == 0) {
+ pr_err("requested zero length: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, len %d\n",
++ "node_size %u, offset %u, len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len);
+ return;
+@@ -202,8 +202,8 @@ void hfs_bnode_clear(struct hfs_bnode *n
+ set_page_dirty(page);
+ }
+
+-void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
+- struct hfs_bnode *src_node, int src, int len)
++void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++ struct hfs_bnode *src_node, u32 src, u32 len)
+ {
+ struct page *src_page, *dst_page;
+
+@@ -225,7 +225,7 @@ void hfs_bnode_copy(struct hfs_bnode *ds
+ set_page_dirty(dst_page);
+ }
+
+-void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
++void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len)
+ {
+ struct page *page;
+ void *ptr;
+--- a/fs/hfs/brec.c
++++ b/fs/hfs/brec.c
+@@ -62,7 +62,7 @@ u16 hfs_brec_keylen(struct hfs_bnode *no
+ return retval;
+ }
+
+-int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
++int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len)
+ {
+ struct hfs_btree *tree;
+ struct hfs_bnode *node, *new_node;
+--- a/fs/hfs/btree.c
++++ b/fs/hfs/btree.c
+@@ -221,7 +221,7 @@ static struct hfs_bnode *hfs_bmap_new_bm
+ }
+
+ /* Make sure @tree has enough space for the @rsvd_nodes */
+-int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes)
++int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes)
+ {
+ struct inode *inode = tree->inode;
+ u32 count;
+--- a/fs/hfs/btree.h
++++ b/fs/hfs/btree.h
+@@ -86,48 +86,49 @@ struct hfs_find_data {
+
+
+ /* btree.c */
+-extern struct hfs_btree *hfs_btree_open(struct super_block *, u32, btree_keycmp);
+-extern void hfs_btree_close(struct hfs_btree *);
+-extern void hfs_btree_write(struct hfs_btree *);
+-extern int hfs_bmap_reserve(struct hfs_btree *, int);
+-extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *);
++extern struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id,
++ btree_keycmp keycmp);
++extern void hfs_btree_close(struct hfs_btree *tree);
++extern void hfs_btree_write(struct hfs_btree *tree);
++extern int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes);
++extern struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree);
+ extern void hfs_bmap_free(struct hfs_bnode *node);
+
+ /* bnode.c */
+-extern void hfs_bnode_read(struct hfs_bnode *, void *, int, int);
+-extern u16 hfs_bnode_read_u16(struct hfs_bnode *, int);
+-extern u8 hfs_bnode_read_u8(struct hfs_bnode *, int);
+-extern void hfs_bnode_read_key(struct hfs_bnode *, void *, int);
+-extern void hfs_bnode_write(struct hfs_bnode *, void *, int, int);
+-extern void hfs_bnode_write_u16(struct hfs_bnode *, int, u16);
+-extern void hfs_bnode_write_u8(struct hfs_bnode *, int, u8);
+-extern void hfs_bnode_clear(struct hfs_bnode *, int, int);
+-extern void hfs_bnode_copy(struct hfs_bnode *, int,
+- struct hfs_bnode *, int, int);
+-extern void hfs_bnode_move(struct hfs_bnode *, int, int, int);
+-extern void hfs_bnode_dump(struct hfs_bnode *);
+-extern void hfs_bnode_unlink(struct hfs_bnode *);
+-extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *, u32);
+-extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *, u32);
+-extern void hfs_bnode_unhash(struct hfs_bnode *);
+-extern void hfs_bnode_free(struct hfs_bnode *);
+-extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *, u32);
+-extern void hfs_bnode_get(struct hfs_bnode *);
+-extern void hfs_bnode_put(struct hfs_bnode *);
++extern void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++extern u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off);
++extern u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off);
++extern void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off);
++extern void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++extern void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data);
++extern void hfs_bnode_write_u8(struct hfs_bnode *node, u32 off, u8 data);
++extern void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len);
++extern void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++ struct hfs_bnode *src_node, u32 src, u32 len);
++extern void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len);
++extern void hfs_bnode_dump(struct hfs_bnode *node);
++extern void hfs_bnode_unlink(struct hfs_bnode *node);
++extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid);
++extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num);
++extern void hfs_bnode_unhash(struct hfs_bnode *node);
++extern void hfs_bnode_free(struct hfs_bnode *node);
++extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num);
++extern void hfs_bnode_get(struct hfs_bnode *node);
++extern void hfs_bnode_put(struct hfs_bnode *node);
+
+ /* brec.c */
+-extern u16 hfs_brec_lenoff(struct hfs_bnode *, u16, u16 *);
+-extern u16 hfs_brec_keylen(struct hfs_bnode *, u16);
+-extern int hfs_brec_insert(struct hfs_find_data *, void *, int);
+-extern int hfs_brec_remove(struct hfs_find_data *);
++extern u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off);
++extern u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec);
++extern int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len);
++extern int hfs_brec_remove(struct hfs_find_data *fd);
+
+ /* bfind.c */
+-extern int hfs_find_init(struct hfs_btree *, struct hfs_find_data *);
+-extern void hfs_find_exit(struct hfs_find_data *);
+-extern int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *);
+-extern int hfs_brec_find(struct hfs_find_data *);
+-extern int hfs_brec_read(struct hfs_find_data *, void *, int);
+-extern int hfs_brec_goto(struct hfs_find_data *, int);
++extern int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd);
++extern void hfs_find_exit(struct hfs_find_data *fd);
++extern int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd);
++extern int hfs_brec_find(struct hfs_find_data *fd);
++extern int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len);
++extern int hfs_brec_goto(struct hfs_find_data *fd, int cnt);
+
+
+ struct hfs_bnode_desc {
+--- a/fs/hfs/hfs_fs.h
++++ b/fs/hfs/hfs_fs.h
+@@ -171,70 +171,85 @@ struct hfs_sb_info {
+ #define HFS_FLG_ALT_MDB_DIRTY 2
+
+ /* bitmap.c */
+-extern u32 hfs_vbm_search_free(struct super_block *, u32, u32 *);
+-extern int hfs_clear_vbm_bits(struct super_block *, u16, u16);
++extern u32 hfs_vbm_search_free(struct super_block *sb, u32 goal, u32 *num_bits);
++extern int hfs_clear_vbm_bits(struct super_block *sb, u16 start, u16 count);
+
+ /* catalog.c */
+-extern int hfs_cat_keycmp(const btree_key *, const btree_key *);
++extern int hfs_cat_keycmp(const btree_key *key1, const btree_key *key2);
+ struct hfs_find_data;
+-extern int hfs_cat_find_brec(struct super_block *, u32, struct hfs_find_data *);
+-extern int hfs_cat_create(u32, struct inode *, const struct qstr *, struct inode *);
+-extern int hfs_cat_delete(u32, struct inode *, const struct qstr *);
+-extern int hfs_cat_move(u32, struct inode *, const struct qstr *,
+- struct inode *, const struct qstr *);
+-extern void hfs_cat_build_key(struct super_block *, btree_key *, u32, const struct qstr *);
++extern int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
++ struct hfs_find_data *fd);
++extern int hfs_cat_create(u32 cnid, struct inode *dir,
++ const struct qstr *str, struct inode *inode);
++extern int hfs_cat_delete(u32 cnid, struct inode *dir, const struct qstr *str);
++extern int hfs_cat_move(u32 cnid, struct inode *src_dir,
++ const struct qstr *src_name,
++ struct inode *dst_dir,
++ const struct qstr *dst_name);
++extern void hfs_cat_build_key(struct super_block *sb, btree_key *key,
++ u32 parent, const struct qstr *name);
+
+ /* dir.c */
+ extern const struct file_operations hfs_dir_operations;
+ extern const struct inode_operations hfs_dir_inode_operations;
+
+ /* extent.c */
+-extern int hfs_ext_keycmp(const btree_key *, const btree_key *);
+-extern int hfs_free_fork(struct super_block *, struct hfs_cat_file *, int);
+-extern int hfs_ext_write_extent(struct inode *);
+-extern int hfs_extend_file(struct inode *);
+-extern void hfs_file_truncate(struct inode *);
++extern int hfs_ext_keycmp(const btree_key *key1, const btree_key *key2);
++extern int hfs_free_fork(struct super_block *sb,
++ struct hfs_cat_file *file, int type);
++extern int hfs_ext_write_extent(struct inode *inode);
++extern int hfs_extend_file(struct inode *inode);
++extern void hfs_file_truncate(struct inode *inode);
+
+-extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
++extern int hfs_get_block(struct inode *inode, sector_t block,
++ struct buffer_head *bh_result, int create);
+
+ /* inode.c */
+ extern const struct address_space_operations hfs_aops;
+ extern const struct address_space_operations hfs_btree_aops;
+
+-extern struct inode *hfs_new_inode(struct inode *, const struct qstr *, umode_t);
+-extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
+-extern int hfs_write_inode(struct inode *, struct writeback_control *);
+-extern int hfs_inode_setattr(struct dentry *, struct iattr *);
++extern struct inode *hfs_new_inode(struct inode *dir, const struct qstr *name,
++ umode_t mode);
++extern void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext,
++ __be32 *log_size, __be32 *phys_size);
++extern int hfs_write_inode(struct inode *inode, struct writeback_control *wbc);
++extern int hfs_inode_setattr(struct dentry *dentry, struct iattr *attr);
+ extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,
+- __be32 log_size, __be32 phys_size, u32 clump_size);
+-extern struct inode *hfs_iget(struct super_block *, struct hfs_cat_key *, hfs_cat_rec *);
+-extern void hfs_evict_inode(struct inode *);
+-extern void hfs_delete_inode(struct inode *);
++ __be32 __log_size, __be32 phys_size,
++ u32 clump_size);
++extern struct inode *hfs_iget(struct super_block *sb, struct hfs_cat_key *key,
++ hfs_cat_rec *rec);
++extern void hfs_evict_inode(struct inode *inode);
++extern void hfs_delete_inode(struct inode *inode);
+
+ /* attr.c */
+ extern const struct xattr_handler *hfs_xattr_handlers[];
+
+ /* mdb.c */
+-extern int hfs_mdb_get(struct super_block *);
+-extern void hfs_mdb_commit(struct super_block *);
+-extern void hfs_mdb_close(struct super_block *);
+-extern void hfs_mdb_put(struct super_block *);
++extern int hfs_mdb_get(struct super_block *sb);
++extern void hfs_mdb_commit(struct super_block *sb);
++extern void hfs_mdb_close(struct super_block *sb);
++extern void hfs_mdb_put(struct super_block *sb);
+
+ /* part_tbl.c */
+-extern int hfs_part_find(struct super_block *, sector_t *, sector_t *);
++extern int hfs_part_find(struct super_block *sb,
++ sector_t *part_start, sector_t *part_size);
+
+ /* string.c */
+ extern const struct dentry_operations hfs_dentry_operations;
+
+-extern int hfs_hash_dentry(const struct dentry *, struct qstr *);
+-extern int hfs_strcmp(const unsigned char *, unsigned int,
+- const unsigned char *, unsigned int);
++extern int hfs_hash_dentry(const struct dentry *dentry, struct qstr *this);
++extern int hfs_strcmp(const unsigned char *s1, unsigned int len1,
++ const unsigned char *s2, unsigned int len2);
+ extern int hfs_compare_dentry(const struct dentry *dentry,
+- unsigned int len, const char *str, const struct qstr *name);
++ unsigned int len, const char *str,
++ const struct qstr *name);
+
+ /* trans.c */
+-extern void hfs_asc2mac(struct super_block *, struct hfs_name *, const struct qstr *);
+-extern int hfs_mac2asc(struct super_block *, char *, const struct hfs_name *);
++extern void hfs_asc2mac(struct super_block *sb,
++ struct hfs_name *out, const struct qstr *in);
++extern int hfs_mac2asc(struct super_block *sb,
++ char *out, const struct hfs_name *in);
+
+ /* super.c */
+ extern void hfs_mark_mdb_dirty(struct super_block *sb);
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -50,7 +50,7 @@ static void hfs_write_failed(struct addr
+ }
+
+ static int hfs_write_begin(struct file *file, struct address_space *mapping,
+- loff_t pos, unsigned len, unsigned flags,
++ loff_t pos, unsigned int len, unsigned flags,
+ struct page **pagep, void **fsdata)
+ {
+ int ret;
+--- a/fs/hfsplus/bfind.c
++++ b/fs/hfsplus/bfind.c
+@@ -210,7 +210,7 @@ release:
+ return res;
+ }
+
+-int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len)
++int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len)
+ {
+ int res;
+
+--- a/fs/hfsplus/bnode.c
++++ b/fs/hfsplus/bnode.c
+@@ -20,10 +20,10 @@
+
+
+ /* Copy a specified range of bytes from the raw data of a node */
+-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+ struct page **pagep;
+- int l;
++ u32 l;
+
+ memset(buf, 0, len);
+
+@@ -33,7 +33,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+ if (len == 0) {
+ pr_err("requested zero length: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, len %d\n",
++ "node_size %u, offset %u, len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len);
+ return;
+@@ -45,19 +45,19 @@ void hfs_bnode_read(struct hfs_bnode *no
+ pagep = node->page + (off >> PAGE_SHIFT);
+ off &= ~PAGE_MASK;
+
+- l = min_t(int, len, PAGE_SIZE - off);
++ l = min_t(u32, len, PAGE_SIZE - off);
+ memcpy(buf, kmap(*pagep) + off, l);
+ kunmap(*pagep);
+
+ while ((len -= l) != 0) {
+ buf += l;
+- l = min_t(int, len, PAGE_SIZE);
++ l = min_t(u32, len, PAGE_SIZE);
+ memcpy(buf, kmap(*++pagep), l);
+ kunmap(*pagep);
+ }
+ }
+
+-u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
++u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off)
+ {
+ __be16 data;
+ /* TODO: optimize later... */
+@@ -65,7 +65,7 @@ u16 hfs_bnode_read_u16(struct hfs_bnode
+ return be16_to_cpu(data);
+ }
+
+-u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off)
++u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off)
+ {
+ u8 data;
+ /* TODO: optimize later... */
+@@ -73,10 +73,10 @@ u8 hfs_bnode_read_u8(struct hfs_bnode *n
+ return data;
+ }
+
+-void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
++void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off)
+ {
+ struct hfs_btree *tree;
+- int key_len;
++ u32 key_len;
+
+ tree = node->tree;
+ if (node->type == HFS_NODE_LEAF ||
+@@ -88,17 +88,17 @@ void hfs_bnode_read_key(struct hfs_bnode
+
+ if (key_len > sizeof(hfsplus_btree_key) || key_len < 1) {
+ memset(key, 0, sizeof(hfsplus_btree_key));
+- pr_err("hfsplus: Invalid key length: %d\n", key_len);
++ pr_err("hfsplus: Invalid key length: %u\n", key_len);
+ return;
+ }
+
+ hfs_bnode_read(node, key, off, key_len);
+ }
+
+-void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+ struct page **pagep;
+- int l;
++ u32 l;
+
+ if (!is_bnode_offset_valid(node, off))
+ return;
+@@ -106,7 +106,7 @@ void hfs_bnode_write(struct hfs_bnode *n
+ if (len == 0) {
+ pr_err("requested zero length: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, len %d\n",
++ "node_size %u, offset %u, len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len);
+ return;
+@@ -118,31 +118,31 @@ void hfs_bnode_write(struct hfs_bnode *n
+ pagep = node->page + (off >> PAGE_SHIFT);
+ off &= ~PAGE_MASK;
+
+- l = min_t(int, len, PAGE_SIZE - off);
++ l = min_t(u32, len, PAGE_SIZE - off);
+ memcpy(kmap(*pagep) + off, buf, l);
+ set_page_dirty(*pagep);
+ kunmap(*pagep);
+
+ while ((len -= l) != 0) {
+ buf += l;
+- l = min_t(int, len, PAGE_SIZE);
++ l = min_t(u32, len, PAGE_SIZE);
+ memcpy(kmap(*++pagep), buf, l);
+ set_page_dirty(*pagep);
+ kunmap(*pagep);
+ }
+ }
+
+-void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data)
++void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data)
+ {
+ __be16 v = cpu_to_be16(data);
+ /* TODO: optimize later... */
+ hfs_bnode_write(node, &v, off, 2);
+ }
+
+-void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
++void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len)
+ {
+ struct page **pagep;
+- int l;
++ u32 l;
+
+ if (!is_bnode_offset_valid(node, off))
+ return;
+@@ -150,7 +150,7 @@ void hfs_bnode_clear(struct hfs_bnode *n
+ if (len == 0) {
+ pr_err("requested zero length: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, len %d\n",
++ "node_size %u, offset %u, len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len);
+ return;
+@@ -162,24 +162,24 @@ void hfs_bnode_clear(struct hfs_bnode *n
+ pagep = node->page + (off >> PAGE_SHIFT);
+ off &= ~PAGE_MASK;
+
+- l = min_t(int, len, PAGE_SIZE - off);
++ l = min_t(u32, len, PAGE_SIZE - off);
+ memset(kmap(*pagep) + off, 0, l);
+ set_page_dirty(*pagep);
+ kunmap(*pagep);
+
+ while ((len -= l) != 0) {
+- l = min_t(int, len, PAGE_SIZE);
++ l = min_t(u32, len, PAGE_SIZE);
+ memset(kmap(*++pagep), 0, l);
+ set_page_dirty(*pagep);
+ kunmap(*pagep);
+ }
+ }
+
+-void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
+- struct hfs_bnode *src_node, int src, int len)
++void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++ struct hfs_bnode *src_node, u32 src, u32 len)
+ {
+ struct page **src_page, **dst_page;
+- int l;
++ u32 l;
+
+ hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len);
+ if (!len)
+@@ -196,14 +196,14 @@ void hfs_bnode_copy(struct hfs_bnode *ds
+ dst &= ~PAGE_MASK;
+
+ if (src == dst) {
+- l = min_t(int, len, PAGE_SIZE - src);
++ l = min_t(u32, len, PAGE_SIZE - src);
+ memcpy(kmap(*dst_page) + src, kmap(*src_page) + src, l);
+ kunmap(*src_page);
+ set_page_dirty(*dst_page);
+ kunmap(*dst_page);
+
+ while ((len -= l) != 0) {
+- l = min_t(int, len, PAGE_SIZE);
++ l = min_t(u32, len, PAGE_SIZE);
+ memcpy(kmap(*++dst_page), kmap(*++src_page), l);
+ kunmap(*src_page);
+ set_page_dirty(*dst_page);
+@@ -237,10 +237,10 @@ void hfs_bnode_copy(struct hfs_bnode *ds
+ }
+ }
+
+-void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
++void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len)
+ {
+ struct page **src_page, **dst_page;
+- int l;
++ u32 l;
+
+ hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len);
+ if (!len)
+@@ -309,7 +309,7 @@ void hfs_bnode_move(struct hfs_bnode *no
+ dst &= ~PAGE_MASK;
+
+ if (src == dst) {
+- l = min_t(int, len, PAGE_SIZE - src);
++ l = min_t(u32, len, PAGE_SIZE - src);
+ memmove(kmap(*dst_page) + src,
+ kmap(*src_page) + src, l);
+ kunmap(*src_page);
+@@ -317,7 +317,7 @@ void hfs_bnode_move(struct hfs_bnode *no
+ kunmap(*dst_page);
+
+ while ((len -= l) != 0) {
+- l = min_t(int, len, PAGE_SIZE);
++ l = min_t(u32, len, PAGE_SIZE);
+ memmove(kmap(*++dst_page),
+ kmap(*++src_page), l);
+ kunmap(*src_page);
+--- a/fs/hfsplus/brec.c
++++ b/fs/hfsplus/brec.c
+@@ -60,7 +60,7 @@ u16 hfs_brec_keylen(struct hfs_bnode *no
+ return retval;
+ }
+
+-int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
++int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len)
+ {
+ struct hfs_btree *tree;
+ struct hfs_bnode *node, *new_node;
+--- a/fs/hfsplus/btree.c
++++ b/fs/hfsplus/btree.c
+@@ -343,7 +343,7 @@ static struct hfs_bnode *hfs_bmap_new_bm
+ }
+
+ /* Make sure @tree has enough space for the @rsvd_nodes */
+-int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes)
++int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes)
+ {
+ struct inode *inode = tree->inode;
+ struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -399,21 +399,21 @@ u32 hfsplus_calc_btree_clump_size(u32 bl
+ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id);
+ void hfs_btree_close(struct hfs_btree *tree);
+ int hfs_btree_write(struct hfs_btree *tree);
+-int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes);
++int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes);
+ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree);
+ void hfs_bmap_free(struct hfs_bnode *node);
+
+ /* bnode.c */
+-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len);
+-u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off);
+-u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off);
+-void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off);
+-void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len);
+-void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data);
+-void hfs_bnode_clear(struct hfs_bnode *node, int off, int len);
+-void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
+- struct hfs_bnode *src_node, int src, int len);
+-void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len);
++void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off);
++u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off);
++void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off);
++void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data);
++void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len);
++void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++ struct hfs_bnode *src_node, u32 src, u32 len);
++void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len);
+ void hfs_bnode_dump(struct hfs_bnode *node);
+ void hfs_bnode_unlink(struct hfs_bnode *node);
+ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid);
+@@ -428,7 +428,7 @@ bool hfs_bnode_need_zeroout(struct hfs_b
+ /* brec.c */
+ u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off);
+ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec);
+-int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len);
++int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len);
+ int hfs_brec_remove(struct hfs_find_data *fd);
+
+ /* bfind.c */
+@@ -441,7 +441,7 @@ int hfs_find_rec_by_key(struct hfs_bnode
+ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd,
+ search_strategy_t rec_found);
+ int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare);
+-int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len);
++int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len);
+ int hfs_brec_goto(struct hfs_find_data *fd, int cnt);
+
+ /* catalog.c */
+@@ -589,14 +589,14 @@ hfsplus_btree_lock_class(struct hfs_btre
+ }
+
+ static inline
+-bool is_bnode_offset_valid(struct hfs_bnode *node, int off)
++bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off)
+ {
+ bool is_valid = off < node->tree->node_size;
+
+ if (!is_valid) {
+ pr_err("requested invalid offset: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d\n",
++ "node_size %u, offset %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off);
+ }
+@@ -605,7 +605,7 @@ bool is_bnode_offset_valid(struct hfs_bn
+ }
+
+ static inline
+-int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len)
++u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len)
+ {
+ unsigned int node_size;
+
+@@ -615,12 +615,12 @@ int check_and_correct_requested_length(s
+ node_size = node->tree->node_size;
+
+ if ((off + len) > node_size) {
+- int new_len = (int)node_size - off;
++ u32 new_len = node_size - off;
+
+ pr_err("requested length has been corrected: "
+ "NODE: id %u, type %#x, height %u, "
+- "node_size %u, offset %d, "
+- "requested_len %d, corrected_len %d\n",
++ "node_size %u, offset %u, "
++ "requested_len %u, corrected_len %u\n",
+ node->this, node->type, node->height,
+ node->tree->node_size, off, len, new_len);
+
--- /dev/null
+From stable+bounces-277172-greg=kroah.com@vger.kernel.org Fri Jul 17 20:11:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 14:11:32 -0400
+Subject: HID: add haptics page defines
+To: stable@vger.kernel.org
+Cc: Angela Czubak <aczubak@google.com>, Jonathan Denose <jdenose@google.com>, Benjamin Tissoires <bentiss@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717181133.2086215-1-sashal@kernel.org>
+
+From: Angela Czubak <aczubak@google.com>
+
+[ Upstream commit 5e0ae59159e3a07391a35865bb79ff335473fa79 ]
+
+Introduce haptic usages as defined in HID Usage Tables specification.
+Add HID units for newton and gram.
+
+Signed-off-by: Angela Czubak <aczubak@google.com>
+Co-developed-by: Jonathan Denose <jdenose@google.com>
+Signed-off-by: Jonathan Denose <jdenose@google.com>
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Stable-dep-of: 8813b0612275 ("HID: multitouch: fix out-of-bounds bit access on mt_io_flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hid.h | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -152,6 +152,7 @@ struct hid_item {
+ #define HID_UP_TELEPHONY 0x000b0000
+ #define HID_UP_CONSUMER 0x000c0000
+ #define HID_UP_DIGITIZER 0x000d0000
++#define HID_UP_HAPTIC 0x000e0000
+ #define HID_UP_PID 0x000f0000
+ #define HID_UP_HPVENDOR 0xff7f0000
+ #define HID_UP_HPVENDOR2 0xff010000
+@@ -299,6 +300,28 @@ struct hid_item {
+ #define HID_DG_TOOLSERIALNUMBER 0x000d005b
+ #define HID_DG_LATENCYMODE 0x000d0060
+
++#define HID_HP_SIMPLECONTROLLER 0x000e0001
++#define HID_HP_WAVEFORMLIST 0x000e0010
++#define HID_HP_DURATIONLIST 0x000e0011
++#define HID_HP_AUTOTRIGGER 0x000e0020
++#define HID_HP_MANUALTRIGGER 0x000e0021
++#define HID_HP_AUTOTRIGGERASSOCIATEDCONTROL 0x000e0022
++#define HID_HP_INTENSITY 0x000e0023
++#define HID_HP_REPEATCOUNT 0x000e0024
++#define HID_HP_RETRIGGERPERIOD 0x000e0025
++#define HID_HP_WAVEFORMVENDORPAGE 0x000e0026
++#define HID_HP_WAVEFORMVENDORID 0x000e0027
++#define HID_HP_WAVEFORMCUTOFFTIME 0x000e0028
++#define HID_HP_WAVEFORMNONE 0x000e1001
++#define HID_HP_WAVEFORMSTOP 0x000e1002
++#define HID_HP_WAVEFORMCLICK 0x000e1003
++#define HID_HP_WAVEFORMBUZZCONTINUOUS 0x000e1004
++#define HID_HP_WAVEFORMRUMBLECONTINUOUS 0x000e1005
++#define HID_HP_WAVEFORMPRESS 0x000e1006
++#define HID_HP_WAVEFORMRELEASE 0x000e1007
++#define HID_HP_VENDORWAVEFORMMIN 0x000e2001
++#define HID_HP_VENDORWAVEFORMMAX 0x000e2fff
++
+ #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076
+ /*
+ * HID report types --- Ouch! HID spec says 1 2 3!
+@@ -385,6 +408,12 @@ struct hid_item {
+ #define HID_BOOT_PROTOCOL 0
+
+ /*
++ * HID units
++ */
++#define HID_UNIT_GRAM 0x0101
++#define HID_UNIT_NEWTON 0xe111
++
++/*
+ * This is the global environment of the parser. This information is
+ * persistent for main-items. The global environment can be saved and
+ * restored with PUSH/POP statements.
--- /dev/null
+From stable+bounces-277229-greg=kroah.com@vger.kernel.org Sat Jul 18 02:51:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 20:51:23 -0400
+Subject: HID: appleir: fix UAF on pending key_up_timer in remove()
+To: stable@vger.kernel.org
+Cc: Manish Khadka <maskmemanish@gmail.com>, Jiri Kosina <jkosina@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718005123.2484926-1-sashal@kernel.org>
+
+From: Manish Khadka <maskmemanish@gmail.com>
+
+[ Upstream commit 75fe87e19d8aff81eb2c64d15d244ab8da4de945 ]
+
+appleir_remove() runs hid_hw_stop() before timer_delete_sync().
+hid_hw_stop() synchronously unregisters the HID input device via
+hid_disconnect() -> hidinput_disconnect() -> input_unregister_device(),
+which drops the last reference and frees the underlying input_dev when
+no userspace handle holds it open.
+
+key_up_tick() reads appleir->input_dev and calls input_report_key() /
+input_sync() on it. The timer is armed from appleir_raw_event() with
+a HZ/8 (~125 ms) timeout on every keydown and key-repeat report. If a
+key was pressed shortly before the device is disconnected, the timer
+can fire after hid_hw_stop() has freed input_dev but before the
+teardown drains it.
+
+A simple reorder is not sufficient. Putting the timer drain first
+still leaves a window where a USB URB completion (raw_event) running
+during hid_hw_stop() can call mod_timer() and re-arm the timer, which
+then fires after hidinput_disconnect() has freed input_dev. The same
+URB-completion window also lets raw_event() reach key_up(), key_down()
+and battery_flat() directly, all of which dereference
+appleir->input_dev.
+
+Introduce a 'removing' flag on struct appleir, gated by the existing
+spinlock. appleir_remove() sets the flag under the lock and then
+shuts down the timer with timer_shutdown_sync(), which both drains any
+in-flight callback and permanently disables further mod_timer() calls.
+appleir_raw_event() and key_up_tick() bail out early if the flag is
+set, so no path can arm or run the timer, or dereference
+appleir->input_dev, after remove() has started tearing down.
+
+The keyrepeat and flatbattery branches of appleir_raw_event()
+previously called into the input layer without holding the spinlock;
+take it now so the flag check is well-defined. This incidentally
+closes a pre-existing read-side race on appleir->current_key in the
+keyrepeat branch.
+
+This bug is structurally a sibling of commit 4db2af929279 ("HID:
+appletb-kbd: fix UAF in inactivity-timer cleanup path") and has been
+present since the driver was introduced.
+
+Fixes: 9a4a5574ce42 ("HID: appleir: add support for Apple ir devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Manish Khadka <maskmemanish@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-appleir.c | 45 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 35 insertions(+), 10 deletions(-)
+
+--- a/drivers/hid/hid-appleir.c
++++ b/drivers/hid/hid-appleir.c
+@@ -109,9 +109,10 @@ struct appleir {
+ struct hid_device *hid;
+ unsigned short keymap[ARRAY_SIZE(appleir_key_table)];
+ struct timer_list key_up_timer; /* timer for key up */
+- spinlock_t lock; /* protects .current_key */
++ spinlock_t lock; /* protects .current_key, .removing */
+ int current_key; /* the currently pressed key */
+ int prev_key_idx; /* key index in a 2 packets message */
++ bool removing; /* set during teardown; gates input_dev access */
+ };
+
+ static int get_key(int data)
+@@ -172,7 +173,7 @@ static void key_up_tick(struct timer_lis
+ unsigned long flags;
+
+ spin_lock_irqsave(&appleir->lock, flags);
+- if (appleir->current_key) {
++ if (!appleir->removing && appleir->current_key) {
+ key_up(hid, appleir, appleir->current_key);
+ appleir->current_key = 0;
+ }
+@@ -195,6 +196,10 @@ static int appleir_raw_event(struct hid_
+ int index;
+
+ spin_lock_irqsave(&appleir->lock, flags);
++ if (appleir->removing) {
++ spin_unlock_irqrestore(&appleir->lock, flags);
++ goto out;
++ }
+ /*
+ * If we already have a key down, take it up before marking
+ * this one down
+@@ -229,17 +234,25 @@ static int appleir_raw_event(struct hid_
+ appleir->prev_key_idx = 0;
+
+ if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
+- key_down(hid, appleir, appleir->current_key);
+- /*
+- * Remote doesn't do key up, either pull them up, in the test
+- * above, or here set a timer which pulls them up after 1/8 s
+- */
+- mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
++ spin_lock_irqsave(&appleir->lock, flags);
++ if (!appleir->removing) {
++ key_down(hid, appleir, appleir->current_key);
++ /*
++ * Remote doesn't do key up, either pull them up, in
++ * the test above, or here set a timer which pulls them
++ * up after 1/8 s
++ */
++ mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
++ }
++ spin_unlock_irqrestore(&appleir->lock, flags);
+ goto out;
+ }
+
+ if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
+- battery_flat(appleir);
++ spin_lock_irqsave(&appleir->lock, flags);
++ if (!appleir->removing)
++ battery_flat(appleir);
++ spin_unlock_irqrestore(&appleir->lock, flags);
+ /* Fall through */
+ }
+
+@@ -318,8 +331,20 @@ fail:
+ static void appleir_remove(struct hid_device *hid)
+ {
+ struct appleir *appleir = hid_get_drvdata(hid);
++ unsigned long flags;
++
++ /*
++ * Mark the driver as tearing down so that any concurrent raw_event
++ * (e.g. from a USB URB completion that hid_hw_stop() has not yet
++ * killed) and the key_up_timer softirq stop touching input_dev
++ * before hid_hw_stop() frees it via hidinput_disconnect().
++ */
++ spin_lock_irqsave(&appleir->lock, flags);
++ appleir->removing = true;
++ spin_unlock_irqrestore(&appleir->lock, flags);
++
++ timer_delete_sync(&appleir->key_up_timer);
+ hid_hw_stop(hid);
+- del_timer_sync(&appleir->key_up_timer);
+ }
+
+ static const struct hid_device_id appleir_devices[] = {
--- /dev/null
+From stable+bounces-277173-greg=kroah.com@vger.kernel.org Fri Jul 17 20:19:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 14:11:33 -0400
+Subject: HID: multitouch: fix out-of-bounds bit access on mt_io_flags
+To: stable@vger.kernel.org
+Cc: Trung Nguyen <trungnh@cystack.net>, Benjamin Tissoires <bentiss@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717181133.2086215-2-sashal@kernel.org>
+
+From: Trung Nguyen <trungnh@cystack.net>
+
+[ Upstream commit 8813b0612275cc61fe9e6603d0ee019247ade6be ]
+
+mt_io_flags is a single unsigned long, but mt_process_slot(),
+mt_release_pending_palms() and mt_release_contacts() use it as a
+per-slot bitmap indexed by the slot number. That slot number is only
+bounded by td->maxcontacts, which is taken from the device's
+ContactCountMaximum feature report and can be up to 255, not by
+BITS_PER_LONG.
+
+As a result, a multitouch device that advertises a large contact count
+makes set_bit()/clear_bit() operate past the mt_io_flags word and
+corrupt the adjacent members of struct mt_device. The sticky-fingers
+release timer is the easiest way to reach this. mt_release_contacts()
+runs
+
+ for (i = 0; i < mt->num_slots; i++)
+ clear_bit(i, &td->mt_io_flags);
+
+with num_slots == maxcontacts. For maxcontacts around 250 the loop
+clears the bits that overlap td->applications.next, zeroing that list
+head, and the list_for_each_entry() that immediately follows then
+dereferences NULL. The kernel panics from timer (softirq) context. On a
+KASAN build this shows up as a general protection fault in
+mt_release_contacts() with a null-ptr-deref at offset 0x58, which is
+offsetof(struct mt_application, num_received).
+
+The state is reachable from an untrusted USB or Bluetooth HID
+multitouch device; no local privileges are required.
+
+Store the per-slot active state in a separately allocated bitmap sized
+for maxcontacts, the same pattern already used for pending_palm_slots,
+and keep only MT_IO_FLAGS_RUNNING in mt_io_flags. The two
+"mt_io_flags & MT_IO_SLOTS_MASK" arming checks become
+bitmap_empty(td->active_slots, td->maxcontacts).
+
+Move MT_IO_FLAGS_RUNNING back to bit 0. It was bumped to bit 32 by the
+same commit to leave the low byte for the slot bits; with the slot bits
+gone it fits in bit 0 again, which also keeps it within the unsigned
+long on 32-bit.
+
+Fixes: 46f781e0d151 ("HID: multitouch: fix sticky fingers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Trung Nguyen <trungnh@cystack.net>
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -31,6 +31,7 @@
+ * [1] https://gitlab.freedesktop.org/libevdev/hid-tools
+ */
+
++#include <linux/bitmap.h>
+ #include <linux/device.h>
+ #include <linux/hid.h>
+ #include <linux/module.h>
+@@ -81,8 +82,7 @@ enum latency_mode {
+ HID_LATENCY_HIGH = 1,
+ };
+
+-#define MT_IO_SLOTS_MASK GENMASK(7, 0) /* reserve first 8 bits for slot tracking */
+-#define MT_IO_FLAGS_RUNNING 32
++#define MT_IO_FLAGS_RUNNING 0
+
+ static const bool mtrue = true; /* default for true */
+ static const bool mfalse; /* default for false */
+@@ -158,10 +158,9 @@ struct mt_device {
+ struct mt_class mtclass; /* our mt device class */
+ struct timer_list release_timer; /* to release sticky fingers */
+ struct hid_device *hdev; /* hid_device we're attached to */
+- unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING)
+- * first 8 bits are reserved for keeping the slot
+- * states, this is fine because we only support up
+- * to 250 slots (MT_MAX_MAXCONTACT)
++ unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING) */
++ unsigned long *active_slots; /* bitmap of slots with an active
++ * contact, sized for maxcontacts
+ */
+ __u8 inputmode_value; /* InputMode HID feature value */
+ __u8 maxcontacts;
+@@ -915,7 +914,7 @@ static void mt_release_pending_palms(str
+
+ for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) {
+ clear_bit(slotnum, app->pending_palm_slots);
+- clear_bit(slotnum, &td->mt_io_flags);
++ clear_bit(slotnum, td->active_slots);
+
+ input_mt_slot(input, slotnum);
+ input_mt_report_slot_inactive(input);
+@@ -1100,9 +1099,9 @@ static int mt_process_slot(struct mt_dev
+ input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
+ input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
+
+- set_bit(slotnum, &td->mt_io_flags);
++ set_bit(slotnum, td->active_slots);
+ } else {
+- clear_bit(slotnum, &td->mt_io_flags);
++ clear_bit(slotnum, td->active_slots);
+ }
+
+ return 0;
+@@ -1237,7 +1236,7 @@ static void mt_touch_report(struct hid_d
+ * defect.
+ */
+ if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
+- if (td->mt_io_flags & MT_IO_SLOTS_MASK)
++ if (!bitmap_empty(td->active_slots, td->maxcontacts))
+ mod_timer(&td->release_timer,
+ jiffies + msecs_to_jiffies(100));
+ else
+@@ -1277,6 +1276,15 @@ static int mt_touch_input_configured(str
+ if (td->is_buttonpad)
+ __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+
++ if (!td->active_slots) {
++ td->active_slots = devm_kcalloc(&td->hdev->dev,
++ BITS_TO_LONGS(td->maxcontacts),
++ sizeof(long),
++ GFP_KERNEL);
++ if (!td->active_slots)
++ return -ENOMEM;
++ }
++
+ app->pending_palm_slots = devm_kcalloc(&hi->input->dev,
+ BITS_TO_LONGS(td->maxcontacts),
+ sizeof(long),
+@@ -1655,7 +1663,7 @@ static void mt_release_contacts(struct h
+ for (i = 0; i < mt->num_slots; i++) {
+ input_mt_slot(input_dev, i);
+ input_mt_report_slot_inactive(input_dev);
+- clear_bit(i, &td->mt_io_flags);
++ clear_bit(i, td->active_slots);
+ }
+ input_mt_sync_frame(input_dev);
+ input_sync(input_dev);
+@@ -1678,7 +1686,7 @@ static void mt_expired_timeout(struct ti
+ */
+ if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
+ return;
+- if (td->mt_io_flags & MT_IO_SLOTS_MASK)
++ if (!bitmap_empty(td->active_slots, td->maxcontacts))
+ mt_release_contacts(hdev);
+ clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
+ }
--- /dev/null
+From stable+bounces-274099-greg=kroah.com@vger.kernel.org Tue Jul 14 05:05:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:48 -0400
+Subject: iio: common: st_sensors: honour channel endianness in read_axis_data
+To: stable@vger.kernel.org
+Cc: Herman van Hazendonk <github.com@herrie.org>, Andy Shevchenko <andriy.shevchenko@intel.com>, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030448.2382602-2-sashal@kernel.org>
+
+From: Herman van Hazendonk <github.com@herrie.org>
+
+[ Upstream commit 55052184ac9011db2ea983e54d6c21f0b1079a12 ]
+
+st_sensors_read_axis_data() unconditionally decoded multi-byte
+results with get_unaligned_le16() / get_unaligned_le24() regardless
+of the channel's declared scan_type.endianness.
+
+For every ST sensor that has used this helper since it was introduced
+this happened to be fine because the ST IMU/accel/gyro/pressure
+families publish their data registers as little-endian and the
+channel specs in those drivers declare IIO_LE accordingly.
+
+The LSM303DLH magnetometer however publishes its X/Y/Z output as a
+pair of big-endian bytes (the H register sits at the lower address,
+0x03/0x05/0x07, and the L register immediately after), and its
+channel specs in st_magn_core.c correctly declare IIO_BE -- but
+read_axis_data() ignored that and decoded as little-endian, swapping
+the high and low bytes of every magnetometer sample. The LSM303DLHC
+and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and
+were therefore byte-swapped by the same bug; users of those parts
+will see different in_magn_*_raw values after this fix lands.
+
+The bug is most visible on a stationary chip: in earth's field the
+true X reading is small and the high byte sits at 0x00, so swapping
+the bytes pins sysfs X at exactly the low byte's pattern (e.g. 0x00F0
+= 240). Y and Z still appear "to vary" because their magnitudes are
+larger and the noise in the low byte produces big swings in the
+swapped high byte:
+
+ before (LSM303DLH flat, sysfs in_magn_*_raw):
+ X=240 (stuck), Y= 12032..23296, Z=-16128..-9728
+
+ after (direct i2c-dev big-endian decode, same chip same orientation):
+ X≈-4096, Y≈210, Z≈80 (sensible values reflecting earth's
+ ambient field at low gauss range)
+
+Fix read_axis_data() to dispatch on ch->scan_type.endianness and
+call get_unaligned_be16() / get_unaligned_be24() when the channel
+declares IIO_BE. Existing IIO_LE consumers (st_accel, st_gyro,
+st_pressure, st_lsm6dsx and others) are unaffected because their
+channel specs already declare IIO_LE and the LE path is unchanged.
+
+While restructuring the branches, replace the previously implicit
+silent-success-with-uninitialised-*data fall-through for
+byte_for_channel outside 1..3 with an explicit return -EINVAL. No
+in-tree ST sensor publishes such a channel, but the new behaviour
+is strictly safer than handing userspace garbage.
+
+Fixes: 23491b513bcd ("iio:common: Add STMicroelectronics common library")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
+Assisted-by: Sashiko:claude-opus-4-7
+Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/st_sensors/st_sensors_core.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/iio/common/st_sensors/st_sensors_core.c
++++ b/drivers/iio/common/st_sensors/st_sensors_core.c
+@@ -527,6 +527,7 @@ static int st_sensors_read_axis_data(str
+ u8 *outdata;
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ unsigned int byte_for_channel;
++ u32 tmp;
+
+ byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
+ ch->scan_type.shift, 8);
+@@ -539,12 +540,22 @@ static int st_sensors_read_axis_data(str
+ if (err < 0)
+ goto st_sensors_free_memory;
+
+- if (byte_for_channel == 1)
+- *data = (s8)*outdata;
+- else if (byte_for_channel == 2)
+- *data = (s16)get_unaligned_le16(outdata);
+- else if (byte_for_channel == 3)
+- *data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
++ if (byte_for_channel == 1) {
++ tmp = *outdata;
++ } else if (byte_for_channel == 2) {
++ if (ch->scan_type.endianness == IIO_BE)
++ tmp = get_unaligned_be16(outdata);
++ else
++ tmp = get_unaligned_le16(outdata);
++ } else if (byte_for_channel == 3) {
++ if (ch->scan_type.endianness == IIO_BE)
++ tmp = get_unaligned_be24(outdata);
++ else
++ tmp = get_unaligned_le24(outdata);
++ } else {
++ return -EINVAL;
++ }
++ *data = sign_extend32(tmp, BYTES_TO_BITS(byte_for_channel) - 1);
+
+ st_sensors_free_memory:
+ kfree(outdata);
--- /dev/null
+From stable+bounces-273973-greg=kroah.com@vger.kernel.org Mon Jul 13 21:33:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 15:33:36 -0400
+Subject: iio: hid-sensor-rotation: Fix stale or zero output when reading raw values
+To: stable@vger.kernel.org
+Cc: Zhang Lixu <lixu.zhang@intel.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260713193336.2037451-2-sashal@kernel.org>
+
+From: Zhang Lixu <lixu.zhang@intel.com>
+
+[ Upstream commit 3ce8d099e0afc5a7da75a2007a67f67c4f5a4af1 ]
+
+When reading the raw quaternion attribute (in_rot_quaternion_raw), the
+driver currently returns either all zeros (if the sensor was never enabled)
+or stale data (if the sensor was previously enabled) because it reads from
+the internal buffer without explicitly requesting a new sample from the
+sensor.
+
+To fix this, power up the sensor, call sensor_hub_input_attr_read_values()
+to issue a synchronous GET_REPORT and receive the full quaternion data
+directly into a local buffer, then decode the four components.
+
+Fixes: fc18dddc0625 ("iio: hid-sensors: Added device rotation support")
+Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/orientation/hid-sensor-rotation.c | 40 ++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/orientation/hid-sensor-rotation.c
++++ b/drivers/iio/orientation/hid-sensor-rotation.c
+@@ -60,6 +60,13 @@ static int dev_rot_read_raw(struct iio_d
+ long mask)
+ {
+ struct dev_rot_state *rot_state = iio_priv(indio_dev);
++ struct hid_sensor_hub_device *hsdev = rot_state->common_attributes.hsdev;
++ struct hid_sensor_hub_attribute_info *info = &rot_state->quaternion;
++ u32 usage_id = HID_USAGE_SENSOR_ORIENT_QUATERNION;
++ union {
++ s16 val16[4];
++ s32 val32[4];
++ } raw_buf;
+ int ret_type;
+ int i;
+
+@@ -69,8 +76,37 @@ static int dev_rot_read_raw(struct iio_d
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (size >= 4) {
+- for (i = 0; i < 4; ++i)
+- vals[i] = rot_state->sampled_vals[i];
++ if (info->size <= 0 || info->size > sizeof(raw_buf))
++ return -EINVAL;
++
++ hid_sensor_power_state(&rot_state->common_attributes, true);
++
++ ret_type = sensor_hub_input_attr_read_values(hsdev,
++ hsdev->usage,
++ usage_id,
++ info->report_id,
++ SENSOR_HUB_SYNC,
++ info->size,
++ (u8 *)&raw_buf);
++
++ hid_sensor_power_state(&rot_state->common_attributes, false);
++
++ if (ret_type < 0)
++ return ret_type;
++
++ switch (info->size) {
++ case sizeof(raw_buf.val16):
++ for (i = 0; i < ARRAY_SIZE(raw_buf.val16); i++)
++ vals[i] = raw_buf.val16[i];
++ break;
++ case sizeof(raw_buf.val32):
++ for (i = 0; i < ARRAY_SIZE(raw_buf.val32); i++)
++ vals[i] = raw_buf.val32[i];
++ break;
++ default:
++ return -EINVAL;
++ }
++
+ ret_type = IIO_VAL_INT_MULTIPLE;
+ *val_len = 4;
+ } else
--- /dev/null
+From stable+bounces-273955-greg=kroah.com@vger.kernel.org Mon Jul 13 20:33:39 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 14:33:32 -0400
+Subject: iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ
+To: stable@vger.kernel.org
+Cc: Runyu Xiao <runyu.xiao@seu.edu.cn>, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260713183332.1950471-1-sashal@kernel.org>
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 6e1b9bff1202da55c464e36bd34a2b6863d7fe30 ]
+
+devm_adis_probe_trigger() registers iio_trigger_generic_data_rdy_poll()
+through devm_request_irq() on the non-FIFO path, but it does not add
+IRQF_NO_THREAD to the IRQ flags.
+
+When the kernel is booted with forced IRQ threading, the parent IRQ can
+otherwise be threaded by the IRQ core and the subsequent IIO trigger
+child IRQ is then dispatched from irq/... thread context instead of
+hardirq context. Because iio_trigger_generic_data_rdy_poll()
+immediately drives iio_trigger_poll(), this violates the hardirq-only
+IIO trigger helper contract and can push downstream trigger consumers
+through the wrong execution context.
+
+Add IRQF_NO_THREAD on top of the existing adis->irq_flag value for the
+non-FIFO request_irq() path, while preserving the current trigger
+polarity and IRQF_NO_AUTOEN behavior.
+
+Fixes: fec86c6b8369 ("iio: imu: adis: Add Managed device functions")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/adis_trigger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/imu/adis_trigger.c
++++ b/drivers/iio/imu/adis_trigger.c
+@@ -84,7 +84,7 @@ int devm_adis_probe_trigger(struct adis
+
+ ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
+ &iio_trigger_generic_data_rdy_poll,
+- adis->irq_flag,
++ adis->irq_flag | IRQF_NO_THREAD,
+ indio_dev->name,
+ adis->trig);
+ if (ret)
--- /dev/null
+From stable+bounces-274096-greg=kroah.com@vger.kernel.org Tue Jul 14 05:04:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:44 -0400
+Subject: iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-8-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit affe3f077d7a4eeb25937f5323ff059a54b4712c ]
+
+Timestamps are made by measuring the chip clock using the watermark
+interrupts. If we read more than watermark samples as done today, we
+are reducing the period between interrupts and distort the time
+measurement. Fix that by reading only watermark samples in the
+interrupt case.
+
+Fixes: 7f85e42a6c54 ("iio: imu: inv_icm42600: add buffer support in iio devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 9 +++++----
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 1 +
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -257,6 +257,7 @@ int inv_icm42600_buffer_update_watermark
+
+ /* compute watermark value in bytes */
+ wm_size = watermark * packet_size;
++ st->fifo.watermark.value = watermark;
+
+ /* changing FIFO watermark requires to turn off watermark interrupt */
+ ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
+@@ -476,11 +477,10 @@ int inv_icm42600_buffer_fifo_read(struct
+ st->fifo.nb.accel = 0;
+ st->fifo.nb.total = 0;
+
+- /* compute maximum FIFO read size */
++ /* compute maximum FIFO read size (watermark for max = 0 interrupt case) */
+ if (max == 0)
+- max_count = sizeof(st->fifo.data);
+- else
+- max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
++ max = st->fifo.watermark.value;
++ max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
+
+ /* read FIFO count value */
+ raw_fifo_count = (__be16 *)st->buffer;
+@@ -592,6 +592,7 @@ int inv_icm42600_buffer_init(struct inv_
+
+ st->fifo.watermark.eff_gyro = 1;
+ st->fifo.watermark.eff_accel = 1;
++ st->fifo.watermark.value = 1;
+
+ /*
+ * Default FIFO configuration (bits 7 to 5)
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+@@ -34,6 +34,7 @@ struct inv_icm42600_fifo {
+ unsigned int accel;
+ unsigned int eff_gyro;
+ unsigned int eff_accel;
++ unsigned int value;
+ } watermark;
+ size_t count;
+ struct {
--- /dev/null
+From stable+bounces-274090-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:37 -0400
+Subject: iio: imu: inv_icm42600: make timestamp module chip independent
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-1-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit 6e9f2d8375cb24ba75e02e0272e9164d06a1522e ]
+
+Move icm42600 dependent function inside the core module.
+Do some headers cleanup at the same time.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-2-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 11 +++++++++++
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c | 14 +-------------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h | 6 ------
+ 3 files changed, 12 insertions(+), 19 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -522,6 +522,17 @@ static int inv_icm42600_irq_init(struct
+ "inv_icm42600", st);
+ }
+
++static int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st)
++{
++ unsigned int val;
++
++ /* enable timestamp register */
++ val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN |
++ INV_ICM42600_TMST_CONFIG_TMST_EN;
++ return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG,
++ INV_ICM42600_TMST_CONFIG_MASK, val);
++}
++
+ static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st)
+ {
+ int ret;
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c
+@@ -3,11 +3,10 @@
+ * Copyright (C) 2020 Invensense, Inc.
+ */
+
++#include <linux/errno.h>
+ #include <linux/kernel.h>
+-#include <linux/regmap.h>
+ #include <linux/math64.h>
+
+-#include "inv_icm42600.h"
+ #include "inv_icm42600_timestamp.h"
+
+ /* internal chip period is 32kHz, 31250ns */
+@@ -56,17 +55,6 @@ void inv_icm42600_timestamp_init(struct
+ inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
+ }
+
+-int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st)
+-{
+- unsigned int val;
+-
+- /* enable timestamp register */
+- val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN |
+- INV_ICM42600_TMST_CONFIG_TMST_EN;
+- return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG,
+- INV_ICM42600_TMST_CONFIG_MASK, val);
+-}
+-
+ int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+ uint32_t period, bool fifo)
+ {
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h
+@@ -6,10 +6,6 @@
+ #ifndef INV_ICM42600_TIMESTAMP_H_
+ #define INV_ICM42600_TIMESTAMP_H_
+
+-#include <linux/kernel.h>
+-
+-struct inv_icm42600_state;
+-
+ /**
+ * struct inv_icm42600_timestamp_interval - timestamps interval
+ * @lo: interval lower bound
+@@ -53,8 +49,6 @@ struct inv_icm42600_timestamp {
+ void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+ uint32_t period);
+
+-int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st);
+-
+ int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+ uint32_t period, bool fifo);
+
--- /dev/null
+From stable+bounces-274095-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:43 -0400
+Subject: iio: imu: inv_icm42600: stabilized timestamp in interrupt
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-7-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit d7bd473632d07f8a54655c270c0940cc3671c548 ]
+
+Use IRQF_ONESHOT flag to ensure the timestamp is not updated in the
+hard handler during the thread handler. And compute and use the
+effective watermark value that correspond to this first timestamp.
+
+This way we can ensure the timestamp is always corresponding to the
+value used by the timestamping mechanism. Otherwise, it is possible
+that between FIFO count read and FIFO processing the timestamp is
+overwritten in the hard handler.
+
+Fixes: ec74ae9fd37c ("iio: imu: inv_icm42600: add accurate timestamping")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://lore.kernel.org/r/20240529154717.651863-1-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 19 +++++++++++++++++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 2 ++
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 1 +
+ 3 files changed, 20 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -222,10 +222,15 @@ int inv_icm42600_buffer_update_watermark
+ latency_accel = period_accel * wm_accel;
+
+ /* 0 value for watermark means that the sensor is turned off */
++ if (wm_gyro == 0 && wm_accel == 0)
++ return 0;
++
+ if (latency_gyro == 0) {
+ watermark = wm_accel;
++ st->fifo.watermark.eff_accel = wm_accel;
+ } else if (latency_accel == 0) {
+ watermark = wm_gyro;
++ st->fifo.watermark.eff_gyro = wm_gyro;
+ } else {
+ /* compute the smallest latency that is a multiple of both */
+ if (latency_gyro <= latency_accel)
+@@ -241,6 +246,13 @@ int inv_icm42600_buffer_update_watermark
+ watermark = latency / period;
+ if (watermark < 1)
+ watermark = 1;
++ /* update effective watermark */
++ st->fifo.watermark.eff_gyro = latency / period_gyro;
++ if (st->fifo.watermark.eff_gyro < 1)
++ st->fifo.watermark.eff_gyro = 1;
++ st->fifo.watermark.eff_accel = latency / period_accel;
++ if (st->fifo.watermark.eff_accel < 1)
++ st->fifo.watermark.eff_accel = 1;
+ }
+
+ /* compute watermark value in bytes */
+@@ -517,7 +529,7 @@ int inv_icm42600_buffer_fifo_parse(struc
+ /* handle gyroscope timestamp and FIFO data parsing */
+ if (st->fifo.nb.gyro > 0) {
+ ts = iio_priv(st->indio_gyro);
+- inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro,
++ inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro,
+ st->timestamp.gyro);
+ ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+ if (ret)
+@@ -527,7 +539,7 @@ int inv_icm42600_buffer_fifo_parse(struc
+ /* handle accelerometer timestamp and FIFO data parsing */
+ if (st->fifo.nb.accel > 0) {
+ ts = iio_priv(st->indio_accel);
+- inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel,
++ inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel,
+ st->timestamp.accel);
+ ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+ if (ret)
+@@ -578,6 +590,9 @@ int inv_icm42600_buffer_init(struct inv_
+ unsigned int val;
+ int ret;
+
++ st->fifo.watermark.eff_gyro = 1;
++ st->fifo.watermark.eff_accel = 1;
++
+ /*
+ * Default FIFO configuration (bits 7 to 5)
+ * - use invalid value
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+@@ -32,6 +32,8 @@ struct inv_icm42600_fifo {
+ struct {
+ unsigned int gyro;
+ unsigned int accel;
++ unsigned int eff_gyro;
++ unsigned int eff_accel;
+ } watermark;
+ size_t count;
+ struct {
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -518,6 +518,7 @@ static int inv_icm42600_irq_init(struct
+ if (ret)
+ return ret;
+
++ irq_type |= IRQF_ONESHOT;
+ return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
+ inv_icm42600_irq_handler, irq_type,
+ "inv_icm42600", st);
--- /dev/null
+From stable+bounces-274098-greg=kroah.com@vger.kernel.org Tue Jul 14 05:05:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:40 -0400
+Subject: iio: imu: inv_mpu6050: use the common inv_sensors timestamp module
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-4-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit 111e1abd00455971f6a568900f033cbddec9d4e5 ]
+
+Replace timestamping by the new common inv_sensors timestamp
+module. The principle behind is the same but the implementation in
+the new module is far better providing less jitter and a better
+estimation.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-5-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_mpu6050/Kconfig | 1
+ drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 30 +++++++--
+ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 18 ++---
+ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 83 ++------------------------
+ drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 6 +
+ 5 files changed, 45 insertions(+), 93 deletions(-)
+
+--- a/drivers/iio/imu/inv_mpu6050/Kconfig
++++ b/drivers/iio/imu/inv_mpu6050/Kconfig
+@@ -7,6 +7,7 @@ config INV_MPU6050_IIO
+ tristate
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
++ select IIO_INV_SENSORS_TIMESTAMP
+
+ config INV_MPU6050_I2C
+ tristate "Invensense MPU6050 devices (I2C)"
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+@@ -12,12 +12,15 @@
+ #include <linux/jiffies.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+-#include <linux/iio/iio.h>
+ #include <linux/acpi.h>
+ #include <linux/platform_device.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/pm.h>
+ #include <linux/pm_runtime.h>
++
++#include <linux/iio/common/inv_sensors_timestamp.h>
++#include <linux/iio/iio.h>
++
+ #include "inv_mpu_iio.h"
+ #include "inv_mpu_magn.h"
+
+@@ -481,6 +484,7 @@ static int inv_mpu6050_init_config(struc
+ int result;
+ u8 d;
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++ struct inv_sensors_timestamp_chip timestamp;
+
+ result = inv_mpu6050_set_gyro_fsr(st, st->chip_config.fsr);
+ if (result)
+@@ -504,12 +508,12 @@ static int inv_mpu6050_init_config(struc
+ if (result)
+ return result;
+
+- /*
+- * Internal chip period is 1ms (1kHz).
+- * Let's use at the beginning the theorical value before measuring
+- * with interrupt timestamps.
+- */
+- st->chip_period = NSEC_PER_MSEC;
++ /* clock jitter is +/- 2% */
++ timestamp.clock_period = NSEC_PER_SEC / INV_MPU6050_INTERNAL_FREQ_HZ;
++ timestamp.jitter = 20;
++ timestamp.init_period =
++ NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
++ inv_sensors_timestamp_init(&st->timestamp, ×tamp);
+
+ /* magn chip init, noop if not present in the chip */
+ result = inv_mpu_magn_probe(st);
+@@ -900,6 +904,8 @@ inv_mpu6050_fifo_rate_store(struct devic
+ const char *buf, size_t count)
+ {
+ int fifo_rate;
++ u32 fifo_period;
++ bool fifo_on;
+ u8 d;
+ int result;
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+@@ -916,12 +922,21 @@ inv_mpu6050_fifo_rate_store(struct devic
+ d = INV_MPU6050_FIFO_RATE_TO_DIVIDER(fifo_rate);
+ /* compute back the fifo rate to handle truncation cases */
+ fifo_rate = INV_MPU6050_DIVIDER_TO_FIFO_RATE(d);
++ fifo_period = NSEC_PER_SEC / fifo_rate;
+
+ mutex_lock(&st->lock);
+ if (d == st->chip_config.divider) {
+ result = 0;
+ goto fifo_rate_fail_unlock;
+ }
++
++ fifo_on = st->chip_config.accl_fifo_enable ||
++ st->chip_config.gyro_fifo_enable ||
++ st->chip_config.magn_fifo_enable;
++ result = inv_sensors_timestamp_update_odr(&st->timestamp, fifo_period, fifo_on);
++ if (result)
++ goto fifo_rate_fail_unlock;
++
+ result = pm_runtime_get_sync(pdev);
+ if (result < 0) {
+ pm_runtime_put_noidle(pdev);
+@@ -1741,3 +1756,4 @@ EXPORT_SYMBOL_GPL(inv_mpu_pmops);
+ MODULE_AUTHOR("Invensense Corporation");
+ MODULE_DESCRIPTION("Invensense device MPU6050 driver");
+ MODULE_LICENSE("GPL");
++MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP);
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+@@ -9,15 +9,17 @@
+ #include <linux/i2c.h>
+ #include <linux/i2c-mux.h>
+ #include <linux/mutex.h>
+-#include <linux/iio/iio.h>
+-#include <linux/iio/buffer.h>
++#include <linux/platform_data/invensense_mpu6050.h>
+ #include <linux/regmap.h>
+-#include <linux/iio/sysfs.h>
++
++#include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
++#include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+ #include <linux/iio/trigger.h>
+ #include <linux/iio/triggered_buffer.h>
+ #include <linux/iio/trigger_consumer.h>
+-#include <linux/platform_data/invensense_mpu6050.h>
++#include <linux/iio/sysfs.h>
+
+ /**
+ * struct inv_mpu6050_reg_map - Notable registers.
+@@ -163,9 +165,7 @@ struct inv_mpu6050_hw {
+ * @map regmap pointer.
+ * @irq interrupt number.
+ * @irq_mask the int_pin_cfg mask to configure interrupt type.
+- * @chip_period: chip internal period estimation (~1kHz).
+- * @it_timestamp: timestamp from previous interrupt.
+- * @data_timestamp: timestamp for next data sample.
++ * @timestamp: timestamping module
+ * @vdd_supply: VDD voltage regulator for the chip.
+ * @vddio_supply I/O voltage regulator for the chip.
+ * @magn_disabled: magnetometer disabled for backward compatibility reason.
+@@ -189,9 +189,7 @@ struct inv_mpu6050_state {
+ int irq;
+ u8 irq_mask;
+ unsigned skip_samples;
+- s64 chip_period;
+- s64 it_timestamp;
+- s64 data_timestamp;
++ struct inv_sensors_timestamp timestamp;
+ struct regulator *vdd_supply;
+ struct regulator *vddio_supply;
+ bool magn_disabled;
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+@@ -13,81 +13,10 @@
+ #include <linux/interrupt.h>
+ #include <linux/poll.h>
+ #include <linux/math64.h>
+-#include "inv_mpu_iio.h"
+-
+-/**
+- * inv_mpu6050_update_period() - Update chip internal period estimation
+- *
+- * @st: driver state
+- * @timestamp: the interrupt timestamp
+- * @nb: number of data set in the fifo
+- *
+- * This function uses interrupt timestamps to estimate the chip period and
+- * to choose the data timestamp to come.
+- */
+-static void inv_mpu6050_update_period(struct inv_mpu6050_state *st,
+- s64 timestamp, size_t nb)
+-{
+- /* Period boundaries for accepting timestamp */
+- const s64 period_min =
+- (NSEC_PER_MSEC * (100 - INV_MPU6050_TS_PERIOD_JITTER)) / 100;
+- const s64 period_max =
+- (NSEC_PER_MSEC * (100 + INV_MPU6050_TS_PERIOD_JITTER)) / 100;
+- const s32 divider = INV_MPU6050_FREQ_DIVIDER(st);
+- s64 delta, interval;
+- bool use_it_timestamp = false;
+-
+- if (st->it_timestamp == 0) {
+- /* not initialized, forced to use it_timestamp */
+- use_it_timestamp = true;
+- } else if (nb == 1) {
+- /*
+- * Validate the use of it timestamp by checking if interrupt
+- * has been delayed.
+- * nb > 1 means interrupt was delayed for more than 1 sample,
+- * so it's obviously not good.
+- * Compute the chip period between 2 interrupts for validating.
+- */
+- delta = div_s64(timestamp - st->it_timestamp, divider);
+- if (delta > period_min && delta < period_max) {
+- /* update chip period and use it timestamp */
+- st->chip_period = (st->chip_period + delta) / 2;
+- use_it_timestamp = true;
+- }
+- }
+
+- if (use_it_timestamp) {
+- /*
+- * Manage case of multiple samples in the fifo (nb > 1):
+- * compute timestamp corresponding to the first sample using
+- * estimated chip period.
+- */
+- interval = (nb - 1) * st->chip_period * divider;
+- st->data_timestamp = timestamp - interval;
+- }
++#include <linux/iio/common/inv_sensors_timestamp.h>
+
+- /* save it timestamp */
+- st->it_timestamp = timestamp;
+-}
+-
+-/**
+- * inv_mpu6050_get_timestamp() - Return the current data timestamp
+- *
+- * @st: driver state
+- * @return: current data timestamp
+- *
+- * This function returns the current data timestamp and prepares for next one.
+- */
+-static s64 inv_mpu6050_get_timestamp(struct inv_mpu6050_state *st)
+-{
+- s64 ts;
+-
+- /* return current data timestamp and increment */
+- ts = st->data_timestamp;
+- st->data_timestamp += st->chip_period * INV_MPU6050_FREQ_DIVIDER(st);
+-
+- return ts;
+-}
++#include "inv_mpu_iio.h"
+
+ static int inv_reset_fifo(struct iio_dev *indio_dev)
+ {
+@@ -121,6 +50,7 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+ size_t bytes_per_datum;
+ int result;
+ u16 fifo_count;
++ u32 fifo_period;
+ s64 timestamp;
+ int int_status;
+ size_t i, nb;
+@@ -177,7 +107,10 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+
+ /* compute and process all complete datum */
+ nb = fifo_count / bytes_per_datum;
+- inv_mpu6050_update_period(st, pf->timestamp, nb);
++ /* Each FIFO data contains all sensors, so same number for FIFO and sensor data */
++ fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
++ inv_sensors_timestamp_interrupt(&st->timestamp, fifo_period, nb, nb, pf->timestamp);
++ inv_sensors_timestamp_apply_odr(&st->timestamp, fifo_period, nb, 0);
+ for (i = 0; i < nb; ++i) {
+ result = regmap_noinc_read(st->map, st->reg->fifo_r_w,
+ st->data, bytes_per_datum);
+@@ -188,7 +121,7 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+ st->skip_samples--;
+ continue;
+ }
+- timestamp = inv_mpu6050_get_timestamp(st);
++ timestamp = inv_sensors_timestamp_pop(&st->timestamp);
+ iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp);
+ }
+
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+@@ -4,6 +4,9 @@
+ */
+
+ #include <linux/pm_runtime.h>
++
++#include <linux/iio/common/inv_sensors_timestamp.h>
++
+ #include "inv_mpu_iio.h"
+
+ static unsigned int inv_scan_query_mpu6050(struct iio_dev *indio_dev)
+@@ -107,7 +110,8 @@ int inv_mpu6050_prepare_fifo(struct inv_
+ int ret;
+
+ if (enable) {
+- st->it_timestamp = 0;
++ /* reset timestamping */
++ inv_sensors_timestamp_reset(&st->timestamp);
+ /* reset FIFO */
+ d = st->chip_config.user_ctrl | INV_MPU6050_BIT_FIFO_RST;
+ ret = regmap_write(st->map, st->reg->user_ctrl, d);
--- /dev/null
+From stable+bounces-274094-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:42 -0400
+Subject: iio: invensense: fix timestamp glitches when switching frequency
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Stable@vger.kernel.org, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-6-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit bf8367b00c33c64a9391c262bb2e11d274c9f2a4 ]
+
+When a sensor is running and there is a FIFO frequency change due to
+another sensor turned on/off, there are glitches on timestamp. Fix that
+by using only interrupt timestamp when there is the corresponding sensor
+data in the FIFO.
+
+Delete FIFO period handling and simplify internal functions.
+
+Update integration inside inv_mpu6050 and inv_icm42600 drivers.
+
+Fixes: 0ecc363ccea7 ("iio: make invensense timestamp module generic")
+Cc: Stable@vger.kernel.org
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://lore.kernel.org/r/20240426094835.138389-1-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/inv_sensors/inv_sensors_timestamp.c | 30 +++++++----------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 20 ++++-------
+ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 -
+ include/linux/iio/common/inv_sensors_timestamp.h | 3 -
+ 4 files changed, 23 insertions(+), 32 deletions(-)
+
+--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+@@ -70,13 +70,13 @@ int inv_sensors_timestamp_update_odr(str
+ }
+ EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
+
+-static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period, uint32_t mult)
++static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period)
+ {
+ uint32_t period_min, period_max;
+
+ /* check that period is acceptable */
+- period_min = ts->min_period * mult;
+- period_max = ts->max_period * mult;
++ period_min = ts->min_period * ts->mult;
++ period_max = ts->max_period * ts->mult;
+ if (period > period_min && period < period_max)
+ return true;
+ else
+@@ -84,32 +84,30 @@ static bool inv_validate_period(struct i
+ }
+
+ static bool inv_compute_chip_period(struct inv_sensors_timestamp *ts,
+- uint32_t mult, uint32_t period)
++ uint32_t period)
+ {
+ uint32_t new_chip_period;
+
+- if (!inv_validate_period(ts, period, mult))
++ if (!inv_validate_period(ts, period))
+ return false;
+
+ /* update chip internal period estimation */
+- new_chip_period = period / mult;
++ new_chip_period = period / ts->mult;
+ inv_update_acc(&ts->chip_period, new_chip_period);
+
+ return true;
+ }
+
+ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- size_t sensor_nb, int64_t timestamp)
++ size_t sample_nb, int64_t timestamp)
+ {
+ struct inv_sensors_timestamp_interval *it;
+ int64_t delta, interval;
+- const uint32_t fifo_mult = fifo_period / ts->chip.clock_period;
+ uint32_t period;
+ int32_t m;
+ bool valid = false;
+
+- if (fifo_nb == 0)
++ if (sample_nb == 0)
+ return;
+
+ /* update interrupt timestamp and compute chip and sensor periods */
+@@ -119,8 +117,8 @@ void inv_sensors_timestamp_interrupt(str
+ delta = it->up - it->lo;
+ if (it->lo != 0) {
+ /* compute period: delta time divided by number of samples */
+- period = div_s64(delta, fifo_nb);
+- valid = inv_compute_chip_period(ts, fifo_mult, period);
++ period = div_s64(delta, sample_nb);
++ valid = inv_compute_chip_period(ts, period);
+ /* update sensor period if chip internal period is updated */
+ if (valid)
+ ts->period = ts->mult * ts->chip_period.val;
+@@ -129,20 +127,18 @@ void inv_sensors_timestamp_interrupt(str
+ /* no previous data, compute theoritical value from interrupt */
+ if (ts->timestamp == 0) {
+ /* elapsed time: sensor period * sensor samples number */
+- interval = (int64_t)ts->period * (int64_t)sensor_nb;
++ interval = (int64_t)ts->period * (int64_t)sample_nb;
+ ts->timestamp = it->up - interval;
+ return;
+ }
+
+ /* if interrupt interval is valid, sync with interrupt timestamp */
+ if (valid) {
+- /* compute measured fifo_period */
+- fifo_period = fifo_mult * ts->chip_period.val;
+ /* delta time between last sample and last interrupt */
+ delta = it->lo - ts->timestamp;
+ /* if there are multiple samples, go back to first one */
+- while (delta >= (fifo_period * 3 / 2))
+- delta -= fifo_period;
++ while (delta >= (ts->period * 3 / 2))
++ delta -= ts->period;
+ /* compute maximal adjustment value */
+ m = INV_SENSORS_TIMESTAMP_JITTER((int64_t)ts->period, ts->chip.jitter);
+ if (delta > m)
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -515,20 +515,20 @@ int inv_icm42600_buffer_fifo_parse(struc
+ return 0;
+
+ /* handle gyroscope timestamp and FIFO data parsing */
+- ts = iio_priv(st->indio_gyro);
+- inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+- st->fifo.nb.gyro, st->timestamp.gyro);
+ if (st->fifo.nb.gyro > 0) {
++ ts = iio_priv(st->indio_gyro);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro,
++ st->timestamp.gyro);
+ ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+ if (ret)
+ return ret;
+ }
+
+ /* handle accelerometer timestamp and FIFO data parsing */
+- ts = iio_priv(st->indio_accel);
+- inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+- st->fifo.nb.accel, st->timestamp.accel);
+ if (st->fifo.nb.accel > 0) {
++ ts = iio_priv(st->indio_accel);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel,
++ st->timestamp.accel);
+ ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+ if (ret)
+ return ret;
+@@ -556,9 +556,7 @@ int inv_icm42600_buffer_hwfifo_flush(str
+
+ if (st->fifo.nb.gyro > 0) {
+ ts = iio_priv(st->indio_gyro);
+- inv_sensors_timestamp_interrupt(ts, st->fifo.period,
+- st->fifo.nb.total, st->fifo.nb.gyro,
+- gyro_ts);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro, gyro_ts);
+ ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+ if (ret)
+ return ret;
+@@ -566,9 +564,7 @@ int inv_icm42600_buffer_hwfifo_flush(str
+
+ if (st->fifo.nb.accel > 0) {
+ ts = iio_priv(st->indio_accel);
+- inv_sensors_timestamp_interrupt(ts, st->fifo.period,
+- st->fifo.nb.total, st->fifo.nb.accel,
+- accel_ts);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel, accel_ts);
+ ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+ if (ret)
+ return ret;
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+@@ -109,7 +109,7 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+ nb = fifo_count / bytes_per_datum;
+ /* Each FIFO data contains all sensors, so same number for FIFO and sensor data */
+ fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
+- inv_sensors_timestamp_interrupt(&st->timestamp, fifo_period, nb, nb, pf->timestamp);
++ inv_sensors_timestamp_interrupt(&st->timestamp, nb, pf->timestamp);
+ inv_sensors_timestamp_apply_odr(&st->timestamp, fifo_period, nb, 0);
+ for (i = 0; i < nb; ++i) {
+ result = regmap_noinc_read(st->map, st->reg->fifo_r_w,
+--- a/include/linux/iio/common/inv_sensors_timestamp.h
++++ b/include/linux/iio/common/inv_sensors_timestamp.h
+@@ -71,8 +71,7 @@ int inv_sensors_timestamp_update_odr(str
+ uint32_t period, bool fifo);
+
+ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- size_t sensor_nb, int64_t timestamp);
++ size_t sample_nb, int64_t timestamp);
+
+ static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts)
+ {
--- /dev/null
+From stable+bounces-274093-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:41 -0400
+Subject: iio: invensense: remove redundant initialization of variable period
+To: stable@vger.kernel.org
+Cc: Colin Ian King <colin.i.king@gmail.com>, Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-5-sashal@kernel.org>
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit b58b13f156c00c2457035b7071eaaac105fe6836 ]
+
+The variable period is being initialized with a value that is never
+read, it is being re-assigned a new value later on before it is read.
+The initialization is redundant and can be removed.
+
+Cleans up clang scan build warning:
+Value stored to 'period' during its initialization is never
+read [deadcode.DeadStores]
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://lore.kernel.org/r/20240106153202.54861-1-colin.i.king@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/inv_sensors/inv_sensors_timestamp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+@@ -105,7 +105,7 @@ void inv_sensors_timestamp_interrupt(str
+ struct inv_sensors_timestamp_interval *it;
+ int64_t delta, interval;
+ const uint32_t fifo_mult = fifo_period / ts->chip.clock_period;
+- uint32_t period = ts->period;
++ uint32_t period;
+ int32_t m;
+ bool valid = false;
+
--- /dev/null
+From stable+bounces-274092-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:39 -0400
+Subject: iio: make invensense timestamp module generic
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-3-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit 0ecc363ccea71eda6a2cceade120489259bcdb33 ]
+
+Rename common module to inv_sensors_timestamp, add configuration
+at init (chip internal clock, acceptable jitter, ...) and update
+inv_icm42600 driver integration.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-4-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/inv_sensors/Makefile | 2
+ drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c | 192 ----------------
+ drivers/iio/common/inv_sensors/inv_sensors_timestamp.c | 191 +++++++++++++++
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 32 +-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 34 +-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 10
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 32 +-
+ include/linux/iio/common/inv_icm42600_timestamp.h | 79 ------
+ include/linux/iio/common/inv_sensors_timestamp.h | 95 +++++++
+ 9 files changed, 349 insertions(+), 318 deletions(-)
+ rename drivers/iio/common/inv_sensors/{inv_icm42600_timestamp.c => inv_sensors_timestamp.c} (61%)
+ delete mode 100644 include/linux/iio/common/inv_icm42600_timestamp.h
+ create mode 100644 include/linux/iio/common/inv_sensors_timestamp.h
+
+--- a/drivers/iio/common/inv_sensors/Makefile
++++ b/drivers/iio/common/inv_sensors/Makefile
+@@ -3,4 +3,4 @@
+ # Makefile for TDK-InvenSense sensors module.
+ #
+
+-obj-$(CONFIG_IIO_INV_SENSORS_TIMESTAMP) += inv_icm42600_timestamp.o
++obj-$(CONFIG_IIO_INV_SENSORS_TIMESTAMP) += inv_sensors_timestamp.o
+--- a/drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c
++++ /dev/null
+@@ -1,192 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-or-later
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/kernel.h>
+-#include <linux/math64.h>
+-#include <linux/module.h>
+-
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
+-
+-/* internal chip period is 32kHz, 31250ns */
+-#define INV_ICM42600_TIMESTAMP_PERIOD 31250
+-/* allow a jitter of +/- 2% */
+-#define INV_ICM42600_TIMESTAMP_JITTER 2
+-/* compute min and max periods accepted */
+-#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p) \
+- (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p) \
+- (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-
+-/* Add a new value inside an accumulator and update the estimate value */
+-static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val)
+-{
+- uint64_t sum = 0;
+- size_t i;
+-
+- acc->values[acc->idx++] = val;
+- if (acc->idx >= ARRAY_SIZE(acc->values))
+- acc->idx = 0;
+-
+- /* compute the mean of all stored values, use 0 as empty slot */
+- for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
+- if (acc->values[i] == 0)
+- break;
+- sum += acc->values[i];
+- }
+-
+- acc->val = div_u64(sum, i);
+-}
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+- uint32_t period)
+-{
+- /* initial odr for sensor after reset is 1kHz */
+- const uint32_t default_period = 1000000;
+-
+- /* current multiplier and period values after reset */
+- ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD;
+- ts->period = default_period;
+- /* new set multiplier is the one from chip initialization */
+- ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+- /* use theoretical value for chip period */
+- inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_init, IIO_INV_SENSORS_TIMESTAMP);
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t period, bool fifo)
+-{
+- /* when FIFO is on, prevent odr change if one is already pending */
+- if (fifo && ts->new_mult != 0)
+- return -EAGAIN;
+-
+- ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+- return 0;
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
+-
+-static bool inv_validate_period(uint32_t period, uint32_t mult)
+-{
+- const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD;
+- uint32_t period_min, period_max;
+-
+- /* check that period is acceptable */
+- period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult;
+- period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult;
+- if (period > period_min && period < period_max)
+- return true;
+- else
+- return false;
+-}
+-
+-static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts,
+- uint32_t mult, uint32_t period)
+-{
+- uint32_t new_chip_period;
+-
+- if (!inv_validate_period(period, mult))
+- return false;
+-
+- /* update chip internal period estimation */
+- new_chip_period = period / mult;
+- inv_update_acc(&ts->chip_period, new_chip_period);
+-
+- return true;
+-}
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- size_t sensor_nb, int64_t timestamp)
+-{
+- struct inv_icm42600_timestamp_interval *it;
+- int64_t delta, interval;
+- const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+- uint32_t period = ts->period;
+- int32_t m;
+- bool valid = false;
+-
+- if (fifo_nb == 0)
+- return;
+-
+- /* update interrupt timestamp and compute chip and sensor periods */
+- it = &ts->it;
+- it->lo = it->up;
+- it->up = timestamp;
+- delta = it->up - it->lo;
+- if (it->lo != 0) {
+- /* compute period: delta time divided by number of samples */
+- period = div_s64(delta, fifo_nb);
+- valid = inv_compute_chip_period(ts, fifo_mult, period);
+- /* update sensor period if chip internal period is updated */
+- if (valid)
+- ts->period = ts->mult * ts->chip_period.val;
+- }
+-
+- /* no previous data, compute theoritical value from interrupt */
+- if (ts->timestamp == 0) {
+- /* elapsed time: sensor period * sensor samples number */
+- interval = (int64_t)ts->period * (int64_t)sensor_nb;
+- ts->timestamp = it->up - interval;
+- return;
+- }
+-
+- /* if interrupt interval is valid, sync with interrupt timestamp */
+- if (valid) {
+- /* compute measured fifo_period */
+- fifo_period = fifo_mult * ts->chip_period.val;
+- /* delta time between last sample and last interrupt */
+- delta = it->lo - ts->timestamp;
+- /* if there are multiple samples, go back to first one */
+- while (delta >= (fifo_period * 3 / 2))
+- delta -= fifo_period;
+- /* compute maximal adjustment value */
+- m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period;
+- if (delta > m)
+- delta = m;
+- else if (delta < -m)
+- delta = -m;
+- ts->timestamp += delta;
+- }
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP);
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- unsigned int fifo_no)
+-{
+- int64_t interval;
+- uint32_t fifo_mult;
+-
+- if (ts->new_mult == 0)
+- return;
+-
+- /* update to new multiplier and update period */
+- ts->mult = ts->new_mult;
+- ts->new_mult = 0;
+- ts->period = ts->mult * ts->chip_period.val;
+-
+- /*
+- * After ODR change the time interval with the previous sample is
+- * undertermined (depends when the change occures). So we compute the
+- * timestamp from the current interrupt using the new FIFO period, the
+- * total number of samples and the current sample numero.
+- */
+- if (ts->timestamp != 0) {
+- /* compute measured fifo period */
+- fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+- fifo_period = fifo_mult * ts->chip_period.val;
+- /* computes time interval between interrupt and this sample */
+- interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
+- ts->timestamp = ts->it.up - interval;
+- }
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP);
+-
+-MODULE_AUTHOR("InvenSense, Inc.");
+-MODULE_DESCRIPTION("InvenSense sensors timestamp module");
+-MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+@@ -0,0 +1,191 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++
++#include <linux/iio/common/inv_sensors_timestamp.h>
++
++/* compute jitter, min and max following jitter in per mille */
++#define INV_SENSORS_TIMESTAMP_JITTER(_val, _jitter) \
++ (div_s64((_val) * (_jitter), 1000))
++#define INV_SENSORS_TIMESTAMP_MIN(_val, _jitter) \
++ (((_val) * (1000 - (_jitter))) / 1000)
++#define INV_SENSORS_TIMESTAMP_MAX(_val, _jitter) \
++ (((_val) * (1000 + (_jitter))) / 1000)
++
++/* Add a new value inside an accumulator and update the estimate value */
++static void inv_update_acc(struct inv_sensors_timestamp_acc *acc, uint32_t val)
++{
++ uint64_t sum = 0;
++ size_t i;
++
++ acc->values[acc->idx++] = val;
++ if (acc->idx >= ARRAY_SIZE(acc->values))
++ acc->idx = 0;
++
++ /* compute the mean of all stored values, use 0 as empty slot */
++ for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
++ if (acc->values[i] == 0)
++ break;
++ sum += acc->values[i];
++ }
++
++ acc->val = div_u64(sum, i);
++}
++
++void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts,
++ const struct inv_sensors_timestamp_chip *chip)
++{
++ memset(ts, 0, sizeof(*ts));
++
++ /* save chip parameters and compute min and max clock period */
++ ts->chip = *chip;
++ ts->min_period = INV_SENSORS_TIMESTAMP_MIN(chip->clock_period, chip->jitter);
++ ts->max_period = INV_SENSORS_TIMESTAMP_MAX(chip->clock_period, chip->jitter);
++
++ /* current multiplier and period values after reset */
++ ts->mult = chip->init_period / chip->clock_period;
++ ts->period = chip->init_period;
++
++ /* use theoretical value for chip period */
++ inv_update_acc(&ts->chip_period, chip->clock_period);
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_init, IIO_INV_SENSORS_TIMESTAMP);
++
++int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts,
++ uint32_t period, bool fifo)
++{
++ /* when FIFO is on, prevent odr change if one is already pending */
++ if (fifo && ts->new_mult != 0)
++ return -EAGAIN;
++
++ ts->new_mult = period / ts->chip.clock_period;
++
++ return 0;
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period, uint32_t mult)
++{
++ uint32_t period_min, period_max;
++
++ /* check that period is acceptable */
++ period_min = ts->min_period * mult;
++ period_max = ts->max_period * mult;
++ if (period > period_min && period < period_max)
++ return true;
++ else
++ return false;
++}
++
++static bool inv_compute_chip_period(struct inv_sensors_timestamp *ts,
++ uint32_t mult, uint32_t period)
++{
++ uint32_t new_chip_period;
++
++ if (!inv_validate_period(ts, period, mult))
++ return false;
++
++ /* update chip internal period estimation */
++ new_chip_period = period / mult;
++ inv_update_acc(&ts->chip_period, new_chip_period);
++
++ return true;
++}
++
++void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ size_t sensor_nb, int64_t timestamp)
++{
++ struct inv_sensors_timestamp_interval *it;
++ int64_t delta, interval;
++ const uint32_t fifo_mult = fifo_period / ts->chip.clock_period;
++ uint32_t period = ts->period;
++ int32_t m;
++ bool valid = false;
++
++ if (fifo_nb == 0)
++ return;
++
++ /* update interrupt timestamp and compute chip and sensor periods */
++ it = &ts->it;
++ it->lo = it->up;
++ it->up = timestamp;
++ delta = it->up - it->lo;
++ if (it->lo != 0) {
++ /* compute period: delta time divided by number of samples */
++ period = div_s64(delta, fifo_nb);
++ valid = inv_compute_chip_period(ts, fifo_mult, period);
++ /* update sensor period if chip internal period is updated */
++ if (valid)
++ ts->period = ts->mult * ts->chip_period.val;
++ }
++
++ /* no previous data, compute theoritical value from interrupt */
++ if (ts->timestamp == 0) {
++ /* elapsed time: sensor period * sensor samples number */
++ interval = (int64_t)ts->period * (int64_t)sensor_nb;
++ ts->timestamp = it->up - interval;
++ return;
++ }
++
++ /* if interrupt interval is valid, sync with interrupt timestamp */
++ if (valid) {
++ /* compute measured fifo_period */
++ fifo_period = fifo_mult * ts->chip_period.val;
++ /* delta time between last sample and last interrupt */
++ delta = it->lo - ts->timestamp;
++ /* if there are multiple samples, go back to first one */
++ while (delta >= (fifo_period * 3 / 2))
++ delta -= fifo_period;
++ /* compute maximal adjustment value */
++ m = INV_SENSORS_TIMESTAMP_JITTER((int64_t)ts->period, ts->chip.jitter);
++ if (delta > m)
++ delta = m;
++ else if (delta < -m)
++ delta = -m;
++ ts->timestamp += delta;
++ }
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP);
++
++void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ unsigned int fifo_no)
++{
++ int64_t interval;
++ uint32_t fifo_mult;
++
++ if (ts->new_mult == 0)
++ return;
++
++ /* update to new multiplier and update period */
++ ts->mult = ts->new_mult;
++ ts->new_mult = 0;
++ ts->period = ts->mult * ts->chip_period.val;
++
++ /*
++ * After ODR change the time interval with the previous sample is
++ * undertermined (depends when the change occures). So we compute the
++ * timestamp from the current interrupt using the new FIFO period, the
++ * total number of samples and the current sample numero.
++ */
++ if (ts->timestamp != 0) {
++ /* compute measured fifo period */
++ fifo_mult = fifo_period / ts->chip.clock_period;
++ fifo_period = fifo_mult * ts->chip_period.val;
++ /* computes time interval between interrupt and this sample */
++ interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
++ ts->timestamp = ts->it.up - interval;
++ }
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++MODULE_AUTHOR("InvenSense, Inc.");
++MODULE_DESCRIPTION("InvenSense sensors timestamp module");
++MODULE_LICENSE("GPL");
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -12,7 +12,7 @@
+ #include <linux/math64.h>
+
+ #include <linux/iio/buffer.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+
+@@ -99,7 +99,7 @@ static int inv_icm42600_accel_update_sca
+ const unsigned long *scan_mask)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+ unsigned int fifo_en = 0;
+ unsigned int sleep_temp = 0;
+@@ -127,7 +127,7 @@ static int inv_icm42600_accel_update_sca
+ }
+
+ /* update data FIFO write */
+- inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
++ inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+ ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
+
+ out_unlock:
+@@ -308,7 +308,7 @@ static int inv_icm42600_accel_write_odr(
+ int val, int val2)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ struct device *dev = regmap_get_device(st->map);
+ unsigned int idx;
+ struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+@@ -329,8 +329,8 @@ static int inv_icm42600_accel_write_odr(
+ pm_runtime_get_sync(dev);
+ mutex_lock(&st->lock);
+
+- ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
+- iio_buffer_enabled(indio_dev));
++ ret = inv_sensors_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
++ iio_buffer_enabled(indio_dev));
+ if (ret)
+ goto out_unlock;
+
+@@ -706,7 +706,8 @@ struct iio_dev *inv_icm42600_accel_init(
+ {
+ struct device *dev = regmap_get_device(st->map);
+ const char *name;
+- struct inv_icm42600_timestamp *ts;
++ struct inv_sensors_timestamp_chip ts_chip;
++ struct inv_sensors_timestamp *ts;
+ struct iio_dev *indio_dev;
+ struct iio_buffer *buffer;
+ int ret;
+@@ -723,8 +724,15 @@ struct iio_dev *inv_icm42600_accel_init(
+ if (!buffer)
+ return ERR_PTR(-ENOMEM);
+
++ /*
++ * clock period is 32kHz (31250ns)
++ * jitter is +/- 2% (20 per mille)
++ */
++ ts_chip.clock_period = 31250;
++ ts_chip.jitter = 20;
++ ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
+ ts = iio_priv(indio_dev);
+- inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.accel.odr));
++ inv_sensors_timestamp_init(ts, &ts_chip);
+
+ iio_device_set_drvdata(indio_dev, st);
+ indio_dev->name = name;
+@@ -747,7 +755,7 @@ struct iio_dev *inv_icm42600_accel_init(
+ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ ssize_t i, size;
+ unsigned int no;
+ const void *accel, *gyro, *timestamp;
+@@ -771,13 +779,13 @@ int inv_icm42600_accel_parse_fifo(struct
+
+ /* update odr */
+ if (odr & INV_ICM42600_SENSOR_ACCEL)
+- inv_icm42600_timestamp_apply_odr(ts, st->fifo.period,
+- st->fifo.nb.total, no);
++ inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
++ st->fifo.nb.total, no);
+
+ memcpy(&buffer.accel, accel, sizeof(buffer.accel));
+ /* convert 8 bits FIFO temperature in high resolution format */
+ buffer.temp = temp ? (*temp * 64) : 0;
+- ts_val = inv_icm42600_timestamp_pop(ts);
++ ts_val = inv_sensors_timestamp_pop(ts);
+ iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val);
+ }
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -11,7 +11,7 @@
+ #include <linux/delay.h>
+
+ #include <linux/iio/buffer.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+
+ #include "inv_icm42600.h"
+@@ -276,12 +276,12 @@ static int inv_icm42600_buffer_preenable
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+ struct device *dev = regmap_get_device(st->map);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+
+ pm_runtime_get_sync(dev);
+
+ mutex_lock(&st->lock);
+- inv_icm42600_timestamp_reset(ts);
++ inv_sensors_timestamp_reset(ts);
+ mutex_unlock(&st->lock);
+
+ return 0;
+@@ -378,7 +378,7 @@ out_unlock:
+ static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ struct device *dev = regmap_get_device(st->map);
+ unsigned int sensor;
+ unsigned int *watermark;
+@@ -400,7 +400,7 @@ static int inv_icm42600_buffer_postdisab
+
+ mutex_lock(&st->lock);
+
+- inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
++ inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+
+ ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor);
+ if (ret)
+@@ -508,7 +508,7 @@ int inv_icm42600_buffer_fifo_read(struct
+
+ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
+ {
+- struct inv_icm42600_timestamp *ts;
++ struct inv_sensors_timestamp *ts;
+ int ret;
+
+ if (st->fifo.nb.total == 0)
+@@ -516,8 +516,8 @@ int inv_icm42600_buffer_fifo_parse(struc
+
+ /* handle gyroscope timestamp and FIFO data parsing */
+ ts = iio_priv(st->indio_gyro);
+- inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+- st->fifo.nb.gyro, st->timestamp.gyro);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
++ st->fifo.nb.gyro, st->timestamp.gyro);
+ if (st->fifo.nb.gyro > 0) {
+ ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+ if (ret)
+@@ -526,8 +526,8 @@ int inv_icm42600_buffer_fifo_parse(struc
+
+ /* handle accelerometer timestamp and FIFO data parsing */
+ ts = iio_priv(st->indio_accel);
+- inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+- st->fifo.nb.accel, st->timestamp.accel);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
++ st->fifo.nb.accel, st->timestamp.accel);
+ if (st->fifo.nb.accel > 0) {
+ ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+ if (ret)
+@@ -540,7 +540,7 @@ int inv_icm42600_buffer_fifo_parse(struc
+ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
+ unsigned int count)
+ {
+- struct inv_icm42600_timestamp *ts;
++ struct inv_sensors_timestamp *ts;
+ int64_t gyro_ts, accel_ts;
+ int ret;
+
+@@ -556,9 +556,9 @@ int inv_icm42600_buffer_hwfifo_flush(str
+
+ if (st->fifo.nb.gyro > 0) {
+ ts = iio_priv(st->indio_gyro);
+- inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
+- st->fifo.nb.total, st->fifo.nb.gyro,
+- gyro_ts);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.period,
++ st->fifo.nb.total, st->fifo.nb.gyro,
++ gyro_ts);
+ ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+ if (ret)
+ return ret;
+@@ -566,9 +566,9 @@ int inv_icm42600_buffer_hwfifo_flush(str
+
+ if (st->fifo.nb.accel > 0) {
+ ts = iio_priv(st->indio_accel);
+- inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
+- st->fifo.nb.total, st->fifo.nb.accel,
+- accel_ts);
++ inv_sensors_timestamp_interrupt(ts, st->fifo.period,
++ st->fifo.nb.total, st->fifo.nb.accel,
++ accel_ts);
+ ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+ if (ret)
+ return ret;
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -16,7 +16,7 @@
+ #include <linux/property.h>
+ #include <linux/regmap.h>
+
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+
+ #include "inv_icm42600.h"
+@@ -720,8 +720,8 @@ out_unlock:
+ static int __maybe_unused inv_icm42600_resume(struct device *dev)
+ {
+ struct inv_icm42600_state *st = dev_get_drvdata(dev);
+- struct inv_icm42600_timestamp *gyro_ts = iio_priv(st->indio_gyro);
+- struct inv_icm42600_timestamp *accel_ts = iio_priv(st->indio_accel);
++ struct inv_sensors_timestamp *gyro_ts = iio_priv(st->indio_gyro);
++ struct inv_sensors_timestamp *accel_ts = iio_priv(st->indio_accel);
+ int ret = 0;
+
+ mutex_lock(&st->lock);
+@@ -742,8 +742,8 @@ static int __maybe_unused inv_icm42600_r
+
+ /* restore FIFO data streaming */
+ if (st->fifo.on) {
+- inv_icm42600_timestamp_reset(gyro_ts);
+- inv_icm42600_timestamp_reset(accel_ts);
++ inv_sensors_timestamp_reset(gyro_ts);
++ inv_sensors_timestamp_reset(accel_ts);
+ ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
+ INV_ICM42600_FIFO_CONFIG_STREAM);
+ }
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -12,7 +12,7 @@
+ #include <linux/math64.h>
+
+ #include <linux/iio/buffer.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+
+@@ -99,7 +99,7 @@ static int inv_icm42600_gyro_update_scan
+ const unsigned long *scan_mask)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+ unsigned int fifo_en = 0;
+ unsigned int sleep_gyro = 0;
+@@ -127,7 +127,7 @@ static int inv_icm42600_gyro_update_scan
+ }
+
+ /* update data FIFO write */
+- inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
++ inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+ ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
+
+ out_unlock:
+@@ -320,7 +320,7 @@ static int inv_icm42600_gyro_write_odr(s
+ int val, int val2)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ struct device *dev = regmap_get_device(st->map);
+ unsigned int idx;
+ struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+@@ -341,8 +341,8 @@ static int inv_icm42600_gyro_write_odr(s
+ pm_runtime_get_sync(dev);
+ mutex_lock(&st->lock);
+
+- ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
+- iio_buffer_enabled(indio_dev));
++ ret = inv_sensors_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
++ iio_buffer_enabled(indio_dev));
+ if (ret)
+ goto out_unlock;
+
+@@ -717,7 +717,8 @@ struct iio_dev *inv_icm42600_gyro_init(s
+ {
+ struct device *dev = regmap_get_device(st->map);
+ const char *name;
+- struct inv_icm42600_timestamp *ts;
++ struct inv_sensors_timestamp_chip ts_chip;
++ struct inv_sensors_timestamp *ts;
+ struct iio_dev *indio_dev;
+ struct iio_buffer *buffer;
+ int ret;
+@@ -734,8 +735,15 @@ struct iio_dev *inv_icm42600_gyro_init(s
+ if (!buffer)
+ return ERR_PTR(-ENOMEM);
+
++ /*
++ * clock period is 32kHz (31250ns)
++ * jitter is +/- 2% (20 per mille)
++ */
++ ts_chip.clock_period = 31250;
++ ts_chip.jitter = 20;
++ ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
+ ts = iio_priv(indio_dev);
+- inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.gyro.odr));
++ inv_sensors_timestamp_init(ts, &ts_chip);
+
+ iio_device_set_drvdata(indio_dev, st);
+ indio_dev->name = name;
+@@ -758,7 +766,7 @@ struct iio_dev *inv_icm42600_gyro_init(s
+ int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev)
+ {
+ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+- struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++ struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+ ssize_t i, size;
+ unsigned int no;
+ const void *accel, *gyro, *timestamp;
+@@ -782,13 +790,13 @@ int inv_icm42600_gyro_parse_fifo(struct
+
+ /* update odr */
+ if (odr & INV_ICM42600_SENSOR_GYRO)
+- inv_icm42600_timestamp_apply_odr(ts, st->fifo.period,
+- st->fifo.nb.total, no);
++ inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
++ st->fifo.nb.total, no);
+
+ memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro));
+ /* convert 8 bits FIFO temperature in high resolution format */
+ buffer.temp = temp ? (*temp * 64) : 0;
+- ts_val = inv_icm42600_timestamp_pop(ts);
++ ts_val = inv_sensors_timestamp_pop(ts);
+ iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val);
+ }
+
+--- a/include/linux/iio/common/inv_icm42600_timestamp.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-or-later */
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#ifndef INV_ICM42600_TIMESTAMP_H_
+-#define INV_ICM42600_TIMESTAMP_H_
+-
+-/**
+- * struct inv_icm42600_timestamp_interval - timestamps interval
+- * @lo: interval lower bound
+- * @up: interval upper bound
+- */
+-struct inv_icm42600_timestamp_interval {
+- int64_t lo;
+- int64_t up;
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation
+- * @val: current estimation of the value, the mean of all values
+- * @idx: current index of the next free place in values table
+- * @values: table of all measured values, use for computing the mean
+- */
+-struct inv_icm42600_timestamp_acc {
+- uint32_t val;
+- size_t idx;
+- uint32_t values[32];
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp - timestamp management states
+- * @it: interrupts interval timestamps
+- * @timestamp: store last timestamp for computing next data timestamp
+- * @mult: current internal period multiplier
+- * @new_mult: new set internal period multiplier (not yet effective)
+- * @period: measured current period of the sensor
+- * @chip_period: accumulator for computing internal chip period
+- */
+-struct inv_icm42600_timestamp {
+- struct inv_icm42600_timestamp_interval it;
+- int64_t timestamp;
+- uint32_t mult;
+- uint32_t new_mult;
+- uint32_t period;
+- struct inv_icm42600_timestamp_acc chip_period;
+-};
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+- uint32_t period);
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t period, bool fifo);
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- size_t sensor_nb, int64_t timestamp);
+-
+-static inline int64_t
+-inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts)
+-{
+- ts->timestamp += ts->period;
+- return ts->timestamp;
+-}
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- unsigned int fifo_no);
+-
+-static inline void
+-inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts)
+-{
+- const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL};
+-
+- ts->it = interval_init;
+- ts->timestamp = 0;
+-}
+-
+-#endif
+--- /dev/null
++++ b/include/linux/iio/common/inv_sensors_timestamp.h
+@@ -0,0 +1,95 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#ifndef INV_SENSORS_TIMESTAMP_H_
++#define INV_SENSORS_TIMESTAMP_H_
++
++/**
++ * struct inv_sensors_timestamp_chip - chip internal properties
++ * @clock_period: internal clock period in ns
++ * @jitter: acceptable jitter in per-mille
++ * @init_period: chip initial period at reset in ns
++ */
++struct inv_sensors_timestamp_chip {
++ uint32_t clock_period;
++ uint32_t jitter;
++ uint32_t init_period;
++};
++
++/**
++ * struct inv_sensors_timestamp_interval - timestamps interval
++ * @lo: interval lower bound
++ * @up: interval upper bound
++ */
++struct inv_sensors_timestamp_interval {
++ int64_t lo;
++ int64_t up;
++};
++
++/**
++ * struct inv_sensors_timestamp_acc - accumulator for computing an estimation
++ * @val: current estimation of the value, the mean of all values
++ * @idx: current index of the next free place in values table
++ * @values: table of all measured values, use for computing the mean
++ */
++struct inv_sensors_timestamp_acc {
++ uint32_t val;
++ size_t idx;
++ uint32_t values[32];
++};
++
++/**
++ * struct inv_sensors_timestamp - timestamp management states
++ * @chip: chip internal characteristics
++ * @min_period: minimal acceptable clock period
++ * @max_period: maximal acceptable clock period
++ * @it: interrupts interval timestamps
++ * @timestamp: store last timestamp for computing next data timestamp
++ * @mult: current internal period multiplier
++ * @new_mult: new set internal period multiplier (not yet effective)
++ * @period: measured current period of the sensor
++ * @chip_period: accumulator for computing internal chip period
++ */
++struct inv_sensors_timestamp {
++ struct inv_sensors_timestamp_chip chip;
++ uint32_t min_period;
++ uint32_t max_period;
++ struct inv_sensors_timestamp_interval it;
++ int64_t timestamp;
++ uint32_t mult;
++ uint32_t new_mult;
++ uint32_t period;
++ struct inv_sensors_timestamp_acc chip_period;
++};
++
++void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts,
++ const struct inv_sensors_timestamp_chip *chip);
++
++int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts,
++ uint32_t period, bool fifo);
++
++void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ size_t sensor_nb, int64_t timestamp);
++
++static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts)
++{
++ ts->timestamp += ts->period;
++ return ts->timestamp;
++}
++
++void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ unsigned int fifo_no);
++
++static inline void inv_sensors_timestamp_reset(struct inv_sensors_timestamp *ts)
++{
++ const struct inv_sensors_timestamp_interval interval_init = {0LL, 0LL};
++
++ ts->it = interval_init;
++ ts->timestamp = 0;
++}
++
++#endif
--- /dev/null
+From stable+bounces-274091-greg=kroah.com@vger.kernel.org Tue Jul 14 05:04:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:38 -0400
+Subject: iio: move inv_icm42600 timestamp module in common
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-2-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit d99ff463ecf651437e9e4abe68f331dfb6b5bd9d ]
+
+Create new inv_sensors common modules and move inv_icm42600
+timestamp module inside. This module will be used by IMUs and
+also in the future by other chips.
+
+Modify inv_icm42600 driver to use timestamp module and do some
+headers cleanup.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-3-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/Kconfig | 1 +
+ drivers/iio/common/Makefile | 1 +
+ drivers/iio/common/inv_sensors/Kconfig | 7 +++++++
+ drivers/iio/common/inv_sensors/Makefile | 6 ++++++
+ .../inv_sensors}/inv_icm42600_timestamp.c | 11 ++++++++++-
+ drivers/iio/imu/inv_icm42600/Kconfig | 1 +
+ drivers/iio/imu/inv_icm42600/Makefile | 1 -
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 5 +++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 5 +++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 4 +++-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 5 +++--
+ .../linux/iio/common}/inv_icm42600_timestamp.h | 0
+ drivers/iio/common/Kconfig | 1
+ drivers/iio/common/Makefile | 1
+ drivers/iio/common/inv_sensors/Kconfig | 7
+ drivers/iio/common/inv_sensors/Makefile | 6
+ drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c | 192 ++++++++++++++++
+ drivers/iio/imu/inv_icm42600/Kconfig | 1
+ drivers/iio/imu/inv_icm42600/Makefile | 1
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 5
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 5
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 4
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 5
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c | 183 ---------------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h | 79 ------
+ include/linux/iio/common/inv_icm42600_timestamp.h | 79 ++++++
+ 14 files changed, 299 insertions(+), 270 deletions(-)
+ create mode 100644 drivers/iio/common/inv_sensors/Kconfig
+ create mode 100644 drivers/iio/common/inv_sensors/Makefile
+ rename drivers/iio/{imu/inv_icm42600 => common/inv_sensors}/inv_icm42600_timestamp.c (91%)
+ rename {drivers/iio/imu/inv_icm42600 => include/linux/iio/common}/inv_icm42600_timestamp.h (100%)
+
+--- a/drivers/iio/common/Kconfig
++++ b/drivers/iio/common/Kconfig
+@@ -5,6 +5,7 @@
+
+ source "drivers/iio/common/cros_ec_sensors/Kconfig"
+ source "drivers/iio/common/hid-sensors/Kconfig"
++source "drivers/iio/common/inv_sensors/Kconfig"
+ source "drivers/iio/common/ms_sensors/Kconfig"
+ source "drivers/iio/common/ssp_sensors/Kconfig"
+ source "drivers/iio/common/st_sensors/Kconfig"
+--- a/drivers/iio/common/Makefile
++++ b/drivers/iio/common/Makefile
+@@ -10,6 +10,7 @@
+ # When adding new entries keep the list in alphabetical order
+ obj-y += cros_ec_sensors/
+ obj-y += hid-sensors/
++obj-y += inv_sensors/
+ obj-y += ms_sensors/
+ obj-y += ssp_sensors/
+ obj-y += st_sensors/
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/Kconfig
+@@ -0,0 +1,7 @@
++# SPDX-License-Identifier: GPL-2.0-only
++#
++# TDK-InvenSense sensors common library
++#
++
++config IIO_INV_SENSORS_TIMESTAMP
++ tristate
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/Makefile
+@@ -0,0 +1,6 @@
++# SPDX-License-Identifier: GPL-2.0
++#
++# Makefile for TDK-InvenSense sensors module.
++#
++
++obj-$(CONFIG_IIO_INV_SENSORS_TIMESTAMP) += inv_icm42600_timestamp.o
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c
+@@ -0,0 +1,192 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++
++/* internal chip period is 32kHz, 31250ns */
++#define INV_ICM42600_TIMESTAMP_PERIOD 31250
++/* allow a jitter of +/- 2% */
++#define INV_ICM42600_TIMESTAMP_JITTER 2
++/* compute min and max periods accepted */
++#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p) \
++ (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100)
++#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p) \
++ (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100)
++
++/* Add a new value inside an accumulator and update the estimate value */
++static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val)
++{
++ uint64_t sum = 0;
++ size_t i;
++
++ acc->values[acc->idx++] = val;
++ if (acc->idx >= ARRAY_SIZE(acc->values))
++ acc->idx = 0;
++
++ /* compute the mean of all stored values, use 0 as empty slot */
++ for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
++ if (acc->values[i] == 0)
++ break;
++ sum += acc->values[i];
++ }
++
++ acc->val = div_u64(sum, i);
++}
++
++void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
++ uint32_t period)
++{
++ /* initial odr for sensor after reset is 1kHz */
++ const uint32_t default_period = 1000000;
++
++ /* current multiplier and period values after reset */
++ ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD;
++ ts->period = default_period;
++ /* new set multiplier is the one from chip initialization */
++ ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
++
++ /* use theoretical value for chip period */
++ inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_init, IIO_INV_SENSORS_TIMESTAMP);
++
++int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
++ uint32_t period, bool fifo)
++{
++ /* when FIFO is on, prevent odr change if one is already pending */
++ if (fifo && ts->new_mult != 0)
++ return -EAGAIN;
++
++ ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
++
++ return 0;
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++static bool inv_validate_period(uint32_t period, uint32_t mult)
++{
++ const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD;
++ uint32_t period_min, period_max;
++
++ /* check that period is acceptable */
++ period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult;
++ period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult;
++ if (period > period_min && period < period_max)
++ return true;
++ else
++ return false;
++}
++
++static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts,
++ uint32_t mult, uint32_t period)
++{
++ uint32_t new_chip_period;
++
++ if (!inv_validate_period(period, mult))
++ return false;
++
++ /* update chip internal period estimation */
++ new_chip_period = period / mult;
++ inv_update_acc(&ts->chip_period, new_chip_period);
++
++ return true;
++}
++
++void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ size_t sensor_nb, int64_t timestamp)
++{
++ struct inv_icm42600_timestamp_interval *it;
++ int64_t delta, interval;
++ const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
++ uint32_t period = ts->period;
++ int32_t m;
++ bool valid = false;
++
++ if (fifo_nb == 0)
++ return;
++
++ /* update interrupt timestamp and compute chip and sensor periods */
++ it = &ts->it;
++ it->lo = it->up;
++ it->up = timestamp;
++ delta = it->up - it->lo;
++ if (it->lo != 0) {
++ /* compute period: delta time divided by number of samples */
++ period = div_s64(delta, fifo_nb);
++ valid = inv_compute_chip_period(ts, fifo_mult, period);
++ /* update sensor period if chip internal period is updated */
++ if (valid)
++ ts->period = ts->mult * ts->chip_period.val;
++ }
++
++ /* no previous data, compute theoritical value from interrupt */
++ if (ts->timestamp == 0) {
++ /* elapsed time: sensor period * sensor samples number */
++ interval = (int64_t)ts->period * (int64_t)sensor_nb;
++ ts->timestamp = it->up - interval;
++ return;
++ }
++
++ /* if interrupt interval is valid, sync with interrupt timestamp */
++ if (valid) {
++ /* compute measured fifo_period */
++ fifo_period = fifo_mult * ts->chip_period.val;
++ /* delta time between last sample and last interrupt */
++ delta = it->lo - ts->timestamp;
++ /* if there are multiple samples, go back to first one */
++ while (delta >= (fifo_period * 3 / 2))
++ delta -= fifo_period;
++ /* compute maximal adjustment value */
++ m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period;
++ if (delta > m)
++ delta = m;
++ else if (delta < -m)
++ delta = -m;
++ ts->timestamp += delta;
++ }
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP);
++
++void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ unsigned int fifo_no)
++{
++ int64_t interval;
++ uint32_t fifo_mult;
++
++ if (ts->new_mult == 0)
++ return;
++
++ /* update to new multiplier and update period */
++ ts->mult = ts->new_mult;
++ ts->new_mult = 0;
++ ts->period = ts->mult * ts->chip_period.val;
++
++ /*
++ * After ODR change the time interval with the previous sample is
++ * undertermined (depends when the change occures). So we compute the
++ * timestamp from the current interrupt using the new FIFO period, the
++ * total number of samples and the current sample numero.
++ */
++ if (ts->timestamp != 0) {
++ /* compute measured fifo period */
++ fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
++ fifo_period = fifo_mult * ts->chip_period.val;
++ /* computes time interval between interrupt and this sample */
++ interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
++ ts->timestamp = ts->it.up - interval;
++ }
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++MODULE_AUTHOR("InvenSense, Inc.");
++MODULE_DESCRIPTION("InvenSense sensors timestamp module");
++MODULE_LICENSE("GPL");
+--- a/drivers/iio/imu/inv_icm42600/Kconfig
++++ b/drivers/iio/imu/inv_icm42600/Kconfig
+@@ -3,6 +3,7 @@
+ config INV_ICM42600
+ tristate
+ select IIO_BUFFER
++ select IIO_INV_SENSORS_TIMESTAMP
+
+ config INV_ICM42600_I2C
+ tristate "InvenSense ICM-426xx I2C driver"
+--- a/drivers/iio/imu/inv_icm42600/Makefile
++++ b/drivers/iio/imu/inv_icm42600/Makefile
+@@ -6,7 +6,6 @@ inv-icm42600-y += inv_icm42600_gyro.o
+ inv-icm42600-y += inv_icm42600_accel.o
+ inv-icm42600-y += inv_icm42600_temp.o
+ inv-icm42600-y += inv_icm42600_buffer.o
+-inv-icm42600-y += inv_icm42600_timestamp.o
+
+ obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o
+ inv-icm42600-i2c-y += inv_icm42600_i2c.o
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -10,14 +10,15 @@
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+ #include <linux/math64.h>
+-#include <linux/iio/iio.h>
++
+ #include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_temp.h"
+ #include "inv_icm42600_buffer.h"
+-#include "inv_icm42600_timestamp.h"
+
+ #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \
+ { \
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -9,11 +9,12 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+-#include <linux/iio/iio.h>
++
+ #include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/iio.h>
+
+ #include "inv_icm42600.h"
+-#include "inv_icm42600_timestamp.h"
+ #include "inv_icm42600_buffer.h"
+
+ /* FIFO header: 1 byte */
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -15,11 +15,12 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/property.h>
+ #include <linux/regmap.h>
++
++#include <linux/iio/common/inv_icm42600_timestamp.h>
+ #include <linux/iio/iio.h>
+
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_buffer.h"
+-#include "inv_icm42600_timestamp.h"
+
+ static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = {
+ {
+@@ -798,3 +799,4 @@ EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops);
+ MODULE_AUTHOR("InvenSense, Inc.");
+ MODULE_DESCRIPTION("InvenSense ICM-426xx device driver");
+ MODULE_LICENSE("GPL");
++MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP);
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -10,14 +10,15 @@
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+ #include <linux/math64.h>
+-#include <linux/iio/iio.h>
++
+ #include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_temp.h"
+ #include "inv_icm42600_buffer.h"
+-#include "inv_icm42600_timestamp.h"
+
+ #define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info) \
+ { \
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c
++++ /dev/null
+@@ -1,183 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-or-later
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/kernel.h>
+-#include <linux/math64.h>
+-
+-#include "inv_icm42600_timestamp.h"
+-
+-/* internal chip period is 32kHz, 31250ns */
+-#define INV_ICM42600_TIMESTAMP_PERIOD 31250
+-/* allow a jitter of +/- 2% */
+-#define INV_ICM42600_TIMESTAMP_JITTER 2
+-/* compute min and max periods accepted */
+-#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p) \
+- (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p) \
+- (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-
+-/* Add a new value inside an accumulator and update the estimate value */
+-static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val)
+-{
+- uint64_t sum = 0;
+- size_t i;
+-
+- acc->values[acc->idx++] = val;
+- if (acc->idx >= ARRAY_SIZE(acc->values))
+- acc->idx = 0;
+-
+- /* compute the mean of all stored values, use 0 as empty slot */
+- for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
+- if (acc->values[i] == 0)
+- break;
+- sum += acc->values[i];
+- }
+-
+- acc->val = div_u64(sum, i);
+-}
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+- uint32_t period)
+-{
+- /* initial odr for sensor after reset is 1kHz */
+- const uint32_t default_period = 1000000;
+-
+- /* current multiplier and period values after reset */
+- ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD;
+- ts->period = default_period;
+- /* new set multiplier is the one from chip initialization */
+- ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+- /* use theoretical value for chip period */
+- inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
+-}
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t period, bool fifo)
+-{
+- /* when FIFO is on, prevent odr change if one is already pending */
+- if (fifo && ts->new_mult != 0)
+- return -EAGAIN;
+-
+- ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+- return 0;
+-}
+-
+-static bool inv_validate_period(uint32_t period, uint32_t mult)
+-{
+- const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD;
+- uint32_t period_min, period_max;
+-
+- /* check that period is acceptable */
+- period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult;
+- period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult;
+- if (period > period_min && period < period_max)
+- return true;
+- else
+- return false;
+-}
+-
+-static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts,
+- uint32_t mult, uint32_t period)
+-{
+- uint32_t new_chip_period;
+-
+- if (!inv_validate_period(period, mult))
+- return false;
+-
+- /* update chip internal period estimation */
+- new_chip_period = period / mult;
+- inv_update_acc(&ts->chip_period, new_chip_period);
+-
+- return true;
+-}
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- size_t sensor_nb, int64_t timestamp)
+-{
+- struct inv_icm42600_timestamp_interval *it;
+- int64_t delta, interval;
+- const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+- uint32_t period = ts->period;
+- int32_t m;
+- bool valid = false;
+-
+- if (fifo_nb == 0)
+- return;
+-
+- /* update interrupt timestamp and compute chip and sensor periods */
+- it = &ts->it;
+- it->lo = it->up;
+- it->up = timestamp;
+- delta = it->up - it->lo;
+- if (it->lo != 0) {
+- /* compute period: delta time divided by number of samples */
+- period = div_s64(delta, fifo_nb);
+- valid = inv_compute_chip_period(ts, fifo_mult, period);
+- /* update sensor period if chip internal period is updated */
+- if (valid)
+- ts->period = ts->mult * ts->chip_period.val;
+- }
+-
+- /* no previous data, compute theoritical value from interrupt */
+- if (ts->timestamp == 0) {
+- /* elapsed time: sensor period * sensor samples number */
+- interval = (int64_t)ts->period * (int64_t)sensor_nb;
+- ts->timestamp = it->up - interval;
+- return;
+- }
+-
+- /* if interrupt interval is valid, sync with interrupt timestamp */
+- if (valid) {
+- /* compute measured fifo_period */
+- fifo_period = fifo_mult * ts->chip_period.val;
+- /* delta time between last sample and last interrupt */
+- delta = it->lo - ts->timestamp;
+- /* if there are multiple samples, go back to first one */
+- while (delta >= (fifo_period * 3 / 2))
+- delta -= fifo_period;
+- /* compute maximal adjustment value */
+- m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period;
+- if (delta > m)
+- delta = m;
+- else if (delta < -m)
+- delta = -m;
+- ts->timestamp += delta;
+- }
+-}
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- unsigned int fifo_no)
+-{
+- int64_t interval;
+- uint32_t fifo_mult;
+-
+- if (ts->new_mult == 0)
+- return;
+-
+- /* update to new multiplier and update period */
+- ts->mult = ts->new_mult;
+- ts->new_mult = 0;
+- ts->period = ts->mult * ts->chip_period.val;
+-
+- /*
+- * After ODR change the time interval with the previous sample is
+- * undertermined (depends when the change occures). So we compute the
+- * timestamp from the current interrupt using the new FIFO period, the
+- * total number of samples and the current sample numero.
+- */
+- if (ts->timestamp != 0) {
+- /* compute measured fifo period */
+- fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+- fifo_period = fifo_mult * ts->chip_period.val;
+- /* computes time interval between interrupt and this sample */
+- interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
+- ts->timestamp = ts->it.up - interval;
+- }
+-}
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-or-later */
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#ifndef INV_ICM42600_TIMESTAMP_H_
+-#define INV_ICM42600_TIMESTAMP_H_
+-
+-/**
+- * struct inv_icm42600_timestamp_interval - timestamps interval
+- * @lo: interval lower bound
+- * @up: interval upper bound
+- */
+-struct inv_icm42600_timestamp_interval {
+- int64_t lo;
+- int64_t up;
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation
+- * @val: current estimation of the value, the mean of all values
+- * @idx: current index of the next free place in values table
+- * @values: table of all measured values, use for computing the mean
+- */
+-struct inv_icm42600_timestamp_acc {
+- uint32_t val;
+- size_t idx;
+- uint32_t values[32];
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp - timestamp management states
+- * @it: interrupts interval timestamps
+- * @timestamp: store last timestamp for computing next data timestamp
+- * @mult: current internal period multiplier
+- * @new_mult: new set internal period multiplier (not yet effective)
+- * @period: measured current period of the sensor
+- * @chip_period: accumulator for computing internal chip period
+- */
+-struct inv_icm42600_timestamp {
+- struct inv_icm42600_timestamp_interval it;
+- int64_t timestamp;
+- uint32_t mult;
+- uint32_t new_mult;
+- uint32_t period;
+- struct inv_icm42600_timestamp_acc chip_period;
+-};
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+- uint32_t period);
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t period, bool fifo);
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- size_t sensor_nb, int64_t timestamp);
+-
+-static inline int64_t
+-inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts)
+-{
+- ts->timestamp += ts->period;
+- return ts->timestamp;
+-}
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+- uint32_t fifo_period, size_t fifo_nb,
+- unsigned int fifo_no);
+-
+-static inline void
+-inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts)
+-{
+- const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL};
+-
+- ts->it = interval_init;
+- ts->timestamp = 0;
+-}
+-
+-#endif
+--- /dev/null
++++ b/include/linux/iio/common/inv_icm42600_timestamp.h
+@@ -0,0 +1,79 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#ifndef INV_ICM42600_TIMESTAMP_H_
++#define INV_ICM42600_TIMESTAMP_H_
++
++/**
++ * struct inv_icm42600_timestamp_interval - timestamps interval
++ * @lo: interval lower bound
++ * @up: interval upper bound
++ */
++struct inv_icm42600_timestamp_interval {
++ int64_t lo;
++ int64_t up;
++};
++
++/**
++ * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation
++ * @val: current estimation of the value, the mean of all values
++ * @idx: current index of the next free place in values table
++ * @values: table of all measured values, use for computing the mean
++ */
++struct inv_icm42600_timestamp_acc {
++ uint32_t val;
++ size_t idx;
++ uint32_t values[32];
++};
++
++/**
++ * struct inv_icm42600_timestamp - timestamp management states
++ * @it: interrupts interval timestamps
++ * @timestamp: store last timestamp for computing next data timestamp
++ * @mult: current internal period multiplier
++ * @new_mult: new set internal period multiplier (not yet effective)
++ * @period: measured current period of the sensor
++ * @chip_period: accumulator for computing internal chip period
++ */
++struct inv_icm42600_timestamp {
++ struct inv_icm42600_timestamp_interval it;
++ int64_t timestamp;
++ uint32_t mult;
++ uint32_t new_mult;
++ uint32_t period;
++ struct inv_icm42600_timestamp_acc chip_period;
++};
++
++void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
++ uint32_t period);
++
++int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
++ uint32_t period, bool fifo);
++
++void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ size_t sensor_nb, int64_t timestamp);
++
++static inline int64_t
++inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts)
++{
++ ts->timestamp += ts->period;
++ return ts->timestamp;
++}
++
++void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
++ uint32_t fifo_period, size_t fifo_nb,
++ unsigned int fifo_no);
++
++static inline void
++inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts)
++{
++ const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL};
++
++ ts->it = interval_init;
++ ts->timestamp = 0;
++}
++
++#endif
--- /dev/null
+From stable+bounces-277537-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:37 -0400
+Subject: leds: lm3601x: Improve error reporting for problems during .remove()
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Pavel Machek" <pavel@ucw.cz>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-3-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 22a23436891886a66d21af3619f4a4e8809f0e0a ]
+
+Returning an error value in an i2c remove callback results in a generic
+error message being emitted by the i2c core, but otherwise it doesn't
+make a difference. The device goes away anyhow and the devm cleanups are
+called.
+
+So instead of triggering the generic i2c error message, emit a more
+helpful message if a problem occurs and return 0 to suppress the generic
+message.
+
+This patch is a preparation for making i2c remove callbacks return void.
+
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lm3601x.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/leds/leds-lm3601x.c
++++ b/drivers/leds/leds-lm3601x.c
+@@ -443,10 +443,15 @@ static int lm3601x_probe(struct i2c_clie
+ static int lm3601x_remove(struct i2c_client *client)
+ {
+ struct lm3601x_led *led = i2c_get_clientdata(client);
++ int ret;
+
+- return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+- LM3601X_ENABLE_MASK,
+- LM3601X_MODE_STANDBY);
++ ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
++ LM3601X_ENABLE_MASK, LM3601X_MODE_STANDBY);
++ if (ret)
++ dev_warn(&client->dev,
++ "Failed to put into standby (%pe)\n", ERR_PTR(ret));
++
++ return 0;
+ }
+
+ static const struct i2c_device_id lm3601x_id[] = {
--- /dev/null
+From stable+bounces-277536-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:36 -0400
+Subject: leds: lm3697: Remove duplicated error reporting in .remove()
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Pavel Machek" <pavel@ucw.cz>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit af89fa11fae1cee4e07453f780e6e5573ef0f477 ]
+
+Returning an error value from an i2c remove callback results in an error
+message being emitted by the i2c core, but otherwise it doesn't make a
+difference. The device goes away anyhow and the devm cleanups are
+called.
+
+As lm3697_remove() already emits an error message on failure and the
+additional error message by the i2c core doesn't add any useful
+information, don't pass the error value up the stack. Instead continue
+to clean up and return 0.
+
+This patch is a preparation for making i2c remove callbacks return void.
+
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lm3697.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/leds/leds-lm3697.c
++++ b/drivers/leds/leds-lm3697.c
+@@ -337,10 +337,8 @@ static int lm3697_remove(struct i2c_clie
+
+ ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE,
+ LM3697_CTRL_A_B_EN, 0);
+- if (ret) {
++ if (ret)
+ dev_err(dev, "Failed to disable the device\n");
+- return ret;
+- }
+
+ if (led->enable_gpio)
+ gpiod_direction_output(led->enable_gpio, 0);
--- /dev/null
+From stable+bounces-274527-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:53 -0400
+Subject: media: atomisp: replace boolean comparison of values with bool variables
+To: stable@vger.kernel.org
+Cc: Aditya Srivastava <yashsri421@gmail.com>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-1-sashal@kernel.org>
+
+From: Aditya Srivastava <yashsri421@gmail.com>
+
+[ Upstream commit c606970d4250dfb95869a563975c08bab148137a ]
+
+There are certain expressions in a condition in atomisp, where a boolean
+variable is compared with true/false in forms such as (foo == true)
+or (false != bar), which does not comply with the coding style rule by
+checkpatch.pl (CHK: BOOL_COMPARISON), according to which the boolean
+variables should be themselves used in the condition, rather than
+comparing with true or false.
+
+E.g. In drivers/staging/media/atomisp/pci/atomisp_compat_css20.c:
+
+if (asd->stream_prepared == false) {
+
+Can be replaced with:
+if (!asd->stream_prepared) {
+
+Replace such expressions with boolean variables appropriately.
+
+Link: https://lore.kernel.org/linux-media/20201214132716.28157-1-yashsri421@gmail.com
+Signed-off-by: Aditya Srivastava <yashsri421@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/atomisp_compat_css20.c | 2 -
+ drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c | 12 +++++-----
+ drivers/staging/media/atomisp/pci/sh_css.c | 12 +++++-----
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
++++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+@@ -1142,7 +1142,7 @@ int atomisp_css_start(struct atomisp_sub
+ * Thus the stream created in set_fmt get destroyed and need to be
+ * recreated in the next stream on.
+ */
+- if (asd->stream_prepared == false) {
++ if (!asd->stream_prepared) {
+ if (__create_pipes(asd)) {
+ dev_err(isp->dev, "create pipe error.\n");
+ return -EINVAL;
+--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
++++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
+@@ -179,12 +179,12 @@ ia_css_isys_error_t ia_css_isys_stream_c
+ isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id;
+ rc = create_input_system_input_port(isys_stream_descr,
+ &isys_stream->input_port);
+- if (rc == false)
++ if (!rc)
+ return false;
+
+ rc = create_input_system_channel(isys_stream_descr, false,
+ &isys_stream->channel);
+- if (rc == false) {
++ if (!rc) {
+ destroy_input_system_input_port(&isys_stream->input_port);
+ return false;
+ }
+@@ -204,7 +204,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+ if (isys_stream_descr->metadata.enable) {
+ rc = create_input_system_channel(isys_stream_descr, true,
+ &isys_stream->md_channel);
+- if (rc == false) {
++ if (!rc) {
+ destroy_input_system_input_port(&isys_stream->input_port);
+ destroy_input_system_channel(&isys_stream->channel);
+ return false;
+@@ -248,7 +248,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+ isys_stream_descr,
+ &isys_stream_cfg->channel_cfg,
+ false);
+- if (rc == false)
++ if (!rc)
+ return false;
+
+ /* configure metadata channel */
+@@ -260,7 +260,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+ isys_stream_descr,
+ &isys_stream_cfg->md_channel_cfg,
+ true);
+- if (rc == false)
++ if (!rc)
+ return false;
+ }
+
+@@ -269,7 +269,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+ &isys_stream->input_port,
+ isys_stream_descr,
+ &isys_stream_cfg->input_port_cfg);
+- if (rc == false)
++ if (!rc)
+ return false;
+
+ isys_stream->valid = 1;
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -1058,7 +1058,7 @@ sh_css_config_input_network(struct ia_cs
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "sh_css_config_input_network() enter 0x%p:\n", stream);
+
+- if (stream->config.continuous == true)
++ if (stream->config.continuous)
+ {
+ if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
+ pipe = stream->last_pipe;
+@@ -5622,7 +5622,7 @@ static int load_video_binaries(struct ia
+ } else {
+ /* output from main binary is not yuv line. currently this is
+ * possible only when bci is enabled on vfpp output */
+- assert(pipe->config.enable_vfpp_bci == true);
++ assert(pipe->config.enable_vfpp_bci);
+ ia_css_pipe_get_yuvscaler_binarydesc(pipe, &vf_pp_descr,
+ &mycs->video_binary.vf_frame_info,
+ pipe_vf_out_info, NULL, NULL);
+@@ -8068,7 +8068,7 @@ create_host_regular_capture_pipeline(str
+ struct ia_css_frame *tmp_out_frame = NULL;
+
+ for (i = 0; i < num_yuv_scaler; i++) {
+- if (is_output_stage[i] == true)
++ if (is_output_stage[i])
+ tmp_out_frame = out_frame;
+ else
+ tmp_out_frame = NULL;
+@@ -8460,7 +8460,7 @@ sh_css_pipeline_add_acc_stage(struct ia_
+ /* In QoS case, load_extension already called, so skipping */
+ int err = 0;
+
+- if (fw->loaded == false)
++ if (!fw->loaded)
+ err = acc_load_extension(fw);
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -9697,8 +9697,8 @@ ia_css_stream_destroy(struct ia_css_stre
+ assert(entry);
+ if (entry) {
+ /* get the SP thread id */
+- if (ia_css_pipeline_get_sp_thread_id(
+- ia_css_pipe_get_pipe_num(entry), &sp_thread_id) != true)
++ if (!ia_css_pipeline_get_sp_thread_id(
++ ia_css_pipe_get_pipe_num(entry), &sp_thread_id))
+ return -EINVAL;
+ /* get the target input terminal */
+ sp_pipeline_input_terminal =
--- /dev/null
+From stable+bounces-274531-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:57 -0400
+Subject: media: staging: media: atomisp: Fix alignment and line length issues
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-5-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit 7796e455170efa1823457b17a292b1c65bb8c1e0 ]
+
+Fix alignment style issues and adjacent line length issues in sh_css.c
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 619 +++++++++++++++--------------
+ 1 file changed, 333 insertions(+), 286 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -242,8 +242,8 @@ ia_css_reset_defaults(struct sh_css *css
+ static void
+ sh_css_init_host_sp_control_vars(void);
+
+-static int set_num_primary_stages(unsigned int *num,
+- enum ia_css_pipe_version version);
++static int
++set_num_primary_stages(unsigned int *num, enum ia_css_pipe_version version);
+
+ static bool
+ need_capture_pp(const struct ia_css_pipe *pipe);
+@@ -3002,9 +3002,8 @@ static int add_firmwares(
+
+ ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary,
+ out, in, vf, fw, binary_mode);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- &extra_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ &extra_stage);
+ if (err)
+ return err;
+ if (fw->info.isp.sp.enable.output != 0)
+@@ -3112,9 +3111,8 @@ static int add_yuv_scaler_stage(
+ ia_css_pipe_get_generic_stage_desc(&stage_desc,
+ yuv_scaler_binary, out_frames, in_frame, vf_frame);
+ }
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- pre_vf_pp_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ pre_vf_pp_stage);
+ if (err)
+ return err;
+ in_frame = (*pre_vf_pp_stage)->args.out_frame[0];
+@@ -3172,9 +3170,8 @@ static int add_capture_pp_stage(
+ ia_css_pipe_get_generic_stage_desc(&stage_desc,
+ capture_pp_binary, out_frames, NULL, vf_frame);
+ }
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- capture_pp_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ capture_pp_stage);
+ if (err)
+ return err;
+ err = add_firmwares(me, capture_pp_binary, pipe->output_stage, last_fw,
+@@ -3529,9 +3526,8 @@ static int create_host_video_pipeline(st
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+ out_frames, NULL, NULL);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- ©_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ ©_stage);
+ if (err)
+ goto ERR;
+ in_frame = me->stages->args.out_frame[0];
+@@ -3558,9 +3554,8 @@ static int create_host_video_pipeline(st
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
+ out_frames, in_frame, vf_frame);
+ }
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- &video_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ &video_stage);
+ if (err)
+ goto ERR;
+
+@@ -3625,8 +3620,8 @@ static int create_host_video_pipeline(st
+ for (i = 0; i < num_yuv_scaler; i++) {
+ tmp_out_frame = is_output_stage[i] ? out_frame : NULL;
+
+- err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+- NULL,
++ err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
++ tmp_out_frame, NULL,
+ &yuv_scaler_binary[i],
+ &yuv_scaler_stage);
+
+@@ -3765,9 +3760,8 @@ create_host_preview_pipeline(struct ia_c
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+ out_frames, NULL, NULL);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- ©_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ ©_stage);
+ if (err)
+ goto ERR;
+ in_frame = me->stages->args.out_frame[0];
+@@ -3793,9 +3787,8 @@ create_host_preview_pipeline(struct ia_c
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
+ out_frames, in_frame, NULL);
+ }
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- &preview_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ &preview_stage);
+ if (err)
+ goto ERR;
+ /* If we use copy iso preview, the input must be yuv iso raw */
+@@ -4131,8 +4124,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ }
+
+ hmm_store(h_vbuf->vptr,
+- (void *)(&ddr_buffer),
+- sizeof(struct sh_css_hmm_buffer));
++ (void *)(&ddr_buffer),
++ sizeof(struct sh_css_hmm_buffer));
+ if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
+ || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
+ || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) {
+@@ -4293,8 +4286,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+ }
+
+ hmm_load(ddr_buffer_addr,
+- &ddr_buffer,
+- sizeof(struct sh_css_hmm_buffer));
++ &ddr_buffer,
++ sizeof(struct sh_css_hmm_buffer));
+
+ /* if the kernel_ptr is 0 or an invalid, return an error.
+ * do not access the buffer via the kernal_ptr.
+@@ -4949,7 +4942,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+ for (i = 0; i < stream->num_pipes; i++) {
+ /* send the "stop" request to the "ia_css_pipe" instance */
+ IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
+- stream->pipes[i]->pipeline.pipe_id);
++ stream->pipes[i]->pipeline.pipe_id);
+ err = ia_css_pipeline_request_stop(&stream->pipes[i]->pipeline);
+
+ /*
+@@ -4999,7 +4992,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+
+ /* send the "stop" request to "Copy Pipe" */
+ IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
+- copy_pipe->pipeline.pipe_id);
++ copy_pipe->pipeline.pipe_id);
+ err = ia_css_pipeline_request_stop(©_pipe->pipeline);
+ }
+
+@@ -5832,7 +5825,7 @@ static bool need_capt_ldc(
+ }
+
+ static int set_num_primary_stages(unsigned int *num,
+- enum ia_css_pipe_version version)
++ enum ia_css_pipe_version version)
+ {
+ int err = 0;
+
+@@ -6032,10 +6025,13 @@ static int load_primary_binaries(
+ capt_pp_in_info = &prim_out_info;
+
+ ia_css_pipe_get_capturepp_binarydesc(pipe,
+- &capture_pp_descr, capt_pp_in_info,
+- &capt_pp_out_info, &vf_info);
++ &capture_pp_descr,
++ capt_pp_in_info,
++ &capt_pp_out_info,
++ &vf_info);
++
+ err = ia_css_binary_find(&capture_pp_descr,
+- &mycs->capture_pp_binary);
++ &mycs->capture_pp_binary);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -6045,11 +6041,12 @@ static int load_primary_binaries(
+ struct ia_css_binary_descr capt_ldc_descr;
+
+ ia_css_pipe_get_ldc_binarydesc(pipe,
+- &capt_ldc_descr, &prim_out_info,
+- &capt_ldc_out_info);
++ &capt_ldc_descr,
++ &prim_out_info,
++ &capt_ldc_out_info);
+
+ err = ia_css_binary_find(&capt_ldc_descr,
+- &mycs->capture_ldc_binary);
++ &mycs->capture_ldc_binary);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -6066,8 +6063,9 @@ static int load_primary_binaries(
+ if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
+ (i == mycs->num_primary_stage - 1))
+ local_vf_info = &vf_info;
+- ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], &prim_in_info,
+- &prim_out_info, local_vf_info, i);
++ ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i],
++ &prim_in_info, &prim_out_info,
++ local_vf_info, i);
+ err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -6119,8 +6117,8 @@ static int load_primary_binaries(
+ /* ISP Copy */
+ if (need_isp_copy_binary) {
+ err = load_copy_binary(pipe,
+- &mycs->copy_binary,
+- &mycs->primary_binary[0]);
++ &mycs->copy_binary,
++ &mycs->primary_binary[0]);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -6229,7 +6227,7 @@ static int load_advanced_binaries(
+
+ assert(pipe);
+ assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+- pipe->mode == IA_CSS_PIPE_ID_COPY);
++ pipe->mode == IA_CSS_PIPE_ID_COPY);
+ if (pipe->pipe_settings.capture.pre_isp_binary.info)
+ return 0;
+ pipe_out_info = &pipe->output_info[0];
+@@ -6242,17 +6240,18 @@ static int load_advanced_binaries(
+ need_pp = need_capture_pp(pipe);
+
+ ia_css_frame_info_set_format(&vf_info,
+- IA_CSS_FRAME_FORMAT_YUV_LINE);
++ IA_CSS_FRAME_FORMAT_YUV_LINE);
+
+ /* we build up the pipeline starting at the end */
+ /* Capture post-processing */
+ if (need_pp) {
+ struct ia_css_binary_descr capture_pp_descr;
+
+- ia_css_pipe_get_capturepp_binarydesc(pipe,
+- &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
++ ia_css_pipe_get_capturepp_binarydesc(pipe, &capture_pp_descr,
++ &post_out_info,
++ pipe_out_info, &vf_info);
+ err = ia_css_binary_find(&capture_pp_descr,
+- &pipe->pipe_settings.capture.capture_pp_binary);
++ &pipe->pipe_settings.capture.capture_pp_binary);
+ if (err)
+ return err;
+ } else {
+@@ -6263,10 +6262,11 @@ static int load_advanced_binaries(
+ {
+ struct ia_css_binary_descr post_gdc_descr;
+
+- ia_css_pipe_get_post_gdc_binarydesc(pipe,
+- &post_gdc_descr, &post_in_info, &post_out_info, &vf_info);
++ ia_css_pipe_get_post_gdc_binarydesc(pipe, &post_gdc_descr,
++ &post_in_info,
++ &post_out_info, &vf_info);
+ err = ia_css_binary_find(&post_gdc_descr,
+- &pipe->pipe_settings.capture.post_isp_binary);
++ &pipe->pipe_settings.capture.post_isp_binary);
+ if (err)
+ return err;
+ }
+@@ -6276,9 +6276,9 @@ static int load_advanced_binaries(
+ struct ia_css_binary_descr gdc_descr;
+
+ ia_css_pipe_get_gdc_binarydesc(pipe, &gdc_descr, &gdc_in_info,
+- &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
++ &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
+ err = ia_css_binary_find(&gdc_descr,
+- &pipe->pipe_settings.capture.anr_gdc_binary);
++ &pipe->pipe_settings.capture.anr_gdc_binary);
+ if (err)
+ return err;
+ }
+@@ -6290,9 +6290,9 @@ static int load_advanced_binaries(
+ struct ia_css_binary_descr pre_gdc_descr;
+
+ ia_css_pipe_get_pre_gdc_binarydesc(pipe, &pre_gdc_descr, &pre_in_info,
+- &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
++ &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
+ err = ia_css_binary_find(&pre_gdc_descr,
+- &pipe->pipe_settings.capture.pre_isp_binary);
++ &pipe->pipe_settings.capture.pre_isp_binary);
+ if (err)
+ return err;
+ }
+@@ -6314,7 +6314,7 @@ static int load_advanced_binaries(
+ ia_css_pipe_get_vfpp_binarydesc(pipe,
+ &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
+ err = ia_css_binary_find(&vf_pp_descr,
+- &pipe->pipe_settings.capture.vf_pp_binary);
++ &pipe->pipe_settings.capture.vf_pp_binary);
+ if (err)
+ return err;
+ }
+@@ -6326,8 +6326,8 @@ static int load_advanced_binaries(
+ #endif
+ if (need_isp_copy)
+ load_copy_binary(pipe,
+- &pipe->pipe_settings.capture.copy_binary,
+- &pipe->pipe_settings.capture.pre_isp_binary);
++ &pipe->pipe_settings.capture.copy_binary,
++ &pipe->pipe_settings.capture.pre_isp_binary);
+
+ return err;
+ }
+@@ -6342,7 +6342,7 @@ static int load_bayer_isp_binaries(
+ IA_CSS_ENTER_PRIVATE("");
+ assert(pipe);
+ assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+- pipe->mode == IA_CSS_PIPE_ID_COPY);
++ pipe->mode == IA_CSS_PIPE_ID_COPY);
+ pipe_out_info = &pipe->output_info[0];
+
+ if (pipe->pipe_settings.capture.pre_isp_binary.info)
+@@ -6353,11 +6353,11 @@ static int load_bayer_isp_binaries(
+ return err;
+
+ ia_css_pipe_get_pre_de_binarydesc(pipe, &pre_de_descr,
+- &pre_isp_in_info,
+- pipe_out_info);
++ &pre_isp_in_info,
++ pipe_out_info);
+
+ err = ia_css_binary_find(&pre_de_descr,
+- &pipe->pipe_settings.capture.pre_isp_binary);
++ &pipe->pipe_settings.capture.pre_isp_binary);
+
+ return err;
+ }
+@@ -6376,7 +6376,7 @@ static int load_low_light_binaries(
+ IA_CSS_ENTER_PRIVATE("");
+ assert(pipe);
+ assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+- pipe->mode == IA_CSS_PIPE_ID_COPY);
++ pipe->mode == IA_CSS_PIPE_ID_COPY);
+
+ if (pipe->pipe_settings.capture.pre_isp_binary.info)
+ return 0;
+@@ -6391,17 +6391,18 @@ static int load_low_light_binaries(
+ need_pp = need_capture_pp(pipe);
+
+ ia_css_frame_info_set_format(&vf_info,
+- IA_CSS_FRAME_FORMAT_YUV_LINE);
++ IA_CSS_FRAME_FORMAT_YUV_LINE);
+
+ /* we build up the pipeline starting at the end */
+ /* Capture post-processing */
+ if (need_pp) {
+ struct ia_css_binary_descr capture_pp_descr;
+
+- ia_css_pipe_get_capturepp_binarydesc(pipe,
+- &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
++ ia_css_pipe_get_capturepp_binarydesc(pipe, &capture_pp_descr,
++ &post_out_info,
++ pipe_out_info, &vf_info);
+ err = ia_css_binary_find(&capture_pp_descr,
+- &pipe->pipe_settings.capture.capture_pp_binary);
++ &pipe->pipe_settings.capture.capture_pp_binary);
+ if (err)
+ return err;
+ } else {
+@@ -6415,7 +6416,7 @@ static int load_low_light_binaries(
+ ia_css_pipe_get_post_anr_binarydesc(pipe,
+ &post_anr_descr, &post_in_info, &post_out_info, &vf_info);
+ err = ia_css_binary_find(&post_anr_descr,
+- &pipe->pipe_settings.capture.post_isp_binary);
++ &pipe->pipe_settings.capture.post_isp_binary);
+ if (err)
+ return err;
+ }
+@@ -6425,9 +6426,9 @@ static int load_low_light_binaries(
+ struct ia_css_binary_descr anr_descr;
+
+ ia_css_pipe_get_anr_binarydesc(pipe, &anr_descr, &anr_in_info,
+- &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
++ &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
+ err = ia_css_binary_find(&anr_descr,
+- &pipe->pipe_settings.capture.anr_gdc_binary);
++ &pipe->pipe_settings.capture.anr_gdc_binary);
+ if (err)
+ return err;
+ }
+@@ -6439,9 +6440,9 @@ static int load_low_light_binaries(
+ struct ia_css_binary_descr pre_anr_descr;
+
+ ia_css_pipe_get_pre_anr_binarydesc(pipe, &pre_anr_descr, &pre_in_info,
+- &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
++ &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
+ err = ia_css_binary_find(&pre_anr_descr,
+- &pipe->pipe_settings.capture.pre_isp_binary);
++ &pipe->pipe_settings.capture.pre_isp_binary);
+ if (err)
+ return err;
+ }
+@@ -6460,10 +6461,10 @@ static int load_low_light_binaries(
+ {
+ struct ia_css_binary_descr vf_pp_descr;
+
+- ia_css_pipe_get_vfpp_binarydesc(pipe,
+- &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
++ ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr,
++ vf_pp_in_info, pipe_vf_out_info);
+ err = ia_css_binary_find(&vf_pp_descr,
+- &pipe->pipe_settings.capture.vf_pp_binary);
++ &pipe->pipe_settings.capture.vf_pp_binary);
+ if (err)
+ return err;
+ }
+@@ -6475,8 +6476,8 @@ static int load_low_light_binaries(
+ #endif
+ if (need_isp_copy)
+ err = load_copy_binary(pipe,
+- &pipe->pipe_settings.capture.copy_binary,
+- &pipe->pipe_settings.capture.pre_isp_binary);
++ &pipe->pipe_settings.capture.copy_binary,
++ &pipe->pipe_settings.capture.pre_isp_binary);
+
+ return err;
+ }
+@@ -6510,7 +6511,7 @@ static int load_capture_binaries(
+ IA_CSS_ENTER_PRIVATE("");
+ assert(pipe);
+ assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+- pipe->mode == IA_CSS_PIPE_ID_COPY);
++ pipe->mode == IA_CSS_PIPE_ID_COPY);
+
+ if (pipe->pipe_settings.capture.primary_binary[0].info) {
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+@@ -6605,7 +6606,7 @@ unload_capture_binaries(struct ia_css_pi
+
+ static bool
+ need_downscaling(const struct ia_css_resolution in_res,
+- const struct ia_css_resolution out_res)
++ const struct ia_css_resolution out_res)
+ {
+ if (in_res.width > out_res.width || in_res.height > out_res.height)
+ return true;
+@@ -6676,9 +6677,9 @@ static int ia_css_pipe_create_cas_scaler
+ descr->num_output_stage = 1;
+
+ hor_ds_factor = CEIL_DIV(cas_scaler_in_info->res.width,
+- cas_scaler_out_info->res.width);
++ cas_scaler_out_info->res.width);
+ ver_ds_factor = CEIL_DIV(cas_scaler_in_info->res.height,
+- cas_scaler_out_info->res.height);
++ cas_scaler_out_info->res.height);
+ /* use the same horizontal and vertical downscaling factor for simplicity */
+ assert(hor_ds_factor == ver_ds_factor);
+
+@@ -6688,31 +6689,36 @@ static int ia_css_pipe_create_cas_scaler
+ i *= max_scale_factor_per_stage;
+ }
+
+- descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+- GFP_KERNEL);
++ descr->in_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->in_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->internal_out_info = kmalloc(descr->num_stage * sizeof(
+- struct ia_css_frame_info), GFP_KERNEL);
++ descr->internal_out_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->internal_out_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+- GFP_KERNEL);
++ descr->out_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->out_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+- GFP_KERNEL);
++ descr->vf_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->vf_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
++ descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool),
++ GFP_KERNEL);
+ if (!descr->is_output_stage) {
+ err = -ENOMEM;
+ goto ERR;
+@@ -6756,9 +6762,9 @@ static int ia_css_pipe_create_cas_scaler
+ max_scale_factor_per_stage;
+ descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
+ ia_css_frame_info_init(&descr->internal_out_info[i],
+- tmp_in_info.res.width / max_scale_factor_per_stage,
+- tmp_in_info.res.height / max_scale_factor_per_stage,
+- IA_CSS_FRAME_FORMAT_YUV420, 0);
++ tmp_in_info.res.width / max_scale_factor_per_stage,
++ tmp_in_info.res.height / max_scale_factor_per_stage,
++ IA_CSS_FRAME_FORMAT_YUV420, 0);
+ descr->out_info[i].res.width = 0;
+ descr->out_info[i].res.height = 0;
+ descr->vf_info[i].res.width = 0;
+@@ -6834,30 +6840,35 @@ static int ia_css_pipe_create_cas_scaler
+ descr->num_stage = num_stages;
+
+ descr->in_info = kmalloc_array(descr->num_stage,
+- sizeof(struct ia_css_frame_info), GFP_KERNEL);
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->in_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->internal_out_info = kmalloc(descr->num_stage * sizeof(
+- struct ia_css_frame_info), GFP_KERNEL);
++ descr->internal_out_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->internal_out_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+- GFP_KERNEL);
++ descr->out_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->out_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+- GFP_KERNEL);
++ descr->vf_info = kmalloc(descr->num_stage *
++ sizeof(struct ia_css_frame_info),
++ GFP_KERNEL);
+ if (!descr->vf_info) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+- descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
++ descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool),
++ GFP_KERNEL);
+ if (!descr->is_output_stage) {
+ err = -ENOMEM;
+ goto ERR;
+@@ -6867,7 +6878,7 @@ static int ia_css_pipe_create_cas_scaler
+ if (out_info[i]) {
+ if (i > 0) {
+ assert((out_info[i - 1]->res.width >= out_info[i]->res.width) &&
+- (out_info[i - 1]->res.height >= out_info[i]->res.height));
++ (out_info[i - 1]->res.height >= out_info[i]->res.height));
+ }
+ }
+ }
+@@ -6915,9 +6926,9 @@ static int ia_css_pipe_create_cas_scaler
+ max_scale_factor_per_stage;
+ descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
+ ia_css_frame_info_init(&descr->internal_out_info[i],
+- tmp_in_info.res.width / max_scale_factor_per_stage,
+- tmp_in_info.res.height / max_scale_factor_per_stage,
+- IA_CSS_FRAME_FORMAT_YUV420, 0);
++ tmp_in_info.res.width / max_scale_factor_per_stage,
++ tmp_in_info.res.height / max_scale_factor_per_stage,
++ IA_CSS_FRAME_FORMAT_YUV420, 0);
+ descr->out_info[i].res.width = 0;
+ descr->out_info[i].res.height = 0;
+ descr->vf_info[i].res.width = 0;
+@@ -6996,13 +7007,14 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ struct ia_css_binary_descr yuv_scaler_descr;
+
+ err = ia_css_pipe_create_cas_scaler_desc(pipe,
+- &cas_scaler_descr);
++ &cas_scaler_descr);
+ if (err)
+ goto ERR;
+ mycs->num_output = cas_scaler_descr.num_output_stage;
+ mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
+ mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
+- sizeof(struct ia_css_binary), GFP_KERNEL);
++ sizeof(struct ia_css_binary),
++ GFP_KERNEL);
+ if (!mycs->yuv_scaler_binary) {
+ err = -ENOMEM;
+ goto ERR;
+@@ -7016,12 +7028,13 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ for (i = 0; i < cas_scaler_descr.num_stage; i++) {
+ mycs->is_output_stage[i] = cas_scaler_descr.is_output_stage[i];
+ ia_css_pipe_get_yuvscaler_binarydesc(pipe,
+- &yuv_scaler_descr, &cas_scaler_descr.in_info[i],
+- &cas_scaler_descr.out_info[i],
+- &cas_scaler_descr.internal_out_info[i],
+- &cas_scaler_descr.vf_info[i]);
++ &yuv_scaler_descr,
++ &cas_scaler_descr.in_info[i],
++ &cas_scaler_descr.out_info[i],
++ &cas_scaler_descr.internal_out_info[i],
++ &cas_scaler_descr.vf_info[i]);
+ err = ia_css_binary_find(&yuv_scaler_descr,
+- &mycs->yuv_scaler_binary[i]);
++ &mycs->yuv_scaler_binary[i]);
+ if (err)
+ goto ERR;
+ }
+@@ -7061,8 +7074,8 @@ load_yuvpp_binaries(struct ia_css_pipe *
+
+ if (need_isp_copy_binary) {
+ err = load_copy_binary(pipe,
+- &mycs->copy_binary,
+- next_binary);
++ &mycs->copy_binary,
++ next_binary);
+
+ if (err)
+ goto ERR;
+@@ -7107,8 +7120,9 @@ load_yuvpp_binaries(struct ia_css_pipe *
+
+ mycs->num_vf_pp = 1;
+ }
+- mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary),
+- GFP_KERNEL);
++ mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp *
++ sizeof(struct ia_css_binary),
++ GFP_KERNEL);
+ if (!mycs->vf_pp_binary) {
+ err = -ENOMEM;
+ goto ERR;
+@@ -7437,18 +7451,26 @@ create_host_yuvpp_pipeline(struct ia_css
+ #endif
+
+ if (need_scaler) {
+- ia_css_pipe_util_set_output_frames(bin_out_frame, 0, NULL);
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+- bin_out_frame, in_frame_local, NULL);
++ ia_css_pipe_util_set_output_frames(bin_out_frame,
++ 0, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ copy_binary,
++ bin_out_frame,
++ in_frame_local,
++ NULL);
+ } else {
+- ia_css_pipe_util_set_output_frames(bin_out_frame, 0, out_frame[0]);
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+- bin_out_frame, in_frame_local, NULL);
++ ia_css_pipe_util_set_output_frames(bin_out_frame,
++ 0, out_frame[0]);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ copy_binary,
++ bin_out_frame,
++ in_frame_local,
++ NULL);
+ }
+
+ err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- ©_stage);
++ &stage_desc,
++ ©_stage);
+
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7480,10 +7502,11 @@ create_host_yuvpp_pipeline(struct ia_css
+ tmp_vf_frame = NULL;
+ }
+
+- err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+- NULL,
+- &yuv_scaler_binary[i],
+- &yuv_scaler_stage);
++ err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
++ tmp_out_frame,
++ NULL,
++ &yuv_scaler_binary[i],
++ &yuv_scaler_stage);
+
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7494,8 +7517,10 @@ create_host_yuvpp_pipeline(struct ia_css
+ if (pipe->pipe_settings.yuvpp.is_output_stage[i]) {
+ if (tmp_vf_frame && (tmp_vf_frame->info.res.width != 0)) {
+ in_frame = yuv_scaler_stage->args.out_vf_frame;
+- err = add_vf_pp_stage(pipe, in_frame, tmp_vf_frame, &vf_pp_binary[j],
+- &vf_pp_stage);
++ err = add_vf_pp_stage(pipe, in_frame,
++ tmp_vf_frame,
++ &vf_pp_binary[j],
++ &vf_pp_stage);
+
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7508,8 +7533,8 @@ create_host_yuvpp_pipeline(struct ia_css
+ } else if (copy_stage) {
+ if (vf_frame[0] && vf_frame[0]->info.res.width != 0) {
+ in_frame = copy_stage->args.out_vf_frame;
+- err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0],
+- &vf_pp_stage);
++ err = add_vf_pp_stage(pipe, in_frame, vf_frame[0],
++ &vf_pp_binary[0], &vf_pp_stage);
+ }
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7517,7 +7542,8 @@ create_host_yuvpp_pipeline(struct ia_css
+ }
+ }
+
+- ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
++ ia_css_pipeline_finalize_stages(&pipe->pipeline,
++ pipe->stream->config.continuous);
+
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+
+@@ -7526,8 +7552,8 @@ create_host_yuvpp_pipeline(struct ia_css
+
+ static int
+ create_host_copy_pipeline(struct ia_css_pipe *pipe,
+- unsigned int max_input_width,
+- struct ia_css_frame *out_frame)
++ unsigned int max_input_width,
++ struct ia_css_frame *out_frame)
+ {
+ struct ia_css_pipeline *me;
+ int err = 0;
+@@ -7546,12 +7572,8 @@ create_host_copy_pipeline(struct ia_css_
+
+ if (copy_on_sp(pipe) &&
+ pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
+- ia_css_frame_info_init(
+- &out_frame->info,
+- JPEG_BYTES,
+- 1,
+- IA_CSS_FRAME_FORMAT_BINARY_8,
+- 0);
++ ia_css_frame_info_init(&out_frame->info, JPEG_BYTES, 1,
++ IA_CSS_FRAME_FORMAT_BINARY_8, 0);
+ } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) {
+ out_frame->info.raw_bit_depth =
+ ia_css_pipe_util_pipe_input_format_bpp(pipe);
+@@ -7562,12 +7584,12 @@ create_host_copy_pipeline(struct ia_css_
+ pipe->mode = IA_CSS_PIPE_ID_COPY;
+
+ ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame,
+- IA_CSS_PIPELINE_RAW_COPY, max_input_width);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- NULL);
++ IA_CSS_PIPELINE_RAW_COPY,
++ max_input_width);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, NULL);
+
+- ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
++ ia_css_pipeline_finalize_stages(&pipe->pipeline,
++ pipe->stream->config.continuous);
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "create_host_copy_pipeline() leave:\n");
+@@ -7606,9 +7628,10 @@ create_host_isyscopy_capture_pipeline(st
+ me->pipe_id = IA_CSS_PIPE_ID_CAPTURE;
+ pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
+ ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame,
+- IA_CSS_PIPELINE_ISYS_COPY, max_input_width);
++ IA_CSS_PIPELINE_ISYS_COPY,
++ max_input_width);
+ err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc, &out_stage);
++ &stage_desc, &out_stage);
+ if (err)
+ return err;
+
+@@ -7660,7 +7683,8 @@ create_host_regular_capture_pipeline(str
+ IA_CSS_ENTER_PRIVATE("");
+ assert(pipe);
+ assert(pipe->stream);
+- assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
++ assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
++ pipe->mode == IA_CSS_PIPE_ID_COPY);
+
+ me = &pipe->pipeline;
+ mode = pipe->config.default_capture_config.mode;
+@@ -7750,26 +7774,37 @@ create_host_regular_capture_pipeline(str
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ #if defined(ISP2401)
+ if (!continuous) {
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+- out_frames, in_frame, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ copy_binary,
++ out_frames,
++ in_frame,
++ NULL);
+ } else {
+ in_frame = pipe->stream->last_pipe->continuous_frames[0];
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+- out_frames, in_frame, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ copy_binary,
++ out_frames,
++ in_frame,
++ NULL);
+ }
+ #else
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+- out_frames, NULL, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ copy_binary,
++ out_frames,
++ NULL, NULL);
+ #endif
+ } else {
+- ia_css_pipe_util_set_output_frames(out_frames, 0, in_frame);
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+- out_frames, NULL, NULL);
++ ia_css_pipe_util_set_output_frames(out_frames, 0,
++ in_frame);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ copy_binary,
++ out_frames,
++ NULL, NULL);
+ }
+
+ err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- ¤t_stage);
++ &stage_desc,
++ ¤t_stage);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7806,11 +7841,14 @@ create_host_regular_capture_pipeline(str
+ * Proper investigation should be done to come up with the clean
+ * solution.
+ * */
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, primary_binary[i],
+- out_frames, local_in_frame, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ primary_binary[i],
++ out_frames,
++ local_in_frame,
++ NULL);
+ err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- ¤t_stage);
++ &stage_desc,
++ ¤t_stage);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7826,18 +7864,18 @@ create_host_regular_capture_pipeline(str
+ mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+- out_frames, in_frame, NULL);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc, NULL);
++ out_frames, in_frame, NULL);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ NULL);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, anr_gdc_binary,
+- out_frames, NULL, NULL);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc, NULL);
++ out_frames, NULL, NULL);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ NULL);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7845,16 +7883,21 @@ create_host_regular_capture_pipeline(str
+
+ if (need_pp) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary,
+- out_frames, NULL, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ post_isp_binary,
++ out_frames,
++ NULL, NULL);
+ } else {
+- ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary,
+- out_frames, NULL, NULL);
++ ia_css_pipe_util_set_output_frames(out_frames, 0,
++ out_frame);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ post_isp_binary,
++ out_frames,
++ NULL, NULL);
+ }
+
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc, ¤t_stage);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ ¤t_stage);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7862,10 +7905,9 @@ create_host_regular_capture_pipeline(str
+ } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+- out_frames, in_frame, NULL);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- NULL);
++ out_frames, in_frame, NULL);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ NULL);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7880,31 +7922,34 @@ create_host_regular_capture_pipeline(str
+
+ if (need_ldc) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+- ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
+- out_frames, local_in_frame, NULL);
++ ia_css_pipe_get_generic_stage_desc(&stage_desc,
++ capture_ldc_binary,
++ out_frames,
++ local_in_frame,
++ NULL);
+ err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- ¤t_stage);
++ &stage_desc,
++ ¤t_stage);
+ local_in_frame = current_stage->args.out_frame[0];
+ }
+ err = add_capture_pp_stage(pipe, me, local_in_frame,
+- need_yuv_pp ? NULL : out_frame,
++ need_yuv_pp ? NULL : out_frame,
+ #else
+ /* ldc and capture_pp not supported in same pipeline */
+ if (need_ldc && current_stage) {
+ in_frame = current_stage->args.out_frame[0];
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
+- out_frames, in_frame, NULL);
+- err = ia_css_pipeline_create_and_add_stage(me,
+- &stage_desc,
+- NULL);
++ out_frames, in_frame, NULL);
++ err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++ NULL);
+ } else if (need_pp && current_stage) {
+ in_frame = current_stage->args.out_frame[0];
+- err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame,
++ err = add_capture_pp_stage(pipe, me, in_frame,
++ need_yuv_pp ? NULL : out_frame,
+ #endif
+- capture_pp_binary,
+- ¤t_stage);
++ capture_pp_binary,
++ ¤t_stage);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7921,10 +7966,10 @@ create_host_regular_capture_pipeline(str
+ else
+ tmp_out_frame = NULL;
+
+- err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+- NULL,
+- &yuv_scaler_binary[i],
+- &yuv_scaler_stage);
++ err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
++ tmp_out_frame, NULL,
++ &yuv_scaler_binary[i],
++ &yuv_scaler_stage);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7946,7 +7991,7 @@ create_host_regular_capture_pipeline(str
+ if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) {
+ in_frame = current_stage->args.out_vf_frame;
+ err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
+- ¤t_stage);
++ ¤t_stage);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -7998,7 +8043,7 @@ static int capture_start(
+ me = &pipe->pipeline;
+
+ if ((pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW ||
+- pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) &&
++ pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) &&
+ (pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
+ if (copy_on_sp(pipe)) {
+ err = start_copy_on_sp(pipe, &me->out_frame[0]);
+@@ -8042,7 +8087,7 @@ static int capture_start(
+ if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY &&
+ pipe->stream->reconfigure_css_rx) {
+ ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
+- pipe->stream->config.mode);
++ pipe->stream->config.mode);
+ pipe->stream->reconfigure_css_rx = false;
+ }
+ #endif
+@@ -8053,8 +8098,8 @@ static int capture_start(
+
+ static int
+ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
+- struct ia_css_frame_info *info,
+- unsigned int idx)
++ struct ia_css_frame_info *info,
++ unsigned int idx)
+ {
+ assert(pipe);
+ assert(info);
+@@ -8072,7 +8117,7 @@ sh_css_pipe_get_output_frame_info(struct
+ IA_CSS_FRAME_FORMAT_BINARY_8,
+ 0);
+ } else if (info->format == IA_CSS_FRAME_FORMAT_RAW ||
+- info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
++ info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
+ info->raw_bit_depth =
+ ia_css_pipe_util_pipe_input_format_bpp(pipe);
+ }
+@@ -8084,9 +8129,9 @@ sh_css_pipe_get_output_frame_info(struct
+
+ void
+ ia_css_stream_send_input_frame(const struct ia_css_stream *stream,
+- const unsigned short *data,
+- unsigned int width,
+- unsigned int height)
++ const unsigned short *data,
++ unsigned int width,
++ unsigned int height)
+ {
+ assert(stream);
+
+@@ -8110,22 +8155,22 @@ ia_css_stream_start_input_frame(const st
+
+ void
+ ia_css_stream_send_input_line(const struct ia_css_stream *stream,
+- const unsigned short *data,
+- unsigned int width,
+- const unsigned short *data2,
+- unsigned int width2)
++ const unsigned short *data,
++ unsigned int width,
++ const unsigned short *data2,
++ unsigned int width2)
+ {
+ assert(stream);
+
+ ia_css_inputfifo_send_line(stream->config.channel_id,
+- data, width, data2, width2);
++ data, width, data2, width2);
+ }
+
+ void
+ ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream,
+- enum atomisp_input_format format,
+- const unsigned short *data,
+- unsigned int width)
++ enum atomisp_input_format format,
++ const unsigned short *data,
++ unsigned int width)
+ {
+ assert(stream);
+ if (!data || width == 0)
+@@ -8246,7 +8291,7 @@ acc_unload_extension(struct ia_css_fw_in
+ /* Load firmware for extension */
+ static int
+ ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
+- struct ia_css_fw_info *firmware)
++ struct ia_css_fw_info *firmware)
+ {
+ int err = 0;
+
+@@ -8270,7 +8315,7 @@ ia_css_pipe_load_extension(struct ia_css
+ /* Unload firmware for extension */
+ static void
+ ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
+- struct ia_css_fw_info *firmware)
++ struct ia_css_fw_info *firmware)
+ {
+ IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
+
+@@ -8312,7 +8357,7 @@ ia_css_pipeline_uses_params(struct ia_cs
+
+ static int
+ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
+- const void *acc_fw)
++ const void *acc_fw)
+ {
+ struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw;
+ /* In QoS case, load_extension already called, so skipping */
+@@ -8330,8 +8375,8 @@ sh_css_pipeline_add_acc_stage(struct ia_
+
+ ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw);
+ err = ia_css_pipeline_create_and_add_stage(pipeline,
+- &stage_desc,
+- NULL);
++ &stage_desc,
++ NULL);
+ }
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -8344,7 +8389,7 @@ sh_css_pipeline_add_acc_stage(struct ia_
+ * Refer to "sh_css_internal.h" for details.
+ */
+ int ia_css_stream_capture_frame(struct ia_css_stream *stream,
+- unsigned int exp_id)
++ unsigned int exp_id)
+ {
+ struct sh_css_tag_descr tag_descr;
+ u32 encoded_tag_descr;
+@@ -8503,22 +8548,22 @@ sh_css_init_host_sp_control_vars(void)
+ (void)HIVE_ADDR_host_sp_com;
+
+ sp_dmem_store_uint32(SP0_ID,
+- (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started),
+- (uint32_t)(0));
++ (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started),
++ (uint32_t)(0));
+
+ sp_dmem_store_uint32(SP0_ID,
+- (unsigned int)sp_address_of(host_sp_queues_initialized),
+- (uint32_t)(0));
++ (unsigned int)sp_address_of(host_sp_queues_initialized),
++ (uint32_t)(0));
+ sp_dmem_store_uint32(SP0_ID,
+- (unsigned int)sp_address_of(sp_sleep_mode),
+- (uint32_t)(0));
++ (unsigned int)sp_address_of(sp_sleep_mode),
++ (uint32_t)(0));
+ sp_dmem_store_uint32(SP0_ID,
+- (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb),
+- (uint32_t)(false));
++ (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb),
++ (uint32_t)(false));
+ #ifndef ISP2401
+ sp_dmem_store_uint32(SP0_ID,
+- (unsigned int)sp_address_of(sp_stop_copy_preview),
+- my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0));
++ (unsigned int)sp_address_of(sp_stop_copy_preview),
++ my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0));
+ #endif
+ store_sp_array_uint(host_sp_com, o, host2sp_cmd_ready);
+
+@@ -8545,8 +8590,7 @@ void ia_css_pipe_config_defaults(struct
+ }
+
+ void
+-ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config
+- *extra_config)
++ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config *extra_config)
+ {
+ if (!extra_config) {
+ IA_CSS_ERROR("NULL input parameter");
+@@ -8620,8 +8664,8 @@ int ia_css_pipe_create(const struct ia_c
+
+ int
+ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
+- const struct ia_css_pipe_extra_config *extra_config,
+- struct ia_css_pipe **pipe)
++ const struct ia_css_pipe_extra_config *extra_config,
++ struct ia_css_pipe **pipe)
+ {
+ int err = -EINVAL;
+ struct ia_css_pipe *internal_pipe = NULL;
+@@ -8689,7 +8733,7 @@ ia_css_pipe_create_extra(const struct ia
+
+ /* YUV downscaling */
+ if ((internal_pipe->config.vf_pp_in_res.width ||
+- internal_pipe->config.capt_pp_in_res.width)) {
++ internal_pipe->config.capt_pp_in_res.width)) {
+ enum ia_css_frame_format format;
+
+ if (internal_pipe->config.vf_pp_in_res.width) {
+@@ -8765,7 +8809,7 @@ ia_css_pipe_create_extra(const struct ia
+ }
+ if (internal_pipe->config.acc_extension) {
+ err = ia_css_pipe_load_extension(internal_pipe,
+- internal_pipe->config.acc_extension);
++ internal_pipe->config.acc_extension);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ kvfree(internal_pipe);
+@@ -8783,7 +8827,7 @@ ia_css_pipe_create_extra(const struct ia
+
+ int
+ ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
+- struct ia_css_pipe_info *pipe_info)
++ struct ia_css_pipe_info *pipe_info)
+ {
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+ "ia_css_pipe_get_info()\n");
+@@ -8821,8 +8865,8 @@ bool ia_css_pipe_has_dvs_stats(struct ia
+
+ int
+ ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
+- int pin_index,
+- enum ia_css_frame_format new_format)
++ int pin_index,
++ enum ia_css_frame_format new_format)
+ {
+ int err = 0;
+
+@@ -8902,10 +8946,8 @@ ia_css_stream_configure_rx(struct ia_css
+ #endif
+
+ static struct ia_css_pipe *
+-find_pipe(struct ia_css_pipe *pipes[],
+- unsigned int num_pipes,
+- enum ia_css_pipe_mode mode,
+- bool copy_pipe)
++find_pipe(struct ia_css_pipe *pipes[], unsigned int num_pipes,
++ enum ia_css_pipe_mode mode, bool copy_pipe)
+ {
+ unsigned int i;
+
+@@ -8976,7 +9018,7 @@ ia_css_acc_stream_create(struct ia_css_s
+
+ static int
+ metadata_info_init(const struct ia_css_metadata_config *mdc,
+- struct ia_css_metadata_info *md)
++ struct ia_css_metadata_info *md)
+ {
+ /* Either both width and height should be set or neither */
+ if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0))
+@@ -9004,7 +9046,7 @@ static int check_pipe_resolutions(const
+ }
+
+ if (ia_css_util_check_res(pipe->config.input_effective_res.width,
+- pipe->config.input_effective_res.height) != 0) {
++ pipe->config.input_effective_res.height) != 0) {
+ IA_CSS_ERROR("effective resolution not supported");
+ err = -EINVAL;
+ goto EXIT;
+@@ -9012,7 +9054,7 @@ static int check_pipe_resolutions(const
+ if (!ia_css_util_resolution_is_zero(
+ pipe->stream->config.input_config.input_res)) {
+ if (!ia_css_util_res_leq(pipe->config.input_effective_res,
+- pipe->stream->config.input_config.input_res)) {
++ pipe->stream->config.input_config.input_res)) {
+ IA_CSS_ERROR("effective resolution is larger than input resolution");
+ err = -EINVAL;
+ goto EXIT;
+@@ -9035,9 +9077,9 @@ EXIT:
+
+ int
+ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
+- int num_pipes,
+- struct ia_css_pipe *pipes[],
+- struct ia_css_stream **stream)
++ int num_pipes,
++ struct ia_css_pipe *pipes[],
++ struct ia_css_stream **stream)
+ {
+ struct ia_css_pipe *curr_pipe;
+ struct ia_css_stream *curr_stream = NULL;
+@@ -9198,11 +9240,11 @@ ia_css_stream_create(const struct ia_css
+ case IA_CSS_INPUT_MODE_TPG:
+ #if !defined(ISP2401)
+ IA_CSS_LOG("tpg_configuration: x_mask=%d, y_mask=%d, x_delta=%d, y_delta=%d, xy_mask=%d",
+- curr_stream->config.source.tpg.x_mask,
+- curr_stream->config.source.tpg.y_mask,
+- curr_stream->config.source.tpg.x_delta,
+- curr_stream->config.source.tpg.y_delta,
+- curr_stream->config.source.tpg.xy_mask);
++ curr_stream->config.source.tpg.x_mask,
++ curr_stream->config.source.tpg.y_mask,
++ curr_stream->config.source.tpg.x_delta,
++ curr_stream->config.source.tpg.y_delta,
++ curr_stream->config.source.tpg.xy_mask);
+
+ sh_css_sp_configure_tpg(
+ curr_stream->config.source.tpg.x_mask,
+@@ -9227,9 +9269,8 @@ ia_css_stream_create(const struct ia_css
+ }
+
+ #ifdef ISP2401
+- err = aspect_ratio_crop_init(curr_stream,
+- pipes,
+- &aspect_ratio_crop_enabled);
++ err = aspect_ratio_crop_init(curr_stream, pipes,
++ &aspect_ratio_crop_enabled);
+ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ goto ERR;
+@@ -9266,8 +9307,8 @@ ia_css_stream_create(const struct ia_css
+ curr_pipe->config.input_effective_res = effective_res;
+ }
+ IA_CSS_LOG("effective_res=%dx%d",
+- effective_res.width,
+- effective_res.height);
++ effective_res.width,
++ effective_res.height);
+ }
+
+ if (IS_ISP2401) {
+@@ -9295,13 +9336,13 @@ ia_css_stream_create(const struct ia_css
+ if (!spcopyonly) {
+ sensor_binning_changed =
+ sh_css_params_set_binning_factor(curr_stream,
+- curr_stream->config.sensor_binning_factor);
++ curr_stream->config.sensor_binning_factor);
+ } else {
+ sensor_binning_changed = false;
+ }
+
+ IA_CSS_LOG("sensor_binning=%d, changed=%d",
+- curr_stream->config.sensor_binning_factor, sensor_binning_changed);
++ curr_stream->config.sensor_binning_factor, sensor_binning_changed);
+ /* loop over pipes */
+ IA_CSS_LOG("num_pipes=%d", num_pipes);
+ curr_stream->cont_capt = false;
+@@ -9325,17 +9366,18 @@ ia_css_stream_create(const struct ia_css
+
+ /* Create copy pipe here, since it may not be exposed to the driver */
+ preview_pipe = find_pipe(pipes, num_pipes,
+- IA_CSS_PIPE_MODE_PREVIEW, false);
++ IA_CSS_PIPE_MODE_PREVIEW, false);
+ video_pipe = find_pipe(pipes, num_pipes,
+- IA_CSS_PIPE_MODE_VIDEO, false);
+- acc_pipe = find_pipe(pipes, num_pipes,
+- IA_CSS_PIPE_MODE_ACC, false);
++ IA_CSS_PIPE_MODE_VIDEO, false);
++ acc_pipe = find_pipe(pipes, num_pipes, IA_CSS_PIPE_MODE_ACC,
++ false);
+ if (acc_pipe && num_pipes == 2 && curr_stream->cont_capt)
+ curr_stream->cont_capt =
+ false; /* preview + QoS case will not need cont_capt switch */
+ if (curr_stream->cont_capt) {
+ capture_pipe = find_pipe(pipes, num_pipes,
+- IA_CSS_PIPE_MODE_CAPTURE, false);
++ IA_CSS_PIPE_MODE_CAPTURE,
++ false);
+ if (!capture_pipe) {
+ err = -EINVAL;
+ goto ERR;
+@@ -9417,10 +9459,12 @@ ia_css_stream_create(const struct ia_css
+ if (!spcopyonly) {
+ if (!IS_ISP2401)
+ err = sh_css_pipe_get_shading_info(curr_pipe,
+- &pipe_info->shading_info, NULL);
++ &pipe_info->shading_info,
++ NULL);
+ else
+ err = sh_css_pipe_get_shading_info(curr_pipe,
+- &pipe_info->shading_info, &curr_pipe->config);
++ &pipe_info->shading_info,
++ &curr_pipe->config);
+
+ if (err)
+ goto ERR;
+@@ -9430,7 +9474,8 @@ ia_css_stream_create(const struct ia_css
+ goto ERR;
+ for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) {
+ sh_css_pipe_get_viewfinder_frame_info(curr_pipe,
+- &pipe_info->vf_output_info[j], j);
++ &pipe_info->vf_output_info[j],
++ j);
+ if (err)
+ goto ERR;
+ }
+@@ -9615,7 +9660,7 @@ ia_css_stream_destroy(struct ia_css_stre
+
+ int
+ ia_css_stream_get_info(const struct ia_css_stream *stream,
+- struct ia_css_stream_info *stream_info)
++ struct ia_css_stream_info *stream_info)
+ {
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n");
+ assert(stream);
+@@ -9903,7 +9948,7 @@ ia_css_stream_get_3a_binary(const struct
+
+ int
+ ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
+- unsigned int output_padded_width)
++ unsigned int output_padded_width)
+ {
+ struct ia_css_pipe *pipe;
+
+@@ -10380,7 +10425,7 @@ ia_css_unlock_raw_frame(struct ia_css_st
+ */
+ int
+ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+- bool enable)
++ bool enable)
+ {
+ unsigned int thread_id;
+ struct ia_css_pipeline_stage *stage;
+@@ -10426,7 +10471,7 @@ ia_css_pipe_set_qos_ext_state(struct ia_
+ */
+ int
+ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+- bool *enable)
++ bool *enable)
+ {
+ struct ia_css_pipeline_stage *stage;
+ unsigned int thread_id;
+@@ -10462,9 +10507,9 @@ ia_css_pipe_get_qos_ext_state(struct ia_
+ /* ISP2401 */
+ int
+ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
+- u32 fw_handle,
+- struct ia_css_isp_param_css_segments *css_seg,
+- struct ia_css_isp_param_isp_segments *isp_seg)
++ u32 fw_handle,
++ struct ia_css_isp_param_css_segments *css_seg,
++ struct ia_css_isp_param_isp_segments *isp_seg)
+ {
+ unsigned int HIVE_ADDR_sp_group;
+ static struct sh_css_sp_group sp_group;
+@@ -10499,7 +10544,7 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ if (!err) {
+ /* Get the Extension State */
+ enabled = (SH_CSS_QOS_STAGE_IS_ENABLED(&sh_css_sp_group.pipe[thread_id],
+- stage->stage_num)) ? true : false;
++ stage->stage_num)) ? true : false;
+ /* Update mapped arg only when extension stage is not enabled */
+ if (enabled) {
+ IA_CSS_ERROR("Leaving: cannot update when stage is enabled.");
+@@ -10509,13 +10554,14 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+
+ HIVE_ADDR_sp_group = fw->info.sp.group;
+ sp_dmem_load(SP0_ID,
+- (unsigned int)sp_address_of(sp_group),
+- &sp_group, sizeof(struct sh_css_sp_group));
++ (unsigned int)sp_address_of(sp_group),
++ &sp_group,
++ sizeof(struct sh_css_sp_group));
+ hmm_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num],
+- &sp_stage, sizeof(struct sh_css_sp_stage));
++ &sp_stage, sizeof(struct sh_css_sp_stage));
+
+ hmm_load(sp_stage.isp_stage_addr,
+- &isp_stage, sizeof(struct sh_css_isp_stage));
++ &isp_stage, sizeof(struct sh_css_isp_stage));
+
+ for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) {
+ isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address =
+@@ -10531,7 +10577,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ }
+
+ hmm_store(sp_stage.isp_stage_addr,
+- &isp_stage, sizeof(struct sh_css_isp_stage));
++ &isp_stage,
++ sizeof(struct sh_css_isp_stage));
+ }
+ }
+ }
+@@ -10542,8 +10589,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ #ifdef ISP2401
+ static int
+ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
+- struct ia_css_pipe *pipes[],
+- bool *do_crop_status)
++ struct ia_css_pipe *pipes[],
++ bool *do_crop_status)
+ {
+ int err = 0;
+ int i;
+@@ -10589,7 +10636,7 @@ aspect_ratio_crop_check(bool enabled, st
+
+ static int
+ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
+- struct ia_css_resolution *effective_res)
++ struct ia_css_resolution *effective_res)
+ {
+ int err = 0;
+ struct ia_css_resolution crop_res;
+@@ -10649,7 +10696,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+ case IA_CSS_PIPE_MODE_YUVPP:
+ default:
+ IA_CSS_ERROR("aspect ratio cropping invalid args: mode[%d]\n",
+- curr_pipe->config.mode);
++ curr_pipe->config.mode);
+ assert(0);
+ break;
+ }
+@@ -10713,7 +10760,7 @@ static struct sh_css_hmm_buffer_record
+
+ assert(h_vbuf);
+ assert((type > IA_CSS_BUFFER_TYPE_INVALID) &&
+- (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE));
++ (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE));
+ assert(kernel_ptr != 0);
+
+ buffer_record = &hmm_buffer_record[0];
--- /dev/null
+From stable+bounces-274530-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:54 -0400
+Subject: media: staging: media: atomisp: Fix sh_css.c brace coding style issues
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-2-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit 6ceb557604e85c55bce0585216623c21c7a00453 ]
+
+Fix brace coding style issues.
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 224 +++++++++++------------------
+ 1 file changed, 90 insertions(+), 134 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -456,15 +456,15 @@ static enum ia_css_frame_format yuv422_c
+ * by the copy binary given the stream format.
+ * */
+ static int
+-verify_copy_out_frame_format(struct ia_css_pipe *pipe) {
++verify_copy_out_frame_format(struct ia_css_pipe *pipe)
++{
+ enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
+ unsigned int i, found = 0;
+
+ assert(pipe);
+ assert(pipe->stream);
+
+- switch (pipe->stream->config.input_config.format)
+- {
++ switch (pipe->stream->config.input_config.format) {
+ case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
+ case ATOMISP_INPUT_FORMAT_YUV420_8:
+ for (i = 0; i < ARRAY_SIZE(yuv420_copy_formats) && !found; i++)
+@@ -532,7 +532,8 @@ ia_css_stream_input_format_bits_per_pixe
+
+ #if !defined(ISP2401)
+ static int
+-sh_css_config_input_network(struct ia_css_stream *stream) {
++sh_css_config_input_network(struct ia_css_stream *stream)
++{
+ unsigned int fmt_type;
+ struct ia_css_pipe *pipe = stream->last_pipe;
+ struct ia_css_binary *binary = NULL;
+@@ -558,8 +559,7 @@ sh_css_config_input_network(struct ia_cs
+ stream->config.mode);
+
+ if ((binary && (binary->online || stream->config.continuous)) ||
+- pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
+- {
++ pipe->config.mode == IA_CSS_PIPE_MODE_COPY) {
+ err = ia_css_ifmtr_configure(&stream->config,
+ binary);
+ if (err)
+@@ -567,8 +567,7 @@ sh_css_config_input_network(struct ia_cs
+ }
+
+ if (stream->config.mode == IA_CSS_INPUT_MODE_TPG ||
+- stream->config.mode == IA_CSS_INPUT_MODE_PRBS)
+- {
++ stream->config.mode == IA_CSS_INPUT_MODE_PRBS) {
+ unsigned int hblank_cycles = 100,
+ vblank_lines = 6,
+ width,
+@@ -723,35 +722,32 @@ static bool sh_css_translate_stream_cfg_
+ switch (stream_cfg->mode) {
+ case IA_CSS_INPUT_MODE_TPG:
+
+- if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0) {
++ if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
+- } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1) {
++ else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
+- } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2) {
++ else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
+- }
+
+ break;
+ case IA_CSS_INPUT_MODE_PRBS:
+
+- if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0) {
++ if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
+- } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1) {
++ else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
+- } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2) {
++ else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
+- }
+
+ break;
+ case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
+
+- if (stream_cfg->source.port.port == MIPI_PORT0_ID) {
++ if (stream_cfg->source.port.port == MIPI_PORT0_ID)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT0_ID;
+- } else if (stream_cfg->source.port.port == MIPI_PORT1_ID) {
++ else if (stream_cfg->source.port.port == MIPI_PORT1_ID)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT1_ID;
+- } else if (stream_cfg->source.port.port == MIPI_PORT2_ID) {
++ else if (stream_cfg->source.port.port == MIPI_PORT2_ID)
+ isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT2_ID;
+- }
+
+ break;
+ default:
+@@ -804,15 +800,14 @@ static bool sh_css_translate_stream_cfg_
+ rc = true;
+ switch (stream_cfg->mode) {
+ case IA_CSS_INPUT_MODE_TPG:
+- if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP) {
++ if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP)
+ isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_RAMP;
+- } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD) {
++ else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD)
+ isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_CHBO;
+- } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO) {
++ else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO)
+ isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_MONO;
+- } else {
++ else
+ rc = false;
+- }
+
+ /*
+ * TODO
+@@ -951,12 +946,12 @@ static bool sh_css_translate_stream_cfg_
+ stream_cfg->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) &&
+ stream_cfg->source.port.compression.type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
+ if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
+- UNCOMPRESSED_BITS_PER_PIXEL_10) {
++ UNCOMPRESSED_BITS_PER_PIXEL_10)
+ fmt_type = ATOMISP_INPUT_FORMAT_RAW_10;
+- } else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
+- UNCOMPRESSED_BITS_PER_PIXEL_12) {
++ else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
++ UNCOMPRESSED_BITS_PER_PIXEL_12)
+ fmt_type = ATOMISP_INPUT_FORMAT_RAW_12;
+- } else
++ else
+ return false;
+ }
+
+@@ -1043,7 +1038,8 @@ static bool sh_css_translate_binary_info
+ }
+
+ static int
+-sh_css_config_input_network(struct ia_css_stream *stream) {
++sh_css_config_input_network(struct ia_css_stream *stream)
++{
+ bool rc;
+ ia_css_isys_descr_t isys_stream_descr;
+ unsigned int sp_thread_id;
+@@ -1058,19 +1054,16 @@ sh_css_config_input_network(struct ia_cs
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "sh_css_config_input_network() enter 0x%p:\n", stream);
+
+- if (stream->config.continuous)
+- {
+- if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
++ if (stream->config.continuous) {
++ if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE)
+ pipe = stream->last_pipe;
+- } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP) {
++ else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP)
+ pipe = stream->last_pipe;
+- } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) {
++ else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
+ pipe = stream->last_pipe->pipe_settings.preview.copy_pipe;
+- } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) {
++ else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO)
+ pipe = stream->last_pipe->pipe_settings.video.copy_pipe;
+- }
+- } else
+- {
++ } else {
+ pipe = stream->last_pipe;
+ if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
+ /*
+@@ -1093,8 +1086,7 @@ sh_css_config_input_network(struct ia_cs
+ if (pipe->pipeline.stages->binary)
+ binary = pipe->pipeline.stages->binary;
+
+- if (binary)
+- {
++ if (binary) {
+ /* this was being done in ifmtr in 2400.
+ * online and cont bypass the init_in_frameinfo_memory_defaults
+ * so need to do it here
+@@ -1208,11 +1200,10 @@ static inline struct ia_css_pipe *stream
+ struct ia_css_pipe *target_pipe;
+
+ /* get the pipe that consumes the stream */
+- if (stream->config.continuous) {
++ if (stream->config.continuous)
+ target_pipe = stream_get_copy_pipe(stream);
+- } else {
++ else
+ target_pipe = stream_get_last_pipe(stream);
+- }
+
+ return target_pipe;
+ }
+@@ -1386,7 +1377,8 @@ start_binary(struct ia_css_pipe *pipe,
+ /* start the copy function on the SP */
+ static int
+ start_copy_on_sp(struct ia_css_pipe *pipe,
+- struct ia_css_frame *out_frame) {
++ struct ia_css_frame *out_frame)
++{
+ (void)out_frame;
+ assert(pipe);
+ assert(pipe->stream);
+@@ -1404,8 +1396,7 @@ start_copy_on_sp(struct ia_css_pipe *pip
+ sh_css_sp_start_binary_copy(ia_css_pipe_get_pipe_num(pipe), out_frame, pipe->stream->config.pixels_per_clock == 2);
+
+ #if !defined(ISP2401)
+- if (pipe->stream->reconfigure_css_rx)
+- {
++ if (pipe->stream->reconfigure_css_rx) {
+ ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
+ pipe->stream->config.mode);
+ pipe->stream->reconfigure_css_rx = false;
+@@ -1594,7 +1585,8 @@ ia_css_reset_defaults(struct sh_css *css
+
+ int
+ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
+- const struct ia_css_fw *fw) {
++ const struct ia_css_fw *fw)
++{
+ int err;
+
+ if (!env)
+@@ -1605,16 +1597,14 @@ ia_css_load_firmware(struct device *dev,
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() enter\n");
+
+ /* make sure we initialize my_css */
+- if (my_css.flush != env->cpu_mem_env.flush)
+- {
++ if (my_css.flush != env->cpu_mem_env.flush) {
+ ia_css_reset_defaults(&my_css);
+ my_css.flush = env->cpu_mem_env.flush;
+ }
+
+ ia_css_unload_firmware(); /* in case we are called twice */
+ err = sh_css_load_firmware(dev, fw->data, fw->bytes);
+- if (!err)
+- {
++ if (!err) {
+ err = ia_css_binary_init_infos();
+ if (!err)
+ fw_explicitly_loaded = true;
+@@ -1628,7 +1618,8 @@ int
+ ia_css_init(struct device *dev, const struct ia_css_env *env,
+ const struct ia_css_fw *fw,
+ u32 mmu_l1_base,
+- enum ia_css_irq_type irq_type) {
++ enum ia_css_irq_type irq_type)
++{
+ int err;
+ ia_css_spctrl_cfg spctrl_cfg;
+
+@@ -1702,16 +1693,14 @@ ia_css_init(struct device *dev, const st
+ my_css.flush = flush_func;
+
+ err = ia_css_rmgr_init();
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+
+ IA_CSS_LOG("init: %d", my_css_save_initialized);
+
+- if (!my_css_save_initialized)
+- {
++ if (!my_css_save_initialized) {
+ my_css_save_initialized = true;
+ my_css_save.mode = sh_css_mode_working;
+ memset(my_css_save.stream_seeds, 0,
+@@ -1739,19 +1728,16 @@ ia_css_init(struct device *dev, const st
+ gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_0, 0);
+
+ err = ia_css_refcount_init(REFCOUNT_SIZE);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+ err = sh_css_params_init();
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+- if (fw)
+- {
++ if (fw) {
+ ia_css_unload_firmware(); /* in case we already had firmware loaded */
+ err = sh_css_load_firmware(dev, fw->data, fw->bytes);
+ if (err) {
+@@ -1772,23 +1758,20 @@ ia_css_init(struct device *dev, const st
+ return -EINVAL;
+
+ err = ia_css_spctrl_load_fw(SP0_ID, &spctrl_cfg);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+
+ #if WITH_PC_MONITORING
+- if (!thread_alive)
+- {
++ if (!thread_alive) {
+ thread_alive++;
+ sh_css_print("PC_MONITORING: %s() -- create thread DISABLED\n",
+ __func__);
+ spying_thread_create();
+ }
+ #endif
+- if (!sh_css_hrt_system_is_idle())
+- {
++ if (!sh_css_hrt_system_is_idle()) {
+ IA_CSS_LEAVE_ERR(-EBUSY);
+ return -EBUSY;
+ }
+@@ -1821,7 +1804,8 @@ ia_css_init(struct device *dev, const st
+ }
+
+ int
+-ia_css_enable_isys_event_queue(bool enable) {
++ia_css_enable_isys_event_queue(bool enable)
++{
+ if (sh_css_sp_is_running())
+ return -EBUSY;
+ sh_css_sp_enable_isys_event_queue(enable);
+@@ -1842,7 +1826,8 @@ sh_css_flush(struct ia_css_acc_fw *fw)
+ * doing it from stream_create since we could run out of sp threads due to
+ * allocation on inactive pipelines. */
+ static int
+-map_sp_threads(struct ia_css_stream *stream, bool map) {
++map_sp_threads(struct ia_css_stream *stream, bool map)
++{
+ struct ia_css_pipe *main_pipe = NULL;
+ struct ia_css_pipe *copy_pipe = NULL;
+ struct ia_css_pipe *capture_pipe = NULL;
+@@ -1854,8 +1839,7 @@ map_sp_threads(struct ia_css_stream *str
+ IA_CSS_ENTER_PRIVATE("stream = %p, map = %s",
+ stream, map ? "true" : "false");
+
+- if (!stream)
+- {
++ if (!stream) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -1865,8 +1849,7 @@ map_sp_threads(struct ia_css_stream *str
+
+ ia_css_pipeline_map(main_pipe->pipe_num, map);
+
+- switch (pipe_id)
+- {
++ switch (pipe_id) {
+ case IA_CSS_PIPE_ID_PREVIEW:
+ copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
+ capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
+@@ -1885,23 +1868,17 @@ map_sp_threads(struct ia_css_stream *str
+ }
+
+ if (acc_pipe)
+- {
+ ia_css_pipeline_map(acc_pipe->pipe_num, map);
+- }
+
+ if (capture_pipe)
+- {
+ ia_css_pipeline_map(capture_pipe->pipe_num, map);
+- }
+
+ /* Firmware expects copy pipe to be the last pipe mapped. (if needed) */
+ if (copy_pipe)
+- {
+ ia_css_pipeline_map(copy_pipe->pipe_num, map);
+- }
++
+ /* DH regular multi pipe - not continuous mode: map the next pipes too */
+- if (!stream->config.continuous)
+- {
++ if (!stream->config.continuous) {
+ int i;
+
+ for (i = 1; i < stream->num_pipes; i++)
+@@ -1915,7 +1892,8 @@ map_sp_threads(struct ia_css_stream *str
+ /* creates a host pipeline skeleton for all pipes in a stream. Called during
+ * stream_create. */
+ static int
+-create_host_pipeline_structure(struct ia_css_stream *stream) {
++create_host_pipeline_structure(struct ia_css_stream *stream)
++{
+ struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
+ struct ia_css_pipe *acc_pipe = NULL;
+ enum ia_css_pipe_id pipe_id;
+@@ -1927,24 +1905,21 @@ create_host_pipeline_structure(struct ia
+ assert(stream);
+ IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+
+- if (!stream)
+- {
++ if (!stream) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+
+ main_pipe = stream->last_pipe;
+ assert(main_pipe);
+- if (!main_pipe)
+- {
++ if (!main_pipe) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+
+ pipe_id = main_pipe->mode;
+
+- switch (pipe_id)
+- {
++ switch (pipe_id) {
+ case IA_CSS_PIPE_ID_PREVIEW:
+ copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
+ copy_pipe_delay = main_pipe->dvs_frame_delay;
+@@ -1984,30 +1959,23 @@ create_host_pipeline_structure(struct ia
+ }
+
+ if (!(err) && copy_pipe)
+- {
+ err = ia_css_pipeline_create(©_pipe->pipeline,
+ copy_pipe->mode,
+ copy_pipe->pipe_num,
+ copy_pipe_delay);
+- }
+
+ if (!(err) && capture_pipe)
+- {
+ err = ia_css_pipeline_create(&capture_pipe->pipeline,
+ capture_pipe->mode,
+ capture_pipe->pipe_num,
+ capture_pipe_delay);
+- }
+
+ if (!(err) && acc_pipe)
+- {
+ err = ia_css_pipeline_create(&acc_pipe->pipeline, acc_pipe->mode,
+ acc_pipe->pipe_num, main_pipe->dvs_frame_delay);
+- }
+
+ /* DH regular multi pipe - not continuous mode: create the next pipelines too */
+- if (!stream->config.continuous)
+- {
++ if (!stream->config.continuous) {
+ int i;
+
+ for (i = 1; i < stream->num_pipes && 0 == err; i++) {
+@@ -2026,7 +1994,8 @@ create_host_pipeline_structure(struct ia
+ /* creates a host pipeline for all pipes in a stream. Called during
+ * stream_start. */
+ static int
+-create_host_pipeline(struct ia_css_stream *stream) {
++create_host_pipeline(struct ia_css_stream *stream)
++{
+ struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
+ struct ia_css_pipe *acc_pipe = NULL;
+ enum ia_css_pipe_id pipe_id;
+@@ -2035,8 +2004,7 @@ create_host_pipeline(struct ia_css_strea
+ unsigned int max_input_width = 0;
+
+ IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+- if (!stream)
+- {
++ if (!stream) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -2047,8 +2015,7 @@ create_host_pipeline(struct ia_css_strea
+ /* No continuous frame allocation for capture pipe. It uses the
+ * "main" pipe's frames. */
+ if ((pipe_id == IA_CSS_PIPE_ID_PREVIEW) ||
+- (pipe_id == IA_CSS_PIPE_ID_VIDEO))
+- {
++ (pipe_id == IA_CSS_PIPE_ID_VIDEO)) {
+ /* About pipe_id == IA_CSS_PIPE_ID_PREVIEW && stream->config.mode != IA_CSS_INPUT_MODE_MEMORY:
+ * The original condition pipe_id == IA_CSS_PIPE_ID_PREVIEW is too strong. E.g. in SkyCam (with memory
+ * based input frames) there is no continuous mode and thus no need for allocated continuous frames
+@@ -2066,24 +2033,21 @@ create_host_pipeline(struct ia_css_strea
+
+ #if !defined(ISP2401)
+ /* old isys: need to allocate_mipi_frames() even in IA_CSS_PIPE_MODE_COPY */
+- if (pipe_id != IA_CSS_PIPE_ID_ACC)
+- {
++ if (pipe_id != IA_CSS_PIPE_ID_ACC) {
+ err = allocate_mipi_frames(main_pipe, &stream->info);
+ if (err)
+ goto ERR;
+ }
+ #elif defined(ISP2401)
+ if ((pipe_id != IA_CSS_PIPE_ID_ACC) &&
+- (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY))
+- {
++ (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
+ err = allocate_mipi_frames(main_pipe, &stream->info);
+ if (err)
+ goto ERR;
+ }
+ #endif
+
+- switch (pipe_id)
+- {
++ switch (pipe_id) {
+ case IA_CSS_PIPE_ID_PREVIEW:
+ copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
+ capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
+@@ -2133,31 +2097,27 @@ create_host_pipeline(struct ia_css_strea
+ if (err)
+ goto ERR;
+
+- if (copy_pipe)
+- {
++ if (copy_pipe) {
+ err = create_host_copy_pipeline(copy_pipe, max_input_width,
+ main_pipe->continuous_frames[0]);
+ if (err)
+ goto ERR;
+ }
+
+- if (capture_pipe)
+- {
++ if (capture_pipe) {
+ err = create_host_capture_pipeline(capture_pipe);
+ if (err)
+ goto ERR;
+ }
+
+- if (acc_pipe)
+- {
++ if (acc_pipe) {
+ err = create_host_acc_pipeline(acc_pipe);
+ if (err)
+ goto ERR;
+ }
+
+ /* DH regular multi pipe - not continuous mode: create the next pipelines too */
+- if (!stream->config.continuous)
+- {
++ if (!stream->config.continuous) {
+ int i;
+
+ for (i = 1; i < stream->num_pipes && 0 == err; i++) {
+@@ -2199,10 +2159,10 @@ static const struct ia_css_yuvpp_setting
+ static int
+ init_pipe_defaults(enum ia_css_pipe_mode mode,
+ struct ia_css_pipe *pipe,
+- bool copy_pipe) {
++ bool copy_pipe)
++{
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_ERROR("NULL pipe parameter");
+ return -EINVAL;
+ }
+@@ -2211,18 +2171,17 @@ init_pipe_defaults(enum ia_css_pipe_mode
+ memcpy(pipe, &default_pipe, sizeof(default_pipe));
+
+ /* TODO: JB should not be needed, but temporary backward reference */
+- switch (mode)
+- {
++ switch (mode) {
+ case IA_CSS_PIPE_MODE_PREVIEW:
+ pipe->mode = IA_CSS_PIPE_ID_PREVIEW;
+ memcpy(&pipe->pipe_settings.preview, &preview, sizeof(preview));
+ break;
+ case IA_CSS_PIPE_MODE_CAPTURE:
+- if (copy_pipe) {
++ if (copy_pipe)
+ pipe->mode = IA_CSS_PIPE_ID_COPY;
+- } else {
++ else
+ pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
+- }
++
+ memcpy(&pipe->pipe_settings.capture, &capture, sizeof(capture));
+ break;
+ case IA_CSS_PIPE_MODE_VIDEO:
+@@ -2252,27 +2211,25 @@ pipe_global_init(void)
+ u8 i;
+
+ my_css.pipe_counter = 0;
+- for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
++ for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++)
+ my_css.all_pipes[i] = NULL;
+- }
+ }
+
+ static int
+ pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
+- unsigned int *pipe_number) {
++ unsigned int *pipe_number)
++{
+ const u8 INVALID_PIPE_NUM = (uint8_t)~(0);
+ u8 pipe_num = INVALID_PIPE_NUM;
+ u8 i;
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_ERROR("NULL pipe parameter");
+ return -EINVAL;
+ }
+
+ /* Assign a new pipe_num .... search for empty place */
+- for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++)
+- {
++ for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
+ if (!my_css.all_pipes[i]) {
+ /*position is reserved */
+ my_css.all_pipes[i] = (struct ia_css_pipe *)pipe;
+@@ -2280,8 +2237,7 @@ pipe_generate_pipe_num(const struct ia_c
+ break;
+ }
+ }
+- if (pipe_num == INVALID_PIPE_NUM)
+- {
++ if (pipe_num == INVALID_PIPE_NUM) {
+ /* Max number of pipes already allocated */
+ IA_CSS_ERROR("Max number of pipes already created");
+ return -ENOSPC;
--- /dev/null
+From stable+bounces-274532-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:55 -0400
+Subject: media: staging: media: atomisp: Fix the rest of sh_css.c brace issues
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-3-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit 7394bf6d3c1e8316484fcf3a9d71daaab489f211 ]
+
+Fix the remainder of brace coding style issues.
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 1134 ++++++++++++-----------------
+ 1 file changed, 498 insertions(+), 636 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -1101,8 +1101,7 @@ sh_css_config_input_network(struct ia_cs
+ /* get the target input terminal */
+ sp_pipeline_input_terminal = &sh_css_sp_group.pipe_io[sp_thread_id].input;
+
+- for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++)
+- {
++ for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) {
+ /* initialization */
+ memset((void *)(&isys_stream_descr), 0, sizeof(ia_css_isys_descr_t));
+ sp_pipeline_input_terminal->context.virtual_input_system_stream[i].valid = 0;
+@@ -2161,7 +2160,6 @@ init_pipe_defaults(enum ia_css_pipe_mode
+ struct ia_css_pipe *pipe,
+ bool copy_pipe)
+ {
+-
+ if (!pipe) {
+ IA_CSS_ERROR("NULL pipe parameter");
+ return -EINVAL;
+@@ -2263,12 +2261,12 @@ pipe_release_pipe_num(unsigned int pipe_
+ static int
+ create_pipe(enum ia_css_pipe_mode mode,
+ struct ia_css_pipe **pipe,
+- bool copy_pipe) {
++ bool copy_pipe)
++{
+ int err = 0;
+ struct ia_css_pipe *me;
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_ERROR("NULL pipe parameter");
+ return -EINVAL;
+ }
+@@ -2278,15 +2276,13 @@ create_pipe(enum ia_css_pipe_mode mode,
+ return -ENOMEM;
+
+ err = init_pipe_defaults(mode, me, copy_pipe);
+- if (err)
+- {
++ if (err) {
+ kfree(me);
+ return err;
+ }
+
+ err = pipe_generate_pipe_num(me, &me->pipe_num);
+- if (err)
+- {
++ if (err) {
+ kfree(me);
+ return err;
+ }
+@@ -2332,26 +2328,24 @@ static void sh_css_pipe_free_acc_binarie
+ }
+
+ int
+-ia_css_pipe_destroy(struct ia_css_pipe *pipe) {
++ia_css_pipe_destroy(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+
+ IA_CSS_ENTER("pipe = %p", pipe);
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+- if (pipe->stream)
+- {
++ if (pipe->stream) {
+ IA_CSS_LOG("ia_css_stream_destroy not called!");
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+- switch (pipe->config.mode)
+- {
++ switch (pipe->config.mode) {
+ case IA_CSS_PIPE_MODE_PREVIEW:
+ /* need to take into account that this function is also called
+ on the internal copy pipe */
+@@ -2415,9 +2409,8 @@ ia_css_pipe_destroy(struct ia_css_pipe *
+
+ /* Temporarily, not every sh_css_pipe has an acc_extension. */
+ if (pipe->config.acc_extension)
+- {
+ ia_css_pipe_unload_extension(pipe, pipe->config.acc_extension);
+- }
++
+ kfree(pipe);
+ IA_CSS_LEAVE("err = %d", err);
+ return err;
+@@ -2447,9 +2440,9 @@ ia_css_uninit(void)
+ ifmtr_set_if_blocking_mode_reset = true;
+ #endif
+
+- if (!fw_explicitly_loaded) {
++ if (!fw_explicitly_loaded)
+ ia_css_unload_firmware();
+- }
++
+ ia_css_spctrl_unload_fw(SP0_ID);
+ sh_css_sp_set_sp_running(false);
+ /* check and free any remaining mipi frames */
+@@ -2636,7 +2629,8 @@ static int load_copy_binary(
+
+ static int
+ alloc_continuous_frames(
+- struct ia_css_pipe *pipe, bool init_time) {
++ struct ia_css_pipe *pipe, bool init_time)
++{
+ int err = 0;
+ struct ia_css_frame_info ref_info;
+ enum ia_css_pipe_id pipe_id;
+@@ -2646,8 +2640,7 @@ alloc_continuous_frames(
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p, init_time = %d", pipe, init_time);
+
+- if ((!pipe) || (!pipe->stream))
+- {
++ if ((!pipe) || (!pipe->stream)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -2655,26 +2648,22 @@ alloc_continuous_frames(
+ pipe_id = pipe->mode;
+ continuous = pipe->stream->config.continuous;
+
+- if (continuous)
+- {
++ if (continuous) {
+ if (init_time) {
+ num_frames = pipe->stream->config.init_num_cont_raw_buf;
+ pipe->stream->continuous_pipe = pipe;
+- } else
++ } else {
+ num_frames = pipe->stream->config.target_num_cont_raw_buf;
+- } else
+- {
++ }
++ } else {
+ num_frames = NUM_ONLINE_INIT_CONTINUOUS_FRAMES;
+ }
+
+- if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+- {
++ if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
+ ref_info = pipe->pipe_settings.preview.preview_binary.in_frame_info;
+- } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO)
+- {
++ } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) {
+ ref_info = pipe->pipe_settings.video.video_binary.in_frame_info;
+- } else
+- {
++ } else {
+ /* should not happen */
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+@@ -2690,8 +2679,7 @@ alloc_continuous_frames(
+ #endif
+
+ #if !defined(HAS_NO_PACKED_RAW_PIXELS)
+- if (pipe->stream->config.pack_raw_pixels)
+- {
++ if (pipe->stream->config.pack_raw_pixels) {
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW_PACKED\n");
+ ref_info.format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
+@@ -2720,8 +2708,7 @@ alloc_continuous_frames(
+ else
+ idx = pipe->stream->config.init_num_cont_raw_buf;
+
+- for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++)
+- {
++ for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++) {
+ /* free previous frame */
+ if (pipe->continuous_frames[i]) {
+ ia_css_frame_free(pipe->continuous_frames[i]);
+@@ -2751,14 +2738,16 @@ alloc_continuous_frames(
+ }
+
+ int
+-ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream) {
++ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream)
++{
+ if (!stream)
+ return -EINVAL;
+ return alloc_continuous_frames(stream->continuous_pipe, false);
+ }
+
+ static int
+-load_preview_binaries(struct ia_css_pipe *pipe) {
++load_preview_binaries(struct ia_css_pipe *pipe)
++{
+ struct ia_css_frame_info prev_in_info,
+ prev_bds_out_info,
+ prev_out_info,
+@@ -2866,8 +2855,7 @@ load_preview_binaries(struct ia_css_pipe
+ * then the preview binary selection is done again.
+ */
+ if (need_vf_pp &&
+- (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE))
+- {
++ (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE)) {
+ /* Preview step 2 */
+ if (pipe->vf_yuv_ds_input_info.res.width)
+ prev_vf_info = pipe->vf_yuv_ds_input_info;
+@@ -2892,8 +2880,7 @@ load_preview_binaries(struct ia_css_pipe
+ return err;
+ }
+
+- if (need_vf_pp)
+- {
++ if (need_vf_pp) {
+ struct ia_css_binary_descr vf_pp_descr;
+
+ /* Viewfinder post-processing */
+@@ -2924,8 +2911,7 @@ load_preview_binaries(struct ia_css_pipe
+ #endif
+
+ /* Copy */
+- if (need_isp_copy_binary)
+- {
++ if (need_isp_copy_binary) {
+ err = load_copy_binary(pipe,
+ &mycs->copy_binary,
+ &mycs->preview_binary);
+@@ -2933,8 +2919,7 @@ load_preview_binaries(struct ia_css_pipe
+ return err;
+ }
+
+- if (pipe->shading_table)
+- {
++ if (pipe->shading_table) {
+ ia_css_shading_table_free(pipe->shading_table);
+ pipe->shading_table = NULL;
+ }
+@@ -2949,11 +2934,11 @@ ia_css_binary_unload(struct ia_css_binar
+ }
+
+ static int
+-unload_preview_binaries(struct ia_css_pipe *pipe) {
++unload_preview_binaries(struct ia_css_pipe *pipe)
++{
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+
+- if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
+- {
++ if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -3006,15 +2991,15 @@ static int add_firmwares(
+ struct ia_css_frame *in = NULL;
+ struct ia_css_frame *vf = NULL;
+
+- if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame != 0)) {
++ if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame != 0))
+ out[0] = out_frame;
+- }
+- if (fw->info.isp.sp.enable.in_frame != 0) {
++
++ if (fw->info.isp.sp.enable.in_frame != 0)
+ in = in_frame;
+- }
+- if (fw->info.isp.sp.enable.out_frame != 0) {
++
++ if (fw->info.isp.sp.enable.out_frame != 0)
+ vf = vf_frame;
+- }
++
+ ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary,
+ out, in, vf, fw, binary_mode);
+ err = ia_css_pipeline_create_and_add_stage(me,
+@@ -3228,7 +3213,8 @@ static void sh_css_setup_queues(void)
+
+ static int
+ init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
+- struct ia_css_frame *vf_frame, unsigned int idx) {
++ struct ia_css_frame *vf_frame, unsigned int idx)
++{
+ int err = 0;
+ unsigned int thread_id;
+ enum sh_css_queue_id queue_id;
+@@ -3393,7 +3379,8 @@ ia_css_get_crop_offsets(
+
+ static int
+ init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
+- struct ia_css_frame *frame, enum ia_css_frame_format format) {
++ struct ia_css_frame *frame, enum ia_css_frame_format format)
++{
+ struct ia_css_frame *in_frame;
+ int err = 0;
+ unsigned int thread_id;
+@@ -3434,7 +3421,8 @@ init_in_frameinfo_memory_defaults(struct
+
+ static int
+ init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
+- struct ia_css_frame *out_frame, unsigned int idx) {
++ struct ia_css_frame *out_frame, unsigned int idx)
++{
+ int err = 0;
+ unsigned int thread_id;
+ enum sh_css_queue_id queue_id;
+@@ -3665,14 +3653,14 @@ ERR:
+ }
+
+ static int
+-create_host_acc_pipeline(struct ia_css_pipe *pipe) {
++create_host_acc_pipeline(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+ const struct ia_css_fw_info *fw;
+ unsigned int i;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+- if ((!pipe) || (!pipe->stream))
+- {
++ if ((!pipe) || (!pipe->stream)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -3683,15 +3671,13 @@ create_host_acc_pipeline(struct ia_css_p
+ pipe->pipeline.pipe_qos_config = 0;
+
+ fw = pipe->vf_stage;
+- for (i = 0; fw; fw = fw->next)
+- {
++ for (i = 0; fw; fw = fw->next) {
+ err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
+ if (err)
+ goto ERR;
+ }
+
+- for (i = 0; i < pipe->config.num_acc_stages; i++)
+- {
++ for (i = 0; i < pipe->config.num_acc_stages; i++) {
+ struct ia_css_fw_info *fw = pipe->config.acc_stages[i];
+
+ err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
+@@ -3708,7 +3694,8 @@ ERR:
+
+ /* Create stages for preview */
+ static int
+-create_host_preview_pipeline(struct ia_css_pipe *pipe) {
++create_host_preview_pipeline(struct ia_css_pipe *pipe)
++{
+ struct ia_css_pipeline_stage *copy_stage = NULL;
+ struct ia_css_pipeline_stage *preview_stage = NULL;
+ struct ia_css_pipeline_stage *vf_pp_stage = NULL;
+@@ -3728,8 +3715,7 @@ create_host_preview_pipeline(struct ia_c
+ #endif
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+- if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
+- {
++ if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -3757,16 +3743,14 @@ create_host_preview_pipeline(struct ia_c
+ /* Construct in_frame info (only in case we have dynamic input */
+ need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
+ #endif
+- if (need_in_frameinfo_memory)
+- {
++ if (need_in_frameinfo_memory) {
+ err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
+ IA_CSS_FRAME_FORMAT_RAW);
+ if (err)
+ goto ERR;
+
+ in_frame = &me->in_frame;
+- } else
+- {
++ } else {
+ in_frame = NULL;
+ }
+
+@@ -3780,8 +3764,7 @@ create_host_preview_pipeline(struct ia_c
+ if (pipe->pipe_settings.preview.vf_pp_binary.info)
+ vf_pp_binary = &pipe->pipe_settings.preview.vf_pp_binary;
+
+- if (pipe->pipe_settings.preview.copy_binary.info)
+- {
++ if (pipe->pipe_settings.preview.copy_binary.info) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+ out_frames, NULL, NULL);
+@@ -3796,21 +3779,19 @@ create_host_preview_pipeline(struct ia_c
+ /* When continuous is enabled, configure in_frame with the
+ * last pipe, which is the copy pipe.
+ */
+- if (continuous || !online) {
++ if (continuous || !online)
+ in_frame = pipe->stream->last_pipe->continuous_frames[0];
+- }
++
+ #else
+ in_frame = pipe->continuous_frames[0];
+ #endif
+ }
+
+- if (vf_pp_binary)
+- {
++ if (vf_pp_binary) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
+ out_frames, in_frame, NULL);
+- } else
+- {
++ } else {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
+ out_frames, in_frame, NULL);
+@@ -3824,14 +3805,12 @@ create_host_preview_pipeline(struct ia_c
+ preview_stage->args.copy_vf =
+ preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY;
+ preview_stage->args.copy_output = !preview_stage->args.copy_vf;
+- if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame)
+- {
++ if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame) {
+ /* in case of copy, use the vf frame as output frame */
+ preview_stage->args.out_vf_frame =
+ preview_stage->args.out_frame[0];
+ }
+- if (vf_pp_binary)
+- {
++ if (vf_pp_binary) {
+ if (preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY)
+ in_frame = preview_stage->args.out_vf_frame;
+ else
+@@ -3871,7 +3850,8 @@ static void send_raw_frames(struct ia_cs
+ }
+
+ static int
+-preview_start(struct ia_css_pipe *pipe) {
++preview_start(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+ struct ia_css_pipe *copy_pipe, *capture_pipe;
+ struct ia_css_pipe *acc_pipe;
+@@ -3881,8 +3861,7 @@ preview_start(struct ia_css_pipe *pipe)
+ const struct ia_css_isp_parameters *params = NULL;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+- if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
+- {
++ if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -3909,8 +3888,7 @@ preview_start(struct ia_css_pipe *pipe)
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ copy_ovrd = 1 << thread_id;
+
+- if (pipe->stream->cont_capt)
+- {
++ if (pipe->stream->cont_capt) {
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
+ &thread_id);
+ copy_ovrd |= 1 << thread_id;
+@@ -3923,8 +3901,7 @@ preview_start(struct ia_css_pipe *pipe)
+ }
+
+ /* Construct and load the copy pipe */
+- if (pipe->stream->config.continuous)
+- {
++ if (pipe->stream->config.continuous) {
+ sh_css_sp_init_pipeline(©_pipe->pipeline,
+ IA_CSS_PIPE_ID_COPY,
+ (uint8_t)ia_css_pipe_get_pipe_num(copy_pipe),
+@@ -3945,8 +3922,7 @@ preview_start(struct ia_css_pipe *pipe)
+ }
+
+ /* Construct and load the capture pipe */
+- if (pipe->stream->cont_capt)
+- {
++ if (pipe->stream->cont_capt) {
+ sh_css_sp_init_pipeline(&capture_pipe->pipeline,
+ IA_CSS_PIPE_ID_CAPTURE,
+ (uint8_t)ia_css_pipe_get_pipe_num(capture_pipe),
+@@ -3964,8 +3940,7 @@ preview_start(struct ia_css_pipe *pipe)
+ params);
+ }
+
+- if (acc_pipe)
+- {
++ if (acc_pipe) {
+ sh_css_sp_init_pipeline(&acc_pipe->pipeline,
+ IA_CSS_PIPE_ID_ACC,
+ (uint8_t)ia_css_pipe_get_pipe_num(acc_pipe),
+@@ -3991,7 +3966,8 @@ preview_start(struct ia_css_pipe *pipe)
+
+ int
+ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
+- const struct ia_css_buffer *buffer) {
++ const struct ia_css_buffer *buffer)
++{
+ int return_err = 0;
+ unsigned int thread_id;
+ enum sh_css_queue_id queue_id;
+@@ -4006,8 +3982,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+
+ IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer);
+
+- if ((!pipe) || (!buffer))
+- {
++ if ((!pipe) || (!buffer)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+@@ -4016,8 +3991,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ /* following code will be enabled when IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME
+ is removed */
+ #if 0
+- if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
+- {
++ if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
+ bool found_pipe = false;
+
+ for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+@@ -4031,8 +4005,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ if (!found_pipe)
+ return -EINVAL;
+ }
+- if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+- {
++ if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
+ bool found_pipe = false;
+
+ for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+@@ -4055,34 +4028,29 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ assert(buf_type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE);
+ if ((buf_type == IA_CSS_BUFFER_TYPE_INVALID) ||
+ (buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE) ||
+- (pipe_id >= IA_CSS_PIPE_ID_NUM))
+- {
++ (pipe_id >= IA_CSS_PIPE_ID_NUM)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+ ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+- if (!ret_err)
+- {
++ if (!ret_err) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+ ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
+- if (!ret_err)
+- {
++ if (!ret_err) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+- if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES))
+- {
++ if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+- if (!sh_css_sp_is_running())
+- {
++ if (!sh_css_sp_is_running()) {
+ IA_CSS_LOG("SP is not running!");
+ IA_CSS_LEAVE_ERR(-EBUSY);
+ /* SP is not running. The queues are not valid */
+@@ -4100,24 +4068,21 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ ddr_buffer.cookie_ptr = buffer->driver_cookie;
+ ddr_buffer.timing_data = buffer->timing_data;
+
+- if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
+- {
++ if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) {
+ if (!buffer->data.stats_3a) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+ ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_3a);
+ ddr_buffer.payload.s3a = *buffer->data.stats_3a;
+- } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
+- {
++ } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) {
+ if (!buffer->data.stats_dvs) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+ ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_dvs);
+ ddr_buffer.payload.dis = *buffer->data.stats_dvs;
+- } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA)
+- {
++ } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA) {
+ if (!buffer->data.metadata) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+@@ -4128,8 +4093,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
+ || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+ || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
+- || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME))
+- {
++ || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)) {
+ if (!buffer->data.frame) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+@@ -4164,8 +4128,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ assert(h_vbuf);
+ assert(h_vbuf->vptr != 0x0);
+
+- if ((!h_vbuf) || (h_vbuf->vptr == 0x0))
+- {
++ if ((!h_vbuf) || (h_vbuf->vptr == 0x0)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+@@ -4175,8 +4138,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ sizeof(struct sh_css_hmm_buffer));
+ if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
+ || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
+- || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS))
+- {
++ || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) {
+ if (!pipeline) {
+ ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
+ IA_CSS_LOG("pipeline is empty!");
+@@ -4199,8 +4161,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+ || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
+ || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)
+- || (buf_type == IA_CSS_BUFFER_TYPE_METADATA))
+- {
++ || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) {
+ return_err = ia_css_bufq_enqueue_buffer(thread_id,
+ queue_id,
+ (uint32_t)h_vbuf->vptr);
+@@ -4214,8 +4175,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ #endif
+ }
+
+- if (!return_err)
+- {
++ if (!return_err) {
+ if (sh_css_hmm_buffer_record_acquire(
+ h_vbuf, buf_type,
+ HOST_ADDRESS(ddr_buffer.kernel_ptr))) {
+@@ -4230,8 +4190,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ * Tell the SP which queues are not empty,
+ * by sending the software event.
+ */
+- if (!return_err)
+- {
++ if (!return_err) {
+ if (!sh_css_sp_is_running()) {
+ /* SP is not running. The queues are not valid */
+ IA_CSS_LOG("SP is not running!");
+@@ -4243,8 +4202,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ (uint8_t)thread_id,
+ queue_id,
+ 0);
+- } else
+- {
++ } else {
+ ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
+ IA_CSS_ERROR("buffer not enqueued");
+ }
+@@ -4259,7 +4217,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ */
+ int
+ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
+- struct ia_css_buffer *buffer) {
++ struct ia_css_buffer *buffer)
++{
+ int return_err;
+ enum sh_css_queue_id queue_id;
+ ia_css_ptr ddr_buffer_addr = (ia_css_ptr)0;
+@@ -4272,8 +4231,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+
+ IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer);
+
+- if ((!pipe) || (!buffer))
+- {
++ if ((!pipe) || (!buffer)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+@@ -4287,27 +4245,23 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+ ddr_buffer.kernel_ptr = 0;
+
+ ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+- if (!ret_err)
+- {
++ if (!ret_err) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+ ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
+- if (!ret_err)
+- {
++ if (!ret_err) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+- if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES))
+- {
++ if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+- if (!sh_css_sp_is_running())
+- {
++ if (!sh_css_sp_is_running()) {
+ IA_CSS_LOG("SP is not running!");
+ IA_CSS_LEAVE_ERR(-EBUSY);
+ /* SP is not running. The queues are not valid */
+@@ -4317,8 +4271,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+ return_err = ia_css_bufq_dequeue_buffer(queue_id,
+ (uint32_t *)&ddr_buffer_addr);
+
+- if (!return_err)
+- {
++ if (!return_err) {
+ struct ia_css_frame *frame;
+ struct sh_css_hmm_buffer_record *hmm_buffer_record = NULL;
+
+@@ -4460,8 +4413,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+ * Tell the SP which queues are not full,
+ * by sending the software event.
+ */
+- if (!return_err)
+- {
++ if (!return_err) {
+ if (!sh_css_sp_is_running()) {
+ IA_CSS_LOG("SP is not running!");
+ IA_CSS_LEAVE_ERR(-EBUSY);
+@@ -4510,12 +4462,14 @@ static enum ia_css_event_type convert_ev
+ };
+
+ int
+-ia_css_dequeue_event(struct ia_css_event *event) {
++ia_css_dequeue_event(struct ia_css_event *event)
++{
+ return ia_css_dequeue_psys_event(event);
+ }
+
+ int
+-ia_css_dequeue_psys_event(struct ia_css_event *event) {
++ia_css_dequeue_psys_event(struct ia_css_event *event)
++{
+ enum ia_css_pipe_id pipe_id = 0;
+ u8 payload[4] = {0, 0, 0, 0};
+ int ret_err;
+@@ -4530,11 +4484,9 @@ ia_css_dequeue_psys_event(struct ia_css_
+ if (!event)
+ return -EINVAL;
+
++ /* SP is not running. The queues are not valid */
+ if (!sh_css_sp_is_running())
+- {
+- /* SP is not running. The queues are not valid */
+ return -EBUSY;
+- }
+
+ /* dequeue the event (if any) from the psys event queue */
+ ret_err = ia_css_bufq_dequeue_psys_event(payload);
+@@ -4561,8 +4513,7 @@ ia_css_dequeue_psys_event(struct ia_css_
+ event->timer_code = 0;
+ event->timer_subcode = 0;
+
+- if (event->type == IA_CSS_EVENT_TYPE_TIMER)
+- {
++ if (event->type == IA_CSS_EVENT_TYPE_TIMER) {
+ /* timer event ??? get the 2nd event and decode the data into the event struct */
+ u32 tmp_data;
+ /* 1st event: LSB 16-bit timer data and code */
+@@ -4586,37 +4537,32 @@ ia_css_dequeue_psys_event(struct ia_css_
+ tmp_data = ((payload[1] & 0xFF) | ((payload[3] & 0xFF) << 8));
+ event->timer_data |= (tmp_data << 16);
+ event->timer_subcode = payload[2];
+- }
++ } else {
+ /* It's a non timer event. So clear first half of the timer event data.
+ * If the second part of the TIMER event is not received, we discard
+ * the first half of the timer data and process the non timer event without
+ * affecting the flow. So the non timer event falls through
+ * the code. */
+- else {
+ event->timer_data = 0;
+ event->timer_code = 0;
+ event->timer_subcode = 0;
+ IA_CSS_ERROR("Missing 2nd timer event. Timer event discarded");
+ }
+ }
+- if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF)
+- {
++ if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF) {
+ event->port = (enum mipi_port_id)payload[1];
+ event->exp_id = payload[3];
+- } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING)
+- {
++ } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING) {
+ event->fw_warning = (enum ia_css_fw_warning)payload[1];
+ /* exp_id is only available in these warning types */
+ if (event->fw_warning == IA_CSS_FW_WARNING_EXP_ID_LOCKED ||
+ event->fw_warning == IA_CSS_FW_WARNING_TAG_EXP_ID_FAILED)
+ event->exp_id = payload[3];
+- } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT)
+- {
++ } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT) {
+ event->fw_assert_module_id = payload[1]; /* module */
+ event->fw_assert_line_no = (payload[2] << 8) + payload[3];
+ /* payload[2] is line_no>>8, payload[3] is line_no&0xff */
+- } else if (event->type != IA_CSS_EVENT_TYPE_TIMER)
+- {
++ } else if (event->type != IA_CSS_EVENT_TYPE_TIMER) {
+ /* pipe related events.
+ * payload[1] contains the pipe_num,
+ * payload[2] contains the pipe_id. These are different. */
+@@ -4666,7 +4612,8 @@ ia_css_dequeue_psys_event(struct ia_css_
+ }
+
+ int
+-ia_css_dequeue_isys_event(struct ia_css_event *event) {
++ia_css_dequeue_isys_event(struct ia_css_event *event)
++{
+ u8 payload[4] = {0, 0, 0, 0};
+ int err = 0;
+
+@@ -4676,11 +4623,9 @@ ia_css_dequeue_isys_event(struct ia_css_
+ if (!event)
+ return -EINVAL;
+
++ /* SP is not running. The queues are not valid */
+ if (!sh_css_sp_is_running())
+- {
+- /* SP is not running. The queues are not valid */
+ return -EBUSY;
+- }
+
+ err = ia_css_bufq_dequeue_isys_event(payload);
+ if (err)
+@@ -4713,7 +4658,8 @@ acc_start(struct ia_css_pipe *pipe)
+ }
+
+ static int
+-sh_css_pipe_start(struct ia_css_stream *stream) {
++sh_css_pipe_start(struct ia_css_stream *stream)
++{
+ int err = 0;
+
+ struct ia_css_pipe *pipe;
+@@ -4722,22 +4668,19 @@ sh_css_pipe_start(struct ia_css_stream *
+
+ IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+
+- if (!stream)
+- {
++ if (!stream) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+ pipe = stream->last_pipe;
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+
+ pipe_id = pipe->mode;
+
+- if (stream->started)
+- {
++ if (stream->started) {
+ IA_CSS_WARNING("Cannot start stream that is already started");
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+@@ -4745,8 +4688,7 @@ sh_css_pipe_start(struct ia_css_stream *
+
+ pipe->stop_requested = false;
+
+- switch (pipe_id)
+- {
++ switch (pipe_id) {
+ case IA_CSS_PIPE_ID_PREVIEW:
+ err = preview_start(pipe);
+ break;
+@@ -4766,8 +4708,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ err = -EINVAL;
+ }
+ /* DH regular multi pipe - not continuous mode: start the next pipes too */
+- if (!stream->config.continuous)
+- {
++ if (!stream->config.continuous) {
+ int i;
+
+ for (i = 1; i < stream->num_pipes && 0 == err ; i++) {
+@@ -4797,8 +4738,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ }
+ }
+ }
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+@@ -4808,8 +4748,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ * don't use ISP parameters anyway. So this should be okay.
+ * The SP binary (jpeg) copy does not use any parameters.
+ */
+- if (!copy_on_sp(pipe))
+- {
++ if (!copy_on_sp(pipe)) {
+ sh_css_invalidate_params(stream);
+ err = sh_css_param_update_isp_params(pipe,
+ stream->isp_params_configs, true, NULL);
+@@ -4823,8 +4762,7 @@ sh_css_pipe_start(struct ia_css_stream *
+
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+
+- if (!sh_css_sp_is_running())
+- {
++ if (!sh_css_sp_is_running()) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EBUSY);
+ /* SP is not running. The queues are not valid */
+ return -EBUSY;
+@@ -4833,8 +4771,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ (uint8_t)thread_id, 0, 0);
+
+ /* DH regular multi pipe - not continuous mode: enqueue event to the next pipes too */
+- if (!stream->config.continuous)
+- {
++ if (!stream->config.continuous) {
+ int i;
+
+ for (i = 1; i < stream->num_pipes; i++) {
+@@ -4848,8 +4785,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ }
+
+ /* in case of continuous capture mode, we also start capture thread and copy thread*/
+- if (pipe->stream->config.continuous)
+- {
++ if (pipe->stream->config.continuous) {
+ struct ia_css_pipe *copy_pipe = NULL;
+
+ if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+@@ -4868,8 +4804,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ IA_CSS_PSYS_SW_EVENT_START_STREAM,
+ (uint8_t)thread_id, 0, 0);
+ }
+- if (pipe->stream->cont_capt)
+- {
++ if (pipe->stream->cont_capt) {
+ struct ia_css_pipe *capture_pipe = NULL;
+
+ if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+@@ -4890,8 +4825,7 @@ sh_css_pipe_start(struct ia_css_stream *
+ }
+
+ /* in case of PREVIEW mode, check whether QOS acc_pipe is available, then start the qos pipe */
+- if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+- {
++ if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
+ struct ia_css_pipe *acc_pipe = NULL;
+
+ acc_pipe = pipe->pipe_settings.preview.acc_pipe;
+@@ -4942,7 +4876,8 @@ sh_css_continuous_is_enabled(uint8_t pip
+ /* ISP2400 */
+ int
+ ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream,
+- int *buffer_depth) {
++ int *buffer_depth)
++{
+ if (!buffer_depth)
+ return -EINVAL;
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_max_buffer_depth() enter: void\n");
+@@ -4952,7 +4887,8 @@ ia_css_stream_get_max_buffer_depth(struc
+ }
+
+ int
+-ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth) {
++ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth)
++{
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_set_buffer_depth() enter: num_frames=%d\n", buffer_depth);
+ (void)stream;
+ if (buffer_depth > NUM_CONTINUOUS_FRAMES || buffer_depth < 1)
+@@ -4966,7 +4902,8 @@ ia_css_stream_set_buffer_depth(struct ia
+ /* ISP2401 */
+ int
+ ia_css_stream_get_buffer_depth(struct ia_css_stream *stream,
+- int *buffer_depth) {
++ int *buffer_depth)
++{
+ if (!buffer_depth)
+ return -EINVAL;
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_buffer_depth() enter: void\n");
+@@ -4991,8 +4928,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+ int i;
+
+ assert(stream);
+- if (!stream)
+- {
++ if (!stream) {
+ IA_CSS_LOG("stream does NOT exist!");
+ err = -EINVAL;
+ goto ERR;
+@@ -5000,8 +4936,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+
+ main_pipe = stream->last_pipe;
+ assert(main_pipe);
+- if (!main_pipe)
+- {
++ if (!main_pipe) {
+ IA_CSS_LOG("main_pipe does NOT exist!");
+ err = -EINVAL;
+ goto ERR;
+@@ -5014,8 +4949,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+ * Stop all "ia_css_pipe" instances in this target
+ * "ia_css_stream" instance.
+ */
+- for (i = 0; i < stream->num_pipes; i++)
+- {
++ for (i = 0; i < stream->num_pipes; i++) {
+ /* send the "stop" request to the "ia_css_pipe" instance */
+ IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
+ stream->pipes[i]->pipeline.pipe_id);
+@@ -5049,8 +4983,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+ *
+ * We need to stop this "Copy Pipe", as well.
+ */
+- if (main_pipe->stream->config.continuous)
+- {
++ if (main_pipe->stream->config.continuous) {
+ struct ia_css_pipe *copy_pipe = NULL;
+
+ /* get the reference to "Copy Pipe" */
+@@ -5226,8 +5159,7 @@ sh_css_pipe_get_shading_info(struct ia_c
+
+ binary = ia_css_pipe_get_shading_correction_binary(pipe);
+
+- if (binary)
+- {
++ if (binary) {
+ err = ia_css_binary_get_shading_info(binary,
+ IA_CSS_SHADING_CORRECTION_TYPE_1,
+ pipe->required_bds_factor,
+@@ -5237,8 +5169,7 @@ sh_css_pipe_get_shading_info(struct ia_c
+ /* Other function calls can be added here when other shading correction types will be added
+ * in the future.
+ */
+- } else
+- {
++ } else {
+ /* When the pipe does not have a binary which has the shading
+ * correction, this function does not need to fill the shading
+ * information. It is not a error case, and then
+@@ -5251,7 +5182,8 @@ sh_css_pipe_get_shading_info(struct ia_c
+
+ static int
+ sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe,
+- struct ia_css_grid_info *info) {
++ struct ia_css_grid_info *info)
++{
+ int err = 0;
+ struct ia_css_binary *binary = NULL;
+
+@@ -5262,30 +5194,27 @@ sh_css_pipe_get_grid_info(struct ia_css_
+
+ binary = ia_css_pipe_get_s3a_binary(pipe);
+
+- if (binary)
+- {
++ if (binary) {
+ err = ia_css_binary_3a_grid_info(binary, info, pipe);
+ if (err)
+ goto ERR;
+- } else
++ } else {
+ memset(&info->s3a_grid, 0, sizeof(info->s3a_grid));
++ }
+
+ binary = ia_css_pipe_get_sdis_binary(pipe);
+
+- if (binary)
+- {
++ if (binary) {
+ ia_css_binary_dvs_grid_info(binary, info, pipe);
+ ia_css_binary_dvs_stat_grid_info(binary, info, pipe);
+- } else
+- {
++ } else {
+ memset(&info->dvs_grid.dvs_grid_info, 0,
+ sizeof(info->dvs_grid.dvs_grid_info));
+ memset(&info->dvs_grid.dvs_stat_grid_info, 0,
+ sizeof(info->dvs_grid.dvs_stat_grid_info));
+ }
+
+- if (binary)
+- {
++ if (binary) {
+ /* copy pipe does not have ISP binary*/
+ info->isp_in_width = binary->internal_frame_info.res.width;
+ info->isp_in_height = binary->internal_frame_info.res.height;
+@@ -5305,7 +5234,8 @@ ERR :
+ */
+ static int
+ ia_css_pipe_check_format(struct ia_css_pipe *pipe,
+- enum ia_css_frame_format format) {
++ enum ia_css_frame_format format)
++{
+ const enum ia_css_frame_format *supported_formats;
+ int number_of_formats;
+ int found = 0;
+@@ -5313,8 +5243,7 @@ ia_css_pipe_check_format(struct ia_css_p
+
+ IA_CSS_ENTER_PRIVATE("");
+
+- if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info)
+- {
++ if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info) {
+ IA_CSS_ERROR("Pipe or binary info is not set");
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+@@ -5323,15 +5252,13 @@ ia_css_pipe_check_format(struct ia_css_p
+ supported_formats = pipe->pipe_settings.video.video_binary.info->output_formats;
+ number_of_formats = sizeof(pipe->pipe_settings.video.video_binary.info->output_formats) / sizeof(enum ia_css_frame_format);
+
+- for (i = 0; i < number_of_formats && !found; i++)
+- {
++ for (i = 0; i < number_of_formats && !found; i++) {
+ if (supported_formats[i] == format) {
+ found = 1;
+ break;
+ }
+ }
+- if (!found)
+- {
++ if (!found) {
+ IA_CSS_ERROR("Requested format is not supported by binary");
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+@@ -5483,10 +5410,10 @@ static int load_video_binaries(struct ia
+ &mycs->video_binary);
+
+ if (err) {
+- if (video_vf_info) {
+- /* This will do another video binary lookup later for YUV_LINE format*/
++ /* This will do another video binary lookup later for YUV_LINE format*/
++ if (video_vf_info)
+ need_vf_pp = true;
+- } else
++ else
+ return err;
+ } else if (video_vf_info) {
+ /* The first video binary lookup is successful, but we may
+@@ -5649,13 +5576,13 @@ static int load_video_binaries(struct ia
+ }
+
+ static int
+-unload_video_binaries(struct ia_css_pipe *pipe) {
++unload_video_binaries(struct ia_css_pipe *pipe)
++{
+ unsigned int i;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+
+- if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO))
+- {
++ if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -5805,31 +5732,29 @@ static int
+ sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width,
+ unsigned int height, unsigned int min_width,
+ enum ia_css_frame_format format,
+- unsigned int idx) {
++ unsigned int idx)
++{
+ int err = 0;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, min_width = %d, format = %d, idx = %d\n",
+ pipe, width, height, min_width, format, idx);
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+
+ err = ia_css_util_check_res(width, height);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+ if (pipe->vf_output_info[idx].res.width != width ||
+ pipe->vf_output_info[idx].res.height != height ||
+ pipe->vf_output_info[idx].format != format)
+- {
+ ia_css_frame_info_init(&pipe->vf_output_info[idx], width, height,
+ format, min_width);
+- }
++
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
+ }
+@@ -6209,7 +6134,8 @@ static int load_primary_binaries(
+ }
+
+ static int
+-allocate_delay_frames(struct ia_css_pipe *pipe) {
++allocate_delay_frames(struct ia_css_pipe *pipe)
++{
+ unsigned int num_delay_frames = 0, i = 0;
+ unsigned int dvs_frame_delay = 0;
+ struct ia_css_frame_info ref_info;
+@@ -6219,8 +6145,7 @@ allocate_delay_frames(struct ia_css_pipe
+
+ IA_CSS_ENTER_PRIVATE("");
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_ERROR("Invalid args - pipe %p", pipe);
+ return -EINVAL;
+ }
+@@ -6231,8 +6156,7 @@ allocate_delay_frames(struct ia_css_pipe
+ if (dvs_frame_delay > 0)
+ num_delay_frames = dvs_frame_delay + 1;
+
+- switch (mode)
+- {
++ switch (mode) {
+ case IA_CSS_PIPE_ID_CAPTURE: {
+ struct ia_css_capture_settings *mycs_capture = &pipe->pipe_settings.capture;
+ (void)mycs_capture;
+@@ -6284,8 +6208,7 @@ allocate_delay_frames(struct ia_css_pipe
+ ref_info.raw_bit_depth = SH_CSS_REF_BIT_DEPTH;
+
+ assert(num_delay_frames <= MAX_NUM_VIDEO_DELAY_FRAMES);
+- for (i = 0; i < num_delay_frames; i++)
+- {
++ for (i = 0; i < num_delay_frames; i++) {
+ err = ia_css_frame_allocate_from_info(&delay_frames[i], &ref_info);
+ if (err)
+ return err;
+@@ -6295,7 +6218,8 @@ allocate_delay_frames(struct ia_css_pipe
+ }
+
+ static int load_advanced_binaries(
+- struct ia_css_pipe *pipe) {
++ struct ia_css_pipe *pipe)
++{
+ struct ia_css_frame_info pre_in_info, gdc_in_info,
+ post_in_info, post_out_info,
+ vf_info, *vf_pp_in_info, *pipe_out_info,
+@@ -6412,7 +6336,8 @@ static int load_advanced_binaries(
+ }
+
+ static int load_bayer_isp_binaries(
+- struct ia_css_pipe *pipe) {
++ struct ia_css_pipe *pipe)
++{
+ struct ia_css_frame_info pre_isp_in_info, *pipe_out_info;
+ int err = 0;
+ struct ia_css_binary_descr pre_de_descr;
+@@ -6441,7 +6366,8 @@ static int load_bayer_isp_binaries(
+ }
+
+ static int load_low_light_binaries(
+- struct ia_css_pipe *pipe) {
++ struct ia_css_pipe *pipe)
++{
+ struct ia_css_frame_info pre_in_info, anr_in_info,
+ post_in_info, post_out_info,
+ vf_info, *pipe_vf_out_info, *pipe_out_info,
+@@ -6579,7 +6505,8 @@ static bool copy_on_sp(struct ia_css_pip
+ }
+
+ static int load_capture_binaries(
+- struct ia_css_pipe *pipe) {
++ struct ia_css_pipe *pipe)
++{
+ int err = 0;
+ bool must_be_raw;
+
+@@ -6647,13 +6574,13 @@ static int load_capture_binaries(
+ }
+
+ static int
+-unload_capture_binaries(struct ia_css_pipe *pipe) {
++unload_capture_binaries(struct ia_css_pipe *pipe)
++{
+ unsigned int i;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+
+- if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY)))
+- {
++ if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY))) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -6681,7 +6608,8 @@ unload_capture_binaries(struct ia_css_pi
+
+ static bool
+ need_downscaling(const struct ia_css_resolution in_res,
+- const struct ia_css_resolution out_res) {
++ const struct ia_css_resolution out_res)
++{
+ if (in_res.width > out_res.width || in_res.height > out_res.height)
+ return true;
+
+@@ -6689,7 +6617,8 @@ need_downscaling(const struct ia_css_res
+ }
+
+ static bool
+-need_yuv_scaler_stage(const struct ia_css_pipe *pipe) {
++need_yuv_scaler_stage(const struct ia_css_pipe *pipe)
++{
+ unsigned int i;
+ struct ia_css_resolution in_res, out_res;
+
+@@ -6731,7 +6660,8 @@ static int ia_css_pipe_create_cas_scaler
+ struct ia_css_frame_info *cas_scaler_in_info,
+ struct ia_css_frame_info *cas_scaler_out_info,
+ struct ia_css_frame_info *cas_scaler_vf_info,
+- struct ia_css_cas_binary_descr *descr) {
++ struct ia_css_cas_binary_descr *descr)
++{
+ unsigned int i;
+ unsigned int hor_ds_factor = 0, ver_ds_factor = 0;
+ int err = 0;
+@@ -6849,7 +6779,8 @@ ERR:
+ /* FIXME: merge most of this and single output version */
+ static int ia_css_pipe_create_cas_scaler_desc(
+ struct ia_css_pipe *pipe,
+- struct ia_css_cas_binary_descr *descr) {
++ struct ia_css_cas_binary_descr *descr)
++{
+ struct ia_css_frame_info in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
+ struct ia_css_frame_info *out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
+ struct ia_css_frame_info *vf_out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
+@@ -7005,7 +6936,8 @@ ERR:
+ }
+
+ static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr
+- *descr) {
++ *descr)
++{
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "ia_css_pipe_destroy_cas_scaler_desc() enter:\n");
+ kfree(descr->in_info);
+@@ -7023,7 +6955,8 @@ static void ia_css_pipe_destroy_cas_scal
+ }
+
+ static int
+-load_yuvpp_binaries(struct ia_css_pipe *pipe) {
++load_yuvpp_binaries(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+ bool need_scaler = false;
+ struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
+@@ -7048,8 +6981,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+
+ mycs = &pipe->pipe_settings.yuvpp;
+
+- for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+- {
++ for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+ if (pipe->vf_output_info[i].res.width != 0) {
+ err = ia_css_util_check_vf_out_info(&pipe->output_info[i],
+ &pipe->vf_output_info[i]);
+@@ -7063,8 +6995,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+
+ /* we build up the pipeline starting at the end */
+ /* Capture post-processing */
+- if (need_scaler)
+- {
++ if (need_scaler) {
+ struct ia_css_binary_descr yuv_scaler_descr;
+
+ err = ia_css_pipe_create_cas_scaler_desc(pipe,
+@@ -7098,18 +7029,14 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ goto ERR;
+ }
+ ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
+- } else
+- {
++ } else {
+ mycs->num_output = 1;
+ }
+
+ if (need_scaler)
+- {
+ next_binary = &mycs->yuv_scaler_binary[0];
+- } else
+- {
++ else
+ next_binary = NULL;
+- }
+
+ #if defined(ISP2401)
+ /*
+@@ -7135,8 +7062,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ need_isp_copy_binary = true;
+ #endif /* ISP2401 */
+
+- if (need_isp_copy_binary)
+- {
++ if (need_isp_copy_binary) {
+ err = load_copy_binary(pipe,
+ &mycs->copy_binary,
+ next_binary);
+@@ -7166,8 +7092,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ }
+
+ /* Viewfinder post-processing */
+- if (need_scaler)
+- {
++ if (need_scaler) {
+ for (i = 0, j = 0; i < mycs->num_yuv_scaler; i++) {
+ if (mycs->is_output_stage[i]) {
+ assert(j < 2);
+@@ -7177,19 +7102,17 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ }
+ }
+ mycs->num_vf_pp = j;
+- } else
+- {
++ } else {
+ vf_pp_in_info[0] =
+ &mycs->copy_binary.vf_frame_info;
+- for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
++ for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+ vf_pp_in_info[i] = NULL;
+- }
++
+ mycs->num_vf_pp = 1;
+ }
+ mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary),
+ GFP_KERNEL);
+- if (!mycs->vf_pp_binary)
+- {
++ if (!mycs->vf_pp_binary) {
+ err = -ENOMEM;
+ goto ERR;
+ }
+@@ -7197,8 +7120,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ {
+ struct ia_css_binary_descr vf_pp_descr;
+
+- for (i = 0; i < mycs->num_vf_pp; i++)
+- {
++ for (i = 0; i < mycs->num_vf_pp; i++) {
+ if (pipe->vf_output_info[i].res.width != 0) {
+ ia_css_pipe_get_vfpp_binarydesc(pipe,
+ &vf_pp_descr, vf_pp_in_info[i], &pipe->vf_output_info[i]);
+@@ -7214,34 +7136,31 @@ load_yuvpp_binaries(struct ia_css_pipe *
+
+ ERR:
+ if (need_scaler)
+- {
+ ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
+- }
++
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "load_yuvpp_binaries() leave, err=%d\n",
+ err);
+ return err;
+ }
+
+ static int
+-unload_yuvpp_binaries(struct ia_css_pipe *pipe) {
++unload_yuvpp_binaries(struct ia_css_pipe *pipe)
++{
+ unsigned int i;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+
+- if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP))
+- {
++ if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+ ia_css_binary_unload(&pipe->pipe_settings.yuvpp.copy_binary);
+ for (i = 0; i < pipe->pipe_settings.yuvpp.num_yuv_scaler; i++)
+- {
+ ia_css_binary_unload(&pipe->pipe_settings.yuvpp.yuv_scaler_binary[i]);
+- }
++
+ for (i = 0; i < pipe->pipe_settings.yuvpp.num_vf_pp; i++)
+- {
+ ia_css_binary_unload(&pipe->pipe_settings.yuvpp.vf_pp_binary[i]);
+- }
++
+ kfree(pipe->pipe_settings.yuvpp.is_output_stage);
+ pipe->pipe_settings.yuvpp.is_output_stage = NULL;
+ kfree(pipe->pipe_settings.yuvpp.yuv_scaler_binary);
+@@ -7291,25 +7210,23 @@ static int yuvpp_start(struct ia_css_pip
+ }
+
+ static int
+-sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) {
++sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+ /* PIPE_MODE_COPY has no binaries, but has output frames to outside*/
+- if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
+- {
++ if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY) {
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
+ }
+
+- switch (pipe->mode)
+- {
++ switch (pipe->mode) {
+ case IA_CSS_PIPE_ID_PREVIEW:
+ err = unload_preview_binaries(pipe);
+ break;
+@@ -7330,7 +7247,8 @@ sh_css_pipe_unload_binaries(struct ia_cs
+ }
+
+ static int
+-sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) {
++sh_css_pipe_load_binaries(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+
+ assert(pipe);
+@@ -7340,8 +7258,7 @@ sh_css_pipe_load_binaries(struct ia_css_
+ if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
+ return err;
+
+- switch (pipe->mode)
+- {
++ switch (pipe->mode) {
+ case IA_CSS_PIPE_ID_PREVIEW:
+ err = load_preview_binaries(pipe);
+ break;
+@@ -7360,8 +7277,7 @@ sh_css_pipe_load_binaries(struct ia_css_
+ err = -EINVAL;
+ break;
+ }
+- if (err)
+- {
++ if (err) {
+ if (sh_css_pipe_unload_binaries(pipe)) {
+ /* currently css does not support multiple error returns in a single function,
+ * using -EINVAL in this case */
+@@ -7372,7 +7288,8 @@ sh_css_pipe_load_binaries(struct ia_css_
+ }
+
+ static int
+-create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
++create_host_yuvpp_pipeline(struct ia_css_pipe *pipe)
++{
+ struct ia_css_pipeline *me;
+ int err = 0;
+ struct ia_css_pipeline_stage *vf_pp_stage = NULL,
+@@ -7399,15 +7316,13 @@ create_host_yuvpp_pipeline(struct ia_css
+ #endif
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+- if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP))
+- {
++ if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+ me = &pipe->pipeline;
+ ia_css_pipeline_clean(me);
+- for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+- {
++ for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+ out_frame[i] = NULL;
+ vf_frame[i] = NULL;
+ }
+@@ -7435,8 +7350,7 @@ create_host_yuvpp_pipeline(struct ia_css
+ /* the input frame can come from:
+ * a) memory: connect yuvscaler to me->in_frame
+ * b) sensor, via copy binary: connect yuvscaler to copy binary later on */
+- if (need_in_frameinfo_memory)
+- {
++ if (need_in_frameinfo_memory) {
+ /* TODO: improve for different input formats. */
+
+ /*
+@@ -7485,13 +7399,11 @@ create_host_yuvpp_pipeline(struct ia_css
+ }
+
+ in_frame = &me->in_frame;
+- } else
+- {
++ } else {
+ in_frame = NULL;
+ }
+
+- for (i = 0; i < num_output_stage; i++)
+- {
++ for (i = 0; i < num_output_stage; i++) {
+ assert(i < IA_CSS_PIPE_MAX_OUTPUT_STAGE);
+ if (pipe->output_info[i].res.width != 0) {
+ err = init_out_frameinfo_defaults(pipe, &me->out_frame[i], i);
+@@ -7518,8 +7430,7 @@ create_host_yuvpp_pipeline(struct ia_css
+ yuv_scaler_binary = pipe->pipe_settings.yuvpp.yuv_scaler_binary;
+ need_scaler = need_yuv_scaler_stage(pipe);
+
+- if (pipe->pipe_settings.yuvpp.copy_binary.info)
+- {
++ if (pipe->pipe_settings.yuvpp.copy_binary.info) {
+ struct ia_css_frame *in_frame_local = NULL;
+
+ #ifdef ISP2401
+@@ -7557,8 +7468,7 @@ create_host_yuvpp_pipeline(struct ia_css
+ }
+ }
+
+- if (need_scaler)
+- {
++ if (need_scaler) {
+ struct ia_css_frame *tmp_out_frame = NULL;
+ struct ia_css_frame *tmp_vf_frame = NULL;
+ struct ia_css_frame *tmp_in_frame = in_frame;
+@@ -7598,8 +7508,7 @@ create_host_yuvpp_pipeline(struct ia_css
+ j++;
+ }
+ }
+- } else if (copy_stage)
+- {
++ } else if (copy_stage) {
+ if (vf_frame[0] && vf_frame[0]->info.res.width != 0) {
+ in_frame = copy_stage->args.out_vf_frame;
+ err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0],
+@@ -7621,7 +7530,8 @@ create_host_yuvpp_pipeline(struct ia_css
+ static int
+ create_host_copy_pipeline(struct ia_css_pipe *pipe,
+ unsigned int max_input_width,
+- struct ia_css_frame *out_frame) {
++ struct ia_css_frame *out_frame)
++{
+ struct ia_css_pipeline *me;
+ int err = 0;
+ struct ia_css_pipeline_stage_desc stage_desc;
+@@ -7638,16 +7548,14 @@ create_host_copy_pipeline(struct ia_css_
+ out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
+
+ if (copy_on_sp(pipe) &&
+- pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8)
+- {
++ pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
+ ia_css_frame_info_init(
+ &out_frame->info,
+ JPEG_BYTES,
+ 1,
+ IA_CSS_FRAME_FORMAT_BINARY_8,
+ 0);
+- } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW)
+- {
++ } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) {
+ out_frame->info.raw_bit_depth =
+ ia_css_pipe_util_pipe_input_format_bpp(pipe);
+ }
+@@ -7671,7 +7579,8 @@ create_host_copy_pipeline(struct ia_css_
+ }
+
+ static int
+-create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) {
++create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe)
++{
+ struct ia_css_pipeline *me = &pipe->pipeline;
+ int err = 0;
+ struct ia_css_pipeline_stage_desc stage_desc;
+@@ -7715,7 +7624,8 @@ create_host_isyscopy_capture_pipeline(st
+ }
+
+ static int
+-create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
++create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
++{
+ struct ia_css_pipeline *me;
+ int err = 0;
+ enum ia_css_capture_mode mode;
+@@ -7779,8 +7689,7 @@ create_host_regular_capture_pipeline(str
+ /* Construct in_frame info (only in case we have dynamic input */
+ need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
+ #endif
+- if (need_in_frameinfo_memory)
+- {
++ if (need_in_frameinfo_memory) {
+ err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
+ IA_CSS_FRAME_FORMAT_RAW);
+ if (err) {
+@@ -7789,22 +7698,19 @@ create_host_regular_capture_pipeline(str
+ }
+
+ in_frame = &me->in_frame;
+- } else
+- {
++ } else {
+ in_frame = NULL;
+ }
+
+ err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+ out_frame = &me->out_frame[0];
+
+ /* Construct vf_frame info (only in case we have VF) */
+- if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0])
+- {
++ if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
+ if (mode == IA_CSS_CAPTURE_MODE_RAW || mode == IA_CSS_CAPTURE_MODE_BAYER) {
+ /* These modes don't support viewfinder output */
+ vf_frame = NULL;
+@@ -7812,22 +7718,20 @@ create_host_regular_capture_pipeline(str
+ init_vf_frameinfo_defaults(pipe, &me->vf_frame[0], 0);
+ vf_frame = &me->vf_frame[0];
+ }
+- } else
+- {
++ } else {
+ vf_frame = NULL;
+ }
+
+ copy_binary = &pipe->pipe_settings.capture.copy_binary;
+ num_primary_stage = pipe->pipe_settings.capture.num_primary_stage;
+- if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY))
+- {
++ if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
++
+ for (i = 0; i < num_primary_stage; i++)
+- {
+ primary_binary[i] = &pipe->pipe_settings.capture.primary_binary[i];
+- }
++
+ vf_pp_binary = &pipe->pipe_settings.capture.vf_pp_binary;
+ pre_isp_binary = &pipe->pipe_settings.capture.pre_isp_binary;
+ anr_gdc_binary = &pipe->pipe_settings.capture.anr_gdc_binary;
+@@ -7844,8 +7748,7 @@ create_host_regular_capture_pipeline(str
+ need_yuv_pp = (yuv_scaler_binary && yuv_scaler_binary->info);
+ need_ldc = (capture_ldc_binary && capture_ldc_binary->info);
+
+- if (pipe->pipe_settings.capture.copy_binary.info)
+- {
++ if (pipe->pipe_settings.capture.copy_binary.info) {
+ if (raw) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ #if defined(ISP2401)
+@@ -7874,13 +7777,11 @@ create_host_regular_capture_pipeline(str
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+- } else if (pipe->stream->config.continuous)
+- {
++ } else if (pipe->stream->config.continuous) {
+ in_frame = pipe->stream->last_pipe->continuous_frames[0];
+ }
+
+- if (mode == IA_CSS_CAPTURE_MODE_PRIMARY)
+- {
++ if (mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
+ struct ia_css_frame *local_in_frame = NULL;
+ struct ia_css_frame *local_out_frame = NULL;
+
+@@ -7925,8 +7826,7 @@ create_host_regular_capture_pipeline(str
+ IA_CSS_BINARY_MODE_COPY;
+ current_stage->args.copy_output = current_stage->args.copy_vf;
+ } else if (mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
+- mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT)
+- {
++ mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+ out_frames, in_frame, NULL);
+@@ -7962,8 +7862,7 @@ create_host_regular_capture_pipeline(str
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+- } else if (mode == IA_CSS_CAPTURE_MODE_BAYER)
+- {
++ } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) {
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+ out_frames, in_frame, NULL);
+@@ -7977,8 +7876,7 @@ create_host_regular_capture_pipeline(str
+ }
+
+ #ifndef ISP2401
+- if (need_pp && current_stage)
+- {
++ if (need_pp && current_stage) {
+ struct ia_css_frame *local_in_frame = NULL;
+
+ local_in_frame = current_stage->args.out_frame[0];
+@@ -7996,8 +7894,7 @@ create_host_regular_capture_pipeline(str
+ need_yuv_pp ? NULL : out_frame,
+ #else
+ /* ldc and capture_pp not supported in same pipeline */
+- if (need_ldc && current_stage)
+- {
++ if (need_ldc && current_stage) {
+ in_frame = current_stage->args.out_frame[0];
+ ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
+@@ -8005,8 +7902,7 @@ create_host_regular_capture_pipeline(str
+ err = ia_css_pipeline_create_and_add_stage(me,
+ &stage_desc,
+ NULL);
+- } else if (need_pp && current_stage)
+- {
++ } else if (need_pp && current_stage) {
+ in_frame = current_stage->args.out_frame[0];
+ err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame,
+ #endif
+@@ -8018,8 +7914,7 @@ create_host_regular_capture_pipeline(str
+ }
+ }
+
+- if (need_yuv_pp && current_stage)
+- {
++ if (need_yuv_pp && current_stage) {
+ struct ia_css_frame *tmp_in_frame = current_stage->args.out_frame[0];
+ struct ia_css_frame *tmp_out_frame = NULL;
+
+@@ -8051,8 +7946,7 @@ create_host_regular_capture_pipeline(str
+ * should not be considered as a clean solution. Proper
+ * investigation should be done to come up with the clean solution.
+ * */
+- if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame)
+- {
++ if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) {
+ in_frame = current_stage->args.out_vf_frame;
+ err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
+ ¤t_stage);
+@@ -8070,7 +7964,8 @@ create_host_regular_capture_pipeline(str
+ }
+
+ static int
+-create_host_capture_pipeline(struct ia_css_pipe *pipe) {
++create_host_capture_pipeline(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+@@ -8079,8 +7974,7 @@ create_host_capture_pipeline(struct ia_c
+ err = create_host_isyscopy_capture_pipeline(pipe);
+ else
+ err = create_host_regular_capture_pipeline(pipe);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+@@ -8091,7 +7985,8 @@ create_host_capture_pipeline(struct ia_c
+ }
+
+ static int capture_start(
+- struct ia_css_pipe *pipe) {
++ struct ia_css_pipe *pipe)
++{
+ struct ia_css_pipeline *me;
+
+ int err = 0;
+@@ -8162,7 +8057,8 @@ static int capture_start(
+ static int
+ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
+ struct ia_css_frame_info *info,
+- unsigned int idx) {
++ unsigned int idx)
++{
+ assert(pipe);
+ assert(info);
+
+@@ -8171,8 +8067,7 @@ sh_css_pipe_get_output_frame_info(struct
+
+ *info = pipe->output_info[idx];
+ if (copy_on_sp(pipe) &&
+- pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8)
+- {
++ pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
+ ia_css_frame_info_init(
+ info,
+ JPEG_BYTES,
+@@ -8180,8 +8075,7 @@ sh_css_pipe_get_output_frame_info(struct
+ IA_CSS_FRAME_FORMAT_BINARY_8,
+ 0);
+ } else if (info->format == IA_CSS_FRAME_FORMAT_RAW ||
+- info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED)
+- {
++ info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
+ info->raw_bit_depth =
+ ia_css_pipe_util_pipe_input_format_bpp(pipe);
+ }
+@@ -8195,7 +8089,8 @@ void
+ ia_css_stream_send_input_frame(const struct ia_css_stream *stream,
+ const unsigned short *data,
+ unsigned int width,
+- unsigned int height) {
++ unsigned int height)
++{
+ assert(stream);
+
+ ia_css_inputfifo_send_input_frame(
+@@ -8206,7 +8101,8 @@ ia_css_stream_send_input_frame(const str
+ }
+
+ void
+-ia_css_stream_start_input_frame(const struct ia_css_stream *stream) {
++ia_css_stream_start_input_frame(const struct ia_css_stream *stream)
++{
+ assert(stream);
+
+ ia_css_inputfifo_start_frame(
+@@ -8220,7 +8116,8 @@ ia_css_stream_send_input_line(const stru
+ const unsigned short *data,
+ unsigned int width,
+ const unsigned short *data2,
+- unsigned int width2) {
++ unsigned int width2)
++{
+ assert(stream);
+
+ ia_css_inputfifo_send_line(stream->config.channel_id,
+@@ -8231,7 +8128,8 @@ void
+ ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream,
+ enum atomisp_input_format format,
+ const unsigned short *data,
+- unsigned int width) {
++ unsigned int width)
++{
+ assert(stream);
+ if (!data || width == 0)
+ return;
+@@ -8240,14 +8138,16 @@ ia_css_stream_send_input_embedded_line(c
+ }
+
+ void
+-ia_css_stream_end_input_frame(const struct ia_css_stream *stream) {
++ia_css_stream_end_input_frame(const struct ia_css_stream *stream)
++{
+ assert(stream);
+
+ ia_css_inputfifo_end_frame(stream->config.channel_id);
+ }
+
+ static void
+-append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) {
++append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
++{
+ IA_CSS_ENTER_PRIVATE("l = %p, firmware = %p", l, firmware);
+ if (!l) {
+ IA_CSS_ERROR("NULL fw_info");
+@@ -8262,7 +8162,8 @@ append_firmware(struct ia_css_fw_info **
+ }
+
+ static void
+-remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) {
++remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
++{
+ assert(*l);
+ assert(firmware);
+ (void)l;
+@@ -8304,12 +8205,12 @@ static int upload_isp_code(struct ia_css
+ }
+
+ static int
+-acc_load_extension(struct ia_css_fw_info *firmware) {
++acc_load_extension(struct ia_css_fw_info *firmware)
++{
+ int err;
+ struct ia_css_fw_info *hd = firmware;
+
+- while (hd)
+- {
++ while (hd) {
+ err = upload_isp_code(hd);
+ if (err)
+ return err;
+@@ -8323,7 +8224,8 @@ acc_load_extension(struct ia_css_fw_info
+ }
+
+ static void
+-acc_unload_extension(struct ia_css_fw_info *firmware) {
++acc_unload_extension(struct ia_css_fw_info *firmware)
++{
+ struct ia_css_fw_info *hd = firmware;
+ struct ia_css_fw_info *hdn = NULL;
+
+@@ -8347,13 +8249,13 @@ acc_unload_extension(struct ia_css_fw_in
+ /* Load firmware for extension */
+ static int
+ ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
+- struct ia_css_fw_info *firmware) {
++ struct ia_css_fw_info *firmware)
++{
+ int err = 0;
+
+ IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
+
+- if ((!firmware) || (!pipe))
+- {
++ if ((!firmware) || (!pipe)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -8371,7 +8273,8 @@ ia_css_pipe_load_extension(struct ia_css
+ /* Unload firmware for extension */
+ static void
+ ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
+- struct ia_css_fw_info *firmware) {
++ struct ia_css_fw_info *firmware)
++{
+ IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
+
+ if ((!firmware) || (!pipe)) {
+@@ -8390,7 +8293,8 @@ ia_css_pipe_unload_extension(struct ia_c
+ }
+
+ bool
+-ia_css_pipeline_uses_params(struct ia_css_pipeline *me) {
++ia_css_pipeline_uses_params(struct ia_css_pipeline *me)
++{
+ struct ia_css_pipeline_stage *stage;
+
+ assert(me);
+@@ -8411,7 +8315,8 @@ ia_css_pipeline_uses_params(struct ia_cs
+
+ static int
+ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
+- const void *acc_fw) {
++ const void *acc_fw)
++{
+ struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw;
+ /* In QoS case, load_extension already called, so skipping */
+ int err = 0;
+@@ -8423,8 +8328,7 @@ sh_css_pipeline_add_acc_stage(struct ia_
+ "sh_css_pipeline_add_acc_stage() enter: pipeline=%p, acc_fw=%p\n",
+ pipeline, acc_fw);
+
+- if (!err)
+- {
++ if (!err) {
+ struct ia_css_pipeline_stage_desc stage_desc;
+
+ ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw);
+@@ -8443,7 +8347,8 @@ sh_css_pipeline_add_acc_stage(struct ia_
+ * Refer to "sh_css_internal.h" for details.
+ */
+ int ia_css_stream_capture_frame(struct ia_css_stream *stream,
+- unsigned int exp_id) {
++ unsigned int exp_id)
++{
+ struct sh_css_tag_descr tag_descr;
+ u32 encoded_tag_descr;
+ int err;
+@@ -8485,7 +8390,8 @@ int ia_css_stream_capture(
+ struct ia_css_stream *stream,
+ int num_captures,
+ unsigned int skip,
+- int offset) {
++ int offset)
++{
+ struct sh_css_tag_descr tag_descr;
+ unsigned int encoded_tag_descr;
+ int return_err;
+@@ -8548,8 +8454,9 @@ void ia_css_stream_request_flash(struct
+ ia_css_debug_dump_sp_sw_debug_info();
+ ia_css_debug_dump_debug_info(NULL);
+ }
+- } else
++ } else {
+ IA_CSS_LOG("SP is not running!");
++ }
+
+ #endif
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -8557,7 +8464,8 @@ void ia_css_stream_request_flash(struct
+ }
+
+ static void
+-sh_css_init_host_sp_control_vars(void) {
++sh_css_init_host_sp_control_vars(void)
++{
+ const struct ia_css_fw_info *fw;
+ unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started;
+
+@@ -8641,7 +8549,8 @@ void ia_css_pipe_config_defaults(struct
+
+ void
+ ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config
+- *extra_config) {
++ *extra_config)
++{
+ if (!extra_config) {
+ IA_CSS_ERROR("NULL input parameter");
+ return;
+@@ -8671,11 +8580,11 @@ void ia_css_stream_config_defaults(struc
+ }
+
+ static int
+-ia_css_acc_pipe_create(struct ia_css_pipe *pipe) {
++ia_css_acc_pipe_create(struct ia_css_pipe *pipe)
++{
+ int err = 0;
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_ERROR("NULL input parameter");
+ return -EINVAL;
+ }
+@@ -8685,9 +8594,7 @@ ia_css_acc_pipe_create(struct ia_css_pip
+ pipe->config.acc_num_execs = 1;
+
+ if (pipe->config.acc_extension)
+- {
+ err = ia_css_pipe_load_extension(pipe, pipe->config.acc_extension);
+- }
+
+ return err;
+ }
+@@ -8706,9 +8613,8 @@ int ia_css_pipe_create(const struct ia_c
+
+ err = ia_css_pipe_create_extra(config, NULL, pipe);
+
+- if (err == 0) {
++ if (err == 0)
+ IA_CSS_LOG("pipe created successfully = %p", *pipe);
+- }
+
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+
+@@ -8718,7 +8624,8 @@ int ia_css_pipe_create(const struct ia_c
+ int
+ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
+ const struct ia_css_pipe_extra_config *extra_config,
+- struct ia_css_pipe **pipe) {
++ struct ia_css_pipe **pipe)
++{
+ int err = -EINVAL;
+ struct ia_css_pipe *internal_pipe = NULL;
+ unsigned int i;
+@@ -8726,14 +8633,12 @@ ia_css_pipe_create_extra(const struct ia
+ IA_CSS_ENTER_PRIVATE("config = %p, extra_config = %p and pipe = %p", config, extra_config, pipe);
+
+ /* do not allow to create more than the maximum limit */
+- if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX)
+- {
++ if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOSPC);
+ return -EINVAL;
+ }
+
+- if ((!pipe) || (!config))
+- {
++ if ((!pipe) || (!config)) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+@@ -8742,8 +8647,7 @@ ia_css_pipe_create_extra(const struct ia
+ ia_css_debug_dump_pipe_extra_config(extra_config);
+
+ err = create_pipe(config->mode, &internal_pipe, false);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+@@ -8755,8 +8659,7 @@ ia_css_pipe_create_extra(const struct ia
+ else
+ ia_css_pipe_extra_config_defaults(&internal_pipe->extra_config);
+
+- if (config->mode == IA_CSS_PIPE_MODE_ACC)
+- {
++ if (config->mode == IA_CSS_PIPE_MODE_ACC) {
+ /* Temporary hack to migrate acceleration to CSS 2.0.
+ * In the future the code for all pipe types should be
+ * unified. */
+@@ -8783,15 +8686,13 @@ ia_css_pipe_create_extra(const struct ia
+ set bayer_ds_out_res equal to IF output resolution(IF may do cropping on
+ sensor output) or use default decimation factor 1. */
+ if (internal_pipe->extra_config.enable_raw_binning &&
+- internal_pipe->config.bayer_ds_out_res.width)
+- {
++ internal_pipe->config.bayer_ds_out_res.width) {
+ /* fill some code here, if no code is needed, please remove it during integration */
+ }
+
+ /* YUV downscaling */
+ if ((internal_pipe->config.vf_pp_in_res.width ||
+- internal_pipe->config.capt_pp_in_res.width))
+- {
++ internal_pipe->config.capt_pp_in_res.width)) {
+ enum ia_css_frame_format format;
+
+ if (internal_pipe->config.vf_pp_in_res.width) {
+@@ -8812,8 +8713,7 @@ ia_css_pipe_create_extra(const struct ia
+ }
+ }
+ if (internal_pipe->config.vf_pp_in_res.width &&
+- internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
+- {
++ internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) {
+ ia_css_frame_info_init(
+ &internal_pipe->vf_yuv_ds_input_info,
+ internal_pipe->config.vf_pp_in_res.width,
+@@ -8821,8 +8721,7 @@ ia_css_pipe_create_extra(const struct ia
+ IA_CSS_FRAME_FORMAT_YUV_LINE, 0);
+ }
+ /* handle bayer downscaling output info */
+- if (internal_pipe->config.bayer_ds_out_res.width)
+- {
++ if (internal_pipe->config.bayer_ds_out_res.width) {
+ ia_css_frame_info_init(
+ &internal_pipe->bds_output_info,
+ internal_pipe->config.bayer_ds_out_res.width,
+@@ -8831,8 +8730,7 @@ ia_css_pipe_create_extra(const struct ia
+ }
+
+ /* handle output info, assume always needed */
+- for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+- {
++ for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+ if (internal_pipe->config.output_info[i].res.width) {
+ err = sh_css_pipe_configure_output(
+ internal_pipe,
+@@ -8868,8 +8766,7 @@ ia_css_pipe_create_extra(const struct ia
+ }
+ }
+ }
+- if (internal_pipe->config.acc_extension)
+- {
++ if (internal_pipe->config.acc_extension) {
+ err = ia_css_pipe_load_extension(internal_pipe,
+ internal_pipe->config.acc_extension);
+ if (err) {
+@@ -8889,18 +8786,18 @@ ia_css_pipe_create_extra(const struct ia
+
+ int
+ ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
+- struct ia_css_pipe_info *pipe_info) {
++ struct ia_css_pipe_info *pipe_info)
++{
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+ "ia_css_pipe_get_info()\n");
++
+ assert(pipe_info);
+- if (!pipe_info)
+- {
++ if (!pipe_info) {
+ ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
+ "ia_css_pipe_get_info: pipe_info cannot be NULL\n");
+ return -EINVAL;
+ }
+- if (!pipe || !pipe->stream)
+- {
++ if (!pipe || !pipe->stream) {
+ ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
+ "ia_css_pipe_get_info: ia_css_stream_create needs to be called before ia_css_[stream/pipe]_get_info\n");
+ return -EINVAL;
+@@ -8928,40 +8825,36 @@ bool ia_css_pipe_has_dvs_stats(struct ia
+ int
+ ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
+ int pin_index,
+- enum ia_css_frame_format new_format) {
++ enum ia_css_frame_format new_format)
++{
+ int err = 0;
+
+ IA_CSS_ENTER_PRIVATE("pipe = %p, pin_index = %d, new_formats = %d", pipe, pin_index, new_format);
+
+- if (!pipe)
+- {
++ if (!pipe) {
+ IA_CSS_ERROR("pipe is not set");
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+- if (0 != pin_index && 1 != pin_index)
+- {
++ if (0 != pin_index && 1 != pin_index) {
+ IA_CSS_ERROR("pin index is not valid");
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+- if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY)
+- {
++ if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY) {
+ IA_CSS_ERROR("new format is not valid");
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+- } else
+- {
++ } else {
+ err = ia_css_pipe_check_format(pipe, new_format);
+ if (!err) {
+- if (pin_index == 0) {
++ if (pin_index == 0)
+ pipe->output_info[0].format = new_format;
+- } else {
++ else
+ pipe->vf_output_info[0].format = new_format;
+- }
+ }
+ }
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -8971,7 +8864,8 @@ ia_css_pipe_override_frame_format(struct
+ #if !defined(ISP2401)
+ /* Configuration of INPUT_SYSTEM_VERSION_2401 is done on SP */
+ static int
+-ia_css_stream_configure_rx(struct ia_css_stream *stream) {
++ia_css_stream_configure_rx(struct ia_css_stream *stream)
++{
+ struct ia_css_input_port *config;
+
+ assert(stream);
+@@ -9000,11 +8894,10 @@ ia_css_stream_configure_rx(struct ia_css
+ if (config->compression.type == IA_CSS_CSI2_COMPRESSION_TYPE_NONE)
+ stream->csi_rx_config.comp = MIPI_PREDICTOR_NONE;
+ else
+- {
+ /* not implemented yet, requires extension of the rx_cfg_t
+ * struct */
+ return -EINVAL;
+- }
++
+ stream->csi_rx_config.is_two_ppc = (stream->config.pixels_per_clock == 2);
+ stream->reconfigure_css_rx = true;
+ return 0;
+@@ -9015,7 +8908,8 @@ static struct ia_css_pipe *
+ find_pipe(struct ia_css_pipe *pipes[],
+ unsigned int num_pipes,
+ enum ia_css_pipe_mode mode,
+- bool copy_pipe) {
++ bool copy_pipe)
++{
+ unsigned int i;
+
+ assert(pipes);
+@@ -9031,21 +8925,20 @@ find_pipe(struct ia_css_pipe *pipes[],
+ }
+
+ static int
+-ia_css_acc_stream_create(struct ia_css_stream *stream) {
++ia_css_acc_stream_create(struct ia_css_stream *stream)
++{
+ int i;
+ int err = 0;
+
+ assert(stream);
+ IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+
+- if (!stream)
+- {
++ if (!stream) {
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
+ }
+
+- for (i = 0; i < stream->num_pipes; i++)
+- {
++ for (i = 0; i < stream->num_pipes; i++) {
+ struct ia_css_pipe *pipe = stream->pipes[i];
+
+ assert(pipe);
+@@ -9059,14 +8952,12 @@ ia_css_acc_stream_create(struct ia_css_s
+
+ /* Map SP threads before doing anything. */
+ err = map_sp_threads(stream, true);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+
+- for (i = 0; i < stream->num_pipes; i++)
+- {
++ for (i = 0; i < stream->num_pipes; i++) {
+ struct ia_css_pipe *pipe = stream->pipes[i];
+
+ assert(pipe);
+@@ -9074,8 +8965,7 @@ ia_css_acc_stream_create(struct ia_css_s
+ }
+
+ err = create_host_pipeline_structure(stream);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+ }
+@@ -9089,7 +8979,8 @@ ia_css_acc_stream_create(struct ia_css_s
+
+ static int
+ metadata_info_init(const struct ia_css_metadata_config *mdc,
+- struct ia_css_metadata_info *md) {
++ struct ia_css_metadata_info *md)
++{
+ /* Either both width and height should be set or neither */
+ if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0))
+ return -EINVAL;
+@@ -9149,7 +9040,8 @@ int
+ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
+ int num_pipes,
+ struct ia_css_pipe *pipes[],
+- struct ia_css_stream **stream) {
++ struct ia_css_stream **stream)
++{
+ struct ia_css_pipe *curr_pipe;
+ struct ia_css_stream *curr_stream = NULL;
+ bool spcopyonly;
+@@ -9168,8 +9060,7 @@ ia_css_stream_create(const struct ia_css
+ /* some checks */
+ if (num_pipes == 0 ||
+ !stream ||
+- !pipes)
+- {
++ !pipes) {
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+@@ -9178,8 +9069,7 @@ ia_css_stream_create(const struct ia_css
+ #if !defined(ISP2401)
+ /* We don't support metadata for JPEG stream, since they both use str2mem */
+ if (stream_config->input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8 &&
+- stream_config->metadata_config.resolution.height > 0)
+- {
++ stream_config->metadata_config.resolution.height > 0) {
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+@@ -9187,8 +9077,7 @@ ia_css_stream_create(const struct ia_css
+ #endif
+
+ #ifdef ISP2401
+- if (stream_config->online && stream_config->pack_raw_pixels)
+- {
++ if (stream_config->online && stream_config->pack_raw_pixels) {
+ IA_CSS_LOG("online and pack raw is invalid on input system 2401");
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR(err);
+@@ -9243,16 +9132,14 @@ ia_css_stream_create(const struct ia_css
+
+ /* Currently we only supported metadata up to a certain size. */
+ err = metadata_info_init(&stream_config->metadata_config, &md_info);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+
+ /* allocate the stream instance */
+ curr_stream = kzalloc(sizeof(struct ia_css_stream), GFP_KERNEL);
+- if (!curr_stream)
+- {
++ if (!curr_stream) {
+ err = -ENOMEM;
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+@@ -9263,8 +9150,7 @@ ia_css_stream_create(const struct ia_css
+ /* allocate pipes */
+ curr_stream->num_pipes = num_pipes;
+ curr_stream->pipes = kcalloc(num_pipes, sizeof(struct ia_css_pipe *), GFP_KERNEL);
+- if (!curr_stream->pipes)
+- {
++ if (!curr_stream->pipes) {
+ curr_stream->num_pipes = 0;
+ kfree(curr_stream);
+ curr_stream = NULL;
+@@ -9287,8 +9173,7 @@ ia_css_stream_create(const struct ia_css
+ #endif
+
+ #ifdef ISP2401
+- if (curr_stream->config.online)
+- {
++ if (curr_stream->config.online) {
+ curr_stream->config.source.port.num_lanes =
+ stream_config->source.port.num_lanes;
+ curr_stream->config.mode = IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
+@@ -9306,8 +9191,7 @@ ia_css_stream_create(const struct ia_css
+ curr_stream->config.lock_all);
+
+ /* copy mode specific stuff */
+- switch (curr_stream->config.mode)
+- {
++ switch (curr_stream->config.mode) {
+ case IA_CSS_INPUT_MODE_SENSOR:
+ case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
+ #if !defined(ISP2401)
+@@ -9349,14 +9233,12 @@ ia_css_stream_create(const struct ia_css
+ err = aspect_ratio_crop_init(curr_stream,
+ pipes,
+ &aspect_ratio_crop_enabled);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ goto ERR;
+ }
+ #endif
+- for (i = 0; i < num_pipes; i++)
+- {
++ for (i = 0; i < num_pipes; i++) {
+ struct ia_css_resolution effective_res;
+
+ curr_pipe = pipes[i];
+@@ -9396,9 +9278,8 @@ ia_css_stream_create(const struct ia_css
+ if (pipes[i]->config.mode != IA_CSS_PIPE_MODE_ACC &&
+ pipes[i]->config.mode != IA_CSS_PIPE_MODE_COPY) {
+ err = check_pipe_resolutions(pipes[i]);
+- if (err) {
++ if (err)
+ goto ERR;
+- }
+ }
+ }
+ }
+@@ -9408,20 +9289,17 @@ ia_css_stream_create(const struct ia_css
+ goto ERR;
+ IA_CSS_LOG("isp_params_configs: %p", curr_stream->isp_params_configs);
+
+- if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC)
+- {
++ if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC) {
+ *stream = curr_stream;
+ err = ia_css_acc_stream_create(curr_stream);
+ goto ERR;
+ }
+ /* sensor binning */
+- if (!spcopyonly)
+- {
++ if (!spcopyonly) {
+ sensor_binning_changed =
+ sh_css_params_set_binning_factor(curr_stream,
+ curr_stream->config.sensor_binning_factor);
+- } else
+- {
++ } else {
+ sensor_binning_changed = false;
+ }
+
+@@ -9432,8 +9310,7 @@ ia_css_stream_create(const struct ia_css
+ curr_stream->cont_capt = false;
+ /* Temporary hack: we give the preview pipe a reference to the capture
+ * pipe in continuous capture mode. */
+- if (curr_stream->config.continuous)
+- {
++ if (curr_stream->config.continuous) {
+ /* Search for the preview pipe and create the copy pipe */
+ struct ia_css_pipe *preview_pipe;
+ struct ia_css_pipe *video_pipe;
+@@ -9481,9 +9358,9 @@ ia_css_stream_create(const struct ia_css
+ preview_pipe->pipe_settings.preview.copy_pipe = copy_pipe;
+ copy_pipe->stream = curr_stream;
+ }
+- if (preview_pipe && curr_stream->cont_capt) {
++ if (preview_pipe && curr_stream->cont_capt)
+ preview_pipe->pipe_settings.preview.capture_pipe = capture_pipe;
+- }
++
+ if (video_pipe && !video_pipe->pipe_settings.video.copy_pipe) {
+ err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, ©_pipe, true);
+ if (err)
+@@ -9492,15 +9369,13 @@ ia_css_stream_create(const struct ia_css
+ video_pipe->pipe_settings.video.copy_pipe = copy_pipe;
+ copy_pipe->stream = curr_stream;
+ }
+- if (video_pipe && curr_stream->cont_capt) {
++ if (video_pipe && curr_stream->cont_capt)
+ video_pipe->pipe_settings.video.capture_pipe = capture_pipe;
+- }
+- if (preview_pipe && acc_pipe) {
++
++ if (preview_pipe && acc_pipe)
+ preview_pipe->pipe_settings.preview.acc_pipe = acc_pipe;
+- }
+ }
+- for (i = 0; i < num_pipes; i++)
+- {
++ for (i = 0; i < num_pipes; i++) {
+ curr_pipe = pipes[i];
+ /* set current stream */
+ curr_pipe->stream = curr_stream;
+@@ -9521,8 +9396,7 @@ ia_css_stream_create(const struct ia_css
+ }
+
+ /* now pipes have been configured, info should be available */
+- for (i = 0; i < num_pipes; i++)
+- {
++ for (i = 0; i < num_pipes; i++) {
+ struct ia_css_pipe_info *pipe_info = NULL;
+
+ curr_pipe = pipes[i];
+@@ -9572,22 +9446,19 @@ ia_css_stream_create(const struct ia_css
+
+ /* Map SP threads before doing anything. */
+ err = map_sp_threads(curr_stream, true);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LOG("map_sp_threads: return_err=%d", err);
+ goto ERR;
+ }
+
+- for (i = 0; i < num_pipes; i++)
+- {
++ for (i = 0; i < num_pipes; i++) {
+ curr_pipe = pipes[i];
+ ia_css_pipe_map_queue(curr_pipe, true);
+ }
+
+ /* Create host side pipeline objects without stages */
+ err = create_host_pipeline_structure(curr_stream);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LOG("create_host_pipeline_structure: return_err=%d", err);
+ goto ERR;
+ }
+@@ -9625,13 +9496,13 @@ ERR:
+ }
+
+ int
+-ia_css_stream_destroy(struct ia_css_stream *stream) {
++ia_css_stream_destroy(struct ia_css_stream *stream)
++{
+ int i;
+ int err = 0;
+
+ IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+- if (!stream)
+- {
++ if (!stream) {
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
+@@ -9640,8 +9511,7 @@ ia_css_stream_destroy(struct ia_css_stre
+ ia_css_stream_isp_parameters_uninit(stream);
+
+ if ((stream->last_pipe) &&
+- ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num))
+- {
++ ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num)) {
+ #if defined(ISP2401)
+ bool free_mpi;
+
+@@ -9703,8 +9573,7 @@ ia_css_stream_destroy(struct ia_css_stre
+ }
+
+ /* remove references from pipes to stream */
+- for (i = 0; i < stream->num_pipes; i++)
+- {
++ for (i = 0; i < stream->num_pipes; i++) {
+ struct ia_css_pipe *entry = stream->pipes[i];
+
+ assert(entry);
+@@ -9733,8 +9602,7 @@ ia_css_stream_destroy(struct ia_css_stre
+ /* working mode: take out of the seed list */
+ if (my_css_save.mode == sh_css_mode_working) {
+ for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
+- if (my_css_save.stream_seeds[i].stream == stream)
+- {
++ if (my_css_save.stream_seeds[i].stream == stream) {
+ IA_CSS_LOG("took out stream %d", i);
+ my_css_save.stream_seeds[i].stream = NULL;
+ break;
+@@ -9750,7 +9618,8 @@ ia_css_stream_destroy(struct ia_css_stre
+
+ int
+ ia_css_stream_get_info(const struct ia_css_stream *stream,
+- struct ia_css_stream_info *stream_info) {
++ struct ia_css_stream_info *stream_info)
++{
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n");
+ assert(stream);
+ assert(stream_info);
+@@ -9766,15 +9635,15 @@ ia_css_stream_get_info(const struct ia_c
+ * The stream handle is used to identify the correct entry in the css_save struct
+ */
+ int
+-ia_css_stream_load(struct ia_css_stream *stream) {
++ia_css_stream_load(struct ia_css_stream *stream)
++{
+ if (!IS_ISP2401) {
+ int i;
+ int err;
+
+ assert(stream);
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n");
+- for (i = 0; i < MAX_ACTIVE_STREAMS; i++)
+- {
++ for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
+ if (my_css_save.stream_seeds[i].stream == stream) {
+ int j;
+
+@@ -9813,12 +9682,12 @@ ia_css_stream_load(struct ia_css_stream
+ }
+
+ int
+-ia_css_stream_start(struct ia_css_stream *stream) {
++ia_css_stream_start(struct ia_css_stream *stream)
++{
+ int err = 0;
+
+ IA_CSS_ENTER("stream = %p", stream);
+- if ((!stream) || (!stream->last_pipe))
+- {
++ if ((!stream) || (!stream->last_pipe)) {
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
+ }
+@@ -9828,8 +9697,7 @@ ia_css_stream_start(struct ia_css_stream
+
+ /* Create host side pipeline. */
+ err = create_host_pipeline(stream);
+- if (err)
+- {
++ if (err) {
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+@@ -9842,8 +9710,7 @@ ia_css_stream_start(struct ia_css_stream
+
+ #if !defined(ISP2401)
+ /* Initialize mipi size checks */
+- if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
+- {
++ if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
+ unsigned int idx;
+ unsigned int port = (unsigned int)(stream->config.source.port.port);
+
+@@ -9854,8 +9721,7 @@ ia_css_stream_start(struct ia_css_stream
+ }
+ #endif
+
+- if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY)
+- {
++ if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) {
+ err = sh_css_config_input_network(stream);
+ if (err)
+ return err;
+@@ -9867,7 +9733,8 @@ ia_css_stream_start(struct ia_css_stream
+ }
+
+ int
+-ia_css_stream_stop(struct ia_css_stream *stream) {
++ia_css_stream_stop(struct ia_css_stream *stream)
++{
+ int err = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_stop() enter/exit\n");
+@@ -9878,22 +9745,19 @@ ia_css_stream_stop(struct ia_css_stream
+
+ #if !defined(ISP2401)
+ /* De-initialize mipi size checks */
+- if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
+- {
++ if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
+ unsigned int idx;
+ unsigned int port = (unsigned int)(stream->config.source.port.port);
+
+- for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++) {
++ for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++)
+ sh_css_sp_group.config.mipi_sizes_for_check[port][idx] = 0;
+- }
+ }
+ #endif
+
+- if (!IS_ISP2401) {
++ if (!IS_ISP2401)
+ err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline);
+- } else {
++ else
+ err = sh_css_pipes_stop(stream);
+- }
+
+ if (err)
+ return err;
+@@ -9906,16 +9770,16 @@ ia_css_stream_stop(struct ia_css_stream
+ }
+
+ bool
+-ia_css_stream_has_stopped(struct ia_css_stream *stream) {
++ia_css_stream_has_stopped(struct ia_css_stream *stream)
++{
+ bool stopped;
+
+ assert(stream);
+
+- if (!IS_ISP2401) {
++ if (!IS_ISP2401)
+ stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline);
+- } else {
++ else
+ stopped = sh_css_pipes_have_stopped(stream);
+- }
+
+ return stopped;
+ }
+@@ -9926,7 +9790,8 @@ ia_css_stream_has_stopped(struct ia_css_
+ * The stream handle is used to identify the correct entry in the css_save struct
+ */
+ int
+-ia_css_stream_unload(struct ia_css_stream *stream) {
++ia_css_stream_unload(struct ia_css_stream *stream)
++{
+ int i;
+
+ assert(stream);
+@@ -9934,8 +9799,7 @@ ia_css_stream_unload(struct ia_css_strea
+ /* some checks */
+ assert(stream);
+ for (i = 0; i < MAX_ACTIVE_STREAMS; i++)
+- if (my_css_save.stream_seeds[i].stream == stream)
+- {
++ if (my_css_save.stream_seeds[i].stream == stream) {
+ int j;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -9955,7 +9819,8 @@ ia_css_stream_unload(struct ia_css_strea
+
+ int
+ ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe,
+- enum ia_css_pipe_id *pipe_id) {
++ enum ia_css_pipe_id *pipe_id)
++{
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_temp_pipe_to_pipe_id() enter/exit\n");
+ if (pipe)
+ *pipe_id = pipe->mode;
+@@ -9966,18 +9831,21 @@ ia_css_temp_pipe_to_pipe_id(const struct
+ }
+
+ enum atomisp_input_format
+-ia_css_stream_get_format(const struct ia_css_stream *stream) {
++ia_css_stream_get_format(const struct ia_css_stream *stream)
++{
+ return stream->config.input_config.format;
+ }
+
+ bool
+-ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream) {
++ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream)
++{
+ return (stream->config.pixels_per_clock == 2);
+ }
+
+ struct ia_css_binary *
+ ia_css_stream_get_shading_correction_binary(const struct ia_css_stream
+- *stream) {
++ *stream)
++{
+ struct ia_css_pipe *pipe;
+
+ assert(stream);
+@@ -9995,7 +9863,8 @@ ia_css_stream_get_shading_correction_bin
+ }
+
+ struct ia_css_binary *
+-ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream) {
++ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream)
++{
+ int i;
+ struct ia_css_pipe *video_pipe = NULL;
+
+@@ -10014,7 +9883,8 @@ ia_css_stream_get_dvs_binary(const struc
+ }
+
+ struct ia_css_binary *
+-ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) {
++ia_css_stream_get_3a_binary(const struct ia_css_stream *stream)
++{
+ struct ia_css_pipe *pipe;
+ struct ia_css_binary *s3a_binary = NULL;
+
+@@ -10036,7 +9906,8 @@ ia_css_stream_get_3a_binary(const struct
+
+ int
+ ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
+- unsigned int output_padded_width) {
++ unsigned int output_padded_width)
++{
+ struct ia_css_pipe *pipe;
+
+ assert(stream);
+@@ -10053,7 +9924,8 @@ ia_css_stream_set_output_padded_width(st
+ }
+
+ static struct ia_css_binary *
+-ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe)
++{
+ struct ia_css_binary *binary = NULL;
+
+ assert(pipe);
+@@ -10098,7 +9970,8 @@ ia_css_pipe_get_shading_correction_binar
+ }
+
+ static struct ia_css_binary *
+-ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe)
++{
+ struct ia_css_binary *binary = NULL;
+
+ assert(pipe);
+@@ -10121,9 +9994,9 @@ ia_css_pipe_get_s3a_binary(const struct
+ }
+ }
+ } else if (pipe->config.default_capture_config.mode ==
+- IA_CSS_CAPTURE_MODE_BAYER)
++ IA_CSS_CAPTURE_MODE_BAYER) {
+ binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary;
+- else if (pipe->config.default_capture_config.mode ==
++ } else if (pipe->config.default_capture_config.mode ==
+ IA_CSS_CAPTURE_MODE_ADVANCED ||
+ pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
+ if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1)
+@@ -10145,7 +10018,8 @@ ia_css_pipe_get_s3a_binary(const struct
+ }
+
+ static struct ia_css_binary *
+-ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe)
++{
+ struct ia_css_binary *binary = NULL;
+
+ assert(pipe);
+@@ -10165,14 +10039,16 @@ ia_css_pipe_get_sdis_binary(const struct
+ }
+
+ struct ia_css_pipeline *
+-ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe)
++{
+ assert(pipe);
+
+ return (struct ia_css_pipeline *)&pipe->pipeline;
+ }
+
+ unsigned int
+-ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe)
++{
+ assert(pipe);
+
+ /* KW was not sure this function was not returning a value
+@@ -10189,7 +10065,8 @@ ia_css_pipe_get_pipe_num(const struct ia
+ }
+
+ unsigned int
+-ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe)
++{
+ assert(pipe);
+
+ return (unsigned int)pipe->config.isp_pipe_version;
+@@ -10198,7 +10075,8 @@ ia_css_pipe_get_isp_pipe_version(const s
+ #define SP_START_TIMEOUT_US 30000000
+
+ int
+-ia_css_start_sp(void) {
++ia_css_start_sp(void)
++{
+ unsigned long timeout;
+ int err = 0;
+
+@@ -10207,13 +10085,11 @@ ia_css_start_sp(void) {
+
+ /* waiting for the SP is completely started */
+ timeout = SP_START_TIMEOUT_US;
+- while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout)
+- {
++ while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout) {
+ timeout--;
+ udelay(1);
+ }
+- if (timeout == 0)
+- {
++ if (timeout == 0) {
+ IA_CSS_ERROR("timeout during SP initialization");
+ return -EINVAL;
+ }
+@@ -10241,14 +10117,14 @@ ia_css_start_sp(void) {
+ #define SP_SHUTDOWN_TIMEOUT_US 200000
+
+ int
+-ia_css_stop_sp(void) {
++ia_css_stop_sp(void)
++{
+ unsigned long timeout;
+ int err = 0;
+
+ IA_CSS_ENTER("void");
+
+- if (!sh_css_sp_is_running())
+- {
++ if (!sh_css_sp_is_running()) {
+ err = -EINVAL;
+ IA_CSS_LEAVE("SP already stopped : return_err=%d", err);
+
+@@ -10260,8 +10136,7 @@ ia_css_stop_sp(void) {
+ if (!IS_ISP2401) {
+ sh_css_write_host2sp_command(host2sp_cmd_terminate);
+ } else {
+- if (!sh_css_write_host2sp_command(host2sp_cmd_terminate))
+- {
++ if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) {
+ IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed");
+ ia_css_debug_dump_sp_sw_debug_info();
+ ia_css_debug_dump_debug_info(NULL);
+@@ -10271,27 +10146,23 @@ ia_css_stop_sp(void) {
+ sh_css_sp_set_sp_running(false);
+
+ timeout = SP_SHUTDOWN_TIMEOUT_US;
+- while (!ia_css_spctrl_is_idle(SP0_ID) && timeout)
+- {
++ while (!ia_css_spctrl_is_idle(SP0_ID) && timeout) {
+ timeout--;
+ udelay(1);
+ }
+ if ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_TERMINATED))
+ IA_CSS_WARNING("SP has not terminated (SW)");
+
+- if (timeout == 0)
+- {
++ if (timeout == 0) {
+ IA_CSS_WARNING("SP is not idle");
+ ia_css_debug_dump_sp_sw_debug_info();
+ }
+ timeout = SP_SHUTDOWN_TIMEOUT_US;
+- while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout)
+- {
++ while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout) {
+ timeout--;
+ udelay(1);
+ }
+- if (timeout == 0)
+- {
++ if (timeout == 0) {
+ IA_CSS_WARNING("ISP is not idle");
+ ia_css_debug_dump_sp_sw_debug_info();
+ }
+@@ -10306,7 +10177,8 @@ ia_css_stop_sp(void) {
+ }
+
+ int
+-ia_css_update_continuous_frames(struct ia_css_stream *stream) {
++ia_css_update_continuous_frames(struct ia_css_stream *stream)
++{
+ struct ia_css_pipe *pipe;
+ unsigned int i;
+
+@@ -10314,8 +10186,7 @@ ia_css_update_continuous_frames(struct i
+ IA_CSS_DEBUG_TRACE,
+ "sh_css_update_continuous_frames() enter:\n");
+
+- if (!stream)
+- {
++ if (!stream) {
+ ia_css_debug_dtrace(
+ IA_CSS_DEBUG_TRACE,
+ "sh_css_update_continuous_frames() leave: invalid stream, return_void\n");
+@@ -10326,10 +10197,9 @@ ia_css_update_continuous_frames(struct i
+
+ for (i = stream->config.init_num_cont_raw_buf;
+ i < stream->config.target_num_cont_raw_buf; i++)
+- {
+ sh_css_update_host2sp_offline_frame(i,
+ pipe->continuous_frames[i], pipe->cont_md_buffers[i]);
+- }
++
+ sh_css_update_host2sp_cont_num_raw_frames
+ (stream->config.target_num_cont_raw_buf, true);
+ ia_css_debug_dtrace(
+@@ -10455,7 +10325,8 @@ void ia_css_pipe_map_queue(struct ia_css
+
+ #if CONFIG_ON_FRAME_ENQUEUE()
+ static int set_config_on_frame_enqueue(struct ia_css_frame_info
+- *info, struct frame_data_wrapper *frame) {
++ *info, struct frame_data_wrapper *frame)
++{
+ frame->config_on_frame_enqueue.padded_width = 0;
+
+ /* currently we support configuration on frame enqueue only on YUV formats */
+@@ -10463,11 +10334,11 @@ static int set_config_on_frame_enqueue(s
+ switch (info->format) {
+ case IA_CSS_FRAME_FORMAT_YUV420:
+ case IA_CSS_FRAME_FORMAT_NV12:
+- if (info->padded_width > info->res.width) {
++ if (info->padded_width > info->res.width)
+ frame->config_on_frame_enqueue.padded_width = info->padded_width;
+- } else if ((info->padded_width < info->res.width) && (info->padded_width > 0)) {
++ else if ((info->padded_width < info->res.width) && (info->padded_width > 0))
+ return -EINVAL;
+- }
++
+ /* nothing to do if width == padded width or padded width is zeroed (the same) */
+ break;
+ default:
+@@ -10479,22 +10350,21 @@ static int set_config_on_frame_enqueue(s
+ #endif
+
+ int
+-ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) {
++ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
++{
+ int ret;
+
+ IA_CSS_ENTER("");
+
+ /* Only continuous streams have a tagger to which we can send the
+ * unlock message. */
+- if (!stream || !stream->config.continuous)
+- {
++ if (!stream || !stream->config.continuous) {
+ IA_CSS_ERROR("invalid stream pointer");
+ return -EINVAL;
+ }
+
+ if (exp_id > IA_CSS_ISYS_MAX_EXPOSURE_ID ||
+- exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID)
+- {
++ exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID) {
+ IA_CSS_ERROR("invalid exposure ID: %d\n", exp_id);
+ return -EINVAL;
+ }
+@@ -10513,7 +10383,8 @@ ia_css_unlock_raw_frame(struct ia_css_st
+ */
+ int
+ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+- bool enable) {
++ bool enable)
++{
+ unsigned int thread_id;
+ struct ia_css_pipeline_stage *stage;
+ int err = 0;
+@@ -10521,20 +10392,16 @@ ia_css_pipe_set_qos_ext_state(struct ia_
+ IA_CSS_ENTER("");
+
+ /* Parameter Check */
+- if (!pipe || !pipe->stream)
+- {
++ if (!pipe || !pipe->stream) {
+ IA_CSS_ERROR("Invalid Pipe.");
+ err = -EINVAL;
+- } else if (!(pipe->config.acc_extension))
+- {
++ } else if (!(pipe->config.acc_extension)) {
+ IA_CSS_ERROR("Invalid Pipe(No Extension Firmware)");
+ err = -EINVAL;
+- } else if (!sh_css_sp_is_running())
+- {
++ } else if (!sh_css_sp_is_running()) {
+ IA_CSS_ERROR("Leaving: queue unavailable.");
+ err = -EBUSY;
+- } else
+- {
++ } else {
+ /* Query the threadid and stage_num for the Extension firmware*/
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
+@@ -10562,7 +10429,8 @@ ia_css_pipe_set_qos_ext_state(struct ia_
+ */
+ int
+ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+- bool *enable) {
++ bool *enable)
++{
+ struct ia_css_pipeline_stage *stage;
+ unsigned int thread_id;
+ int err = 0;
+@@ -10570,20 +10438,16 @@ ia_css_pipe_get_qos_ext_state(struct ia_
+ IA_CSS_ENTER("");
+
+ /* Parameter Check */
+- if (!pipe || !pipe->stream)
+- {
++ if (!pipe || !pipe->stream) {
+ IA_CSS_ERROR("Invalid Pipe.");
+ err = -EINVAL;
+- } else if (!(pipe->config.acc_extension))
+- {
++ } else if (!(pipe->config.acc_extension)) {
+ IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
+ err = -EINVAL;
+- } else if (!sh_css_sp_is_running())
+- {
++ } else if (!sh_css_sp_is_running()) {
+ IA_CSS_ERROR("Leaving: queue unavailable.");
+ err = -EBUSY;
+- } else
+- {
++ } else {
+ /* Query the threadid and stage_num corresponding to the Extension firmware*/
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
+@@ -10603,7 +10467,8 @@ int
+ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
+ u32 fw_handle,
+ struct ia_css_isp_param_css_segments *css_seg,
+- struct ia_css_isp_param_isp_segments *isp_seg) {
++ struct ia_css_isp_param_isp_segments *isp_seg)
++{
+ unsigned int HIVE_ADDR_sp_group;
+ static struct sh_css_sp_group sp_group;
+ static struct sh_css_sp_stage sp_stage;
+@@ -10621,20 +10486,16 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ fw = &sh_css_sp_fw;
+
+ /* Parameter Check */
+- if (!pipe || !pipe->stream)
+- {
++ if (!pipe || !pipe->stream) {
+ IA_CSS_ERROR("Invalid Pipe.");
+ err = -EINVAL;
+- } else if (!(pipe->config.acc_extension))
+- {
++ } else if (!(pipe->config.acc_extension)) {
+ IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
+ err = -EINVAL;
+- } else if (!sh_css_sp_is_running())
+- {
++ } else if (!sh_css_sp_is_running()) {
+ IA_CSS_ERROR("Leaving: queue unavailable.");
+ err = -EBUSY;
+- } else
+- {
++ } else {
+ /* Query the thread_id and stage_num corresponding to the Extension firmware */
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
+@@ -10685,7 +10546,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ static int
+ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
+ struct ia_css_pipe *pipes[],
+- bool *do_crop_status) {
++ bool *do_crop_status)
++{
+ int err = 0;
+ int i;
+ struct ia_css_pipe *curr_pipe;
+@@ -10694,15 +10556,13 @@ aspect_ratio_crop_init(struct ia_css_str
+ if ((!curr_stream) ||
+ (curr_stream->num_pipes == 0) ||
+ (!pipes) ||
+- (!do_crop_status))
+- {
++ (!do_crop_status)) {
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+ }
+
+- for (i = 0; i < curr_stream->num_pipes; i++)
+- {
++ for (i = 0; i < curr_stream->num_pipes; i++) {
+ curr_pipe = pipes[i];
+ pipe_mask |= (1 << curr_pipe->config.mode);
+ }
+@@ -10716,7 +10576,8 @@ aspect_ratio_crop_init(struct ia_css_str
+ }
+
+ static bool
+-aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) {
++aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe)
++{
+ bool status = false;
+
+ if ((curr_pipe) && enabled) {
+@@ -10731,7 +10592,8 @@ aspect_ratio_crop_check(bool enabled, st
+
+ static int
+ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
+- struct ia_css_resolution *effective_res) {
++ struct ia_css_resolution *effective_res)
++{
+ int err = 0;
+ struct ia_css_resolution crop_res;
+ struct ia_css_resolution *in_res = NULL;
+@@ -10741,8 +10603,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+ bool use_capt_pp_in_res = false;
+
+ if ((!curr_pipe) ||
+- (!effective_res))
+- {
++ (!effective_res)) {
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+@@ -10750,8 +10611,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+
+ if ((curr_pipe->config.mode != IA_CSS_PIPE_MODE_PREVIEW) &&
+ (curr_pipe->config.mode != IA_CSS_PIPE_MODE_VIDEO) &&
+- (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE))
+- {
++ (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE)) {
+ err = -EINVAL;
+ IA_CSS_LEAVE_ERR(err);
+ return err;
+@@ -10772,8 +10632,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+ in_res = &curr_pipe->stream->config.input_config.effective_res;
+ out_res = &curr_pipe->output_info[0].res;
+
+- switch (curr_pipe->config.mode)
+- {
++ switch (curr_pipe->config.mode) {
+ case IA_CSS_PIPE_MODE_PREVIEW:
+ if (use_bds_output_info)
+ out_res = &curr_pipe->bds_output_info.res;
+@@ -10800,20 +10659,19 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+
+ err = ia_css_frame_find_crop_resolution(in_res, out_res, &crop_res);
+ if (!err)
+- {
+ *effective_res = crop_res;
+- } else
+- {
++ else
+ /* in case of error fallback to default
+ * effective resolution from driver. */
+ IA_CSS_LOG("ia_css_frame_find_crop_resolution() failed with err(%d)", err);
+- }
++
+ return err;
+ }
+ #endif
+
+ static void
+-sh_css_hmm_buffer_record_init(void) {
++sh_css_hmm_buffer_record_init(void)
++{
+ int i;
+
+ for (i = 0; i < MAX_HMM_BUFFER_NUM; i++)
+@@ -10821,7 +10679,8 @@ sh_css_hmm_buffer_record_init(void) {
+ }
+
+ static void
+-sh_css_hmm_buffer_record_uninit(void) {
++sh_css_hmm_buffer_record_uninit(void)
++{
+ int i;
+ struct sh_css_hmm_buffer_record *buffer_record = NULL;
+
+@@ -10837,7 +10696,8 @@ sh_css_hmm_buffer_record_uninit(void) {
+ }
+
+ static void
+-sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record) {
++sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record)
++{
+ assert(buffer_record);
+ buffer_record->in_use = false;
+ buffer_record->type = IA_CSS_BUFFER_TYPE_INVALID;
+@@ -10848,7 +10708,8 @@ sh_css_hmm_buffer_record_reset(struct sh
+ static struct sh_css_hmm_buffer_record
+ *sh_css_hmm_buffer_record_acquire(struct ia_css_rmgr_vbuf_handle *h_vbuf,
+ enum ia_css_buffer_type type,
+- hrt_address kernel_ptr) {
++ hrt_address kernel_ptr)
++{
+ int i;
+ struct sh_css_hmm_buffer_record *buffer_record = NULL;
+ struct sh_css_hmm_buffer_record *out_buffer_record = NULL;
+@@ -10876,7 +10737,8 @@ static struct sh_css_hmm_buffer_record
+
+ static struct sh_css_hmm_buffer_record
+ *sh_css_hmm_buffer_record_validate(ia_css_ptr ddr_buffer_addr,
+- enum ia_css_buffer_type type) {
++ enum ia_css_buffer_type type)
++{
+ int i;
+ struct sh_css_hmm_buffer_record *buffer_record = NULL;
+ bool found_record = false;
--- /dev/null
+From stable+bounces-274528-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:56 -0400
+Subject: media: staging: media: atomisp: Replace if else clause with a ternary
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-4-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit d4bc34d18201120b247506b4a6ed17af694dfcf7 ]
+
+Use the ternary operator for conditional variable assignment in
+create_host_video_pipeline().
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -3623,11 +3623,8 @@ static int create_host_video_pipeline(st
+ struct ia_css_frame *tmp_out_frame = NULL;
+
+ for (i = 0; i < num_yuv_scaler; i++) {
+- if (is_output_stage[i]) {
+- tmp_out_frame = out_frame;
+- } else {
+- tmp_out_frame = NULL;
+- }
++ tmp_out_frame = is_output_stage[i] ? out_frame : NULL;
++
+ err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+ NULL,
+ &yuv_scaler_binary[i],
--- /dev/null
+From stable+bounces-275063-greg=kroah.com@vger.kernel.org Wed Jul 15 23:32:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 17:31:45 -0400
+Subject: netfilter: ebtables: Use vmalloc_array() to improve code
+To: stable@vger.kernel.org
+Cc: Qianfeng Rong <rongqianfeng@vivo.com>, Florian Westphal <fw@strlen.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715213146.296837-1-sashal@kernel.org>
+
+From: Qianfeng Rong <rongqianfeng@vivo.com>
+
+[ Upstream commit 46015e6b3ea75297b28d4806564f3f692cf11861 ]
+
+Remove array_size() calls and replace vmalloc() with vmalloc_array() to
+simplify the code. vmalloc_array() is also optimized better, uses fewer
+instructions, and handles overflow more concisely[1].
+
+[1]: https://lore.kernel.org/lkml/abc66ec5-85a4-47e1-9759-2f60ab111971@vivo.com/
+Signed-off-by: Qianfeng Rong <rongqianfeng@vivo.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Stable-dep-of: cbfe53599eeb ("netfilter: ebtables: zero chainstack array")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/netfilter/ebtables.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -884,8 +884,8 @@ static int translate_table(struct net *n
+ * if an error occurs
+ */
+ newinfo->chainstack =
+- vmalloc(array_size(nr_cpu_ids,
+- sizeof(*(newinfo->chainstack))));
++ vmalloc_array(nr_cpu_ids,
++ sizeof(*(newinfo->chainstack)));
+ if (!newinfo->chainstack)
+ return -ENOMEM;
+ for_each_possible_cpu(i) {
+@@ -900,7 +900,7 @@ static int translate_table(struct net *n
+ }
+ }
+
+- cl_s = vmalloc(array_size(udc_cnt, sizeof(*cl_s)));
++ cl_s = vmalloc_array(udc_cnt, sizeof(*cl_s));
+ if (!cl_s)
+ return -ENOMEM;
+ i = 0; /* the i'th udc */
+@@ -980,8 +980,8 @@ static int do_replace_finish(struct net
+ * the check on the size is done later, when we have the lock
+ */
+ if (repl->num_counters) {
+- unsigned long size = repl->num_counters * sizeof(*counterstmp);
+- counterstmp = vmalloc(size);
++ counterstmp = vmalloc_array(repl->num_counters,
++ sizeof(*counterstmp));
+ if (!counterstmp)
+ return -ENOMEM;
+ }
+@@ -1276,7 +1276,7 @@ static int do_update_counters(struct net
+ if (num_counters == 0)
+ return -EINVAL;
+
+- tmp = vmalloc(array_size(num_counters, sizeof(*tmp)));
++ tmp = vmalloc_array(num_counters, sizeof(*tmp));
+ if (!tmp)
+ return -ENOMEM;
+
+@@ -1417,7 +1417,7 @@ static int copy_counters_to_user(struct
+ if (num_counters != nentries)
+ return -EINVAL;
+
+- counterstmp = vmalloc(array_size(nentries, sizeof(*counterstmp)));
++ counterstmp = vmalloc_array(nentries, sizeof(*counterstmp));
+ if (!counterstmp)
+ return -ENOMEM;
+
--- /dev/null
+From stable+bounces-275064-greg=kroah.com@vger.kernel.org Wed Jul 15 23:32:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 17:31:46 -0400
+Subject: netfilter: ebtables: zero chainstack array
+To: stable@vger.kernel.org
+Cc: Florian Westphal <fw@strlen.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715213146.296837-2-sashal@kernel.org>
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit cbfe53599eebffd188938ab6774cc41794f6f9d5 ]
+
+sashiko reports:
+ looking at ebtables table
+ translation, could a sparse cpu_possible_mask lead to an uninitialized pointer
+ free?
+
+ If cpu_possible_mask is sparse (for example, CPU 0 and CPU 2 are possible,
+ but CPU 1 is not), the allocation loop skips CPU 1. If vmalloc_node() fails at
+ CPU 2, the cleanup loop will blindly decrement and call vfree() on
+ newinfo->chainstack[1].
+
+Not a real-world bug, such allocation isn't expected to fail
+in the first place.
+
+Cc: stable@vger.kernel.org
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/netfilter/ebtables.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -884,8 +884,7 @@ static int translate_table(struct net *n
+ * if an error occurs
+ */
+ newinfo->chainstack =
+- vmalloc_array(nr_cpu_ids,
+- sizeof(*(newinfo->chainstack)));
++ vcalloc(nr_cpu_ids, sizeof(*(newinfo->chainstack)));
+ if (!newinfo->chainstack)
+ return -ENOMEM;
+ for_each_possible_cpu(i) {
--- /dev/null
+From stable+bounces-274990-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:21 -0400
+Subject: PCI: Add kerneldoc for pci_resize_resource()
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Bjorn Helgaas" <bhelgaas@google.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-4-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit d787018e2dfdc4c1331538e7a8717690d1b7c9b3 ]
+
+As pci_resize_resource() is meant to be used also outside of PCI core,
+document the interface with kerneldoc.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Link: https://patch.msgid.link/20251113162628.5946-8-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/setup-res.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -422,6 +422,26 @@ void pci_release_resource(struct pci_dev
+ }
+ EXPORT_SYMBOL(pci_release_resource);
+
++/**
++ * pci_resize_resource - reconfigure a Resizable BAR and resources
++ * @dev: the PCI device
++ * @resno: index of the BAR to be resized
++ * @size: new size as defined in the spec (0=1MB, 31=128TB)
++ * @exclude_bars: a mask of BARs that should not be released
++ *
++ * Reconfigure @resno to @size and re-run resource assignment algorithm
++ * with the new size.
++ *
++ * Prior to resize, release @dev resources that share a bridge window with
++ * @resno. This unpins the bridge window resource to allow changing it.
++ *
++ * The caller may prevent releasing a particular BAR by providing
++ * @exclude_bars mask, but this may result in the resize operation failing
++ * due to insufficient space.
++ *
++ * Return: 0 on success, or negative on error. In case of an error, the
++ * resources are restored to their original places.
++ */
+ int pci_resize_resource(struct pci_dev *dev, int resno, int size,
+ int exclude_bars)
+ {
--- /dev/null
+From stable+bounces-274492-greg=kroah.com@vger.kernel.org Tue Jul 14 19:50:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 13:49:16 -0400
+Subject: PCI: altera: Fix resource leaks on probe failure
+To: stable@vger.kernel.org
+Cc: Mahesh Vaidya <mahesh.vaidya@altera.com>, Manivannan Sadhasivam <mani@kernel.org>, "Subhransu S. Prusty" <subhransu.sekhar.prusty@altera.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714174916.3041625-1-sashal@kernel.org>
+
+From: Mahesh Vaidya <mahesh.vaidya@altera.com>
+
+[ Upstream commit 7a94138caeb27f3c49c1dbd93bf422098925bb28 ]
+
+The chained IRQ handler is set during probe, but is only removed during the
+driver remove(). If pci_host_probe() fails, the handler and INTx IRQ
+domain remain set even though the devm-managed host bridge storage
+containing struct altera_pcie will be released, leaving the handler with
+a stale data pointer.
+
+Interrupts are also enabled before pci_host_probe() is called. If probe
+fails after that point, the controller interrupt source should be disabled
+before the chained handler and INTx domain are removed.
+
+So set the chained handler only after the INTx domain has been created.
+Disable controller interrupts during IRQ teardown, and tear the IRQ setup
+down if pci_host_probe() fails.
+
+Fixes: c63aed7334c2 ("PCI: altera: Use pci_host_probe() to register host")
+Signed-off-by: Mahesh Vaidya <mahesh.vaidya@altera.com>
+[mani: commit log]
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Subhransu S. Prusty <subhransu.sekhar.prusty@altera.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260430204330.3121003-3-mahesh.vaidya@altera.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-altera.c | 28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/pcie-altera.c
++++ b/drivers/pci/controller/pcie-altera.c
+@@ -685,8 +685,18 @@ static int altera_pcie_init_irq_domain(s
+ return 0;
+ }
+
++static void altera_pcie_disable_irq(struct altera_pcie *pcie)
++{
++ if (pcie->pcie_data->version == ALTERA_PCIE_V1 ||
++ pcie->pcie_data->version == ALTERA_PCIE_V2) {
++ /* Disable all P2A interrupts */
++ cra_writel(pcie, 0, P2A_INT_ENABLE);
++ }
++}
++
+ static void altera_pcie_irq_teardown(struct altera_pcie *pcie)
+ {
++ altera_pcie_disable_irq(pcie);
+ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
+ irq_domain_remove(pcie->irq_domain);
+ }
+@@ -711,7 +721,6 @@ static int altera_pcie_parse_dt(struct a
+ if (pcie->irq < 0)
+ return pcie->irq;
+
+- irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
+ return 0;
+ }
+
+@@ -796,6 +805,12 @@ static int altera_pcie_probe(struct plat
+ return ret;
+ }
+
++ /*
++ * The chained handler uses pcie->irq_domain, so set it only after the
++ * INTx domain has been created.
++ */
++ irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
++
+ /* clear all interrupts */
+ cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
+ /* enable all interrupts */
+@@ -806,7 +821,16 @@ static int altera_pcie_probe(struct plat
+ bridge->busnr = pcie->root_bus_nr;
+ bridge->ops = &altera_pcie_ops;
+
+- return pci_host_probe(bridge);
++ ret = pci_host_probe(bridge);
++ if (ret)
++ goto err_teardown_irq;
++
++ return 0;
++
++err_teardown_irq:
++ altera_pcie_irq_teardown(pcie);
++
++ return ret;
+ }
+
+ static int altera_pcie_remove(struct platform_device *pdev)
--- /dev/null
+From stable+bounces-274659-greg=kroah.com@vger.kernel.org Wed Jul 15 03:23:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 21:22:53 -0400
+Subject: PCI: controller: Use dev_fwnode() instead of of_fwnode_handle()
+To: stable@vger.kernel.org
+Cc: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>, Arnd Bergmann <arnd@arndb.de>, Bjorn Helgaas <bhelgaas@google.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715012255.4073217-1-sashal@kernel.org>
+
+From: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+
+[ Upstream commit a103d2dede5683dabbac2c3374bc24b6a9434478 ]
+
+All irq_domain functions now accept fwnode instead of of_node. But many
+PCI controllers still extract dev to of_node and then of_node to fwnode.
+
+Instead, clean this up and simply use the dev_fwnode() helper to extract
+fwnode directly from dev. Internally, it still does dev => of_node =>
+fwnode steps, but it's now hidden from the users.
+
+In the case of altera, this also removes an unused 'node' variable that is
+only used when CONFIG_OF is enabled:
+
+ drivers/pci/controller/pcie-altera.c: In function 'altera_pcie_init_irq_domain':
+ drivers/pci/controller/pcie-altera.c:855:29: error: unused variable 'node' [-Werror=unused-variable]
+ 855 | struct device_node *node = dev->of_node;
+
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de> # altera
+[bhelgaas: squash together, rebase to precede msi-parent]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://patch.msgid.link/20250521163329.2137973-1-arnd@kernel.org
+Link: https://patch.msgid.link/20250611104348.192092-16-jirislaby@kernel.org
+Link: https://patch.msgid.link/20250723065907.1841758-1-jirislaby@kernel.org
+Stable-dep-of: f865a57896bd ("PCI: mediatek: Fix IRQ domain leak when port fails to enable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-host.c | 2 +-
+ drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 8 +++-----
+ drivers/pci/controller/pcie-altera-msi.c | 2 +-
+ drivers/pci/controller/pcie-altera.c | 3 +--
+ drivers/pci/controller/pcie-mediatek.c | 2 +-
+ drivers/pci/controller/pcie-xilinx-nwl.c | 2 +-
+ 6 files changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -233,7 +233,7 @@ static const struct irq_domain_ops dw_pc
+ int dw_pcie_allocate_domains(struct pcie_port *pp)
+ {
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+- struct fwnode_handle *fwnode = of_node_to_fwnode(pci->dev->of_node);
++ struct fwnode_handle *fwnode = dev_fwnode(pci->dev);
+
+ pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors,
+ &dw_pcie_msi_domain_ops, pp);
+--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
++++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+@@ -452,7 +452,7 @@ static const struct irq_domain_ops msi_d
+ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
+ {
+ struct device *dev = &pcie->pdev->dev;
+- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++ struct fwnode_handle *fwnode = dev_fwnode(dev);
+ struct mobiveil_msi *msi = &pcie->rp.msi;
+
+ mutex_init(&msi->lock);
+@@ -478,13 +478,11 @@ static int mobiveil_allocate_msi_domains
+ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
+ {
+ struct device *dev = &pcie->pdev->dev;
+- struct device_node *node = dev->of_node;
+ struct mobiveil_root_port *rp = &pcie->rp;
+
+ /* setup INTx */
+- rp->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
+- &intx_domain_ops, pcie);
+-
++ rp->intx_domain = irq_domain_create_linear(dev_fwnode(dev), PCI_NUM_INTX, &intx_domain_ops,
++ pcie);
+ if (!rp->intx_domain) {
+ dev_err(dev, "Failed to get a INTx IRQ domain\n");
+ return -ENOMEM;
+--- a/drivers/pci/controller/pcie-altera-msi.c
++++ b/drivers/pci/controller/pcie-altera-msi.c
+@@ -173,7 +173,7 @@ static const struct irq_domain_ops msi_d
+
+ static int altera_allocate_domains(struct altera_msi *msi)
+ {
+- struct fwnode_handle *fwnode = of_node_to_fwnode(msi->pdev->dev.of_node);
++ struct fwnode_handle *fwnode = dev_fwnode(&msi->pdev->dev);
+
+ msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
+ &msi_domain_ops, msi);
+--- a/drivers/pci/controller/pcie-altera.c
++++ b/drivers/pci/controller/pcie-altera.c
+@@ -672,10 +672,9 @@ static void altera_pcie_isr(struct irq_d
+ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
+ {
+ struct device *dev = &pcie->pdev->dev;
+- struct device_node *node = dev->of_node;
+
+ /* Setup INTx */
+- pcie->irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
++ pcie->irq_domain = irq_domain_create_linear(dev_fwnode(dev), PCI_NUM_INTX,
+ &intx_domain_ops, pcie);
+ if (!pcie->irq_domain) {
+ dev_err(dev, "Failed to get a INTx IRQ domain\n");
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -497,7 +497,7 @@ static struct msi_domain_info mtk_msi_do
+
+ static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port)
+ {
+- struct fwnode_handle *fwnode = of_node_to_fwnode(port->pcie->dev->of_node);
++ struct fwnode_handle *fwnode = dev_fwnode(port->pcie->dev);
+
+ mutex_init(&port->lock);
+
+--- a/drivers/pci/controller/pcie-xilinx-nwl.c
++++ b/drivers/pci/controller/pcie-xilinx-nwl.c
+@@ -515,7 +515,7 @@ static int nwl_pcie_init_msi_irq_domain(
+ {
+ #ifdef CONFIG_PCI_MSI
+ struct device *dev = pcie->dev;
+- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++ struct fwnode_handle *fwnode = dev_fwnode(dev);
+ struct nwl_msi *msi = &pcie->msi;
+
+ msi->dev_domain = irq_domain_add_linear(NULL, INT_PCI_MSI_NR,
--- /dev/null
+From stable+bounces-274989-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:20 -0400
+Subject: PCI: Fix restoring BARs on BAR resize rollback path
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Simon Richter" <Simon.Richter@hogyros.de>, "Alex Bennée" <alex.bennee@linaro.org>, "Bjorn Helgaas" <bhelgaas@google.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-3-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 337b1b566db087347194e4543ddfdfa5645275cc ]
+
+BAR resize operation is implemented in the pci_resize_resource() and
+pbus_reassign_bridge_resources() functions. pci_resize_resource() can be
+called either from __resource_resize_store() from sysfs or directly by the
+driver for the Endpoint Device.
+
+The pci_resize_resource() requires that caller has released the device
+resources that share the bridge window with the BAR to be resized as
+otherwise the bridge window is pinned in place and cannot be changed.
+
+pbus_reassign_bridge_resources() rolls back resources if the resize
+operation fails, but rollback is performed only for the bridge windows.
+Because releasing the device resources are done by the caller of the BAR
+resize interface, these functions performing the BAR resize do not have
+access to the device resources as they were before the resize.
+
+pbus_reassign_bridge_resources() could try __pci_bridge_assign_resources()
+after rolling back the bridge windows as they were, however, it will not
+guarantee the resource are assigned due to differences in how FW and the
+kernel assign the resources (alignment of the start address and tail).
+
+To perform rollback robustly, the BAR resize interface has to be altered to
+also release the device resources that share the bridge window with the BAR
+to be resized.
+
+Also, remove restoring from the entries failed list as saved list should
+now contain both the bridge windows and device resources so the extra
+restore is duplicated work.
+
+Some drivers (currently only amdgpu) want to prevent releasing some
+resources. Add exclude_bars param to pci_resize_resource() and make amdgpu
+pass its register BAR (BAR 2 or 5), which should never be released during
+resize operation. Normally 64-bit prefetchable resources do not share a
+bridge window with the 32-bit only register BAR, but there are various
+fallbacks in the resource assignment logic which may make the resources
+share the bridge window in rare cases.
+
+This change (together with the driver side changes) is to counter the
+resource releases that had to be done to prevent resource tree corruption
+in the ("PCI: Release assigned resource before restoring them") change. As
+such, it likely restores functionality in cases where device resources were
+released to avoid resource tree conflicts which appeared to be "working"
+when such conflicts were not correctly detected by the kernel.
+
+Reported-by: Simon Richter <Simon.Richter@hogyros.de>
+Link: https://lore.kernel.org/linux-pci/f9a8c975-f5d3-4dd2-988e-4371a1433a60@hogyros.de/
+Reported-by: Alex Bennée <alex.bennee@linaro.org>
+Link: https://lore.kernel.org/linux-pci/874irqop6b.fsf@draig.linaro.org/
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+[bhelgaas: squash amdgpu BAR selection from
+https: //lore.kernel.org/r/20251114103053.13778-1-ilpo.jarvinen@linux.intel.com]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Link: https://patch.msgid.link/20251113162628.5946-7-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 -
+ drivers/pci/pci.h | 3
+ drivers/pci/setup-bus.c | 97 +++++++++++++++++++----------
+ drivers/pci/setup-res.c | 19 +----
+ include/linux/pci.h | 4 -
+ 5 files changed, 79 insertions(+), 48 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -1141,7 +1141,9 @@ int amdgpu_device_resize_fb_bar(struct a
+
+ pci_release_resource(adev->pdev, 0);
+
+- r = pci_resize_resource(adev->pdev, 0, rbar_size);
++ r = pci_resize_resource(adev->pdev, 0, rbar_size,
++ (adev->asic_type >= CHIP_BONAIRE) ? 1 << 5
++ : 1 << 2);
+ if (r == -ENOSPC)
+ DRM_INFO("Not enough PCI address space for a large BAR.");
+ else if (r && r != -ENOTSUPP)
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -284,6 +284,9 @@ enum pci_bar_type {
+ struct device *pci_get_host_bridge_device(struct pci_dev *dev);
+ void pci_put_host_bridge_device(struct device *dev);
+
++int pci_do_resource_release_and_resize(struct pci_dev *dev, int resno, int size,
++ int exclude_bars);
++
+ int pci_configure_extended_tags(struct pci_dev *dev, void *ign);
+ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
+ int crs_timeout);
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2166,18 +2166,16 @@ enable_all:
+ }
+ EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
+
+-int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
++static int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type,
++ struct list_head *saved)
+ {
+ struct pci_dev_resource *dev_res;
+ struct pci_dev *next;
+- LIST_HEAD(saved);
+ LIST_HEAD(added);
+ LIST_HEAD(failed);
+ unsigned int i;
+ int ret;
+
+- down_read(&pci_bus_sem);
+-
+ /* Walk to the root hub, releasing bridge BARs when possible */
+ next = bridge;
+ do {
+@@ -2193,9 +2191,9 @@ int pci_reassign_bridge_resources(struct
+ if (res->child)
+ continue;
+
+- ret = add_to_list(&saved, bridge, res, 0, 0);
++ ret = add_to_list(saved, bridge, res, 0, 0);
+ if (ret)
+- goto cleanup;
++ return ret;
+
+ pci_info(bridge, "BAR %d: releasing %pR\n",
+ i, res);
+@@ -2212,67 +2210,104 @@ int pci_reassign_bridge_resources(struct
+ next = bridge->bus ? bridge->bus->self : NULL;
+ } while (next);
+
+- if (list_empty(&saved)) {
+- up_read(&pci_bus_sem);
++ if (list_empty(saved))
+ return -ENOENT;
+- }
+
+ __pci_bus_size_bridges(bridge->subordinate, &added);
+ __pci_bridge_assign_resources(bridge, &added, &failed);
+ BUG_ON(!list_empty(&added));
+
+ if (!list_empty(&failed)) {
+- ret = -ENOSPC;
+- goto cleanup;
++ free_list(&failed);
++ return -ENOSPC;
+ }
+
+- list_for_each_entry(dev_res, &saved, list) {
++ list_for_each_entry(dev_res, saved, list) {
+ /* Skip the bridge we just assigned resources for */
+ if (bridge == dev_res->dev)
+ continue;
+
++ if (!dev_res->dev->subordinate)
++ continue;
++
+ bridge = dev_res->dev;
+ pci_setup_bridge(bridge->subordinate);
+ }
+
+- free_list(&saved);
+- up_read(&pci_bus_sem);
+ return 0;
++}
+
+-cleanup:
+- /* Restore size and flags */
+- list_for_each_entry(dev_res, &failed, list) {
+- struct resource *res = dev_res->res;
++int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size,
++ int exclude_bars)
++{
++ struct resource *res = pdev->resource + resno;
++ unsigned long flags = res->flags;
++ struct pci_dev_resource *dev_res;
++ struct pci_bus *bus = pdev->bus;
++ LIST_HEAD(saved);
++ unsigned int i;
++ int ret = 0;
+
+- res->start = dev_res->start;
+- res->end = dev_res->end;
+- res->flags = dev_res->flags;
++ down_read(&pci_bus_sem);
++
++ for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
++ struct resource *r = &pdev->resource[i];
++
++ if (exclude_bars & BIT(i))
++ continue;
++
++ if (!pci_resource_len(pdev, i) || r->flags != flags)
++ continue;
++
++ ret = add_to_list(&saved, pdev, r, 0, 0);
++ if (ret)
++ goto restore;
++ pci_release_resource(pdev, i);
+ }
+- free_list(&failed);
+
++ res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
++
++ if (!bus->self)
++ goto out;
++
++ ret = pci_reassign_bridge_resources(bus->self, res->flags, &saved);
++ if (ret)
++ goto restore;
++
++out:
++ up_read(&pci_bus_sem);
++ free_list(&saved);
++ return ret;
++
++restore:
+ /* Revert to the old configuration */
+ list_for_each_entry(dev_res, &saved, list) {
+ struct resource *res = dev_res->res;
++ struct pci_dev *dev = dev_res->dev;
+
+- bridge = dev_res->dev;
+- i = res - bridge->resource;
++ i = res - dev->resource;
+
+ if (res->parent) {
+ release_child_resources(res);
+- pci_release_resource(bridge, i);
++ pci_release_resource(dev, i);
+ }
+
+ res->start = dev_res->start;
+ res->end = dev_res->end;
+ res->flags = dev_res->flags;
+
+- pci_claim_resource(bridge, i);
+- pci_setup_bridge(bridge->subordinate);
+- }
+- up_read(&pci_bus_sem);
+- free_list(&saved);
++ if (pci_claim_resource(dev, i))
++ continue;
+
+- return ret;
++ if (i < PCI_BRIDGE_RESOURCES) {
++ pci_update_resource(dev, i);
++ pci_info(dev, "BAR %d: old value restored %pR\n",
++ i, res);
++ }
++ if (dev->subordinate)
++ pci_setup_bridge(dev->subordinate);
++ }
++ goto out;
+ }
+
+ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -422,9 +422,9 @@ void pci_release_resource(struct pci_dev
+ }
+ EXPORT_SYMBOL(pci_release_resource);
+
+-int pci_resize_resource(struct pci_dev *dev, int resno, int size)
++int pci_resize_resource(struct pci_dev *dev, int resno, int size,
++ int exclude_bars)
+ {
+- struct resource *res = dev->resource + resno;
+ struct pci_host_bridge *host;
+ int old, ret;
+ u32 sizes;
+@@ -435,10 +435,6 @@ int pci_resize_resource(struct pci_dev *
+ if (host->preserve_config)
+ return -ENOTSUPP;
+
+- /* Make sure the resource isn't assigned before resizing it. */
+- if (!(res->flags & IORESOURCE_UNSET))
+- return -EBUSY;
+-
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if (cmd & PCI_COMMAND_MEMORY)
+ return -EBUSY;
+@@ -458,19 +454,14 @@ int pci_resize_resource(struct pci_dev *
+ if (ret)
+ return ret;
+
+- res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
++ ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
++ if (ret)
++ goto error_resize;
+
+- /* Check if the new config works by trying to assign everything. */
+- if (dev->bus->self) {
+- ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
+- if (ret)
+- goto error_resize;
+- }
+ return 0;
+
+ error_resize:
+ pci_rebar_set_size(dev, resno, old);
+- res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
+ return ret;
+ }
+ EXPORT_SYMBOL(pci_resize_resource);
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1257,7 +1257,8 @@ void pci_update_resource(struct pci_dev
+ int __must_check pci_assign_resource(struct pci_dev *dev, int i);
+ int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
+ void pci_release_resource(struct pci_dev *dev, int resno);
+-int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size);
++int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size,
++ int exclude_bars);
+ int pci_select_bars(struct pci_dev *dev, unsigned long flags);
+ bool pci_device_is_present(struct pci_dev *pdev);
+ void pci_ignore_hotplug(struct pci_dev *dev);
+@@ -1332,7 +1333,6 @@ void pci_assign_unassigned_resources(voi
+ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
+ void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
+ void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
+-int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type);
+ void pdev_enable_device(struct pci_dev *);
+ int pci_enable_resources(struct pci_dev *, int mask);
+ void pci_assign_irq(struct pci_dev *dev);
--- /dev/null
+From stable+bounces-274988-greg=kroah.com@vger.kernel.org Wed Jul 15 18:32:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:19 -0400
+Subject: PCI: Free saved list without holding pci_bus_sem
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Bjorn Helgaas" <bhelgaas@google.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-2-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 1d8a0506f69895b7cfd9d5c4546761c508231a8a ]
+
+Freeing the saved list does not require holding pci_bus_sem, so the
+critical section can be made shorter.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Link: https://patch.msgid.link/20251113162628.5946-6-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/setup-bus.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2269,8 +2269,8 @@ cleanup:
+ pci_claim_resource(bridge, i);
+ pci_setup_bridge(bridge->subordinate);
+ }
+- free_list(&saved);
+ up_read(&pci_bus_sem);
++ free_list(&saved);
+
+ return ret;
+ }
--- /dev/null
+From stable+bounces-274572-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:08 -0400
+Subject: PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling
+To: stable@vger.kernel.org
+Cc: Richard Zhu <hongxing.zhu@nxp.com>, Manivannan Sadhasivam <mani@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>, Frank Li <Frank.Li@nxp.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220408.3333635-1-sashal@kernel.org>
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+[ Upstream commit aad953fb4eed0df5486cd54ccad80ac197678e01 ]
+
+The IMX6SX_GPR12_PCIE_TEST_POWERDOWN bit does not control the PCIe
+reference clock on i.MX6SX. Instead, it is part of i.MX6SX PCIe core
+reset sequence.
+
+Move the IMX6SX_GPR12_PCIE_TEST_POWERDOWN assertion/deassertion into
+the core reset functions to properly reflect its purpose. Remove the
+.enable_ref_clk() callback for i.MX6SX since it was incorrectly
+manipulating this bit.
+
+Fixes: e3c06cd063d6 ("PCI: imx6: Add initial imx6sx support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260319090844.444987-1-hongxing.zhu@nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -428,9 +428,6 @@ static int imx6_pcie_enable_ref_clk(stru
+ dev_err(dev, "unable to enable pcie_axi clock\n");
+ break;
+ }
+-
+- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+- IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
+ break;
+ case IMX6QP:
+ case IMX6Q:
+@@ -557,6 +554,8 @@ static void imx6_pcie_deassert_core_rese
+ imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
+ break;
+ case IMX6SX:
++ regmap_clear_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
++ IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
+ break;
--- /dev/null
+From stable+bounces-274660-greg=kroah.com@vger.kernel.org Wed Jul 15 03:23:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 21:22:54 -0400
+Subject: PCI: mediatek: Convert bool to single quirks entry and bitmap
+To: stable@vger.kernel.org
+Cc: Christian Marangi <ansuelsmth@gmail.com>, Manivannan Sadhasivam <mani@kernel.org>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715012255.4073217-2-sashal@kernel.org>
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit 04305367fab7ec9c98eeba315ad09c8b20abce93 ]
+
+To clean Mediatek SoC PCIe struct, convert all the bool to a bitmap and
+use a single quirks to reference all the values. This permits cleaner
+addition of new quirk without having to define a new bool in the struct.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251020111121.31779-4-ansuelsmth@gmail.com
+Stable-dep-of: f865a57896bd ("PCI: mediatek: Fix IRQ domain leak when port fails to enable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-mediatek.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -141,21 +141,29 @@
+ struct mtk_pcie_port;
+
+ /**
++ * enum mtk_pcie_quirks - MTK PCIe quirks
++ * @MTK_PCIE_FIX_CLASS_ID: host's class ID needed to be fixed
++ * @MTK_PCIE_FIX_DEVICE_ID: host's device ID needed to be fixed
++ */
++enum mtk_pcie_quirks {
++ MTK_PCIE_FIX_CLASS_ID = BIT(0),
++ MTK_PCIE_FIX_DEVICE_ID = BIT(1),
++};
++
++/**
+ * struct mtk_pcie_soc - differentiate between host generations
+- * @need_fix_class_id: whether this host's class ID needed to be fixed or not
+- * @need_fix_device_id: whether this host's device ID needed to be fixed or not
+ * @device_id: device ID which this host need to be fixed
+ * @ops: pointer to configuration access functions
+ * @startup: pointer to controller setting functions
+ * @setup_irq: pointer to initialize IRQ functions
++ * @quirks: PCIe device quirks.
+ */
+ struct mtk_pcie_soc {
+- bool need_fix_class_id;
+- bool need_fix_device_id;
+ unsigned int device_id;
+ struct pci_ops *ops;
+ int (*startup)(struct mtk_pcie_port *port);
+ int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
++ enum mtk_pcie_quirks quirks;
+ };
+
+ /**
+@@ -710,7 +718,7 @@ static int mtk_pcie_startup_port_v2(stru
+ writel(val, port->base + PCIE_RST_CTRL);
+
+ /* Set up vendor ID and class code */
+- if (soc->need_fix_class_id) {
++ if (soc->quirks & MTK_PCIE_FIX_CLASS_ID) {
+ val = PCI_VENDOR_ID_MEDIATEK;
+ writew(val, port->base + PCIE_CONF_VEND_ID);
+
+@@ -718,7 +726,7 @@ static int mtk_pcie_startup_port_v2(stru
+ writew(val, port->base + PCIE_CONF_CLASS_ID);
+ }
+
+- if (soc->need_fix_device_id)
++ if (soc->quirks & MTK_PCIE_FIX_DEVICE_ID)
+ writew(soc->device_id, port->base + PCIE_CONF_DEVICE_ID);
+
+ /* 100ms timeout value should be enough for Gen1/2 training */
+@@ -1206,19 +1214,18 @@ static const struct mtk_pcie_soc mtk_pci
+ };
+
+ static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = {
+- .need_fix_class_id = true,
+ .ops = &mtk_pcie_ops_v2,
+ .startup = mtk_pcie_startup_port_v2,
+ .setup_irq = mtk_pcie_setup_irq,
++ .quirks = MTK_PCIE_FIX_CLASS_ID,
+ };
+
+ static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
+- .need_fix_class_id = true,
+- .need_fix_device_id = true,
+ .device_id = PCI_DEVICE_ID_MEDIATEK_7629,
+ .ops = &mtk_pcie_ops_v2,
+ .startup = mtk_pcie_startup_port_v2,
+ .setup_irq = mtk_pcie_setup_irq,
++ .quirks = MTK_PCIE_FIX_CLASS_ID | MTK_PCIE_FIX_DEVICE_ID,
+ };
+
+ static const struct of_device_id mtk_pcie_ids[] = {
--- /dev/null
+From stable+bounces-274661-greg=kroah.com@vger.kernel.org Wed Jul 15 03:23:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 21:22:55 -0400
+Subject: PCI: mediatek: Fix IRQ domain leak when port fails to enable
+To: stable@vger.kernel.org
+Cc: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>, Manivannan Sadhasivam <mani@kernel.org>, Caleb James DeLisle <cjd@cjdns.fr>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715012255.4073217-3-sashal@kernel.org>
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+[ Upstream commit f865a57896bd92d7662eb2818d8f48872e2cbbc7 ]
+
+When mtk_pcie_enable_port() fails, mtk_pcie_port_free() removes the port
+from pcie->ports and frees the port structure. However, the IRQ domains set
+up earlier by mtk_pcie_init_irq_domain() are never freed.
+
+Fix this by refactoring mtk_pcie_irq_teardown() into a per-port helper,
+mtk_pcie_irq_teardown_port(), and calling it from mtk_pcie_setup() when
+mtk_pcie_enable_port() fails. Since the IRQ teardown must only happen in
+the probe error path (during resume, child devices may have active MSI
+mappings and the NOIRQ context prohibits sleeping locks),
+mtk_pcie_enable_port() is changed to return an error code so callers can
+distinguish the two paths and act accordingly.
+
+This issue was reported by Sashiko while reviewing the EcoNet EN7528 SoC
+support series.
+
+Fixes: b099631df160 ("PCI: mediatek: Add controller support for MT2712 and MT7622")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Cc: stable@vger.kernel.org # 5.10
+Cc: Caleb James DeLisle <cjd@cjdns.fr>
+Link: https://patch.msgid.link/20260521174617.17692-1-mani@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-mediatek.c | 67 ++++++++++++++++++++-------------
+ 1 file changed, 42 insertions(+), 25 deletions(-)
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -541,25 +541,29 @@ static void mtk_pcie_enable_msi(struct m
+ writel(val, port->base + PCIE_INT_MASK);
+ }
+
+-static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
++static void mtk_pcie_irq_teardown_port(struct mtk_pcie_port *port)
+ {
+- struct mtk_pcie_port *port, *tmp;
++ irq_set_chained_handler_and_data(port->irq, NULL, NULL);
+
+- list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+- irq_set_chained_handler_and_data(port->irq, NULL, NULL);
++ if (port->irq_domain)
++ irq_domain_remove(port->irq_domain);
+
+- if (port->irq_domain)
+- irq_domain_remove(port->irq_domain);
++ if (IS_ENABLED(CONFIG_PCI_MSI)) {
++ if (port->msi_domain)
++ irq_domain_remove(port->msi_domain);
++ if (port->inner_domain)
++ irq_domain_remove(port->inner_domain);
++ }
+
+- if (IS_ENABLED(CONFIG_PCI_MSI)) {
+- if (port->msi_domain)
+- irq_domain_remove(port->msi_domain);
+- if (port->inner_domain)
+- irq_domain_remove(port->inner_domain);
+- }
++ irq_dispose_mapping(port->irq);
++}
+
+- irq_dispose_mapping(port->irq);
+- }
++static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
++{
++ struct mtk_pcie_port *port, *tmp;
++
++ list_for_each_entry_safe(port, tmp, &pcie->ports, list)
++ mtk_pcie_irq_teardown_port(port);
+ }
+
+ static int mtk_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+@@ -836,7 +840,7 @@ static int mtk_pcie_startup_port(struct
+ return 0;
+ }
+
+-static void mtk_pcie_enable_port(struct mtk_pcie_port *port)
++static int mtk_pcie_enable_port(struct mtk_pcie_port *port)
+ {
+ struct mtk_pcie *pcie = port->pcie;
+ struct device *dev = pcie->dev;
+@@ -845,7 +849,7 @@ static void mtk_pcie_enable_port(struct
+ err = clk_prepare_enable(port->sys_ck);
+ if (err) {
+ dev_err(dev, "failed to enable sys_ck%d clock\n", port->slot);
+- goto err_sys_clk;
++ return err;
+ }
+
+ err = clk_prepare_enable(port->ahb_ck);
+@@ -893,11 +897,15 @@ static void mtk_pcie_enable_port(struct
+ goto err_phy_on;
+ }
+
+- if (!pcie->soc->startup(port))
+- return;
++ err = pcie->soc->startup(port);
++ if (err) {
++ dev_info(dev, "Port%d link down\n", port->slot);
++ goto err_soc_startup;
++ }
+
+- dev_info(dev, "Port%d link down\n", port->slot);
++ return 0;
+
++err_soc_startup:
+ phy_power_off(port->phy);
+ err_phy_on:
+ phy_exit(port->phy);
+@@ -913,8 +921,8 @@ err_aux_clk:
+ clk_disable_unprepare(port->ahb_ck);
+ err_ahb_clk:
+ clk_disable_unprepare(port->sys_ck);
+-err_sys_clk:
+- mtk_pcie_port_free(port);
++
++ return err;
+ }
+
+ static int mtk_pcie_parse_port(struct mtk_pcie *pcie,
+@@ -1077,8 +1085,13 @@ static int mtk_pcie_setup(struct mtk_pci
+ return err;
+
+ /* enable each port, and then check link status */
+- list_for_each_entry_safe(port, tmp, &pcie->ports, list)
+- mtk_pcie_enable_port(port);
++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
++ err = mtk_pcie_enable_port(port);
++ if (err) {
++ mtk_pcie_irq_teardown_port(port);
++ mtk_pcie_port_free(port);
++ }
++ }
+
+ /* power down PCIe subsys if slots are all empty (link down) */
+ if (list_empty(&pcie->ports))
+@@ -1181,14 +1194,18 @@ static int __maybe_unused mtk_pcie_resum
+ {
+ struct mtk_pcie *pcie = dev_get_drvdata(dev);
+ struct mtk_pcie_port *port, *tmp;
++ int err;
+
+ if (list_empty(&pcie->ports))
+ return 0;
+
+ clk_prepare_enable(pcie->free_ck);
+
+- list_for_each_entry_safe(port, tmp, &pcie->ports, list)
+- mtk_pcie_enable_port(port);
++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
++ err = mtk_pcie_enable_port(port);
++ if (err)
++ mtk_pcie_port_free(port);
++ }
+
+ /* In case of EP was removed while system suspend. */
+ if (list_empty(&pcie->ports))
--- /dev/null
+From stable+bounces-274991-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:22 -0400
+Subject: PCI: Move Resizable BAR code to rebar.c
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Bjorn Helgaas" <bhelgaas@google.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-5-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 9f71938cd77f32a448f40a288e409eca60e55486 ]
+
+For lack of a better place to put it, Resizable BAR code has been placed
+inside pci.c and setup-res.c that do not use it for anything. Upcoming
+changes are going to add more Resizable BAR related functions, increasing
+the code size.
+
+As pci.c is huge as is, move the Resizable BAR related code and the BAR
+resize code from setup-res.c to rebar.c.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Link: https://patch.msgid.link/20251113180053.27944-2-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/driver-api/pci/pci.rst | 3
+ drivers/pci/Makefile | 2
+ drivers/pci/pci.c | 135 ----------------------
+ drivers/pci/pci.h | 1
+ drivers/pci/rebar.c | 211 +++++++++++++++++++++++++++++++++++
+ drivers/pci/setup-res.c | 64 ----------
+ 6 files changed, 216 insertions(+), 200 deletions(-)
+ create mode 100644 drivers/pci/rebar.c
+
+--- a/Documentation/driver-api/pci/pci.rst
++++ b/Documentation/driver-api/pci/pci.rst
+@@ -31,6 +31,9 @@ PCI Support Library
+ .. kernel-doc:: drivers/pci/slot.c
+ :export:
+
++.. kernel-doc:: drivers/pci/rebar.c
++ :export:
++
+ .. kernel-doc:: drivers/pci/rom.c
+ :export:
+
+--- a/drivers/pci/Makefile
++++ b/drivers/pci/Makefile
+@@ -4,7 +4,7 @@
+
+ obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o \
+ remove.o pci.o pci-driver.o search.o \
+- pci-sysfs.o rom.o setup-res.o irq.o vpd.o \
++ pci-sysfs.o rebar.o rom.o setup-res.o irq.o vpd.o \
+ setup-bus.o vc.o mmap.o setup-irq.o
+
+ obj-$(CONFIG_PCI) += pcie/
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1626,33 +1626,6 @@ static void pci_restore_config_space(str
+ }
+ }
+
+-static void pci_restore_rebar_state(struct pci_dev *pdev)
+-{
+- unsigned int pos, nbars, i;
+- u32 ctrl;
+-
+- pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+- if (!pos)
+- return;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+- nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
+- PCI_REBAR_CTRL_NBAR_SHIFT;
+-
+- for (i = 0; i < nbars; i++, pos += 8) {
+- struct resource *res;
+- int bar_idx, size;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+- bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+- res = pdev->resource + bar_idx;
+- size = ilog2(resource_size(res)) - 20;
+- ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
+- ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
+- pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
+- }
+-}
+-
+ /**
+ * pci_restore_state - Restore the saved state of a PCI device
+ * @dev: PCI device that we're dealing with
+@@ -3558,114 +3531,6 @@ void pci_acs_init(struct pci_dev *dev)
+ }
+
+ /**
+- * pci_rebar_find_pos - find position of resize ctrl reg for BAR
+- * @pdev: PCI device
+- * @bar: BAR to find
+- *
+- * Helper to find the position of the ctrl register for a BAR.
+- * Returns -ENOTSUPP if resizable BARs are not supported at all.
+- * Returns -ENOENT if no ctrl register for the BAR could be found.
+- */
+-static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
+-{
+- unsigned int pos, nbars, i;
+- u32 ctrl;
+-
+- pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+- if (!pos)
+- return -ENOTSUPP;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+- nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
+- PCI_REBAR_CTRL_NBAR_SHIFT;
+-
+- for (i = 0; i < nbars; i++, pos += 8) {
+- int bar_idx;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+- bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+- if (bar_idx == bar)
+- return pos;
+- }
+-
+- return -ENOENT;
+-}
+-
+-/**
+- * pci_rebar_get_possible_sizes - get possible sizes for BAR
+- * @pdev: PCI device
+- * @bar: BAR to query
+- *
+- * Get the possible sizes of a resizable BAR as bitmask defined in the spec
+- * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable.
+- */
+-u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
+-{
+- int pos;
+- u32 cap;
+-
+- pos = pci_rebar_find_pos(pdev, bar);
+- if (pos < 0)
+- return 0;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
+- cap &= PCI_REBAR_CAP_SIZES;
+-
+- /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
+- if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
+- bar == 0 && cap == 0x7000)
+- cap = 0x3f000;
+-
+- return cap >> 4;
+-}
+-
+-/**
+- * pci_rebar_get_current_size - get the current size of a BAR
+- * @pdev: PCI device
+- * @bar: BAR to set size to
+- *
+- * Read the size of a BAR from the resizable BAR config.
+- * Returns size if found or negative error code.
+- */
+-int pci_rebar_get_current_size(struct pci_dev *pdev, int bar)
+-{
+- int pos;
+- u32 ctrl;
+-
+- pos = pci_rebar_find_pos(pdev, bar);
+- if (pos < 0)
+- return pos;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+- return (ctrl & PCI_REBAR_CTRL_BAR_SIZE) >> PCI_REBAR_CTRL_BAR_SHIFT;
+-}
+-
+-/**
+- * pci_rebar_set_size - set a new size for a BAR
+- * @pdev: PCI device
+- * @bar: BAR to set size to
+- * @size: new size as defined in the spec (0=1MB, 19=512GB)
+- *
+- * Set the new size of a BAR as defined in the spec.
+- * Returns zero if resizing was successful, error code otherwise.
+- */
+-int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
+-{
+- int pos;
+- u32 ctrl;
+-
+- pos = pci_rebar_find_pos(pdev, bar);
+- if (pos < 0)
+- return pos;
+-
+- pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+- ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
+- ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
+- pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
+- return 0;
+-}
+-
+-/**
+ * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
+ * @dev: the PCI device
+ * @cap_mask: mask of desired AtomicOp sizes, including one or more of:
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -629,6 +629,7 @@ static inline int acpi_get_rc_resources(
+ #endif
+
+ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar);
++void pci_restore_rebar_state(struct pci_dev *pdev);
+ int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
+ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size);
+ static inline u64 pci_rebar_size_to_bytes(int size)
+--- /dev/null
++++ b/drivers/pci/rebar.c
+@@ -0,0 +1,211 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PCI Resizable BAR Extended Capability handling.
++ */
++
++#include <linux/bitfield.h>
++#include <linux/errno.h>
++#include <linux/export.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <linux/types.h>
++
++#include "pci.h"
++
++/**
++ * pci_rebar_find_pos - find position of resize ctrl reg for BAR
++ * @pdev: PCI device
++ * @bar: BAR to find
++ *
++ * Helper to find the position of the ctrl register for a BAR.
++ * Returns -ENOTSUPP if resizable BARs are not supported at all.
++ * Returns -ENOENT if no ctrl register for the BAR could be found.
++ */
++static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
++{
++ unsigned int pos, nbars, i;
++ u32 ctrl;
++
++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
++ if (!pos)
++ return -ENOTSUPP;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
++ PCI_REBAR_CTRL_NBAR_SHIFT;
++
++ for (i = 0; i < nbars; i++, pos += 8) {
++ int bar_idx;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
++ if (bar_idx == bar)
++ return pos;
++ }
++
++ return -ENOENT;
++}
++
++/**
++ * pci_rebar_get_possible_sizes - get possible sizes for BAR
++ * @pdev: PCI device
++ * @bar: BAR to query
++ *
++ * Get the possible sizes of a resizable BAR as bitmask defined in the spec
++ * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable.
++ */
++u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
++{
++ int pos;
++ u32 cap;
++
++ pos = pci_rebar_find_pos(pdev, bar);
++ if (pos < 0)
++ return 0;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
++ cap &= PCI_REBAR_CAP_SIZES;
++
++ /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
++ if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
++ bar == 0 && cap == 0x7000)
++ cap = 0x3f000;
++
++ return cap >> 4;
++}
++
++/**
++ * pci_rebar_get_current_size - get the current size of a BAR
++ * @pdev: PCI device
++ * @bar: BAR to set size to
++ *
++ * Read the size of a BAR from the resizable BAR config.
++ * Returns size if found or negative error code.
++ */
++int pci_rebar_get_current_size(struct pci_dev *pdev, int bar)
++{
++ int pos;
++ u32 ctrl;
++
++ pos = pci_rebar_find_pos(pdev, bar);
++ if (pos < 0)
++ return pos;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ return (ctrl & PCI_REBAR_CTRL_BAR_SIZE) >> PCI_REBAR_CTRL_BAR_SHIFT;
++}
++
++/**
++ * pci_rebar_set_size - set a new size for a BAR
++ * @pdev: PCI device
++ * @bar: BAR to set size to
++ * @size: new size as defined in the spec (0=1MB, 19=512GB)
++ *
++ * Set the new size of a BAR as defined in the spec.
++ * Returns zero if resizing was successful, error code otherwise.
++ */
++int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
++{
++ int pos;
++ u32 ctrl;
++
++ pos = pci_rebar_find_pos(pdev, bar);
++ if (pos < 0)
++ return pos;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
++ ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
++ pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
++ return 0;
++}
++
++void pci_restore_rebar_state(struct pci_dev *pdev)
++{
++ unsigned int pos, nbars, i;
++ u32 ctrl;
++
++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
++ if (!pos)
++ return;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl);
++
++ for (i = 0; i < nbars; i++, pos += 8) {
++ struct resource *res;
++ int bar_idx, size;
++
++ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
++ res = pdev->resource + bar_idx;
++ size = ilog2(resource_size(res)) - 20;
++ ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
++ ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
++ pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
++ }
++}
++
++/**
++ * pci_resize_resource - reconfigure a Resizable BAR and resources
++ * @dev: the PCI device
++ * @resno: index of the BAR to be resized
++ * @size: new size as defined in the spec (0=1MB, 31=128TB)
++ * @exclude_bars: a mask of BARs that should not be released
++ *
++ * Reconfigure @resno to @size and re-run resource assignment algorithm
++ * with the new size.
++ *
++ * Prior to resize, release @dev resources that share a bridge window with
++ * @resno. This unpins the bridge window resource to allow changing it.
++ *
++ * The caller may prevent releasing a particular BAR by providing
++ * @exclude_bars mask, but this may result in the resize operation failing
++ * due to insufficient space.
++ *
++ * Return: 0 on success, or negative on error. In case of an error, the
++ * resources are restored to their original places.
++ */
++int pci_resize_resource(struct pci_dev *dev, int resno, int size,
++ int exclude_bars)
++{
++ struct pci_host_bridge *host;
++ int old, ret;
++ u32 sizes;
++ u16 cmd;
++
++ /* Check if we must preserve the firmware's resource assignment */
++ host = pci_find_host_bridge(dev->bus);
++ if (host->preserve_config)
++ return -ENOTSUPP;
++
++ pci_read_config_word(dev, PCI_COMMAND, &cmd);
++ if (cmd & PCI_COMMAND_MEMORY)
++ return -EBUSY;
++
++ sizes = pci_rebar_get_possible_sizes(dev, resno);
++ if (!sizes)
++ return -ENOTSUPP;
++
++ if (!(sizes & BIT(size)))
++ return -EINVAL;
++
++ old = pci_rebar_get_current_size(dev, resno);
++ if (old < 0)
++ return old;
++
++ ret = pci_rebar_set_size(dev, resno, size);
++ if (ret)
++ return ret;
++
++ ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
++ if (ret)
++ goto error_resize;
++
++ return 0;
++
++error_resize:
++ pci_rebar_set_size(dev, resno, old);
++ return ret;
++}
++EXPORT_SYMBOL(pci_resize_resource);
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -422,70 +422,6 @@ void pci_release_resource(struct pci_dev
+ }
+ EXPORT_SYMBOL(pci_release_resource);
+
+-/**
+- * pci_resize_resource - reconfigure a Resizable BAR and resources
+- * @dev: the PCI device
+- * @resno: index of the BAR to be resized
+- * @size: new size as defined in the spec (0=1MB, 31=128TB)
+- * @exclude_bars: a mask of BARs that should not be released
+- *
+- * Reconfigure @resno to @size and re-run resource assignment algorithm
+- * with the new size.
+- *
+- * Prior to resize, release @dev resources that share a bridge window with
+- * @resno. This unpins the bridge window resource to allow changing it.
+- *
+- * The caller may prevent releasing a particular BAR by providing
+- * @exclude_bars mask, but this may result in the resize operation failing
+- * due to insufficient space.
+- *
+- * Return: 0 on success, or negative on error. In case of an error, the
+- * resources are restored to their original places.
+- */
+-int pci_resize_resource(struct pci_dev *dev, int resno, int size,
+- int exclude_bars)
+-{
+- struct pci_host_bridge *host;
+- int old, ret;
+- u32 sizes;
+- u16 cmd;
+-
+- /* Check if we must preserve the firmware's resource assignment */
+- host = pci_find_host_bridge(dev->bus);
+- if (host->preserve_config)
+- return -ENOTSUPP;
+-
+- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+- if (cmd & PCI_COMMAND_MEMORY)
+- return -EBUSY;
+-
+- sizes = pci_rebar_get_possible_sizes(dev, resno);
+- if (!sizes)
+- return -ENOTSUPP;
+-
+- if (!(sizes & BIT(size)))
+- return -EINVAL;
+-
+- old = pci_rebar_get_current_size(dev, resno);
+- if (old < 0)
+- return old;
+-
+- ret = pci_rebar_set_size(dev, resno, size);
+- if (ret)
+- return ret;
+-
+- ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
+- if (ret)
+- goto error_resize;
+-
+- return 0;
+-
+-error_resize:
+- pci_rebar_set_size(dev, resno, old);
+- return ret;
+-}
+-EXPORT_SYMBOL(pci_resize_resource);
+-
+ int pci_enable_resources(struct pci_dev *dev, int mask)
+ {
+ u16 cmd, old_cmd;
--- /dev/null
+From stable+bounces-274987-greg=kroah.com@vger.kernel.org Wed Jul 15 18:32:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:18 -0400
+Subject: PCI: Prevent resource tree corruption when BAR resize fails
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Simon Richter" <Simon.Richter@hogyros.de>, "Alex Bennée" <alex.bennee@linaro.org>, "Bjorn Helgaas" <bhelgaas@google.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-1-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 91c4c89db41499eea1b29c56655f79c3bae66e93 ]
+
+pbus_reassign_bridge_resources() saves bridge windows into the saved
+list before attempting to adjust resource assignments to perform a BAR
+resize operation. If resource adjustments cannot be completed fully,
+rollback is attempted by restoring the resource from the saved list.
+
+The rollback, however, does not check whether the resources it restores were
+assigned by the partial resize attempt. If restore changes addresses of the
+resource, it can result in corrupting the resource tree.
+
+An example of a corrupted resource tree with overlapping addresses:
+
+ 6200000000000-6203fbfffffff : pciex@620c3c0000000
+ 6200000000000-6203fbff0ffff : PCI Bus 0030:01
+ 6200020000000-62000207fffff : 0030:01:00.0
+ 6200000000000-6203fbff0ffff : PCI Bus 0030:02
+
+A resource that are assigned into the resource tree must remain
+unchanged. Thus, release such a resource before attempting to restore
+and claim it back.
+
+For simplicity, always do the release and claim back for the resource
+even in the cases where it is restored to the same address range.
+
+Note: this fix may "break" some cases where devices "worked" because
+the resource tree corruption allowed address space double counting to
+fit more resource than what can now be assigned without double
+counting. The upcoming changes to BAR resizing should address those
+scenarios (to the extent possible).
+
+Fixes: 8bb705e3e79d ("PCI: Add pci_resize_resource() for resizing BARs")
+Reported-by: Simon Richter <Simon.Richter@hogyros.de>
+Link: https://lore.kernel.org/linux-pci/67840a16-99b4-4d8c-9b5c-4721ab0970a2@hogyros.de/
+Reported-by: Alex Bennée <alex.bennee@linaro.org>
+Link: https://lore.kernel.org/linux-pci/874irqop6b.fsf@draig.linaro.org/
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Link: https://patch.msgid.link/20251113162628.5946-2-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/setup-bus.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2257,6 +2257,11 @@ cleanup:
+ bridge = dev_res->dev;
+ i = res - bridge->resource;
+
++ if (res->parent) {
++ release_child_resources(res);
++ pci_release_resource(bridge, i);
++ }
++
+ res->start = dev_res->start;
+ res->end = dev_res->end;
+ res->flags = dev_res->flags;
--- /dev/null
+From stable+bounces-274992-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:23 -0400
+Subject: PCI: Skip Resizable BAR restore on read error
+To: stable@vger.kernel.org
+Cc: Marco Nenciarini <mnencia@kcore.it>, Bjorn Helgaas <bhelgaas@google.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715163223.952417-6-sashal@kernel.org>
+
+From: Marco Nenciarini <mnencia@kcore.it>
+
+[ Upstream commit ee7471fe968d210939be9046089a924cd23c8c3b ]
+
+pci_restore_rebar_state() uses the Resizable BAR Control register to decide
+how many BARs to restore (nbars) and which BAR each iteration addresses
+(bar_idx).
+
+When a device does not respond, config reads typically return
+PCI_ERROR_RESPONSE (~0). Both fields are 3 bits wide, so nbars and bar_idx
+both evaluate to 7, past the spec's valid ranges for both fields.
+pci_resource_n() then returns an unrelated resource slot, whose size is
+used to derive a nonsensical value written back to the Resizable BAR
+Control register.
+
+Bail out if any Resizable BAR Control read returns PCI_ERROR_RESPONSE. No
+further BARs are touched, which is safe because a config read that returns
+PCI_ERROR_RESPONSE indicates the device is unreachable and restoration is
+pointless.
+
+Fixes: d3252ace0bc6 ("PCI: Restore resized BAR state on resume")
+Signed-off-by: Marco Nenciarini <mnencia@kcore.it>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/666cac19b5daa0ab0e0ab64454e76b4d24465dbd.1776429882.git.mnencia@kcore.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/rebar.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/pci/rebar.c
++++ b/drivers/pci/rebar.c
+@@ -130,6 +130,9 @@ void pci_restore_rebar_state(struct pci_
+ return;
+
+ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ if (PCI_POSSIBLE_ERROR(ctrl))
++ return;
++
+ nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl);
+
+ for (i = 0; i < nbars; i++, pos += 8) {
+@@ -137,6 +140,9 @@ void pci_restore_rebar_state(struct pci_
+ int bar_idx, size;
+
+ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ if (PCI_POSSIBLE_ERROR(ctrl))
++ return;
++
+ bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+ res = pdev->resource + bar_idx;
+ size = ilog2(resource_size(res)) - 20;
--- /dev/null
+From stable+bounces-277135-greg=kroah.com@vger.kernel.org Fri Jul 17 18:38:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 12:38:21 -0400
+Subject: proc: protect ptrace_may_access() with exec_update_lock (FD links)
+To: stable@vger.kernel.org
+Cc: Jann Horn <jannh@google.com>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717163821.2035203-3-sashal@kernel.org>
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 6255da28d4bb5349fe18e84cb043ccd394eba75d ]
+
+proc_pid_get_link() and proc_pid_readlink() currently look up the task from
+the pid once, then do the ptrace access check on that task, then look up
+the task from the pid a second time to do the actual access.
+That's racy in several ways.
+
+To fix it, pass the task to the ->proc_get_link() handler, and instead of
+proc_fd_access_allowed(), introduce a new helper call_proc_get_link() that
+looks up and locks the task, does the access check, and calls
+->proc_get_link().
+
+Fixes: 778c1144771f ("[PATCH] proc: Use sane permission checks on the /proc/<pid>/fd/ symlinks")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://patch.msgid.link/20260518-procfs-lockfix-part1-v1-2-5c3d20e0ac33@google.com
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/base.c | 119 ++++++++++++++++++++---------------------------------
+ fs/proc/fd.c | 25 ++++-------
+ fs/proc/internal.h | 2
+ 3 files changed, 58 insertions(+), 88 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -217,33 +217,24 @@ static int get_task_root(struct task_str
+ return result;
+ }
+
+-static int proc_cwd_link(struct dentry *dentry, struct path *path)
++static int proc_cwd_link(struct dentry *dentry, struct path *path,
++ struct task_struct *task)
+ {
+- struct task_struct *task = get_proc_task(d_inode(dentry));
+ int result = -ENOENT;
+
+- if (task) {
+- task_lock(task);
+- if (task->fs) {
+- get_fs_pwd(task->fs, path);
+- result = 0;
+- }
+- task_unlock(task);
+- put_task_struct(task);
++ task_lock(task);
++ if (task->fs) {
++ get_fs_pwd(task->fs, path);
++ result = 0;
+ }
++ task_unlock(task);
+ return result;
+ }
+
+-static int proc_root_link(struct dentry *dentry, struct path *path)
++static int proc_root_link(struct dentry *dentry, struct path *path,
++ struct task_struct *task)
+ {
+- struct task_struct *task = get_proc_task(d_inode(dentry));
+- int result = -ENOENT;
+-
+- if (task) {
+- result = get_task_root(task, path);
+- put_task_struct(task);
+- }
+- return result;
++ return get_task_root(task, path);
+ }
+
+ /*
+@@ -703,23 +694,6 @@ static int proc_pid_syscall(struct seq_f
+ /* Here the fs part begins */
+ /************************************************************************/
+
+-/* permission checks */
+-static int proc_fd_access_allowed(struct inode *inode)
+-{
+- struct task_struct *task;
+- int allowed = 0;
+- /* Allow access to a task's file descriptors if it is us or we
+- * may use ptrace attach to the process and find out that
+- * information.
+- */
+- task = get_proc_task(inode);
+- if (task) {
+- allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
+- put_task_struct(task);
+- }
+- return allowed;
+-}
+-
+ int proc_nochmod_setattr(struct dentry *dentry, struct iattr *attr)
+ {
+ int error;
+@@ -1774,16 +1748,12 @@ static const struct file_operations proc
+ .release = single_release,
+ };
+
+-static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
++static int proc_exe_link(struct dentry *dentry, struct path *exe_path,
++ struct task_struct *task)
+ {
+- struct task_struct *task;
+ struct file *exe_file;
+
+- task = get_proc_task(d_inode(dentry));
+- if (!task)
+- return -ENOENT;
+ exe_file = get_task_exe_file(task);
+- put_task_struct(task);
+ if (exe_file) {
+ *exe_path = exe_file->f_path;
+ path_get(&exe_file->f_path);
+@@ -1793,26 +1763,42 @@ static int proc_exe_link(struct dentry *
+ return -ENOENT;
+ }
+
++static int call_proc_get_link(struct dentry *dentry, struct inode *inode, struct path *path_out)
++{
++ struct task_struct *task;
++ int ret;
++
++ task = get_proc_task(inode);
++ if (!task)
++ return -ENOENT;
++ ret = down_read_killable(&task->signal->exec_update_lock);
++ if (ret)
++ goto out_put_task;
++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
++ ret = -EACCES;
++ goto out;
++ }
++ ret = PROC_I(inode)->op.proc_get_link(dentry, path_out, task);
++
++out:
++ up_read(&task->signal->exec_update_lock);
++out_put_task:
++ put_task_struct(task);
++ return ret;
++}
++
+ static const char *proc_pid_get_link(struct dentry *dentry,
+ struct inode *inode,
+ struct delayed_call *done)
+ {
+ struct path path;
+- int error = -EACCES;
++ int error;
+
+ if (!dentry)
+ return ERR_PTR(-ECHILD);
+-
+- /* Are we allowed to snoop on the tasks file descriptors? */
+- if (!proc_fd_access_allowed(inode))
+- goto out;
+-
+- error = PROC_I(inode)->op.proc_get_link(dentry, &path);
+- if (error)
+- goto out;
+-
+- error = nd_jump_link(&path);
+-out:
++ error = call_proc_get_link(dentry, inode, &path);
++ if (!error)
++ error = nd_jump_link(&path);
+ return ERR_PTR(error);
+ }
+
+@@ -1846,17 +1832,11 @@ static int proc_pid_readlink(struct dent
+ struct inode *inode = d_inode(dentry);
+ struct path path;
+
+- /* Are we allowed to snoop on the tasks file descriptors? */
+- if (!proc_fd_access_allowed(inode))
+- goto out;
+-
+- error = PROC_I(inode)->op.proc_get_link(dentry, &path);
+- if (error)
+- goto out;
+-
+- error = do_proc_readlink(&path, buffer, buflen);
+- path_put(&path);
+-out:
++ error = call_proc_get_link(dentry, inode, &path);
++ if (!error) {
++ error = do_proc_readlink(&path, buffer, buflen);
++ path_put(&path);
++ }
+ return error;
+ }
+
+@@ -2242,21 +2222,16 @@ static const struct dentry_operations ti
+ .d_delete = pid_delete_dentry,
+ };
+
+-static int map_files_get_link(struct dentry *dentry, struct path *path)
++static int map_files_get_link(struct dentry *dentry, struct path *path,
++ struct task_struct *task)
+ {
+ unsigned long vm_start, vm_end;
+ struct vm_area_struct *vma;
+- struct task_struct *task;
+ struct mm_struct *mm;
+ int rc;
+
+ rc = -ENOENT;
+- task = get_proc_task(d_inode(dentry));
+- if (!task)
+- goto out;
+-
+ mm = get_task_mm(task);
+- put_task_struct(task);
+ if (!mm)
+ goto out;
+
+--- a/fs/proc/fd.c
++++ b/fs/proc/fd.c
+@@ -140,24 +140,19 @@ static const struct dentry_operations ti
+ .d_delete = pid_delete_dentry,
+ };
+
+-static int proc_fd_link(struct dentry *dentry, struct path *path)
++static int proc_fd_link(struct dentry *dentry, struct path *path,
++ struct task_struct *task)
+ {
+- struct task_struct *task;
+ int ret = -ENOENT;
++ unsigned int fd = proc_fd(d_inode(dentry));
++ struct file *fd_file;
+
+- task = get_proc_task(d_inode(dentry));
+- if (task) {
+- unsigned int fd = proc_fd(d_inode(dentry));
+- struct file *fd_file;
+-
+- fd_file = fget_task(task, fd);
+- if (fd_file) {
+- *path = fd_file->f_path;
+- path_get(&fd_file->f_path);
+- ret = 0;
+- fput(fd_file);
+- }
+- put_task_struct(task);
++ fd_file = fget_task(task, fd);
++ if (fd_file) {
++ *path = fd_file->f_path;
++ path_get(&fd_file->f_path);
++ ret = 0;
++ fput(fd_file);
+ }
+
+ return ret;
+--- a/fs/proc/internal.h
++++ b/fs/proc/internal.h
+@@ -97,7 +97,7 @@ extern struct kmem_cache *proc_dir_entry
+ void pde_free(struct proc_dir_entry *pde);
+
+ union proc_op {
+- int (*proc_get_link)(struct dentry *, struct path *);
++ int (*proc_get_link)(struct dentry *, struct path *, struct task_struct *);
+ int (*proc_show)(struct seq_file *m,
+ struct pid_namespace *ns, struct pid *pid,
+ struct task_struct *task);
--- /dev/null
+From stable+bounces-277189-greg=kroah.com@vger.kernel.org Fri Jul 17 21:24:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 15:23:58 -0400
+Subject: proc: protect ptrace_may_access() with exec_update_lock (part 1)
+To: stable@vger.kernel.org
+Cc: Jann Horn <jannh@google.com>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717192358.2131761-1-sashal@kernel.org>
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 6650527444dadc63d84aa939d14ecba4fadb2f69 ]
+
+Fix the easy cases where procfs currently calls ptrace_may_access() without
+exec_update_lock protection, where the fix is to simply add the extra lock
+or use mm_access():
+
+ - do_task_stat(): grab exec_update_lock
+ - proc_pid_wchan(): grab exec_update_lock
+ - proc_map_files_lookup(): use mm_access() instead of get_task_mm()
+ - proc_map_files_readdir(): use mm_access() instead of get_task_mm()
+ - proc_ns_get_link(): grab exec_update_lock
+ - proc_ns_readlink(): grab exec_update_lock
+
+Fixes: f83ce3e6b02d ("proc: avoid information leaks to non-privileged processes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://patch.msgid.link/20260518-procfs-lockfix-part1-v1-1-5c3d20e0ac33@google.com
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+[ converted NULL return from mm_access() to ERR_PTR(-ESRCH) at call sites since 5.15's mm_access() returns NULL when the task has no mm ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/array.c | 6 ++++++
+ fs/proc/base.c | 41 ++++++++++++++++++++++++-----------------
+ fs/proc/namespaces.c | 12 ++++++++++++
+ 3 files changed, 42 insertions(+), 17 deletions(-)
+
+--- a/fs/proc/array.c
++++ b/fs/proc/array.c
+@@ -449,6 +449,11 @@ static int do_task_stat(struct seq_file
+ unsigned long flags;
+ struct signal_struct *sig = task->signal;
+ unsigned int seq = 1;
++ int ret;
++
++ ret = down_read_killable(&task->signal->exec_update_lock);
++ if (ret)
++ return ret;
+
+ state = *get_task_state(task);
+ vsize = eip = esp = 0;
+@@ -626,6 +631,7 @@ static int do_task_stat(struct seq_file
+ seq_puts(m, " 0");
+
+ seq_putc(m, '\n');
++ up_read(&task->signal->exec_update_lock);
+ if (mm)
+ mmput(mm);
+ return 0;
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -413,18 +413,24 @@ static int proc_pid_wchan(struct seq_fil
+ {
+ unsigned long wchan;
+ char symname[KSYM_NAME_LEN];
++ int err;
+
++ err = down_read_killable(&task->signal->exec_update_lock);
++ if (err)
++ return err;
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+ goto print0;
+
+ wchan = get_wchan(task);
+ if (wchan && !lookup_symbol_name(wchan, symname)) {
+ seq_puts(m, symname);
++ up_read(&task->signal->exec_update_lock);
+ return 0;
+ }
+
+ print0:
+ seq_putc(m, '0');
++ up_read(&task->signal->exec_update_lock);
+ return 0;
+ }
+ #endif /* CONFIG_KALLSYMS */
+@@ -2327,17 +2333,17 @@ static struct dentry *proc_map_files_loo
+ if (!task)
+ goto out;
+
+- result = ERR_PTR(-EACCES);
+- if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+- goto out_put_task;
+-
+ result = ERR_PTR(-ENOENT);
+ if (dname_to_vma_addr(dentry, &vm_start, &vm_end))
+ goto out_put_task;
+
+- mm = get_task_mm(task);
++ mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
+ if (!mm)
++ mm = ERR_PTR(-ESRCH);
++ if (IS_ERR(mm)) {
++ result = ERR_CAST(mm);
+ goto out_put_task;
++ }
+
+ result = ERR_PTR(-EINTR);
+ if (mmap_read_lock_killable(mm))
+@@ -2386,23 +2392,24 @@ proc_map_files_readdir(struct file *file
+ if (!task)
+ goto out;
+
+- ret = -EACCES;
+- if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+- goto out_put_task;
+-
+ ret = 0;
+ if (!dir_emit_dots(file, ctx))
+ goto out_put_task;
+
+- mm = get_task_mm(task);
++ mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
+ if (!mm)
++ mm = ERR_PTR(-ESRCH);
++ if (IS_ERR(mm)) {
++ ret = PTR_ERR(mm);
++ /* if the task has no mm, the directory should just be empty */
++ if (ret == -ESRCH)
++ ret = 0;
+ goto out_put_task;
++ }
+
+ ret = mmap_read_lock_killable(mm);
+- if (ret) {
+- mmput(mm);
+- goto out_put_task;
+- }
++ if (ret)
++ goto out_put_mm;
+
+ nr_files = 0;
+
+@@ -2426,8 +2433,7 @@ proc_map_files_readdir(struct file *file
+ if (!p) {
+ ret = -ENOMEM;
+ mmap_read_unlock(mm);
+- mmput(mm);
+- goto out_put_task;
++ goto out_put_mm;
+ }
+
+ p->start = vma->vm_start;
+@@ -2435,7 +2441,6 @@ proc_map_files_readdir(struct file *file
+ p->mode = vma->vm_file->f_mode;
+ }
+ mmap_read_unlock(mm);
+- mmput(mm);
+
+ for (i = 0; i < nr_files; i++) {
+ char buf[4 * sizeof(long) + 2]; /* max: %lx-%lx\0 */
+@@ -2452,6 +2457,8 @@ proc_map_files_readdir(struct file *file
+ ctx->pos++;
+ }
+
++out_put_mm:
++ mmput(mm);
+ out_put_task:
+ put_task_struct(task);
+ out:
+--- a/fs/proc/namespaces.c
++++ b/fs/proc/namespaces.c
+@@ -55,6 +55,10 @@ static const char *proc_ns_get_link(stru
+ if (!task)
+ return ERR_PTR(-EACCES);
+
++ error = down_read_killable(&task->signal->exec_update_lock);
++ if (error)
++ goto out_put_task;
++
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+ goto out;
+
+@@ -64,6 +68,8 @@ static const char *proc_ns_get_link(stru
+
+ error = nd_jump_link(&ns_path);
+ out:
++ up_read(&task->signal->exec_update_lock);
++out_put_task:
+ put_task_struct(task);
+ return ERR_PTR(error);
+ }
+@@ -80,11 +86,17 @@ static int proc_ns_readlink(struct dentr
+ if (!task)
+ return res;
+
++ res = down_read_killable(&task->signal->exec_update_lock);
++ if (res)
++ goto out_put_task;
++
+ if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
+ res = ns_get_name(name, sizeof(name), task, ns_ops);
+ if (res >= 0)
+ res = readlink_copy(buffer, buflen, name);
+ }
++ up_read(&task->signal->exec_update_lock);
++out_put_task:
+ put_task_struct(task);
+ return res;
+ }
--- /dev/null
+From stable+bounces-277134-greg=kroah.com@vger.kernel.org Fri Jul 17 18:38:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 12:38:20 -0400
+Subject: proc: rename proc_setattr to proc_nochmod_setattr
+To: stable@vger.kernel.org
+Cc: Christoph Hellwig <hch@lst.de>, Jan Kara <jack@suse.cz>, Christian Brauner <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717163821.2035203-2-sashal@kernel.org>
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 690005b0b1e6b567c88b7790e6d90d4d6c9e09cc ]
+
+What is currently proc_setattr is a special version added after the more
+general procfs ->seattr in commit 6d76fa58b050 ("Don't allow chmod() on
+the /proc/<pid>/ files"). Give it a name that reflects that to free the
+proc_setattr name and better describe what is doing.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://patch.msgid.link/20260325063711.3298685-5-hch@lst.de
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 6255da28d4bb ("proc: protect ptrace_may_access() with exec_update_lock (FD links)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/base.c | 22 +++++++++++-----------
+ fs/proc/fd.c | 4 ++--
+ fs/proc/internal.h | 2 +-
+ fs/proc/namespaces.c | 4 ++--
+ fs/proc/proc_net.c | 2 +-
+ 5 files changed, 17 insertions(+), 17 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -720,7 +720,7 @@ static int proc_fd_access_allowed(struct
+ return allowed;
+ }
+
+-int proc_setattr(struct dentry *dentry, struct iattr *attr)
++int proc_nochmod_setattr(struct dentry *dentry, struct iattr *attr)
+ {
+ int error;
+ struct inode *inode = d_inode(dentry);
+@@ -792,7 +792,7 @@ static int proc_pid_permission(struct in
+
+
+ static const struct inode_operations proc_def_inode_operations = {
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static int proc_single_show(struct seq_file *m, void *v)
+@@ -1863,7 +1863,7 @@ out:
+ const struct inode_operations proc_pid_link_inode_operations = {
+ .readlink = proc_pid_readlink,
+ .get_link = proc_pid_get_link,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+
+@@ -2311,7 +2311,7 @@ proc_map_files_get_link(struct dentry *d
+ static const struct inode_operations proc_map_files_link_inode_operations = {
+ .readlink = proc_pid_readlink,
+ .get_link = proc_map_files_get_link,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static struct dentry *
+@@ -2390,7 +2390,7 @@ out:
+ static const struct inode_operations proc_map_files_inode_operations = {
+ .lookup = proc_map_files_lookup,
+ .permission = proc_fd_permission,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static int
+@@ -2882,7 +2882,7 @@ static struct dentry *proc_##LSM##_attr_
+ static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \
+ .lookup = proc_##LSM##_attr_dir_lookup, \
+ .getattr = pid_getattr, \
+- .setattr = proc_setattr, \
++ .setattr = proc_nochmod_setattr, \
+ }
+
+ #ifdef CONFIG_SECURITY_SMACK
+@@ -2941,7 +2941,7 @@ static struct dentry *proc_attr_dir_look
+ static const struct inode_operations proc_attr_dir_inode_operations = {
+ .lookup = proc_attr_dir_lookup,
+ .getattr = pid_getattr,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ #endif
+@@ -3395,7 +3395,7 @@ static struct dentry *proc_tgid_base_loo
+ static const struct inode_operations proc_tgid_base_inode_operations = {
+ .lookup = proc_tgid_base_lookup,
+ .getattr = pid_getattr,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ .permission = proc_pid_permission,
+ };
+
+@@ -3594,7 +3594,7 @@ static int proc_tid_comm_permission(stru
+ }
+
+ static const struct inode_operations proc_tid_comm_inode_operations = {
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ .permission = proc_tid_comm_permission,
+ };
+
+@@ -3718,7 +3718,7 @@ static const struct file_operations proc
+ static const struct inode_operations proc_tid_base_inode_operations = {
+ .lookup = proc_tid_base_lookup,
+ .getattr = pid_getattr,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static struct dentry *proc_task_instantiate(struct dentry *dentry,
+@@ -3913,7 +3913,7 @@ static int proc_task_getattr(const struc
+ static const struct inode_operations proc_task_inode_operations = {
+ .lookup = proc_task_lookup,
+ .getattr = proc_task_getattr,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ .permission = proc_pid_permission,
+ };
+
+--- a/fs/proc/fd.c
++++ b/fs/proc/fd.c
+@@ -297,7 +297,7 @@ int proc_fd_permission(struct inode *ino
+ const struct inode_operations proc_fd_inode_operations = {
+ .lookup = proc_lookupfd,
+ .permission = proc_fd_permission,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry,
+@@ -335,7 +335,7 @@ static int proc_readfdinfo(struct file *
+
+ const struct inode_operations proc_fdinfo_inode_operations = {
+ .lookup = proc_lookupfdinfo,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ const struct file_operations proc_fdinfo_operations = {
+--- a/fs/proc/internal.h
++++ b/fs/proc/internal.h
+@@ -177,7 +177,7 @@ extern int proc_pid_statm(struct seq_fil
+ */
+ extern const struct dentry_operations pid_dentry_operations;
+ extern int pid_getattr(const struct path *, struct kstat *, u32, unsigned int);
+-extern int proc_setattr(struct dentry *, struct iattr *);
++int proc_nochmod_setattr(struct dentry *dentry, struct iattr *attr);
+ extern void proc_pid_evict_inode(struct proc_inode *);
+ extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *, umode_t);
+ extern void pid_update_inode(struct task_struct *, struct inode *);
+--- a/fs/proc/namespaces.c
++++ b/fs/proc/namespaces.c
+@@ -92,7 +92,7 @@ static int proc_ns_readlink(struct dentr
+ static const struct inode_operations proc_ns_link_inode_operations = {
+ .readlink = proc_ns_readlink,
+ .get_link = proc_ns_get_link,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static struct dentry *proc_ns_instantiate(struct dentry *dentry,
+@@ -179,5 +179,5 @@ out_no_task:
+ const struct inode_operations proc_ns_dir_inode_operations = {
+ .lookup = proc_ns_dir_lookup,
+ .getattr = pid_getattr,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+--- a/fs/proc/proc_net.c
++++ b/fs/proc/proc_net.c
+@@ -310,7 +310,7 @@ static int proc_tgid_net_getattr(const s
+ const struct inode_operations proc_net_inode_operations = {
+ .lookup = proc_tgid_net_lookup,
+ .getattr = proc_tgid_net_getattr,
+- .setattr = proc_setattr,
++ .setattr = proc_nochmod_setattr,
+ };
+
+ static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
--- /dev/null
+From stable+bounces-277133-greg=kroah.com@vger.kernel.org Fri Jul 17 18:38:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 12:38:19 -0400
+Subject: proc: use generic setattr() for /proc/$PID/net
+To: stable@vger.kernel.org
+Cc: "Thomas Weißschuh" <linux@weissschuh.net>, "Zhangjin Wu" <falcon@tinylab.org>, "Willy Tarreau" <w@1wt.eu>, "Christian Brauner" <brauner@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260717163821.2035203-1-sashal@kernel.org>
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+[ Upstream commit 18e66ae67673f2c8df6f02428798b1355691f2a9 ]
+
+All other files in /proc/$PID/ use proc_setattr().
+
+Not using it allows the usage of chmod() on /proc/$PID/net, even on
+other processes owned by the same user.
+The same would probably also be true for other attributes to be changed.
+
+As this technically represents an ABI change it is not marked for
+stable so any unlikely regressions are caught during a full release cycle.
+
+Fixes: e9720acd728a ("[NET]: Make /proc/net a symlink on /proc/self/net (v3)")
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://lore.kernel.org/lkml/d0d111ef-edae-4760-83fb-36db84278da1@t-8ch.de/
+Fixes: b4844fa0bdb4 ("selftests/nolibc: implement a few tests for various syscalls")
+Tested-by: Zhangjin Wu <falcon@tinylab.org>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Message-Id: <20230624-proc-net-setattr-v1-2-73176812adee@weissschuh.net>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 6255da28d4bb ("proc: protect ptrace_may_access() with exec_update_lock (FD links)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/proc_net.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/proc/proc_net.c
++++ b/fs/proc/proc_net.c
+@@ -310,6 +310,7 @@ static int proc_tgid_net_getattr(const s
+ const struct inode_operations proc_net_inode_operations = {
+ .lookup = proc_tgid_net_lookup,
+ .getattr = proc_tgid_net_getattr,
++ .setattr = proc_setattr,
+ };
+
+ static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
--- /dev/null
+From stable+bounces-277239-greg=kroah.com@vger.kernel.org Sat Jul 18 03:33:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 21:33:38 -0400
+Subject: serial: 8250_mid: Disable DMA for selected platforms
+To: stable@vger.kernel.org
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>, micas-opensource <zjianan156@gmail.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718013338.2621443-2-sashal@kernel.org>
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit b1b4efea05a56c0995e4702a86d6624b4fdff32f ]
+
+In accordance with Errata (specification updates)
+HSUART May Stop Functioning when DMA is Active.
+
+- Denverton document #572409, rev 3.4, DNV60
+- Ice Lake Xeon D document #714070, ICXD65
+- Snowridge document #731931, SNR44
+
+For a quick fix just disable the respective callbacks during the device probe.
+Depending on the future development we might remove them completely.
+
+Reported-by: micas-opensource <zjianan156@gmail.com>
+Closes: https://lore.kernel.org/linux-serial/20250625031409.2404219-1-opensource@ruijie.com.cn/
+Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20260626094937.561776-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250_mid.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_mid.c
++++ b/drivers/tty/serial/8250/8250_mid.c
+@@ -10,6 +10,7 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/rational.h>
++#include <linux/util_macros.h>
+
+ #include <linux/dma/hsu.h>
+
+@@ -371,8 +372,16 @@ static const struct mid8250_board dnv_bo
+ .freq = 133333333,
+ .base_baud = 115200,
+ .bar = 1,
+- .setup = dnv_setup,
+- .exit = dnv_exit,
++ /*
++ * Errata:
++ * HSUART May Stop Functioning when DMA is Active.
++ *
++ * - Denverton document #572409, rev 3.4, DNV60
++ * - Ice Lake Xeon D document #714070, ICXD65
++ * - Snowridge document #731931, SNR44
++ */
++ .setup = PTR_IF(false, dnv_setup),
++ .exit = PTR_IF(false, dnv_exit),
+ };
+
+ #define MID_DEVICE(id, board) { PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&board }
--- /dev/null
+From stable+bounces-277238-greg=kroah.com@vger.kernel.org Sat Jul 18 03:33:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 21:33:37 -0400
+Subject: serial: 8250_mid: Remove 8250_pci usage
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260718013338.2621443-1-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit a136abd7e7abe0f1247f8ffde6cc7c8ab09f985b ]
+
+8250_mid uses FL_*BASE* from linux/8250_pci.h and nothing else. The
+code can be simplified by directly defining BARs within the driver
+instead.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20230915094336.13278-1-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: b1b4efea05a5 ("serial: 8250_mid: Disable DMA for selected platforms")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250_mid.c | 18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_mid.c
++++ b/drivers/tty/serial/8250/8250_mid.c
+@@ -12,7 +12,6 @@
+ #include <linux/rational.h>
+
+ #include <linux/dma/hsu.h>
+-#include <linux/8250_pci.h>
+
+ #include "8250.h"
+
+@@ -32,9 +31,9 @@
+ struct mid8250;
+
+ struct mid8250_board {
+- unsigned int flags;
+ unsigned long freq;
+ unsigned int base_baud;
++ unsigned int bar;
+ int (*setup)(struct mid8250 *, struct uart_port *p);
+ void (*exit)(struct mid8250 *);
+ };
+@@ -169,7 +168,6 @@ static int dnv_setup(struct mid8250 *mid
+ {
+ struct hsu_dma_chip *chip = &mid->dma_chip;
+ struct pci_dev *pdev = to_pci_dev(p->dev);
+- unsigned int bar = FL_GET_BASE(mid->board->flags);
+ int ret;
+
+ pci_set_master(pdev);
+@@ -183,7 +181,7 @@ static int dnv_setup(struct mid8250 *mid
+ chip->dev = &pdev->dev;
+ chip->irq = pci_irq_vector(pdev, 0);
+ chip->regs = p->membase;
+- chip->length = pci_resource_len(pdev, bar);
++ chip->length = pci_resource_len(pdev, mid->board->bar);
+ chip->offset = DNV_DMA_CHAN_OFFSET;
+
+ /* Falling back to PIO mode if DMA probing fails */
+@@ -292,7 +290,6 @@ static int mid8250_probe(struct pci_dev
+ {
+ struct uart_8250_port uart;
+ struct mid8250 *mid;
+- unsigned int bar;
+ int ret;
+
+ ret = pcim_enable_device(pdev);
+@@ -304,7 +301,6 @@ static int mid8250_probe(struct pci_dev
+ return -ENOMEM;
+
+ mid->board = (struct mid8250_board *)id->driver_data;
+- bar = FL_GET_BASE(mid->board->flags);
+
+ memset(&uart, 0, sizeof(struct uart_8250_port));
+
+@@ -317,8 +313,8 @@ static int mid8250_probe(struct pci_dev
+ uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+ uart.port.set_termios = mid8250_set_termios;
+
+- uart.port.mapbase = pci_resource_start(pdev, bar);
+- uart.port.membase = pcim_iomap(pdev, bar, 0);
++ uart.port.mapbase = pci_resource_start(pdev, mid->board->bar);
++ uart.port.membase = pcim_iomap(pdev, mid->board->bar, 0);
+ if (!uart.port.membase)
+ return -ENOMEM;
+
+@@ -356,25 +352,25 @@ static void mid8250_remove(struct pci_de
+ }
+
+ static const struct mid8250_board pnw_board = {
+- .flags = FL_BASE0,
+ .freq = 50000000,
+ .base_baud = 115200,
++ .bar = 0,
+ .setup = pnw_setup,
+ .exit = pnw_exit,
+ };
+
+ static const struct mid8250_board tng_board = {
+- .flags = FL_BASE0,
+ .freq = 38400000,
+ .base_baud = 1843200,
++ .bar = 0,
+ .setup = tng_setup,
+ .exit = tng_exit,
+ };
+
+ static const struct mid8250_board dnv_board = {
+- .flags = FL_BASE1,
+ .freq = 133333333,
+ .base_baud = 115200,
++ .bar = 1,
+ .setup = dnv_setup,
+ .exit = dnv_exit,
+ };
crypto-crypto4xx-remove-ahash-related-code.patch
crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch
batman-adv-clean-untagged-vlan-on-netdev-registration-failure.patch
+acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch
+iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch
+iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch
+iio-imu-inv_icm42600-make-timestamp-module-chip-independent.patch
+iio-move-inv_icm42600-timestamp-module-in-common.patch
+iio-make-invensense-timestamp-module-generic.patch
+iio-imu-inv_mpu6050-use-the-common-inv_sensors-timestamp-module.patch
+iio-invensense-remove-redundant-initialization-of-variable-period.patch
+iio-invensense-fix-timestamp-glitches-when-switching-frequency.patch
+iio-imu-inv_icm42600-stabilized-timestamp-in-interrupt.patch
+iio-imu-inv_icm42600-fix-timestamping-by-limiting-fifo-reading.patch
+bitops-make-bytes_to_bits-treewide-available.patch
+iio-common-st_sensors-honour-channel-endianness-in-read_axis_data.patch
+alsa-aoa-check-snd_ctl_new1-return-value.patch
+bluetooth-btintel-fix-offset-calculation-boot-address-parameter.patch
+bluetooth-btintel-check-firmware-version-before-download.patch
+bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch
+bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch
+vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch
+binder-fix-uaf-in-binder_free_transaction.patch
+pci-altera-fix-resource-leaks-on-probe-failure.patch
+media-atomisp-replace-boolean-comparison-of-values-with-bool-variables.patch
+media-staging-media-atomisp-fix-sh_css.c-brace-coding-style-issues.patch
+media-staging-media-atomisp-fix-the-rest-of-sh_css.c-brace-issues.patch
+media-staging-media-atomisp-replace-if-else-clause-with-a-ternary.patch
+media-staging-media-atomisp-fix-alignment-and-line-length-issues.patch
+staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch
+cifs-create-a-new-shared-file-holding-smb2-pdu-definitions.patch
+cifs-remove-check-of-list-iterator-against-head-past-the-loop-body.patch
+smb2-small-refactor-in-smb2_check_message.patch
+cifs-remove-unused-server-parameter-from-calc_smb_size.patch
+smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch
+pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch
+staging-rtl8723bs-split-too-long-line.patch
+staging-rtl8723bs-remove-commented-out-rt_assert-occurrences.patch
+staging-rtl8723bs-remove-all-5ghz-network-types.patch
+staging-rtl8723bs-remove-5ghz-code-related-to-channel-plan-definition.patch
+staging-rtl8723bs-remove-5ghz-code-blocks.patch
+staging-rtl8723bs-remove-commented-out-condition.patch
+staging-rtl8723bs-clean-up-comparsions-to-null.patch
+staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch
+staging-rtl8723bs-fix-space-issues.patch
+staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch
+staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch
+pci-controller-use-dev_fwnode-instead-of-of_fwnode_handle.patch
+pci-mediatek-convert-bool-to-single-quirks-entry-and-bitmap.patch
+pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch
+staging-rtl8723bs-remove-dbg_871x-log-argument.patch
+crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch
+pci-prevent-resource-tree-corruption-when-bar-resize-fails.patch
+pci-free-saved-list-without-holding-pci_bus_sem.patch
+pci-fix-restoring-bars-on-bar-resize-rollback-path.patch
+pci-add-kerneldoc-for-pci_resize_resource.patch
+pci-move-resizable-bar-code-to-rebar.c.patch
+pci-skip-resizable-bar-restore-on-read-error.patch
+coresight-etb10-restore-atomic_t-for-shared-reading-state.patch
+netfilter-ebtables-use-vmalloc_array-to-improve-code.patch
+netfilter-ebtables-zero-chainstack-array.patch
+bluetooth-l2cap-fix-not-tracking-outstanding-tx-ident.patch
+bluetooth-l2cap-fix-deadlock-in-l2cap_conn_del.patch
+bluetooth-l2cap-cancel-pending_rx_work-before-taking-conn-lock.patch
+smb-client-fix-next-buffer-leak-in-receive_encrypted_standard.patch
+smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch
+smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch
+smb-client-harden-posix-sid-length-parsing.patch
+writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch
+x.509-fix-validation-of-asn.1-certificate-header.patch
+proc-use-generic-setattr-for-proc-pid-net.patch
+proc-rename-proc_setattr-to-proc_nochmod_setattr.patch
+proc-protect-ptrace_may_access-with-exec_update_lock-fd-links.patch
+hid-add-haptics-page-defines.patch
+hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch
+cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch
+proc-protect-ptrace_may_access-with-exec_update_lock-part-1.patch
+hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch
+serial-8250_mid-remove-8250_pci-usage.patch
+serial-8250_mid-disable-dma-for-selected-platforms.patch
+xfs-reflect-sb-features-in-xfs_mount.patch
+xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch
+xfs-use-null-daddr-for-unset-first-bad-log-block.patch
+hfs-hfsplus-prevent-getting-negative-values-of-offset-length.patch
+hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch
+usb-gadget-function-simplify-diagnostic-messaging-in-printer.patch
+usb-gadget-f_printer-take-kref-only-for-successful-open.patch
+usb-free-iso-schedules-on-failed-submit.patch
+usb-iowarrior-remove-inherent-race-with-minor-number.patch
+usb-serial-digi_acceleport-fix-write-buffer-corruption.patch
+drm-i2c-sil164-drop-no-op-remove-function.patch
+leds-lm3697-remove-duplicated-error-reporting-in-.remove.patch
+leds-lm3601x-improve-error-reporting-for-problems-during-.remove.patch
+gpio-pca953x-make-platform-teardown-callback-return-void.patch
+usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch
+usb-atm-ueagle-atm-wait-for-pre-firmware-load-in-.disconnect.patch
+usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch
+usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch
+crypto-atmel-sha204a-mark-of-related-data-as-maybe-unused.patch
+crypto-atmel-drop-explicit-initialization-of-struct-i2c_device_id-driver_data-to-0.patch
+crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
+usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch
+btrfs-do-not-trim-a-device-which-is-not-writeable.patch
+crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch
+crypto-qat-validate-rsa-crt-component-lengths.patch
+audit-add-audit_log_nf_skb-helper-function.patch
+audit-fix-potential-integer-overflow-in-audit_log_n_hex.patch
--- /dev/null
+From stable+bounces-276753-greg=kroah.com@vger.kernel.org Thu Jul 16 18:51:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 11:36:57 -0400
+Subject: smb: client: Fix next buffer leak in receive_encrypted_standard()
+To: stable@vger.kernel.org
+Cc: Haoxiang Li <haoxiang_li2024@163.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716153657.582978-2-sashal@kernel.org>
+
+From: Haoxiang Li <haoxiang_li2024@163.com>
+
+[ Upstream commit 1c6267a1d5cf4c73b656f8181b310cbbb3e4767b ]
+
+receive_encrypted_standard() allocates next_buffer before checking
+whether the number of compound PDUs already reached MAX_COMPOUND. If
+the limit check fails, the function returns immediately and the newly
+allocated next_buffer is not assigned to server->smallbuf/server->bigbuf,
+making it leaked.
+
+Move the MAX_COMPOUND check before allocating next_buffer.
+
+Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses")
+Cc: stable@vger.kernel.org
+Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2ops.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -4961,6 +4961,12 @@ receive_encrypted_standard(struct TCP_Se
+ one_more:
+ shdr = (struct smb2_hdr *)buf;
+ next_cmd = le32_to_cpu(shdr->NextCommand);
++
++ if (*num_mids >= MAX_COMPOUND) {
++ cifs_server_dbg(VFS, "too many PDUs in compound\n");
++ return -1;
++ }
++
+ if (next_cmd) {
+ if (WARN_ON_ONCE(next_cmd > pdu_length))
+ return -1;
+@@ -4984,10 +4990,6 @@ one_more:
+ mid_entry->resp_buf_size = server->pdu_size;
+ }
+
+- if (*num_mids >= MAX_COMPOUND) {
+- cifs_server_dbg(VFS, "too many PDUs in compound\n");
+- return -1;
+- }
+ bufs[*num_mids] = buf;
+ mids[(*num_mids)++] = mid_entry;
+
--- /dev/null
+From stable+bounces-276773-greg=kroah.com@vger.kernel.org Thu Jul 16 18:32:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 12:28:12 -0400
+Subject: smb: client: harden POSIX SID length parsing
+To: stable@vger.kernel.org
+Cc: Zihan Xi <xizh2024@lzu.edu.cn>, Yuan Tan <yuantan098@gmail.com>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716162812.635414-1-sashal@kernel.org>
+
+From: Zihan Xi <xizh2024@lzu.edu.cn>
+
+[ Upstream commit 7ad2bcf2441430bb2e918fb3ef9a90d775a6e422 ]
+
+posix_info_sid_size() reads sid[1] to obtain the subauthority count,
+but its existing boundary check still accepts buffers with only one
+remaining byte. Require two bytes before reading sid[1] so all client
+paths that reuse the helper reject truncated POSIX SIDs safely.
+
+Fixes: 349e13ad30b4 ("cifs: add smb2 POSIX info level")
+Cc: stable@vger.kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -4518,7 +4518,7 @@ int posix_info_sid_size(const void *beg,
+ size_t subauth;
+ int total;
+
+- if (beg + 1 > end)
++ if (beg + 2 > end)
+ return -1;
+
+ subauth = *(u8 *)(beg+1);
--- /dev/null
+From stable+bounces-276771-greg=kroah.com@vger.kernel.org Thu Jul 16 19:13:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 12:28:08 -0400
+Subject: smb: client: mask server-provided mode to 07777 in modefromsid
+To: stable@vger.kernel.org
+Cc: Norbert Manthey <nmanthey@amazon.de>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716162808.635328-1-sashal@kernel.org>
+
+From: Norbert Manthey <nmanthey@amazon.de>
+
+[ Upstream commit e3d9c7160d483fc8f9e225aafad8ecbbc43f3151 ]
+
+When modefromsid is active, parse_dacl() applies the server-provided
+sub_auth[2] value from the NFS mode SID to cf_mode without masking to
+07777. Apply the correct masking, same as in the read path.
+
+Fixes: e2f8fbfb8d09c ("cifs: get mode bits from special sid on stat")
+Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
+Assisted-by: Kiro:claude-opus-4.6
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifsacl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -767,7 +767,7 @@ static void parse_dacl(struct cifs_acl *
+ */
+ fattr->cf_mode &= ~07777;
+ fattr->cf_mode |=
+- le32_to_cpu(ppace[i]->sid.sub_auth[2]);
++ le32_to_cpu(ppace[i]->sid.sub_auth[2]) & 07777;
+ break;
+ } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
+ access_flags_to_mode(ppace[i]->access_req,
--- /dev/null
+From stable+bounces-274573-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:05 -0400
+Subject: smb: client: restrict implied bcc[0] exemption to responses without data area
+To: stable@vger.kernel.org
+Cc: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-5-sashal@kernel.org>
+
+From: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+
+[ Upstream commit 53b7c271f06be4dd5cfc8c6ef552a8355c891a7f ]
+
+smb2_check_message() has a long-standing quirk that accepts a response
+whose calculated length is one byte larger than the bytes actually
+received ("server can return one byte more due to implied bcc[0]").
+This was introduced to accommodate servers that omit the trailing bcc[0]
+overlap byte when no data area is present.
+
+However, the exemption is applied unconditionally, regardless of whether
+the command actually carries a data area (has_smb2_data_area[]). When a
+response with a data area is subject to the +1 exemption, the reported
+data can extend one byte beyond the bytes actually received, yet
+smb2_check_message() still accepts it. The subsequent decoder then reads
+past the end of the receive buffer. This is reachable during NEGOTIATE
+and SESSION_SETUP, before the session is established.
+
+The resulting out-of-bounds reads are visible under KASAN when mounting
+against a non-conforming server; both the SPNEGO/negTokenInit and the
+NTLMSSP challenge decoders are affected:
+
+ BUG: KASAN: slab-out-of-bounds in asn1_ber_decoder+0x16a7/0x1b00
+ Read of size 1 at addr ffff8880084d67c0 by task mount.cifs/81
+ CPU: 1 UID: 0 PID: 81 Comm: mount.cifs Not tainted 7.1.0-rc6 #1
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x4e/0x70
+ print_report+0x157/0x4c9
+ kasan_report+0xce/0x100
+ asn1_ber_decoder+0x16a7/0x1b00
+ decode_negTokenInit+0x19/0x30
+ SMB2_negotiate+0x31d9/0x4c90
+ cifs_negotiate_protocol+0x1f2/0x3f0
+ cifs_get_smb_ses+0x93f/0x17e0
+ cifs_mount_get_session+0x7f/0x3a0
+ cifs_mount+0xb4/0xcf0
+ cifs_smb3_do_mount+0x23a/0x1500
+ smb3_get_tree+0x3b0/0x630
+ vfs_get_tree+0x82/0x2d0
+ fc_mount+0x10/0x1b0
+ path_mount+0x50d/0x1de0
+ __x64_sys_mount+0x20b/0x270
+ do_syscall_64+0xee/0x590
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+ Allocated by task 85:
+ kmem_cache_alloc_noprof+0x106/0x380
+ mempool_alloc_noprof+0x116/0x1e0
+ cifs_small_buf_get+0x31/0x80
+ allocate_buffers+0x10d/0x2b0
+ cifs_demultiplex_thread+0x1d5/0x1d50
+ kthread+0x2c6/0x390
+ ret_from_fork+0x36e/0x5a0
+ ret_from_fork_asm+0x1a/0x30
+ The buggy address is located 0 bytes to the right of
+ allocated 448-byte region [ffff8880084d6600, ffff8880084d67c0)
+ which belongs to the cache cifs_small_rq of size 448
+
+ BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x36/0x50
+ Read of size 329 at addr ffff88800726c678 by task mount.cifs/89
+ CPU: 0 UID: 0 PID: 89 Comm: mount.cifs Tainted: G B 7.1.0-rc6 #1
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x4e/0x70
+ print_report+0x157/0x4c9
+ kasan_report+0xce/0x100
+ kasan_check_range+0x10f/0x1e0
+ __asan_memcpy+0x23/0x60
+ kmemdup_noprof+0x36/0x50
+ decode_ntlmssp_challenge+0x457/0x680
+ SMB2_sess_auth_rawntlmssp_negotiate+0x6f0/0xcb0
+ SMB2_sess_setup+0x219/0x4f0
+ cifs_setup_session+0x248/0xaf0
+ cifs_get_smb_ses+0xf79/0x17e0
+ cifs_mount_get_session+0x7f/0x3a0
+ cifs_mount+0xb4/0xcf0
+ cifs_smb3_do_mount+0x23a/0x1500
+ smb3_get_tree+0x3b0/0x630
+ vfs_get_tree+0x82/0x2d0
+ fc_mount+0x10/0x1b0
+ path_mount+0x50d/0x1de0
+ __x64_sys_mount+0x20b/0x270
+ do_syscall_64+0xee/0x590
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+ Allocated by task 93:
+ kmem_cache_alloc_noprof+0x106/0x380
+ mempool_alloc_noprof+0x116/0x1e0
+ cifs_small_buf_get+0x31/0x80
+ allocate_buffers+0x10d/0x2b0
+ cifs_demultiplex_thread+0x1d5/0x1d50
+ kthread+0x2c6/0x390
+ ret_from_fork+0x36e/0x5a0
+ ret_from_fork_asm+0x1a/0x30
+ The buggy address is located 120 bytes inside of
+ allocated 448-byte region [ffff88800726c600, ffff88800726c7c0)
+ which belongs to the cache cifs_small_rq of size 448
+
+Restrict the +1 exemption to responses that have no data area, so that
+it still covers the bcc[0] omission it was meant for. When a data area
+is present, the +1 discrepancy instead means the reported data length
+overruns the received buffer, so the response must be rejected.
+
+Fixes: 093b2bdad322 ("CIFS: Make demultiplex_thread work with SMB2 code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2misc.c | 32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -30,6 +30,8 @@
+ #include "smb2glob.h"
+ #include "nterr.h"
+
++static unsigned int __smb2_calc_size(void *buf, bool *have_data);
++
+ static int
+ check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
+ {
+@@ -145,6 +147,7 @@ smb2_check_message(char *buf, unsigned i
+ int command;
+ __u32 calc_len; /* calculated length */
+ __u64 mid;
++ bool have_data;
+
+ /*
+ * Add function to do table lookup of StructureSize by command
+@@ -225,7 +228,8 @@ smb2_check_message(char *buf, unsigned i
+ }
+ }
+
+- calc_len = smb2_calc_size(buf);
++ have_data = false;
++ calc_len = __smb2_calc_size(buf, &have_data);
+
+ /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
+ * be 0, and not a real miscalculation */
+@@ -243,8 +247,13 @@ smb2_check_message(char *buf, unsigned i
+ /* Windows 7 server returns 24 bytes more */
+ if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
+ return 0;
+- /* server can return one byte more due to implied bcc[0] */
+- if (calc_len == len + 1)
++ /*
++ * Server can return one byte more due to implied bcc[0].
++ * Allow it only when there is no data area; if data_length > 0
++ * the +1 gap indicates an overreported data length rather than
++ * the bcc[0] omission.
++ */
++ if (calc_len == len + 1 && !have_data)
+ return 0;
+
+ /*
+@@ -405,14 +414,17 @@ smb2_get_data_area_len(int *off, int *le
+ /*
+ * Calculate the size of the SMB message based on the fixed header
+ * portion, the number of word parameters and the data portion of the message.
++ * If have_data is non-NULL, it is set to true when a non-empty data area was
++ * found (data_length > 0), allowing callers to distinguish the implied bcc[0]
++ * case (no data area) from an overreported data length.
+ */
+-unsigned int
+-smb2_calc_size(void *buf)
++static unsigned int
++__smb2_calc_size(void *buf, bool *have_data)
+ {
+ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+ struct smb2_hdr *shdr = &pdu->hdr;
+ int offset; /* the offset from the beginning of SMB to data area */
+- int data_length; /* the length of the variable length data area */
++ int data_length = 0; /* the length of the variable length data area */
+ /* Structure Size has already been checked to make sure it is 64 */
+ int len = le16_to_cpu(shdr->StructureSize);
+
+@@ -445,9 +457,17 @@ smb2_calc_size(void *buf)
+ }
+ calc_size_exit:
+ cifs_dbg(FYI, "SMB2 len %d\n", len);
++ if (have_data)
++ *have_data = (data_length > 0);
+ return len;
+ }
+
++unsigned int
++smb2_calc_size(void *buf)
++{
++ return __smb2_calc_size(buf, NULL);
++}
++
+ /* Note: caller must free return buffer */
+ __le16 *
+ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
--- /dev/null
+From stable+bounces-276772-greg=kroah.com@vger.kernel.org Thu Jul 16 18:33:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 12:28:10 -0400
+Subject: smb: client: use unaligned reads in parse_posix_ctxt()
+To: stable@vger.kernel.org
+Cc: Zihan Xi <xizh2024@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716162810.635369-1-sashal@kernel.org>
+
+From: Zihan Xi <xizh2024@lzu.edu.cn>
+
+[ Upstream commit b86467cd2691192ad4809a5a6e922fc24b8e9839 ]
+
+The server controls create-context DataOffset, so the POSIX context data
+pointer may be misaligned on strict-alignment architectures. Use
+get_unaligned_le32() when reading nlink, reparse_tag, and mode.
+
+Fixes: 69dda3059e7a ("cifs: add SMB2_open() arg to return POSIX data")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1973,9 +1973,9 @@ parse_posix_ctxt(struct create_context *
+
+ memset(posix, 0, sizeof(*posix));
+
+- posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
+- posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
+- posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
++ posix->nlink = get_unaligned_le32(beg);
++ posix->reparse_tag = get_unaligned_le32(beg + 4);
++ posix->mode = get_unaligned_le32(beg + 8);
+
+ sid = beg + 12;
+ sid_len = posix_info_sid_size(sid, end);
--- /dev/null
+From stable+bounces-274569-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:03 -0400
+Subject: smb2: small refactor in smb2_check_message()
+To: stable@vger.kernel.org
+Cc: Enzo Matsumiya <ematsumiya@suse.de>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-3-sashal@kernel.org>
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+[ Upstream commit da3847894fddc27ca95d5ac0012f444a77a5e0c3 ]
+
+If the command is SMB2_IOCTL, OutputLength and OutputContext are
+optional and can be zero, so return early and skip calculated length
+check.
+
+Move the mismatched length message to the end of the check, to avoid
+unnecessary logs when the check was not a real miscalculation.
+
+Also change the pr_warn_once() to a pr_warn() so we're sure to get a
+log for the real mismatches.
+
+Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/connect.c | 13 ++++++-------
+ fs/cifs/smb2misc.c | 47 ++++++++++++++++++++++++++++-------------------
+ 2 files changed, 34 insertions(+), 26 deletions(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1012,19 +1012,18 @@ int
+ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+ {
+ char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
+- int length;
++ int rc;
+
+ /*
+ * We know that we received enough to get to the MID as we
+ * checked the pdu_length earlier. Now check to see
+- * if the rest of the header is OK. We borrow the length
+- * var for the rest of the loop to avoid a new stack var.
++ * if the rest of the header is OK.
+ *
+ * 48 bytes is enough to display the header and a little bit
+ * into the payload for debugging purposes.
+ */
+- length = server->ops->check_message(buf, server->total_read, server);
+- if (length != 0)
++ rc = server->ops->check_message(buf, server->total_read, server);
++ if (rc)
+ cifs_dump_mem("Bad SMB: ", buf,
+ min_t(unsigned int, server->total_read, 48));
+
+@@ -1039,9 +1038,9 @@ cifs_handle_standard(struct TCP_Server_I
+ return -1;
+
+ if (!mid)
+- return length;
++ return rc;
+
+- handle_mid(mid, server, buf, length);
++ handle_mid(mid, server, buf, rc);
+ return 0;
+ }
+
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -136,15 +136,15 @@ static __u32 get_neg_ctxt_len(struct smb
+ }
+
+ int
+-smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
++smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ {
+ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+ struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
+- __u64 mid;
+- __u32 clc_len; /* calculated length */
+- int command;
+- int pdu_size = sizeof(struct smb2_pdu);
+ int hdr_size = sizeof(struct smb2_hdr);
++ int pdu_size = sizeof(struct smb2_pdu);
++ int command;
++ __u32 calc_len; /* calculated length */
++ __u64 mid;
+
+ /*
+ * Add function to do table lookup of StructureSize by command
+@@ -158,7 +158,7 @@ smb2_check_message(char *buf, unsigned i
+
+ /* decrypt frame now that it is completely read in */
+ spin_lock(&cifs_tcp_ses_lock);
+- list_for_each_entry(iter, &srvr->smb_ses_list, smb_ses_list) {
++ list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
+ if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
+ ses = iter;
+ break;
+@@ -225,30 +225,33 @@ smb2_check_message(char *buf, unsigned i
+ }
+ }
+
+- clc_len = smb2_calc_size(buf, srvr);
++ calc_len = smb2_calc_size(buf, server);
++
++ /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
++ * be 0, and not a real miscalculation */
++ if (command == SMB2_IOCTL_HE && calc_len == 0)
++ return 0;
+
+- if (shdr->Command == SMB2_NEGOTIATE)
+- clc_len += get_neg_ctxt_len(shdr, len, clc_len);
++ if (command == SMB2_NEGOTIATE_HE)
++ calc_len += get_neg_ctxt_len(shdr, len, calc_len);
+
+- if (len != clc_len) {
+- cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
+- clc_len, len, mid);
++ if (len != calc_len) {
+ /* create failed on symlink */
+ if (command == SMB2_CREATE_HE &&
+ shdr->Status == STATUS_STOPPED_ON_SYMLINK)
+ return 0;
+ /* Windows 7 server returns 24 bytes more */
+- if (clc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
++ if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
+ return 0;
+ /* server can return one byte more due to implied bcc[0] */
+- if (clc_len == len + 1)
++ if (calc_len == len + 1)
+ return 0;
+
+ /*
+ * Some windows servers (win2016) will pad also the final
+ * PDU in a compound to 8 bytes.
+ */
+- if (((clc_len + 7) & ~7) == len)
++ if (((calc_len + 7) & ~7) == len)
+ return 0;
+
+ /*
+@@ -257,12 +260,18 @@ smb2_check_message(char *buf, unsigned i
+ * SMB2/SMB3 frame length (header + smb2 response specific data)
+ * Some windows servers also pad up to 8 bytes when compounding.
+ */
+- if (clc_len < len)
++ if (calc_len < len)
+ return 0;
+
+- pr_warn_once(
+- "srv rsp too short, len %d not %d. cmd:%d mid:%llu\n",
+- len, clc_len, command, mid);
++ /* Only log a message if len was really miscalculated */
++ if (unlikely(cifsFYI))
++ cifs_dbg(FYI, "Server response too short: calculated "
++ "length %u doesn't match read length %u (cmd=%d, mid=%llu)\n",
++ calc_len, len, command, mid);
++ else
++ pr_warn("Server response too short: calculated length "
++ "%u doesn't match read length %u (cmd=%d, mid=%llu)\n",
++ calc_len, len, command, mid);
+
+ return 1;
+ }
--- /dev/null
+From stable+bounces-274529-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:58 -0400
+Subject: staging: media: atomisp: reduce load_primary_binaries() stack usage
+To: stable@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>, Andy Shevchenko <andriy.shevchenko@intel.com>, Sakari Ailus <sakari.ailus@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-6-sashal@kernel.org>
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit f4d51e55dd47ef467fbe37d8575e20eee41b092d ]
+
+The load_primary_binaries() function is overly complex and has som large
+variables on the stack, which can cause warnings depending on CONFIG_FRAME_WARN
+setting:
+
+drivers/staging/media/atomisp/pci/sh_css.c: In function 'load_primary_binaries':
+drivers/staging/media/atomisp/pci/sh_css.c:5260:1: error: the frame size of 1560 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
+
+Half of the stack usage is for the prim_descr[] array, but only one
+member of the array is used at any given time.
+
+Reduce the stack usage by turning the array into a single structure.
+
+Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -5870,7 +5870,6 @@ static int load_primary_binaries(
+ struct ia_css_capture_settings *mycs;
+ unsigned int i;
+ bool need_extra_yuv_scaler = false;
+- struct ia_css_binary_descr prim_descr[MAX_NUM_PRIMARY_STAGES];
+
+ IA_CSS_ENTER_PRIVATE("");
+ assert(pipe);
+@@ -6058,15 +6057,16 @@ static int load_primary_binaries(
+
+ /* Primary */
+ for (i = 0; i < mycs->num_primary_stage; i++) {
++ struct ia_css_binary_descr prim_descr;
+ struct ia_css_frame_info *local_vf_info = NULL;
+
+ if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
+ (i == mycs->num_primary_stage - 1))
+ local_vf_info = &vf_info;
+- ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i],
++ ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr,
+ &prim_in_info, &prim_out_info,
+ local_vf_info, i);
+- err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
++ err = ia_css_binary_find(&prim_descr, &mycs->primary_binary[i]);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
--- /dev/null
+From stable+bounces-274606-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:06 -0400
+Subject: staging: rtl8723bs: clean up comparsions to NULL
+To: stable@vger.kernel.org
+Cc: Michael Straube <straube.linux@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-7-sashal@kernel.org>
+
+From: Michael Straube <straube.linux@gmail.com>
+
+[ Upstream commit cd1f1450092216b3e39516f8db58869b6fc20575 ]
+
+Clean up comparsions to NULL reported by checkpatch.
+
+x == NULL -> !x
+x != NULL -> x
+
+Signed-off-by: Michael Straube <straube.linux@gmail.com>
+Link: https://lore.kernel.org/r/20210829154533.11054-1-straube.linux@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_ap.c | 20 ++--
+ drivers/staging/rtl8723bs/core/rtw_cmd.c | 96 +++++++++++-----------
+ drivers/staging/rtl8723bs/core/rtw_ioctl_set.c | 4
+ drivers/staging/rtl8723bs/core/rtw_mlme.c | 6 -
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 56 ++++++------
+ drivers/staging/rtl8723bs/core/rtw_security.c | 6 -
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 24 ++---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 18 ++--
+ drivers/staging/rtl8723bs/os_dep/os_intfs.c | 4
+ 9 files changed, 117 insertions(+), 117 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
+@@ -1033,7 +1033,7 @@ int rtw_check_beacon_data(struct adapter
+ &ie_len,
+ (pbss_network->IELength - _BEACON_IE_OFFSET_)
+ );
+- if (p != NULL) {
++ if (p) {
+ memcpy(supportRate, p + 2, ie_len);
+ supportRateNum = ie_len;
+ }
+@@ -1045,7 +1045,7 @@ int rtw_check_beacon_data(struct adapter
+ &ie_len,
+ pbss_network->IELength - _BEACON_IE_OFFSET_
+ );
+- if (p != NULL) {
++ if (p) {
+ memcpy(supportRate + supportRateNum, p + 2, ie_len);
+ supportRateNum += ie_len;
+ }
+@@ -1133,7 +1133,7 @@ int rtw_check_beacon_data(struct adapter
+ break;
+ }
+
+- if ((p == NULL) || (ie_len == 0))
++ if (!p || ie_len == 0)
+ break;
+ }
+
+@@ -1162,7 +1162,7 @@ int rtw_check_beacon_data(struct adapter
+ break;
+ }
+
+- if ((p == NULL) || (ie_len == 0))
++ if (!p || ie_len == 0)
+ break;
+ }
+ }
+@@ -1290,7 +1290,7 @@ int rtw_check_beacon_data(struct adapter
+ psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
+ if (!psta) {
+ psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
+- if (psta == NULL)
++ if (!psta)
+ return _FAIL;
+ }
+
+@@ -1447,7 +1447,7 @@ u8 rtw_ap_set_pairwise_key(struct adapte
+ }
+
+ psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+- if (psetstakey_para == NULL) {
++ if (!psetstakey_para) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1485,12 +1485,12 @@ static int rtw_ap_set_key(
+ /* DBG_871X("%s\n", __func__); */
+
+ pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmd == NULL) {
++ if (!pcmd) {
+ res = _FAIL;
+ goto exit;
+ }
+ psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
+- if (psetkeyparm == NULL) {
++ if (!psetkeyparm) {
+ kfree(pcmd);
+ res = _FAIL;
+ goto exit;
+@@ -1662,11 +1662,11 @@ static void update_bcn_wps_ie(struct ada
+ &wps_ielen
+ );
+
+- if (pwps_ie == NULL || wps_ielen == 0)
++ if (!pwps_ie || wps_ielen == 0)
+ return;
+
+ pwps_ie_src = pmlmepriv->wps_beacon_ie;
+- if (pwps_ie_src == NULL)
++ if (!pwps_ie_src)
+ return;
+
+ wps_offset = (uint)(pwps_ie - ie);
+--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
++++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+@@ -259,7 +259,7 @@ int _rtw_enqueue_cmd(struct __queue *que
+ {
+ _irqL irqL;
+
+- if (obj == NULL)
++ if (!obj)
+ goto exit;
+
+ /* spin_lock_bh(&queue->lock); */
+@@ -335,7 +335,7 @@ int rtw_enqueue_cmd(struct cmd_priv *pcm
+ int res = _FAIL;
+ struct adapter *padapter = pcmdpriv->padapter;
+
+- if (cmd_obj == NULL) {
++ if (!cmd_obj) {
+ goto exit;
+ }
+
+@@ -509,7 +509,7 @@ post_process:
+ /* call callback function for post-processed */
+ if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
+ pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
+- if (pcmd_callback == NULL) {
++ if (!pcmd_callback) {
+ RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode));
+ rtw_free_cmd_obj(pcmd);
+ } else {
+@@ -530,7 +530,7 @@ post_process:
+ /* free all cmd_obj resources */
+ do {
+ pcmd = rtw_dequeue_cmd(pcmdpriv);
+- if (pcmd == NULL) {
++ if (!pcmd) {
+ rtw_unregister_cmd_alive(padapter);
+ break;
+ }
+@@ -572,11 +572,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *p
+ }
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL)
++ if (!ph2c)
+ return _FAIL;
+
+ psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
+- if (psurveyPara == NULL) {
++ if (!psurveyPara) {
+ kfree(ph2c);
+ return _FAIL;
+ }
+@@ -640,13 +640,13 @@ u8 rtw_setdatarate_cmd(struct adapter *p
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pbsetdataratepara = rtw_zmalloc(sizeof(struct setdatarate_parm));
+- if (pbsetdataratepara == NULL) {
++ if (!pbsetdataratepara) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -683,7 +683,7 @@ u8 rtw_createbss_cmd(struct adapter *pa
+ }
+
+ pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmd == NULL) {
++ if (!pcmd) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -716,7 +716,7 @@ int rtw_startbss_cmd(struct adapter *pa
+ } else {
+ /* need enqueue, prepare cmd_obj and enqueue */
+ pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmd == NULL) {
++ if (!pcmd) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -774,7 +774,7 @@ u8 rtw_joinbss_cmd(struct adapter *pada
+ }
+
+ pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmd == NULL) {
++ if (!pcmd) {
+ res = _FAIL;
+ RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
+ goto exit;
+@@ -891,7 +891,7 @@ u8 rtw_disassoc_cmd(struct adapter *pada
+
+ /* prepare cmd parameter */
+ param = rtw_zmalloc(sizeof(*param));
+- if (param == NULL) {
++ if (!param) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -900,7 +900,7 @@ u8 rtw_disassoc_cmd(struct adapter *pada
+ if (enqueue) {
+ /* need enqueue, prepare cmd_obj and enqueue */
+ cmdobj = rtw_zmalloc(sizeof(*cmdobj));
+- if (cmdobj == NULL) {
++ if (!cmdobj) {
+ res = _FAIL;
+ kfree(param);
+ goto exit;
+@@ -928,7 +928,7 @@ u8 rtw_setopmode_cmd(struct adapter *pa
+
+ psetop = rtw_zmalloc(sizeof(struct setopmode_parm));
+
+- if (psetop == NULL) {
++ if (!psetop) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -936,7 +936,7 @@ u8 rtw_setopmode_cmd(struct adapter *pa
+
+ if (enqueue) {
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ kfree(psetop);
+ res = _FAIL;
+ goto exit;
+@@ -964,7 +964,7 @@ u8 rtw_setstakey_cmd(struct adapter *pad
+ u8 res = _SUCCESS;
+
+ psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+- if (psetstakey_para == NULL) {
++ if (!psetstakey_para) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -988,14 +988,14 @@ u8 rtw_setstakey_cmd(struct adapter *pad
+
+ if (enqueue) {
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ kfree(psetstakey_para);
+ res = _FAIL;
+ goto exit;
+ }
+
+ psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
+- if (psetstakey_rsp == NULL) {
++ if (!psetstakey_rsp) {
+ kfree(ph2c);
+ kfree(psetstakey_para);
+ res = _FAIL;
+@@ -1031,20 +1031,20 @@ u8 rtw_clearstakey_cmd(struct adapter *p
+ }
+ } else {
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+- if (psetstakey_para == NULL) {
++ if (!psetstakey_para) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+ }
+
+ psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
+- if (psetstakey_rsp == NULL) {
++ if (!psetstakey_rsp) {
+ kfree(ph2c);
+ kfree(psetstakey_para);
+ res = _FAIL;
+@@ -1076,13 +1076,13 @@ u8 rtw_addbareq_cmd(struct adapter *pada
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm));
+- if (paddbareq_parm == NULL) {
++ if (!paddbareq_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1110,13 +1110,13 @@ u8 rtw_reset_securitypriv_cmd(struct ada
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1145,13 +1145,13 @@ u8 rtw_free_assoc_resources_cmd(struct a
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1181,13 +1181,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter
+
+ /* only primary padapter does this cmd */
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1231,7 +1231,7 @@ u8 rtw_set_chplan_cmd(struct adapter *pa
+
+ /* prepare cmd parameter */
+ setChannelPlan_param = rtw_zmalloc(sizeof(struct SetChannelPlan_param));
+- if (setChannelPlan_param == NULL) {
++ if (!setChannelPlan_param) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -1240,7 +1240,7 @@ u8 rtw_set_chplan_cmd(struct adapter *pa
+ if (enqueue) {
+ /* need enqueue, prepare cmd_obj and enqueue */
+ pcmdobj = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmdobj == NULL) {
++ if (!pcmdobj) {
+ kfree(setChannelPlan_param);
+ res = _FAIL;
+ goto exit;
+@@ -1501,13 +1501,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *p
+
+ if (enqueue) {
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1543,13 +1543,13 @@ u8 rtw_dm_in_lps_wk_cmd(struct adapter *
+
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1616,13 +1616,13 @@ u8 rtw_dm_ra_mask_wk_cmd(struct adapter
+
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1651,13 +1651,13 @@ u8 rtw_ps_cmd(struct adapter *padapter)
+ u8 res = _SUCCESS;
+
+ ppscmd = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ppscmd == NULL) {
++ if (!ppscmd) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ppscmd);
+ res = _FAIL;
+ goto exit;
+@@ -1723,13 +1723,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1817,13 +1817,13 @@ u8 rtw_c2h_packet_wk_cmd(struct adapter
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -1852,13 +1852,13 @@ u8 rtw_c2h_wk_cmd(struct adapter *padapt
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+- if (pdrvextra_cmd_parm == NULL) {
++ if (!pdrvextra_cmd_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -2036,7 +2036,7 @@ void rtw_createbss_cmd_callback(struct a
+ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
+ struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
+
+- if (pcmd->parmbuf == NULL)
++ if (!pcmd->parmbuf)
+ goto exit;
+
+ if ((pcmd->res != H2C_SUCCESS)) {
+@@ -2063,9 +2063,9 @@ void rtw_createbss_cmd_callback(struct a
+ } else {
+ pwlan = rtw_alloc_network(pmlmepriv);
+ spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
+- if (pwlan == NULL) {
++ if (!pwlan) {
+ pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
+- if (pwlan == NULL) {
++ if (!pwlan) {
+ RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n"));
+ spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
+ goto createbss_cmd_fail;
+--- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
+@@ -508,7 +508,7 @@ u8 rtw_set_802_11_bssid_list_scan(struct
+
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
+
+- if (padapter == NULL) {
++ if (!padapter) {
+ res = false;
+ goto exit;
+ }
+@@ -649,7 +649,7 @@ u16 rtw_get_cur_max_rate(struct adapter
+ return 0;
+
+ psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+- if (psta == NULL)
++ if (!psta)
+ return 0;
+
+ short_GI = query_ra_short_GI(psta);
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+@@ -472,7 +472,7 @@ struct wlan_network *rtw_get_oldest_wlan
+ pwlan = LIST_CONTAINOR(plist, struct wlan_network, list);
+
+ if (!pwlan->fixed) {
+- if (oldest == NULL || time_after(oldest->last_scanned, pwlan->last_scanned))
++ if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
+ oldest = pwlan;
+ }
+
+@@ -603,7 +603,7 @@ void rtw_update_scanned_network(struct a
+ /* TODO: don't select netowrk in the same ess as oldest if it's new enough*/
+ }
+
+- if (oldest == NULL || time_after(oldest->last_scanned, pnetwork->last_scanned))
++ if (!oldest || time_after(oldest->last_scanned, pnetwork->last_scanned))
+ oldest = pnetwork;
+
+ plist = get_next(plist);
+@@ -2023,7 +2023,7 @@ static int rtw_check_join_candidate(stru
+ goto exit;
+ }
+
+- if (*candidate == NULL || (*candidate)->network.Rssi < competitor->network.Rssi) {
++ if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) {
+ *candidate = competitor;
+ updated = true;
+ }
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -934,12 +934,12 @@ unsigned int OnAuth(struct adapter *pada
+ }
+
+ pstat = rtw_get_stainfo(pstapriv, sa);
+- if (pstat == NULL) {
++ if (!pstat) {
+
+ /* allocate a new one */
+ DBG_871X("going to alloc stainfo for sa ="MAC_FMT"\n", MAC_ARG(sa));
+ pstat = rtw_alloc_stainfo(pstapriv, sa);
+- if (pstat == NULL) {
++ if (!pstat) {
+ DBG_871X(" Exceed the upper limit of supported clients...\n");
+ status = _STATS_UNABLE_HANDLE_STA_;
+ goto auth_fail;
+@@ -1014,7 +1014,7 @@ unsigned int OnAuth(struct adapter *pada
+ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
+ len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
+
+- if ((p == NULL) || (ie_len <= 0)) {
++ if (!p || ie_len <= 0) {
+ DBG_871X("auth rejected because challenge failure!(1)\n");
+ status = _STATS_CHALLENGE_FAIL_;
+ goto auth_fail;
+@@ -1255,7 +1255,7 @@ unsigned int OnAssocReq(struct adapter *
+
+ /* check if the supported rate is ok */
+ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
+- if (p == NULL) {
++ if (!p) {
+ DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
+ /* use our own rate set as statoin used */
+ /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
+@@ -1272,7 +1272,7 @@ unsigned int OnAssocReq(struct adapter *
+
+ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
+ pkt_len - WLAN_HDR_A3_LEN - ie_offset);
+- if (p != NULL) {
++ if (p) {
+
+ if (supportRateNum + ie_len <= sizeof(supportRate)) {
+ memcpy(supportRate+supportRateNum, p+2, ie_len);
+@@ -1538,7 +1538,7 @@ unsigned int OnAssocReq(struct adapter *
+ DBG_871X(" old AID %d\n", pstat->aid);
+ } else {
+ for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
+- if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
++ if (!pstapriv->sta_aid[pstat->aid - 1])
+ break;
+
+ /* if (pstat->aid > NUM_STA) { */
+@@ -2226,7 +2226,7 @@ static struct xmit_frame *_alloc_mgtxmit
+ }
+
+ pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
+- if (pxmitbuf == NULL) {
++ if (!pxmitbuf) {
+ DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ pmgntframe = NULL;
+@@ -2596,7 +2596,7 @@ void issue_probersp(struct adapter *pada
+
+ /* DBG_871X("%s\n", __func__); */
+
+- if (da == NULL)
++ if (!da)
+ return;
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+@@ -2961,7 +2961,7 @@ void issue_auth(struct adapter *padapter
+ __le16 le_tmp;
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL)
++ if (!pmgntframe)
+ return;
+
+ /* update attribute */
+@@ -3097,7 +3097,7 @@ void issue_asocrsp(struct adapter *padap
+ DBG_871X("%s\n", __func__);
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL)
++ if (!pmgntframe)
+ return;
+
+ /* update attribute */
+@@ -3185,7 +3185,7 @@ void issue_asocrsp(struct adapter *padap
+ break;
+ }
+
+- if ((pbuf == NULL) || (ie_len == 0)) {
++ if (!pbuf || ie_len == 0) {
+ break;
+ }
+ }
+@@ -3229,7 +3229,7 @@ void issue_assocreq(struct adapter *pada
+ u8 vs_ie_length = 0;
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL)
++ if (!pmgntframe)
+ goto exit;
+
+ /* update attribute */
+@@ -3420,7 +3420,7 @@ static int _issue_nulldata(struct adapte
+ pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL)
++ if (!pmgntframe)
+ goto exit;
+
+ /* update attribute */
+@@ -3573,7 +3573,7 @@ static int _issue_qos_nulldata(struct ad
+ DBG_871X("%s\n", __func__);
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL)
++ if (!pmgntframe)
+ goto exit;
+
+ /* update attribute */
+@@ -3698,7 +3698,7 @@ static int _issue_deauth(struct adapter
+ /* DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL) {
++ if (!pmgntframe) {
+ goto exit;
+ }
+
+@@ -4047,7 +4047,7 @@ static void issue_action_BSSCoexistPacke
+ action = ACT_PUBLIC_BSSCOEXIST;
+
+ pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+- if (pmgntframe == NULL) {
++ if (!pmgntframe) {
+ return;
+ }
+
+@@ -4114,7 +4114,7 @@ static void issue_action_BSSCoexistPacke
+ pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
+
+ p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
+- if ((p == NULL) || (len == 0)) {/* non-HT */
++ if (!p || len == 0) {/* non-HT */
+
+ if (pbss_network->Configuration.DSConfig <= 0)
+ continue;
+@@ -4177,7 +4177,7 @@ unsigned int send_delba(struct adapter *
+ return _SUCCESS;
+
+ psta = rtw_get_stainfo(pstapriv, addr);
+- if (psta == NULL)
++ if (!psta)
+ return _SUCCESS;
+
+ /* DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR"); */
+@@ -5153,13 +5153,13 @@ void report_del_sta_event(struct adapter
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmd_obj == NULL) {
++ if (!pcmd_obj) {
+ return;
+ }
+
+ cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
+ pevtcmd = rtw_zmalloc(cmdsz);
+- if (pevtcmd == NULL) {
++ if (!pevtcmd) {
+ kfree(pcmd_obj);
+ return;
+ }
+@@ -5207,12 +5207,12 @@ void report_add_sta_event(struct adapter
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (pcmd_obj == NULL)
++ if (!pcmd_obj)
+ return;
+
+ cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
+ pevtcmd = rtw_zmalloc(cmdsz);
+- if (pevtcmd == NULL) {
++ if (!pevtcmd) {
+ kfree(pcmd_obj);
+ return;
+ }
+@@ -5732,12 +5732,12 @@ void survey_timer_hdl(struct timer_list
+ }
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ goto exit_survey_timer_hdl;
+ }
+
+ psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
+- if (psurveyPara == NULL) {
++ if (!psurveyPara) {
+ kfree(ph2c);
+ goto exit_survey_timer_hdl;
+ }
+@@ -6467,7 +6467,7 @@ u8 chk_bmc_sleepq_cmd(struct adapter *pa
+ u8 res = _SUCCESS;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+@@ -6491,13 +6491,13 @@ u8 set_tx_beacon_cmd(struct adapter *pad
+ int len_diff = 0;
+
+ ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+- if (ph2c == NULL) {
++ if (!ph2c) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param));
+- if (ptxBeacon_parm == NULL) {
++ if (!ptxBeacon_parm) {
+ kfree(ph2c);
+ res = _FAIL;
+ goto exit;
+@@ -6529,7 +6529,7 @@ u8 mlme_evt_hdl(struct adapter *padapter
+ void (*event_callback)(struct adapter *dev, u8 *pbuf);
+ struct evt_priv *pevt_priv = &(padapter->evtpriv);
+
+- if (pbuf == NULL)
++ if (!pbuf)
+ goto _abort_event_;
+
+ peventbuf = (uint *)pbuf;
+--- a/drivers/staging/rtl8723bs/core/rtw_security.c
++++ b/drivers/staging/rtl8723bs/core/rtw_security.c
+@@ -226,7 +226,7 @@ void rtw_wep_encrypt(struct adapter *pad
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+- if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++ if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+ return;
+
+ hw_hdr_offset = TXDESC_OFFSET;
+@@ -669,7 +669,7 @@ u32 rtw_tkip_encrypt(struct adapter *pad
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ u32 res = _SUCCESS;
+
+- if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++ if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+ return _FAIL;
+
+ hw_hdr_offset = TXDESC_OFFSET;
+@@ -1489,7 +1489,7 @@ u32 rtw_aes_encrypt(struct adapter *pada
+
+ u32 res = _SUCCESS;
+
+- if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++ if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+ return _FAIL;
+
+ hw_hdr_offset = TXDESC_OFFSET;
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -418,7 +418,7 @@ void rtw_cfg80211_ibss_indicate_connect(
+ }
+ else
+ {
+- if (scanned == NULL) {
++ if (!scanned) {
+ rtw_warn_on(1);
+ return;
+ }
+@@ -466,7 +466,7 @@ void rtw_cfg80211_indicate_connect(struc
+
+ /* DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
+
+- if (scanned == NULL) {
++ if (!scanned) {
+ rtw_warn_on(1);
+ goto check_bss;
+ }
+@@ -597,7 +597,7 @@ static int rtw_cfg80211_ap_set_encryptio
+ }
+ }
+
+- if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL))
++ if (strcmp(param->u.crypt.alg, "none") == 0 && !psta)
+ {
+ /* todo:clear default encryption keys */
+
+@@ -607,7 +607,7 @@ static int rtw_cfg80211_ap_set_encryptio
+ }
+
+
+- if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL))
++ if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta)
+ {
+ DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
+
+@@ -1001,7 +1001,7 @@ static int rtw_cfg80211_set_encryption(s
+ }
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+- if (pbcmc_sta == NULL)
++ if (!pbcmc_sta)
+ {
+ /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+ }
+@@ -1050,7 +1050,7 @@ static int cfg80211_rtw_add_key(struct w
+
+ param_len = sizeof(struct ieee_param) + params->key_len;
+ param = rtw_malloc(param_len);
+- if (param == NULL)
++ if (!param)
+ return -1;
+
+ memset(param, 0, param_len);
+@@ -1214,7 +1214,7 @@ static int cfg80211_rtw_get_station(stru
+ }
+
+ psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
+- if (psta == NULL) {
++ if (!psta) {
+ DBG_8192C("%s, sta_info is null\n", __func__);
+ ret = -ENOENT;
+ goto exit;
+@@ -1495,7 +1495,7 @@ static int cfg80211_rtw_scan(struct wiph
+ struct rtw_wdev_priv *pwdev_priv;
+ struct mlme_priv *pmlmepriv;
+
+- if (ndev == NULL) {
++ if (!ndev) {
+ ret = -EINVAL;
+ goto exit;
+ }
+@@ -1783,7 +1783,7 @@ static int rtw_cfg80211_set_wpa_ie(struc
+ u8 *pwpa, *pwpa2;
+ u8 null_addr[] = {0, 0, 0, 0, 0, 0};
+
+- if (pie == NULL || !ielen) {
++ if (!pie || !ielen) {
+ /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
+ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+ goto exit;
+@@ -1795,7 +1795,7 @@ static int rtw_cfg80211_set_wpa_ie(struc
+ }
+
+ buf = rtw_zmalloc(ielen);
+- if (buf == NULL) {
++ if (!buf) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+@@ -2138,7 +2138,7 @@ static int cfg80211_rtw_connect(struct w
+ wep_key_len = wep_key_len <= 5 ? 5 : 13;
+ wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
+ pwep = rtw_malloc(wep_total_len);
+- if (pwep == NULL) {
++ if (!pwep) {
+ DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
+ ret = -ENOMEM;
+ goto exit;
+@@ -3073,7 +3073,7 @@ static int cfg80211_rtw_mgmt_tx(struct w
+ struct adapter *padapter;
+ struct rtw_wdev_priv *pwdev_priv;
+
+- if (ndev == NULL) {
++ if (!ndev) {
+ ret = -EINVAL;
+ goto exit;
+ }
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -519,7 +519,7 @@ static int wpa_set_encryption(struct net
+
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
+ psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+- if (psta == NULL) {
++ if (!psta) {
+ /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
+ } else {
+ /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -578,7 +578,7 @@ static int wpa_set_encryption(struct net
+ }
+
+ pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+- if (pbcmc_sta == NULL) {
++ if (!pbcmc_sta) {
+ /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+ } else {
+ /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -608,9 +608,9 @@ static int rtw_set_wpa_ie(struct adapter
+ int ret = 0;
+ u8 null_addr[] = {0, 0, 0, 0, 0, 0};
+
+- if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
++ if (ielen > MAX_WPA_IE_LEN || !pie) {
+ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+- if (pie == NULL)
++ if (!pie)
+ return ret;
+ else
+ return -EINVAL;
+@@ -618,7 +618,7 @@ static int rtw_set_wpa_ie(struct adapter
+
+ if (ielen) {
+ buf = rtw_zmalloc(ielen);
+- if (buf == NULL) {
++ if (!buf) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+@@ -3366,7 +3366,7 @@ static int wpa_supplicant_ioctl(struct n
+ return -EINVAL;
+
+ param = rtw_malloc(p->length);
+- if (param == NULL)
++ if (!param)
+ return -ENOMEM;
+
+ if (copy_from_user(param, p->pointer, p->length)) {
+@@ -3448,7 +3448,7 @@ static int rtw_set_encryption(struct net
+ }
+ }
+
+- if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
++ if (strcmp(param->u.crypt.alg, "none") == 0 && !psta) {
+ /* todo:clear default encryption keys */
+
+ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
+@@ -3462,7 +3462,7 @@ static int rtw_set_encryption(struct net
+ }
+
+
+- if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
++ if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta) {
+ DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
+
+ wep_key_idx = param->u.crypt.idx;
+@@ -4187,7 +4187,7 @@ static int rtw_hostapd_ioctl(struct net_
+ return -EINVAL;
+
+ param = rtw_malloc(p->length);
+- if (param == NULL)
++ if (!param)
+ return -ENOMEM;
+
+ if (copy_from_user(param, p->pointer, p->length)) {
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -525,7 +525,7 @@ void rtw_unregister_netdevs(struct dvobj
+
+ padapter = dvobj->padapters;
+
+- if (padapter == NULL)
++ if (!padapter)
+ return;
+
+ pnetdev = padapter->pnetdev;
+@@ -638,7 +638,7 @@ struct dvobj_priv *devobj_init(void)
+ struct dvobj_priv *pdvobj = NULL;
+
+ pdvobj = rtw_zmalloc(sizeof(*pdvobj));
+- if (pdvobj == NULL)
++ if (!pdvobj)
+ return NULL;
+
+ mutex_init(&pdvobj->hw_init_mutex);
--- /dev/null
+From stable+bounces-274607-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:11 -0400
+Subject: staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
+To: stable@vger.kernel.org
+Cc: Alexandru Hossu <hossu.alexandru@gmail.com>, stable <stable@kernel.org>, Luka Gejak <luka.gejak@linux.dev>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233411.3592079-2-sashal@kernel.org>
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+[ Upstream commit 5a752a616e756844388a1a45404db9fc29fec655 ]
+
+supplicant_ie is a 256-byte array in struct security_priv. The WPA and
+WPA2 IE copy paths use:
+
+ memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
+
+where wpa_ielen is the raw IE length field (u8, 0-255). When a local user
+supplies a connect request via nl80211 with a crafted WPA IE of length 255,
+wpa_ielen + 2 equals 257, overflowing the 256-byte buffer by one byte into
+the adjacent last_mic_err_time field.
+
+rtw_parse_wpa_ie() does not prevent this: its length consistency check
+compares *(wpa_ie+1) against (u8)(wpa_ie_len-2), which is (u8)(255) == 255
+when wpa_ie_len = 257, so the check passes silently.
+
+Add explicit bounds checks for both the WPA and WPA2 paths before the
+memcpy, rejecting any IE whose total size (wpa_ielen + 2) exceeds the
+supplicant_ie buffer.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-4-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -1818,6 +1818,10 @@ static int rtw_cfg80211_set_wpa_ie(struc
+
+ pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
+ if (pwpa && wpa_ielen > 0) {
++ if (wpa_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
++ ret = -EINVAL;
++ goto exit;
++ }
+ if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
+@@ -1829,6 +1833,10 @@ static int rtw_cfg80211_set_wpa_ie(struc
+
+ pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
+ if (pwpa2 && wpa2_ielen > 0) {
++ if (wpa2_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
++ ret = -EINVAL;
++ goto exit;
++ }
+ if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
--- /dev/null
+From stable+bounces-274633-greg=kroah.com@vger.kernel.org Wed Jul 15 02:18:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 20:17:26 -0400
+Subject: staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()
+To: stable@vger.kernel.org
+Cc: Alexandru Hossu <hossu.alexandru@gmail.com>, stable <stable@kernel.org>, Luka Gejak <luka.gejak@linux.dev>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715001726.3782263-1-sashal@kernel.org>
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+[ Upstream commit ef61d628dfad38fead1fd2e08979ae9126d011d5 ]
+
+Two IE parsing loops are missing the header bounds checks before they
+dereference pIE->length:
+
+ - issue_assocreq() walks pmlmeinfo->network.ies to build the
+ association request. If the stored IE data ends with only an
+ element_id byte and no length byte, pIE->length is read one byte
+ past the end of the buffer.
+
+ - join_cmd_hdl() walks pnetwork->ies during station join and has
+ the same problem under the same conditions.
+
+Both buffers are filled from AP beacon and probe-response frames, so a
+malicious AP that sends a truncated final IE can trigger the issue.
+
+Apply the two-guard pattern established in update_beacon_info():
+ 1. Break if fewer than sizeof(*pIE) bytes remain.
+ 2. Break if the IE's declared data extends past the buffer end.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-3-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ replaced sizeof(*pIE) with literal 2 (5.10's ndis_80211_var_ie still has data[1]) and used pre-rename field names IELength/IEs/ElementID/Length ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -3341,7 +3341,11 @@ void issue_assocreq(struct adapter *pada
+
+ /* vendor specific IE, such as WPA, WMM, WPS */
+ for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) {
++ if (i + 2 > pmlmeinfo->network.IELength)
++ break;
+ pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i);
++ if (i + 2 + pIE->Length > pmlmeinfo->network.IELength)
++ break;
+
+ switch (pIE->ElementID) {
+ case _VENDOR_SPECIFIC_IE_:
+@@ -6105,7 +6109,11 @@ u8 join_cmd_hdl(struct adapter *padapter
+
+ /* sizeof(struct ndis_802_11_fix_ie) */
+ for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;) {
++ if (i + 2 > pnetwork->IELength)
++ break;
+ pIE = (struct ndis_80211_var_ie *)(pnetwork->IEs + i);
++ if (i + 2 + pIE->Length > pnetwork->IELength)
++ break;
+
+ switch (pIE->ElementID) {
+ case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
--- /dev/null
+From stable+bounces-274604-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:10 -0400
+Subject: staging: rtl8723bs: Fix space issues
+To: stable@vger.kernel.org
+Cc: Franziska Naepelt <franziska.naepelt@googlemail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233411.3592079-1-sashal@kernel.org>
+
+From: Franziska Naepelt <franziska.naepelt@googlemail.com>
+
+[ Upstream commit c4b811b9361b0d7ea167a79587f5ec0a13fd8863 ]
+
+Fix the following checkpatch space issues:
+- CHECK: spaces preferred around that '*' (ctx:VxV)
+- CHECK: spaces preferred around that '+' (ctx:VxV)
+- CHECK: spaces preferred around that '-' (ctx:VxV)
+- CHECK: spaces preferred around that '|' (ctx:VxV)
+- CHECK: No space is necessary after a cast
+- WARNING: please, no spaces at the start of a line
+
+Signed-off-by: Franziska Naepelt <franziska.naepelt@googlemail.com>
+Link: https://lore.kernel.org/r/20230701102538.5359-1-franziska.naepelt@googlemail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 5a752a616e75 ("staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 84 ++++++++++------------
+ 1 file changed, 40 insertions(+), 44 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -98,14 +98,14 @@ static struct ieee80211_channel rtw_2ghz
+ static void rtw_2g_channels_init(struct ieee80211_channel *channels)
+ {
+ memcpy((void *)channels, (void *)rtw_2ghz_channels,
+- sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
++ sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM
+ );
+ }
+
+ static void rtw_2g_rates_init(struct ieee80211_rate *rates)
+ {
+ memcpy(rates, rtw_g_rates,
+- sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
++ sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM
+ );
+ }
+
+@@ -132,8 +132,8 @@ static struct ieee80211_supported_band *
+ if (!spt_band)
+ goto exit;
+
+- spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band)+sizeof(struct ieee80211_supported_band));
+- spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
++ spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band) + sizeof(struct ieee80211_supported_band));
++ spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels) + sizeof(struct ieee80211_channel) * n_channels);
+ spt_band->band = band;
+ spt_band->n_channels = n_channels;
+ spt_band->n_bitrates = n_bitrates;
+@@ -267,10 +267,10 @@ struct cfg80211_bss *rtw_cfg80211_inform
+ u32 wpsielen = 0;
+ u8 *wpsie = NULL;
+
+- wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
++ wpsie = rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
+
+ if (wpsie && wpsielen > 0)
+- psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
++ psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
+
+ if (sr != 0)
+ {
+@@ -306,9 +306,9 @@ struct cfg80211_bss *rtw_cfg80211_inform
+ /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
+ is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
+- notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */
++ notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */
+ } else {
+- notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/* dbm */
++ notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/* dbm */
+ }
+
+ buf = kzalloc(MAX_BSSINFO_LEN, GFP_ATOMIC);
+@@ -507,22 +507,22 @@ check_bss:
+ roam_info.channel = notify_channel;
+ roam_info.bssid = cur_network->network.MacAddress;
+ roam_info.req_ie =
+- pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2;
++ pmlmepriv->assoc_req + sizeof(struct ieee80211_hdr_3addr) + 2;
+ roam_info.req_ie_len =
+- pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2;
++ pmlmepriv->assoc_req_len - sizeof(struct ieee80211_hdr_3addr) - 2;
+ roam_info.resp_ie =
+- pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6;
++ pmlmepriv->assoc_rsp + sizeof(struct ieee80211_hdr_3addr) + 6;
+ roam_info.resp_ie_len =
+- pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6;
++ pmlmepriv->assoc_rsp_len - sizeof(struct ieee80211_hdr_3addr) - 6;
+ cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
+ }
+ else
+ {
+ cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
+- , pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2
+- , pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2
+- , pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6
+- , pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6
++ , pmlmepriv->assoc_req + sizeof(struct ieee80211_hdr_3addr) + 2
++ , pmlmepriv->assoc_req_len - sizeof(struct ieee80211_hdr_3addr) - 2
++ , pmlmepriv->assoc_rsp + sizeof(struct ieee80211_hdr_3addr) + 6
++ , pmlmepriv->assoc_rsp_len - sizeof(struct ieee80211_hdr_3addr) - 6
+ , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
+ }
+ }
+@@ -855,7 +855,7 @@ static int rtw_cfg80211_set_encryption(s
+ param->u.crypt.err = 0;
+ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+
+- if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
++ if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len)
+ {
+ ret = -EINVAL;
+ goto exit;
+@@ -1252,10 +1252,10 @@ static int cfg80211_rtw_get_station(stru
+ }
+
+ /* for Ad-Hoc/AP mode */
+- if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
+- || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
+- || check_fwstate(pmlmepriv, WIFI_AP_STATE))
+- && check_fwstate(pmlmepriv, _FW_LINKED)
++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
++ check_fwstate(pmlmepriv, WIFI_AP_STATE)) &&
++ check_fwstate(pmlmepriv, _FW_LINKED)
+ )
+ {
+ /* TODO: should acquire station info... */
+@@ -1518,7 +1518,7 @@ static int cfg80211_rtw_scan(struct wiph
+ DBG_871X("%s under WIFI_AP_STATE\n", __func__);
+ #endif
+
+- if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
++ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == true)
+ {
+ DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
+
+@@ -1591,7 +1591,7 @@ static int cfg80211_rtw_scan(struct wiph
+ }
+
+ /* parsing channels, n_channels */
+- memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
++ memset(ch, 0, sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
+ for (i = 0; i < request->n_channels && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
+ #ifdef DEBUG_CFG80211
+ DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
+@@ -1609,7 +1609,7 @@ static int cfg80211_rtw_scan(struct wiph
+ for (j = request->n_channels - 1; j >= 0; j--)
+ for (i = 0; i < survey_times; i++)
+ {
+- memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
++ memcpy(&ch[j * survey_times + i], &ch[j], sizeof(struct rtw_ieee80211_channel));
+ }
+ _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
+ } else {
+@@ -1789,7 +1789,7 @@ static int rtw_cfg80211_set_wpa_ie(struc
+ goto exit;
+ }
+
+- if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
++ if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
+ ret = -EINVAL;
+ goto exit;
+ }
+@@ -1817,26 +1817,22 @@ static int rtw_cfg80211_set_wpa_ie(struc
+ }
+
+ pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
+- if (pwpa && wpa_ielen > 0)
+- {
+- if (rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+- {
++ if (pwpa && wpa_ielen > 0) {
++ if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
+- memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
++ memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
+
+ DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
+ }
+ }
+
+ pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
+- if (pwpa2 && wpa2_ielen > 0)
+- {
+- if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+- {
++ if (pwpa2 && wpa2_ielen > 0) {
++ if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
+- memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
++ memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen + 2);
+
+ DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
+ }
+@@ -2303,7 +2299,7 @@ static int cfg80211_rtw_set_pmksa(struct
+
+ memcpy(psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
+ psecuritypriv->PMKIDList[index].bUsed = true;
+- psecuritypriv->PMKIDIndex = index+1;
++ psecuritypriv->PMKIDIndex = index + 1;
+ blInserted = true;
+ break;
+ }
+@@ -2477,8 +2473,8 @@ static netdev_tx_t rtw_cfg80211_monitor_
+ return _rtw_xmit_entry(skb, padapter->pnetdev);
+
+ }
+- else if ((frame_control & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE))
+- == (IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_ACTION)
++ else if ((frame_control & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
++ == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION)
+ )
+ {
+ /* only for action frames */
+@@ -2616,7 +2612,7 @@ static int rtw_cfg80211_add_monitor_if(s
+ }
+
+ *ndev = pwdev_priv->pmon_ndev = mon_ndev;
+- memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
++ memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
+
+ out:
+ if (ret && mon_wdev) {
+@@ -2719,14 +2715,14 @@ static int rtw_add_beacon(struct adapter
+ if (head_len < 24)
+ return -EINVAL;
+
+- pbuf = rtw_zmalloc(head_len+tail_len);
++ pbuf = rtw_zmalloc(head_len + tail_len);
+ if (!pbuf)
+ return -ENOMEM;
+
+- memcpy(pbuf, (void *)head+24, head_len-24);/* 24 =beacon header len. */
+- memcpy(pbuf+head_len-24, (void *)tail, tail_len);
++ memcpy(pbuf, (void *)head + 24, head_len - 24);/* 24 =beacon header len. */
++ memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
+
+- len = head_len+tail_len-24;
++ len = head_len + tail_len - 24;
+
+ /* check wps ie if inclued */
+ if (rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
+@@ -3082,7 +3078,7 @@ static int cfg80211_rtw_mgmt_tx(struct w
+ pwdev_priv = adapter_wdev_data(padapter);
+
+ /* cookie generation */
+- *cookie = (unsigned long) buf;
++ *cookie = (unsigned long)buf;
+
+ #ifdef DEBUG_CFG80211
+ DBG_871X(FUNC_ADPT_FMT" len =%zu, ch =%d"
--- /dev/null
+From stable+bounces-274605-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:07 -0400
+Subject: staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()
+To: stable@vger.kernel.org
+Cc: Alexandru Hossu <hossu.alexandru@gmail.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-8-sashal@kernel.org>
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+[ Upstream commit a1fc19d61f661d47204f095b593de507884849f7 ]
+
+OnAuth() has two bugs in the shared-key authentication path.
+
+When the Privacy bit is set, rtw_wep_decrypt() is called without
+verifying that the frame is long enough to contain a valid WEP IV and
+ICV. Inside rtw_wep_decrypt(), length is computed as:
+
+ length = len - WLAN_HDR_A3_LEN - iv_len
+
+and then passed as (length - 4) to crc32_le(). If len is less than
+WLAN_HDR_A3_LEN + iv_len + icv_len (32 bytes), length - 4 is negative
+and, after the implicit cast to size_t, causes crc32_le() to read far
+beyond the frame buffer. Add a minimum length check before accessing
+the IV field and calling the decryption path.
+
+When processing a seq=3 response, rtw_get_ie() stores the Challenge
+Text IE length in ie_len, but the subsequent memcmp() always reads 128
+bytes regardless of ie_len. IEEE 802.11 mandates a challenge text of
+exactly 128 bytes; reject any IE whose length field differs, matching
+the check already applied to OnAuthClient().
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004605.1039209-1-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -886,6 +886,9 @@ unsigned int OnAuth(struct adapter *pada
+
+ DBG_871X("+OnAuth\n");
+
++ if (len < WLAN_HDR_A3_LEN)
++ return _FAIL;
++
+ sa = GetAddr2Ptr(pframe);
+
+ auth_mode = psecuritypriv->dot11AuthAlgrthm;
+@@ -897,6 +900,9 @@ unsigned int OnAuth(struct adapter *pada
+ prxattrib->hdrlen = WLAN_HDR_A3_LEN;
+ prxattrib->encrypt = _WEP40_;
+
++ if (len < WLAN_HDR_A3_LEN + 8)
++ return _FAIL;
++
+ iv = pframe+prxattrib->hdrlen;
+ prxattrib->key_index = ((iv[3]>>6)&0x3);
+
+@@ -1014,7 +1020,7 @@ unsigned int OnAuth(struct adapter *pada
+ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
+ len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
+
+- if (!p || ie_len <= 0) {
++ if (!p || ie_len != 128) {
+ DBG_871X("auth rejected because challenge failure!(1)\n");
+ status = _STATS_CHALLENGE_FAIL_;
+ goto auth_fail;
--- /dev/null
+From stable+bounces-274601-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:04 -0400
+Subject: staging: rtl8723bs: remove 5Ghz code blocks
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-5-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit ddd7c8b0033ba01a0ee605697f12a33fd31e6fca ]
+
+remove 5 Ghz code blocks, related to networks
+working over channel numbers above 14.
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/c64443b92ce1a60f568db153842a62e3244a8c3a.1626874164.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 7 ++-----
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 20 +++-----------------
+ 2 files changed, 5 insertions(+), 22 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -4116,7 +4116,7 @@ static void issue_action_BSSCoexistPacke
+ p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
+ if ((p == NULL) || (len == 0)) {/* non-HT */
+
+- if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
++ if (pbss_network->Configuration.DSConfig <= 0)
+ continue;
+
+ ICS[0][pbss_network->Configuration.DSConfig] = 1;
+@@ -6118,10 +6118,7 @@ u8 join_cmd_hdl(struct adapter *padapter
+ {
+ struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
+
+- if (pnetwork->Configuration.DSConfig > 14) {
+- if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20)
+- cbw40_enable = 1;
+- } else {
++ if (pnetwork->Configuration.DSConfig <= 14) {
+ if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
+ cbw40_enable = 1;
+ }
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -135,14 +135,7 @@ static char *translate_scan(struct adapt
+ else
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
+ } else {
+- if (pnetwork->network.Configuration.DSConfig > 14) {
+- if (vht_cap)
+- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
+- else if (ht_cap)
+- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
+- else
+- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
+- } else {
++ if (pnetwork->network.Configuration.DSConfig <= 14) {
+ if (ht_cap)
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
+ else
+@@ -762,7 +755,7 @@ static int rtw_wx_get_name(struct net_de
+ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ u32 ht_ielen = 0;
+ char *p;
+- u8 ht_cap = false, vht_cap = false;
++ u8 ht_cap = false;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+ NDIS_802_11_RATES_EX* prates = NULL;
+@@ -788,14 +781,7 @@ static int rtw_wx_get_name(struct net_de
+ else
+ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
+ } else {
+- if (pcur_bss->Configuration.DSConfig > 14) {
+- if (vht_cap)
+- snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
+- else if (ht_cap)
+- snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
+- else
+- snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
+- } else {
++ if (pcur_bss->Configuration.DSConfig <= 14) {
+ if (ht_cap)
+ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
+ else
--- /dev/null
+From stable+bounces-274602-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:03 -0400
+Subject: staging: rtl8723bs: remove 5Ghz code related to channel plan definition
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Hans de Goede <hdegoede@redhat.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-4-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit ec84d0ae54a6774091b3b7d1e9da32589f48b2f9 ]
+
+remove 5Ghz code related to channel plan definition.
+
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/17a707952cec951893748d2cb59d02a294cdd1be.1624367071.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 210 +++++++++-------------
+ drivers/staging/rtl8723bs/hal/hal_com_phycfg.c | 34 ---
+ drivers/staging/rtl8723bs/include/rtw_mlme_ext.h | 6
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 2
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 1
+ 5 files changed, 94 insertions(+), 159 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -123,93 +123,93 @@ static RT_CHANNEL_PLAN_5G RTW_ChannelPla
+
+ static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
+ /* 0x00 ~ 0x1F , Old Define ===== */
+- {0x02, 0x20}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
+- {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
+- {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
+- {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
+- {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
+- {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
+- {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
+- {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
+- {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
+- {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
+- {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
+- {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
+- {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
+- {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
+- {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
+- {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
+- {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
+- {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
+- {0x01, 0x21}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
+- {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
+- {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
+- {0x00, 0x21}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
+- {0x00, 0x22}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
+- {0x03, 0x21}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
+- {0x06, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
+- {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
+- {0x00, 0x00}, /* 0x1A, */
+- {0x00, 0x00}, /* 0x1B, */
+- {0x00, 0x00}, /* 0x1C, */
+- {0x00, 0x00}, /* 0x1D, */
+- {0x00, 0x00}, /* 0x1E, */
+- {0x06, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
++ {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
++ {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
++ {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
++ {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
++ {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
++ {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
++ {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
++ {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
++ {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
++ {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
++ {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
++ {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
++ {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
++ {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
++ {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
++ {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
++ {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
++ {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
++ {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
++ {0x00}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
++ {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
++ {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
++ {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
++ {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
++ {0x06}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
++ {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
++ {0x00}, /* 0x1A, */
++ {0x00}, /* 0x1B, */
++ {0x00}, /* 0x1C, */
++ {0x00}, /* 0x1D, */
++ {0x00}, /* 0x1E, */
++ {0x06}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
+ /* 0x20 ~ 0x7F , New Define ===== */
+- {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
+- {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
+- {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
+- {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
+- {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
+- {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
+- {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
+- {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
+- {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
+- {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
+- {0x00, 0x00}, /* 0x2A, */
+- {0x00, 0x00}, /* 0x2B, */
+- {0x00, 0x00}, /* 0x2C, */
+- {0x00, 0x00}, /* 0x2D, */
+- {0x00, 0x00}, /* 0x2E, */
+- {0x00, 0x00}, /* 0x2F, */
+- {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
+- {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
+- {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
+- {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
+- {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
+- {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
+- {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
+- {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
+- {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
+- {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
+- {0x00, 0x00}, /* 0x3A, */
+- {0x00, 0x00}, /* 0x3B, */
+- {0x00, 0x00}, /* 0x3C, */
+- {0x00, 0x00}, /* 0x3D, */
+- {0x00, 0x00}, /* 0x3E, */
+- {0x00, 0x00}, /* 0x3F, */
+- {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
+- {0x05, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */
+- {0x01, 0x12}, /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */
+- {0x02, 0x05}, /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */
+- {0x02, 0x11}, /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */
+- {0x00, 0x13}, /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */
+- {0x02, 0x14}, /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */
+- {0x00, 0x15}, /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */
+- {0x00, 0x16}, /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */
+- {0x00, 0x17}, /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */
+- {0x00, 0x18}, /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */
+- {0x00, 0x19}, /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */
+- {0x00, 0x1A}, /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */
+- {0x02, 0x1B}, /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */
+- {0x00, 0x1C}, /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */
+- {0x02, 0x1D}, /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */
+- {0x00, 0x1E}, /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */
+- {0x02, 0x1F}, /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */
++ {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
++ {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
++ {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
++ {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
++ {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
++ {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
++ {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
++ {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
++ {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
++ {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
++ {0x00}, /* 0x2A, */
++ {0x00}, /* 0x2B, */
++ {0x00}, /* 0x2C, */
++ {0x00}, /* 0x2D, */
++ {0x00}, /* 0x2E, */
++ {0x00}, /* 0x2F, */
++ {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
++ {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
++ {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
++ {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
++ {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
++ {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
++ {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
++ {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
++ {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
++ {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
++ {0x00}, /* 0x3A, */
++ {0x00}, /* 0x3B, */
++ {0x00}, /* 0x3C, */
++ {0x00}, /* 0x3D, */
++ {0x00}, /* 0x3E, */
++ {0x00}, /* 0x3F, */
++ {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
++ {0x05}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */
++ {0x01}, /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */
++ {0x02}, /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */
++ {0x02}, /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */
++ {0x00}, /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */
++ {0x02}, /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */
++ {0x00}, /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */
++ {0x00}, /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */
++ {0x00}, /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */
++ {0x00}, /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */
++ {0x00}, /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */
++ {0x00}, /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */
++ {0x02}, /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */
++ {0x00}, /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */
++ {0x02}, /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */
++ {0x00}, /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */
++ {0x02}, /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */
+ };
+
+ /* use the combination for max channel numbers */
+-static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02};
++static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03};
+
+ /* Search the @param ch in given @param ch_set
+ * @ch_set: the given channel set
+@@ -231,23 +231,6 @@ int rtw_ch_set_search_ch(RT_CHANNEL_INFO
+ return i;
+ }
+
+-/* Check the @param ch is fit with setband setting of @param adapter
+- * @adapter: the given adapter
+- * @ch: the given channel number
+- *
+- * return true when check valid, false not valid
+- */
+-bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch)
+-{
+- if (adapter->setband == GHZ24_50 /* 2.4G and 5G */
+- || (adapter->setband == GHZ_24 && ch < 35) /* 2.4G only */
+- || (adapter->setband == GHZ_50 && ch > 35) /* 5G only */
+- ) {
+- return true;
+- }
+- return false;
+-}
+-
+ /****************************************************************************
+
+ Following are the initialization functions for WiFi MLME
+@@ -424,7 +407,6 @@ static u8 init_channel_set(struct adapte
+ else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
+ channel_set[chanset_size].ScanType = SCAN_PASSIVE;
+ } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
+- RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
+ RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) { /* channel 12~13, passive scan */
+ if (channel_set[chanset_size].ChannelNum <= 11)
+ channel_set[chanset_size].ScanType = SCAN_ACTIVE;
+@@ -4938,10 +4920,6 @@ static void process_80211d(struct adapte
+ while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
+ if (chplan_new[i].ChannelNum == channel) {
+ if (chplan_new[i].ScanType == SCAN_PASSIVE) {
+- /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
+- if (channel >= 52 && channel <= 144)
+- break;
+-
+ chplan_new[i].ScanType = SCAN_ACTIVE;
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
+ ("%s: change channel %d scan type from passive to active\n",
+@@ -6250,7 +6228,6 @@ static int rtw_scan_ch_decision(struct a
+ set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
+ if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
+ && set_idx >= 0
+- && rtw_mlme_band_check(padapter, in[i].hw_value)
+ ) {
+ if (j >= out_num) {
+ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
+@@ -6275,21 +6252,18 @@ static int rtw_scan_ch_decision(struct a
+
+ DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
+
+- if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum)) {
+-
+- if (j >= out_num) {
+- DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
+- FUNC_ADPT_ARG(padapter), out_num);
+- break;
+- }
++ if (j >= out_num) {
++ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
++ FUNC_ADPT_ARG(padapter), out_num);
++ break;
++ }
+
+- out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
++ out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
+
+- if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
+- out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
++ if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
++ out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
+
+- j++;
+- }
++ j++;
+ }
+ }
+
+--- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
++++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
+@@ -2062,139 +2062,105 @@ void Hal_ChannelPlanToRegulation(struct
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_FCC1:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI1:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_MKK1_MKK1:
+ pHalData->Regulation2_4G = TXPWR_LMT_MKK;
+- pHalData->Regulation5G = TXPWR_LMT_MKK;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_KCC1:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_MKK;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_FCC2:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_FCC3:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_FCC4:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_FCC5:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_FCC6:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_FCC7:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI2:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI3:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_MKK1_MKK2:
+ pHalData->Regulation2_4G = TXPWR_LMT_MKK;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_MKK1_MKK3:
+ pHalData->Regulation2_4G = TXPWR_LMT_MKK;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_NCC1:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_NCC2:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_GLOBAL_NULL:
+ pHalData->Regulation2_4G = TXPWR_LMT_WW;
+- pHalData->Regulation5G = TXPWR_LMT_WW;
+ break;
+ case RT_CHANNEL_DOMAIN_ETSI1_ETSI4:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_FCC2:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_NCC3:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI5:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_FCC8:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI6:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI7:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI8:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI9:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI10:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI11:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_NCC4:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI12:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_FCC9:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_WORLD_ETSI13:
+ pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+- pHalData->Regulation5G = TXPWR_LMT_ETSI;
+ break;
+ case RT_CHANNEL_DOMAIN_FCC1_FCC10:
+ pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+- pHalData->Regulation5G = TXPWR_LMT_FCC;
+ break;
+ case RT_CHANNEL_DOMAIN_REALTEK_DEFINE: /* Realtek Reserve */
+ pHalData->Regulation2_4G = TXPWR_LMT_WW;
+- pHalData->Regulation5G = TXPWR_LMT_WW;
+ break;
+ default:
+ break;
+--- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
++++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
+@@ -255,7 +255,6 @@ typedef struct _RT_CHANNEL_PLAN_5G {
+
+ typedef struct _RT_CHANNEL_PLAN_MAP {
+ unsigned char Index2G;
+- unsigned char Index5G;
+ } RT_CHANNEL_PLAN_MAP, *PRT_CHANNEL_PLAN_MAP;
+
+ enum Associated_AP {
+@@ -360,13 +359,13 @@ struct FW_Sta_Info {
+ * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to AP's operating channel for
+ * RTW_STAY_AP_CH_MILLISECOND * SURVEY_TO milliseconds.
+ * Example:
+- * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1,
++ * For chip supports 2.4G and AP mode is operating in channel 1,
+ * RTW_SCAN_NUM_OF_CH is 8, RTW_STAY_AP_CH_MILLISECOND is 3 and SURVEY_TO is 100.
+ * When it's STA mode gets set_scan command,
+ * it would
+ * 1. Doing the scan on channel 1.2.3.4.5.6.7.8
+ * 2. Back to channel 1 for 300 milliseconds
+- * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52
++ * 3. Go through doing site survey on channel 9.10.11
+ * 4. Back to channel 1 for 300 milliseconds
+ * 5. ... and so on, till survey done.
+ */
+@@ -423,7 +422,6 @@ typedef struct _RT_CHANNEL_INFO {
+ } RT_CHANNEL_INFO, *PRT_CHANNEL_INFO;
+
+ int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch);
+-bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch);
+
+ /* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes */
+ #define P2P_MAX_REG_CLASSES 10
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -77,7 +77,6 @@ static struct ieee80211_rate rtw_rates[]
+ #define RTW_G_RATES_NUM 12
+
+ #define RTW_2G_CHANNELS_NUM 14
+-#define RTW_5G_CHANNELS_NUM 37
+
+ static struct ieee80211_channel rtw_2ghz_channels[] = {
+ CHAN2G(1, 2412, 0),
+@@ -1422,7 +1421,6 @@ void rtw_cfg80211_surveydone_event_callb
+
+ /* report network only if the current channel set contains the channel to which this network belongs */
+ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
+- && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
+ && true == rtw_validate_ssid(&(pnetwork->network.Ssid))
+ )
+ {
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -1462,7 +1462,6 @@ static int rtw_wx_get_scan(struct net_de
+
+ /* report network only if the current channel set contains the channel to which this network belongs */
+ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
+- && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
+ && true == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
+
+ ev = translate_scan(padapter, a, pnetwork, ev, stop);
--- /dev/null
+From stable+bounces-274600-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:02 -0400
+Subject: staging: rtl8723bs: remove all 5Ghz network types
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Hans de Goede <hdegoede@redhat.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-3-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 708180a92cd8bff18b3d2ac05172815bcc0b6b9a ]
+
+remove all 5Ghz network types. rtl8723bs works on
+802.11bgn standards and on 2.4Ghz band.
+
+So remove all code related to 802.11a and 802.11ac
+standards, which the device doesn't support.
+
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/7e4644a71d0ba2819370171b3dc78bfc755f6313.1624367071.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_ap.c | 11 ----
+ drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 22 +-------
+ drivers/staging/rtl8723bs/core/rtw_mlme.c | 10 ---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 55 ---------------------
+ drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 14 +----
+ drivers/staging/rtl8723bs/hal/odm.c | 30 -----------
+ drivers/staging/rtl8723bs/hal/odm.h | 3 -
+ drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c | 4 -
+ drivers/staging/rtl8723bs/hal/sdio_halinit.c | 5 -
+ drivers/staging/rtl8723bs/include/hal_phy.h | 3 -
+ drivers/staging/rtl8723bs/include/ieee80211.h | 22 +-------
+ drivers/staging/rtl8723bs/include/wifi.h | 1
+ drivers/staging/rtl8723bs/os_dep/os_intfs.c | 2
+ 13 files changed, 14 insertions(+), 168 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
+@@ -427,11 +427,7 @@ void add_RATid(struct adapter *padapter,
+ shortGIrate = query_ra_short_GI(psta);
+
+ if (pcur_network->Configuration.DSConfig > 14) {
+- if (tx_ra_bitmap & 0xffff000)
+- sta_band |= WIRELESS_11_5N;
+-
+- if (tx_ra_bitmap & 0xff0)
+- sta_band |= WIRELESS_11A;
++ sta_band |= WIRELESS_INVALID;
+ } else {
+ if (tx_ra_bitmap & 0xffff000)
+ sta_band |= WIRELESS_11_24N;
+@@ -503,7 +499,7 @@ void update_bmc_sta(struct adapter *pada
+ } else if (network_type == WIRELESS_INVALID) { /* error handling */
+
+ if (pcur_network->Configuration.DSConfig > 14)
+- network_type = WIRELESS_11A;
++ network_type = WIRELESS_INVALID;
+ else
+ network_type = WIRELESS_11B;
+ }
+@@ -1254,9 +1250,6 @@ int rtw_check_beacon_data(struct adapter
+ case WIRELESS_11BG_24N:
+ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
+ break;
+- case WIRELESS_11A:
+- pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
+- break;
+ default:
+ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
+ break;
+--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
+@@ -96,10 +96,7 @@ bool rtw_is_cckratesonly_included(u8 *ra
+ int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
+ {
+ if (channel > 14) {
+- if (rtw_is_cckrates_included(rate))
+- return WIRELESS_INVALID;
+- else
+- return WIRELESS_11A;
++ return WIRELESS_INVALID;
+ } else { /* could be pure B, pure G, or B/G */
+ if (rtw_is_cckratesonly_included(rate))
+ return WIRELESS_11B;
+@@ -275,10 +272,6 @@ void rtw_set_supported_rate(u8 *Supporte
+ break;
+
+ case WIRELESS_11G:
+- case WIRELESS_11A:
+- case WIRELESS_11_5N:
+- case WIRELESS_11A_5N:/* Todo: no basic rate for ofdm ? */
+- case WIRELESS_11_5AC:
+ memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
+ break;
+
+@@ -336,14 +329,7 @@ int rtw_generate_ie(struct registry_priv
+ ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz);
+
+ /* supported rates */
+- if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) {
+- if (pdev_network->Configuration.DSConfig > 14)
+- wireless_mode = WIRELESS_11A_5N;
+- else
+- wireless_mode = WIRELESS_11BG_24N;
+- } else {
+- wireless_mode = pregistrypriv->wireless_mode;
+- }
++ wireless_mode = pregistrypriv->wireless_mode;
+
+ rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode);
+
+@@ -368,8 +354,8 @@ int rtw_generate_ie(struct registry_priv
+ }
+
+ /* HT Cap. */
+- if (((pregistrypriv->wireless_mode&WIRELESS_11_5N) || (pregistrypriv->wireless_mode&WIRELESS_11_24N))
+- && (pregistrypriv->ht_enable == true)) {
++ if ((pregistrypriv->wireless_mode & WIRELESS_11_24N) &&
++ (pregistrypriv->ht_enable == true)) {
+ /* todo: */
+ }
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+@@ -2438,16 +2438,6 @@ void rtw_update_registrypriv_dev_network
+ case WIRELESS_11BG_24N:
+ pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
+ break;
+- case WIRELESS_11A:
+- case WIRELESS_11A_5N:
+- pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
+- break;
+- case WIRELESS_11ABGN:
+- if (pregistrypriv->channel > 14)
+- pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
+- else
+- pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
+- break;
+ default:
+ /* TODO */
+ break;
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -4918,61 +4918,6 @@ static void process_80211d(struct adapte
+ }
+ }
+
+- if (pregistrypriv->wireless_mode & WIRELESS_11A) {
+- do {
+- if ((i == MAX_CHANNEL_NUM) ||
+- (chplan_sta[i].ChannelNum == 0))
+- break;
+-
+- if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
+- break;
+-
+- if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
+- chplan_new[k].ChannelNum = chplan_ap.Channel[j];
+- chplan_new[k].ScanType = SCAN_ACTIVE;
+- i++;
+- j++;
+- k++;
+- } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
+- chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
+-/* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
+- chplan_new[k].ScanType = SCAN_PASSIVE;
+- i++;
+- k++;
+- } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
+- chplan_new[k].ChannelNum = chplan_ap.Channel[j];
+- chplan_new[k].ScanType = SCAN_ACTIVE;
+- j++;
+- k++;
+- }
+- } while (1);
+-
+- /* change AP not support channel to Passive scan */
+- while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
+- chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
+-/* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
+- chplan_new[k].ScanType = SCAN_PASSIVE;
+- i++;
+- k++;
+- }
+-
+- /* add channel AP supported */
+- while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
+- chplan_new[k].ChannelNum = chplan_ap.Channel[j];
+- chplan_new[k].ScanType = SCAN_ACTIVE;
+- j++;
+- k++;
+- }
+- } else {
+- /* keep original STA 5G channel plan */
+- while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
+- chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
+- chplan_new[k].ScanType = chplan_sta[i].ScanType;
+- i++;
+- k++;
+- }
+- }
+-
+ pmlmeext->update_channel_plan_by_ap_done = 1;
+
+ #ifdef DEBUG_RTL871X
+--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
++++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+@@ -62,9 +62,6 @@ u8 networktype_to_raid_ex(struct adapter
+
+ if (cur_rf_type == RF_1T1R) {
+ rf_type = RF_1T1R;
+- } else if (IsSupportedVHT(psta->wireless_mode)) {
+- if (psta->ra_mask & 0xffc00000)
+- rf_type = RF_2T2R;
+ } else if (IsSupportedHT(psta->wireless_mode)) {
+ if (psta->ra_mask & 0xfff00000)
+ rf_type = RF_2T2R;
+@@ -74,7 +71,6 @@ u8 networktype_to_raid_ex(struct adapter
+ case WIRELESS_11B:
+ raid = RATEID_IDX_B;
+ break;
+- case WIRELESS_11A:
+ case WIRELESS_11G:
+ raid = RATEID_IDX_G;
+ break;
+@@ -82,8 +78,6 @@ u8 networktype_to_raid_ex(struct adapter
+ raid = RATEID_IDX_BG;
+ break;
+ case WIRELESS_11_24N:
+- case WIRELESS_11_5N:
+- case WIRELESS_11A_5N:
+ case WIRELESS_11G_24N:
+ if (rf_type == RF_2T2R)
+ raid = RATEID_IDX_GN_N2SS;
+@@ -810,7 +804,7 @@ void WMMOnAssocRsp(struct adapter *padap
+
+ AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
+
+- if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {
++ if (pmlmeext->cur_wireless_mode & WIRELESS_11G) {
+ ECWMin = 4;
+ ECWMax = 10;
+ } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
+@@ -1695,7 +1689,7 @@ void update_capinfo(struct adapter *Adap
+ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
+ else {
+ /* Filen: See 802.11-2007 p.90 */
+- if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC))
++ if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N))
+ pmlmeinfo->slotTime = SHORT_SLOT_TIME;
+ else if (pmlmeext->cur_wireless_mode & (WIRELESS_11G)) {
+ if ((updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */)
+@@ -1724,9 +1718,7 @@ void update_wireless_mode(struct adapter
+ if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
+ pmlmeinfo->HT_enable = 1;
+
+- if (pmlmeinfo->VHT_enable)
+- network_type = WIRELESS_11AC;
+- else if (pmlmeinfo->HT_enable)
++ if (pmlmeinfo->HT_enable)
+ network_type = WIRELESS_11_24N;
+
+ if (rtw_is_cckratesonly_included(rate))
+--- a/drivers/staging/rtl8723bs/hal/odm.c
++++ b/drivers/staging/rtl8723bs/hal/odm.c
+@@ -975,7 +975,6 @@ u32 ODM_Get_Rate_Bitmap(
+ break;
+
+ case (ODM_WM_G):
+- case (ODM_WM_A):
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x00000f00;
+ else
+@@ -994,7 +993,6 @@ u32 ODM_Get_Rate_Bitmap(
+ case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
+ case (ODM_WM_B|ODM_WM_N24G):
+ case (ODM_WM_G|ODM_WM_N24G):
+- case (ODM_WM_A|ODM_WM_N5G):
+ if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) {
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x000f0000;
+@@ -1020,34 +1018,6 @@ u32 ODM_Get_Rate_Bitmap(
+ }
+ break;
+
+- case (ODM_WM_AC|ODM_WM_G):
+- if (rssi_level == 1)
+- rate_bitmap = 0xfc3f0000;
+- else if (rssi_level == 2)
+- rate_bitmap = 0xfffff000;
+- else
+- rate_bitmap = 0xffffffff;
+- break;
+-
+- case (ODM_WM_AC|ODM_WM_A):
+-
+- if (pDM_Odm->RFType == RF_1T1R) {
+- if (rssi_level == 1) /* add by Gary for ac-series */
+- rate_bitmap = 0x003f8000;
+- else if (rssi_level == 2)
+- rate_bitmap = 0x003ff000;
+- else
+- rate_bitmap = 0x003ff010;
+- } else {
+- if (rssi_level == 1) /* add by Gary for ac-series */
+- rate_bitmap = 0xfe3f8000; /* VHT 2SS MCS3~9 */
+- else if (rssi_level == 2)
+- rate_bitmap = 0xfffff000; /* VHT 2SS MCS0~9 */
+- else
+- rate_bitmap = 0xfffff010; /* All */
+- }
+- break;
+-
+ default:
+ if (pDM_Odm->RFType == RF_1T2R)
+ rate_bitmap = 0x000fffff;
+--- a/drivers/staging/rtl8723bs/hal/odm.h
++++ b/drivers/staging/rtl8723bs/hal/odm.h
+@@ -541,11 +541,8 @@ typedef enum tag_Wireless_Mode_Definitio
+ ODM_WM_UNKNOWN = 0x0,
+ ODM_WM_B = BIT0,
+ ODM_WM_G = BIT1,
+- ODM_WM_A = BIT2,
+ ODM_WM_N24G = BIT3,
+- ODM_WM_N5G = BIT4,
+ ODM_WM_AUTO = BIT5,
+- ODM_WM_AC = BIT6,
+ } ODM_WIRELESS_MODE_E;
+
+ /* ODM_CMNINFO_BAND */
+--- a/drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c
++++ b/drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c
+@@ -142,12 +142,10 @@ void odm_EdcaTurboCheckCE(void *pDM_VOID
+ } else if ((iot_peer == HT_IOT_PEER_CISCO) &&
+ ((wirelessmode == ODM_WM_G) ||
+ (wirelessmode == (ODM_WM_B | ODM_WM_G)) ||
+- (wirelessmode == ODM_WM_A) ||
+ (wirelessmode == ODM_WM_B))) {
+ EDCA_BE_DL = edca_setting_DL_GMode[iot_peer];
+ } else if ((iot_peer == HT_IOT_PEER_AIRGO) &&
+- ((wirelessmode == ODM_WM_G) ||
+- (wirelessmode == ODM_WM_A))) {
++ (wirelessmode == ODM_WM_G)) {
+ EDCA_BE_DL = 0xa630;
+ } else if (iot_peer == HT_IOT_PEER_MARVELL) {
+ EDCA_BE_DL = edca_setting_DL[iot_peer];
+--- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c
++++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c
+@@ -599,8 +599,6 @@ static void _InitOperationMode(struct ad
+ case WIRELESS_MODE_B:
+ regBwOpMode = BW_OPMODE_20MHZ;
+ break;
+- case WIRELESS_MODE_A:
+- break;
+ case WIRELESS_MODE_G:
+ regBwOpMode = BW_OPMODE_20MHZ;
+ break;
+@@ -612,9 +610,6 @@ static void _InitOperationMode(struct ad
+ /* CCK rate will be filtered out only when associated AP does not support it. */
+ regBwOpMode = BW_OPMODE_20MHZ;
+ break;
+- case WIRELESS_MODE_N_5G:
+- regBwOpMode = BW_OPMODE_5G;
+- break;
+
+ default: /* for MacOSX compiler warning. */
+ break;
+--- a/drivers/staging/rtl8723bs/include/hal_phy.h
++++ b/drivers/staging/rtl8723bs/include/hal_phy.h
+@@ -118,13 +118,10 @@ enum HW_BLOCK {
+
+ enum WIRELESS_MODE {
+ WIRELESS_MODE_UNKNOWN = 0x00,
+- WIRELESS_MODE_A = 0x01,
+ WIRELESS_MODE_B = 0x02,
+ WIRELESS_MODE_G = 0x04,
+ WIRELESS_MODE_AUTO = 0x08,
+ WIRELESS_MODE_N_24G = 0x10,
+- WIRELESS_MODE_N_5G = 0x20,
+- WIRELESS_MODE_AC_5G = 0x40,
+ WIRELESS_MODE_AC_24G = 0x80,
+ WIRELESS_MODE_AC_ONLY = 0x100,
+ };
+--- a/drivers/staging/rtl8723bs/include/ieee80211.h
++++ b/drivers/staging/rtl8723bs/include/ieee80211.h
+@@ -157,33 +157,20 @@ enum NETWORK_TYPE {
+ /* Sub-Element */
+ WIRELESS_11B = BIT(0), /* tx: cck only , rx: cck only, hw: cck */
+ WIRELESS_11G = BIT(1), /* tx: ofdm only, rx: ofdm & cck, hw: cck & ofdm */
+- WIRELESS_11A = BIT(2), /* tx: ofdm only, rx: ofdm only, hw: ofdm only */
+ WIRELESS_11_24N = BIT(3), /* tx: MCS only, rx: MCS & cck, hw: MCS & cck */
+- WIRELESS_11_5N = BIT(4), /* tx: MCS only, rx: MCS & ofdm, hw: ofdm only */
+ WIRELESS_AUTO = BIT(5),
+- WIRELESS_11AC = BIT(6),
+
+ /* Combination */
+ /* Type for current wireless mode */
+ WIRELESS_11BG = (WIRELESS_11B|WIRELESS_11G), /* tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm */
+ WIRELESS_11G_24N = (WIRELESS_11G|WIRELESS_11_24N), /* tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm */
+- WIRELESS_11A_5N = (WIRELESS_11A|WIRELESS_11_5N), /* tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only */
+ WIRELESS_11B_24N = (WIRELESS_11B|WIRELESS_11_24N), /* tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */
+ WIRELESS_11BG_24N = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N), /* tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */
+- WIRELESS_11_24AC = (WIRELESS_11G|WIRELESS_11AC),
+- WIRELESS_11_5AC = (WIRELESS_11A|WIRELESS_11AC),
+-
+-
+- /* Type for registry default wireless mode */
+- WIRELESS_11AGN = (WIRELESS_11A|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), /* tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only */
+- WIRELESS_11ABGN = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N),
+- WIRELESS_MODE_24G = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11AC),
+- WIRELESS_MODE_MAX = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N|WIRELESS_11AC),
+ };
+
+ #define SUPPORTED_24G_NETTYPE_MSK (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N)
+
+-#define IsLegacyOnly(NetType) ((NetType) == ((NetType) & (WIRELESS_11BG|WIRELESS_11A)))
++#define IsLegacyOnly(NetType) ((NetType) == ((NetType) & (WIRELESS_11BG)))
+
+ #define IsSupported24G(NetType) ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? true : false)
+
+@@ -195,11 +182,8 @@ enum NETWORK_TYPE {
+ #define IsSupportedRxHT(NetType) IsEnableHWOFDM(NetType)
+
+ #define IsSupportedTxCCK(NetType) (((NetType) & (WIRELESS_11B)) ? true : false)
+-#define IsSupportedTxOFDM(NetType) (((NetType) & (WIRELESS_11G|WIRELESS_11A)) ? true : false)
+-#define IsSupportedHT(NetType) (((NetType) & (WIRELESS_11_24N|WIRELESS_11_5N)) ? true : false)
+-
+-#define IsSupportedVHT(NetType) (((NetType) & (WIRELESS_11AC)) ? true : false)
+-
++#define IsSupportedTxOFDM(NetType) (((NetType) & (WIRELESS_11G) ? true : false)
++#define IsSupportedHT(NetType) (((NetType) & (WIRELESS_11_24N)) ? true : false)
+
+ struct ieee_param {
+ u32 cmd;
+--- a/drivers/staging/rtl8723bs/include/wifi.h
++++ b/drivers/staging/rtl8723bs/include/wifi.h
+@@ -457,7 +457,6 @@ static inline int IsFrameTypeCtrl(unsign
+ #define _PRE_ALLOCICVHDR_ 5
+ #define _PRE_ALLOCMICHDR_ 6
+
+-#define _SIFSTIME_ ((priv->pmib->dot11BssType.net_work_type&WIRELESS_11A)?16:10)
+ #define _ACKCTSLNG_ 14 /* 14 bytes long, including crclng */
+ #define _CRCLNG_ 4
+
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -24,7 +24,7 @@ static int rtw_lbkmode;/* RTL8712_AIR_TR
+ static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure;infra, ad-hoc, auto */
+ /* struct ndis_802_11_ssid ssid; */
+ static int rtw_channel = 1;/* ad-hoc support requirement */
+-static int rtw_wireless_mode = WIRELESS_MODE_MAX;
++static int rtw_wireless_mode = WIRELESS_11BG_24N;
+ static int rtw_vrtl_carrier_sense = AUTO_VCS;
+ static int rtw_vcs_type = RTS_CTS;/* */
+ static int rtw_rts_thresh = 2347;/* */
--- /dev/null
+From stable+bounces-274603-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:05 -0400
+Subject: staging: rtl8723bs: remove commented out condition
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-6-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 2a62ff13132a22a754d042b2230117bbea0af477 ]
+
+remove commented out condition checking channel > 14.
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/83762719c0c13ac8b78612a32db26e691eef17d1.1626874164.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -165,7 +165,7 @@ static char *translate_scan(struct adapt
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
+ }
+
+- if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig > 14*/)
++ if (pnetwork->network.Configuration.DSConfig < 1)
+ pnetwork->network.Configuration.DSConfig = 1;
+
+ /* Add frequency/channel */
--- /dev/null
+From stable+bounces-274599-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:01 -0400
+Subject: staging: rtl8723bs: remove commented out RT_ASSERT occurrences
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Dan Carpenter <dan.carpenter@oracle.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-2-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 2172a6576388e63958f47923e435c46af8d006ba ]
+
+remove commented out obsoete RT_ASSERT macro occurences.
+
+Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/3ee98d7bf1685af627e625f413de355fce58d52d.1619794331.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_recv.c | 2 --
+ drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c | 1 -
+ drivers/staging/rtl8723bs/hal/sdio_halinit.c | 5 -----
+ 3 files changed, 8 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
++++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
+@@ -2165,8 +2165,6 @@ int recv_indicatepkts_in_order(struct ad
+ /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */
+
+ /* Indicate packets */
+- /* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */
+-
+
+ /* indicate this recv_frame */
+ /* DbgPrint("recv_indicatepkts_in_order, indicate_seq =%d, seq_num =%d\n", precvpriv->indicate_seq, pattrib->seq_num); */
+--- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
++++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
+@@ -158,7 +158,6 @@ static int _WriteFW(struct adapter *pada
+ u8 *bufferPtr = buffer;
+
+ pageNums = size / MAX_DLFW_PAGE_SIZE;
+- /* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
+ remainSize = size % MAX_DLFW_PAGE_SIZE;
+
+ for (page = 0; page < pageNums; page++) {
+--- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c
++++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c
+@@ -313,7 +313,6 @@ static void _InitNormalChipOneOutEpPrior
+ value = QUEUE_NORMAL;
+ break;
+ default:
+- /* RT_ASSERT(false, ("Shall not reach here!\n")); */
+ break;
+ }
+
+@@ -347,7 +346,6 @@ static void _InitNormalChipTwoOutEpPrior
+ valueLow = QUEUE_NORMAL;
+ break;
+ default:
+- /* RT_ASSERT(false, ("Shall not reach here!\n")); */
+ break;
+ }
+
+@@ -412,7 +410,6 @@ static void _InitQueuePriority(struct ad
+ _InitNormalChipThreeOutEpPriority(Adapter);
+ break;
+ default:
+- /* RT_ASSERT(false, ("Shall not reach here!\n")); */
+ break;
+ }
+
+@@ -603,7 +600,6 @@ static void _InitOperationMode(struct ad
+ regBwOpMode = BW_OPMODE_20MHZ;
+ break;
+ case WIRELESS_MODE_A:
+-/* RT_ASSERT(false, ("Error wireless a mode\n")); */
+ break;
+ case WIRELESS_MODE_G:
+ regBwOpMode = BW_OPMODE_20MHZ;
+@@ -617,7 +613,6 @@ static void _InitOperationMode(struct ad
+ regBwOpMode = BW_OPMODE_20MHZ;
+ break;
+ case WIRELESS_MODE_N_5G:
+-/* RT_ASSERT(false, ("Error wireless mode")); */
+ regBwOpMode = BW_OPMODE_5G;
+ break;
+
--- /dev/null
+From stable+bounces-274677-greg=kroah.com@vger.kernel.org Wed Jul 15 04:45:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 22:45:34 -0400
+Subject: staging: rtl8723bs: remove DBG_871X log argument
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715024543.105642-1-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 42c3243ff23d119331a8ace011e0c18b222a1138 ]
+
+This patch prepares the application of the semantic
+patch aimed to remove all DBG_871X logs.
+
+One occurrence of the DBG_871X macro has one
+repeated argument, that's not even comma separated
+value with the previous one nor a format string
+parameter associated.
+
+In normal conditions this worked, for the macro
+is usually not expanded (the do nothing behaviour),
+but if I try to apply the sempantic patch to remove
+all macro occurrences, all macros call after that
+abnormal declaration are left untouched (not removed).
+
+Remove all of the DBG_871X logs as they currently
+do nothing as they require the code to be modified by
+hand in order to be turned on. This obviously has not happened
+since the code was merged, so just remove them as they are unused.
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/3473925ae9ee5a3bcd0ab86613dbce80b6d3f33f.1617802415.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: ed51de4a86e1 ("staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_recv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
++++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
+@@ -923,7 +923,7 @@ sint ap2sta_data_frame(
+ #ifdef DBG_RX_DROP_FRAME
+ DBG_871X("DBG_RX_DROP_FRAME %s BSSID ="MAC_FMT", mybssid ="MAC_FMT"\n",
+ __func__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
+- DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct adapter->adapter_type);
++ DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct);
+ #endif
+
+ if (!bmcast) {
--- /dev/null
+From stable+bounces-274598-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:00 -0400
+Subject: staging: rtl8723bs: split too long line
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-1-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 98dc120895a9a669e35155ee03b98452723aba95 ]
+
+fix the following post-commit hook checkpatch issue.
+
+WARNING: line length of 103 exceeds 100 columns
+30: FILE: drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:711:
++
+receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/4e87fb741205b9f314aec739921405a7ebef908a.1618480688.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -835,7 +835,8 @@ unsigned int OnBeacon(struct adapter *pa
+ ret = rtw_check_bcn_info(padapter, pframe, len);
+ if (!ret) {
+ DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
+- receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
++ receive_disconnect(padapter,
++ pmlmeinfo->network.MacAddress, 0);
+ return _SUCCESS;
+ }
+ /* update WMM, ERP in the beacon */
--- /dev/null
+From stable+bounces-277539-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:43 -0400
+Subject: usb: atm: ueagle-atm: wait for pre-firmware load in .disconnect()
+To: stable@vger.kernel.org
+Cc: Mauricio Faria de Oliveira <mfo@igalia.com>, stable <stable@kernel.org>, syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com, syzbot+306212936b13e520679d@syzkaller.appspotmail.com, syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com, Andrey Tsygunka <aitsygunka@yandex.ru>, Stanislaw Gruszka <stf_xl@wp.pl>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720023543.2969189-1-sashal@kernel.org>
+
+From: Mauricio Faria de Oliveira <mfo@igalia.com>
+
+[ Upstream commit e2674dfbed8a30d57e2bc872c4bfa6c3eec918bf ]
+
+ueagle-atm uses the asynchronous request_firmware_nowait() in .probe(),
+but does not wait for its completion, not even in .disconnect(); so, if the
+device is unplugged meanwhile, its teardown runs concurrently with that.
+
+Even though this inconsistency is worth addressing on its own, it has also
+triggered several bug reports in syzbot over the years (some auto-closed)
+where the firmware sysfs fallback mechanism (CONFIG_FW_LOADER_USER_HELPER)
+creates a firmware subdirectory in the device directory during its removal,
+which might hit unexpected conditions in kernfs, apparently, depending at
+which point the add and remove operations raced. (See links.)
+
+The pattern is:
+
+usb ?-?: Direct firmware load for ueagle-atm/eagle?.fw failed with error -2
+usb ?-?: Falling back to sysfs fallback for: ueagle-atm/eagle?.fw
+<ERROR>
+Call trace:
+ ...
+ kernfs_create_dir_ns
+ sysfs_create_dir_ns
+ create_dir
+ kobject_add_internal
+ kobject_add_varg
+ kobject_add
+ class_dir_create_and_add
+ get_device_parent
+ device_add
+ fw_load_sysfs_fallback
+ fw_load_from_user_helper
+ firmware_fallback_sysfs
+ _request_firmware
+ request_firmware_work_func
+ ...
+
+(Some variations are observed, after fw_load_sysfs_fallback(), e.g., [1].)
+
+While the kernfs side is being looked at, the ueagle-atm side can be fixed
+by waiting for the pre-firmware load in the .disconnect() handler.
+
+This change has a similar approach to previous work by Andrey Tsygunka [2]
+(wait_for_completion() in .disconnect()), but it is relatively different in
+design/implementation; using the Originally-by tag for credit assignment.
+
+This has been tested with:
+- synthetic reproducer to check the error path;
+- USB gadget (virtual device) to check the firmware upload path;
+- QEMU device emulator to check the device ID re-enumeration path;
+(The latter two were written by Claude; no other code/text in this commit.)
+
+Links (year first reported):
+ 2025 https://syzbot.org/bug?extid=ce1e5a1b4e086b43e56d
+ 2025 https://syzbot.org/bug?extid=9af8471255ac36e34fd4
+ 2024 https://syzbot.org/bug?extid=306212936b13e520679d
+ 2023 https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
+ 2022 https://syzbot.org/bug?extid=782984d6f1701b526edb
+ 2021 https://syzbot.org/bug?id=f3f221579f4ef7e9691281f3c6f56c05f83e8490
+ 2021 https://syzbot.org/bug?id=84d86f0d71394829df6fc53daf6642c045983881
+ 2021 https://syzbot.org/bug?id=3302dc1c0e2b9c94f2e8edb404eabc9267bc6f90
+
+[1] https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
+[2] https://lore.kernel.org/lkml/20250410093146.3776801-2-aitsygunka@yandex.ru/
+
+Cc: stable <stable@kernel.org>
+Reported-by: syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com
+Closes: https://syzbot.org/bug?extid=ce1e5a1b4e086b43e56d
+Reported-by: syzbot+306212936b13e520679d@syzkaller.appspotmail.com
+Closes: https://syzbot.org/bug?extid=306212936b13e520679d
+Reported-by: syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
+Originally-by: Andrey Tsygunka <aitsygunka@yandex.ru>
+Fixes: b72458a80c75 ("[PATCH] USB: Eagle and ADI 930 usb adsl modem driver")
+Assisted-by: Claude:claude-opus-4.7 # usb gadget & qemu device for testing
+Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Link: https://patch.msgid.link/20260526-ueagle-atm_req-fw-sync-v3-1-93c01961daaf@igalia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/atm/ueagle-atm.c | 36 +++++++++++++++++++++++++++++++-----
+ 1 file changed, 31 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/atm/ueagle-atm.c
++++ b/drivers/usb/atm/ueagle-atm.c
+@@ -599,7 +599,9 @@ static int uea_send_modem_cmd(struct usb
+ static void uea_upload_pre_firmware(const struct firmware *fw_entry,
+ void *context)
+ {
+- struct usb_device *usb = context;
++ struct usb_interface *intf = context;
++ struct usb_device *usb = interface_to_usbdev(intf);
++ struct completion *fw_done = usb_get_intfdata(intf);
+ const u8 *pfw;
+ u8 value;
+ u32 crc = 0;
+@@ -670,15 +672,17 @@ err_fw_corrupted:
+ err:
+ release_firmware(fw_entry);
+ uea_leaves(usb);
++ complete(fw_done);
+ }
+
+ /*
+ * uea_load_firmware - Load usb firmware for pre-firmware devices.
+ */
+-static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
++static int uea_load_firmware(struct usb_interface *intf, unsigned int ver)
+ {
+ int ret;
+ char *fw_name = EAGLE_FIRMWARE;
++ struct usb_device *usb = interface_to_usbdev(intf);
+
+ uea_enters(usb);
+ uea_info(usb, "pre-firmware device, uploading firmware\n");
+@@ -702,7 +706,7 @@ static int uea_load_firmware(struct usb_
+ }
+
+ ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
+- GFP_KERNEL, usb,
++ GFP_KERNEL, intf,
+ uea_upload_pre_firmware);
+ if (ret)
+ uea_err(usb, "firmware %s is not available\n", fw_name);
+@@ -2598,8 +2602,23 @@ static int uea_probe(struct usb_interfac
+
+ usb_reset_device(usb);
+
+- if (UEA_IS_PREFIRM(id))
+- return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
++ if (UEA_IS_PREFIRM(id)) {
++ struct completion *fw_done;
++
++ /* Wait for the firmware load to be done, in .disconnect() */
++ fw_done = kzalloc(sizeof(*fw_done), GFP_KERNEL);
++ if (!fw_done)
++ return -ENOMEM;
++
++ init_completion(fw_done);
++ usb_set_intfdata(intf, fw_done);
++
++ ret = uea_load_firmware(intf, UEA_CHIP_VERSION(id));
++ if (ret)
++ kfree(fw_done);
++
++ return ret;
++ }
+
+ ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ if (ret == 0) {
+@@ -2630,6 +2649,13 @@ static void uea_disconnect(struct usb_in
+ usbatm_usb_disconnect(intf);
+ mutex_unlock(&uea_mutex);
+ uea_info(usb, "ADSL device removed\n");
++ } else if (usb->config->desc.bNumInterfaces == 1) {
++ struct completion *fw_done = usb_get_intfdata(intf);
++
++ uea_dbg(usb, "pre-firmware device, waiting firmware upload\n");
++ wait_for_completion(fw_done);
++ uea_dbg(usb, "pre-firmware device, finished waiting\n");
++ kfree(fw_done);
+ }
+
+ uea_leaves(usb);
--- /dev/null
+From stable+bounces-277457-greg=kroah.com@vger.kernel.org Sun Jul 19 16:53:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 10:53:46 -0400
+Subject: usb: free iso schedules on failed submit
+To: stable@vger.kernel.org
+Cc: Dawei Feng <dawei.feng@seu.edu.cn>, stable <stable@kernel.org>, Alan Stern <stern@rowland.harvard.edu>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719145346.5460-1-sashal@kernel.org>
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit b9399d25fbb34a05bbe76eeedd730f62ff2670e9 ]
+
+EHCI and FOTG210 isochronous submits build an ehci_iso_sched before
+linking the URB to the endpoint queue, and keep the staged schedule in
+urb->hcpriv until iso_stream_schedule() and the link helpers consume it.
+If the controller is no longer accessible, or usb_hcd_link_urb_to_ep()
+fails, submit jumps to done_not_linked before that handoff happens and
+leaks the staged schedule still attached to urb->hcpriv.
+
+Free the staged schedule from done_not_linked when submit fails before
+the URB is linked and clear urb->hcpriv after the free.
+
+The bug was first flagged by an experimental analysis tool we are
+developing for kernel memory-management bugs while analyzing
+v6.13-rc1. The tool is still under development and is not yet publicly
+available. Manual inspection confirms that the bug is still
+present in v7.1.1.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have an
+EHCI host controller with a USB isochronous device to test with, no
+runtime testing was able to be performed.
+
+Fixes: 8de98402652c ("[PATCH] USB: Fix USB suspend/resume crasher (#2)")
+Fixes: e9df41c5c589 ("USB: make HCDs responsible for managing endpoint queues")
+Fixes: 7d50195f6c50 ("usb: host: Faraday fotg210-hcd driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://patch.msgid.link/20260630071419.349161-1-dawei.feng@seu.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/ehci-sched.c | 11 +++++++++--
+ drivers/usb/host/fotg210-hcd.c | 6 ++++--
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1613,6 +1613,7 @@ iso_stream_schedule(
+ status = 1; /* and give it back immediately */
+ iso_sched_free(stream, sched);
+ sched = NULL;
++ urb->hcpriv = NULL;
+ }
+ }
+ urb->error_count = skip / period;
+@@ -1643,8 +1644,6 @@ iso_stream_schedule(
+ return status;
+
+ fail:
+- iso_sched_free(stream, sched);
+- urb->hcpriv = NULL;
+ return status;
+ }
+
+@@ -1956,6 +1955,10 @@ static int itd_submit(struct ehci_hcd *e
+ usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+ }
+ done_not_linked:
++ if (status < 0) {
++ iso_sched_free(stream, urb->hcpriv);
++ urb->hcpriv = NULL;
++ }
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ done:
+ return status;
+@@ -2333,6 +2336,10 @@ static int sitd_submit(struct ehci_hcd *
+ usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+ }
+ done_not_linked:
++ if (status < 0) {
++ iso_sched_free(stream, urb->hcpriv);
++ urb->hcpriv = NULL;
++ }
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ done:
+ return status;
+--- a/drivers/usb/host/fotg210-hcd.c
++++ b/drivers/usb/host/fotg210-hcd.c
+@@ -4271,8 +4271,6 @@ static int iso_stream_schedule(struct fo
+ return 0;
+
+ fail:
+- iso_sched_free(stream, sched);
+- urb->hcpriv = NULL;
+ return status;
+ }
+
+@@ -4566,6 +4564,10 @@ static int itd_submit(struct fotg210_hcd
+ else
+ usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+ done_not_linked:
++ if (status < 0) {
++ iso_sched_free(stream, urb->hcpriv);
++ urb->hcpriv = NULL;
++ }
+ spin_unlock_irqrestore(&fotg210->lock, flags);
+ done:
+ return status;
--- /dev/null
+From sashal@kernel.org Mon Jul 20 15:59:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 09:59:20 -0400
+Subject: usb: gadget: f_fs: initialize reset_work at allocation time
+To: stable@vger.kernel.org
+Cc: "Tyler Baker" <tyler.baker@oss.qualcomm.com>, stable <stable@kernel.org>, "Loic Poulain" <loic.poulain@oss.qualcomm.com>, "Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>, "Srinivas Kandagatla" <srinivas.kandagatla@oss.qualcomm.com>, "Peter Chen" <peter.chen@kernel.org>, "Michał Nazarewicz" <mina86@mina86.com>, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720135920.1408367-1-sashal@kernel.org>
+
+From: Tyler Baker <tyler.baker@oss.qualcomm.com>
+
+[ Upstream commit 3137b243c93982fe3460335e12f9247739766e10 ]
+
+ffs_fs_kill_sb() unconditionally calls cancel_work_sync() on
+ffs->reset_work when a functionfs instance is unmounted:
+
+ ffs_data_reset(ffs);
+ cancel_work_sync(&ffs->reset_work);
+
+However ffs->reset_work is only ever initialized via INIT_WORK() in
+ffs_func_set_alt() and ffs_func_disable(), and only on the
+FFS_DEACTIVATED path. That state is reached solely by ffs_data_closed()
+when the instance is mounted with the "no_disconnect" option, so for the
+common case (no "no_disconnect", or mounted and unmounted without ever
+being deactivated) reset_work is never initialized.
+
+ffs_data_new() allocates the ffs_data with kzalloc_obj() and does not
+initialize reset_work, and ffs_data_reset()/ffs_data_clear() do not touch
+it either, so reset_work.func is left NULL. cancel_work_sync() on such a
+work then trips the WARN_ON(!work->func) guard in __flush_work():
+
+ WARNING: kernel/workqueue.c:4301 at __flush_work+0x330/0x360, CPU#3: umount
+ Call trace:
+ __flush_work
+ cancel_work_sync
+ ffs_fs_kill_sb [usb_f_fs]
+ deactivate_locked_super
+ deactivate_super
+ cleanup_mnt
+ __cleanup_mnt
+ task_work_run
+ exit_to_user_mode_loop
+ el0_svc
+
+On older kernels cancel_work_sync() on a zero-initialized work struct was
+a silent no-op, which hid the missing initialization.
+
+Initialize reset_work once in ffs_data_new() so it is always valid for
+the lifetime of the ffs_data, and drop the now-redundant INIT_WORK()
+calls from the two deactivation paths.
+
+Fixes: 18d6b32fca38 ("usb: gadget: f_fs: add "no_disconnect" mode")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Tyler Baker <tyler.baker@oss.qualcomm.com>
+Cc: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Cc: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Cc: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Tested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Acked-by: Michał Nazarewicz <mina86@mina86.com>
+Link: https://patch.msgid.link/20260609193635.2284430-1-tyler.baker@oss.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ dropped the ffs_func_disable hunk since 6.6 predates the disable-body split and routes disable through ffs_func_set_alt, so removing the single lazy INIT_WORK there covers both paths ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_fs.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -254,6 +254,7 @@ static int ffs_acquire_dev(const char *d
+ static void ffs_release_dev(struct ffs_dev *ffs_dev);
+ static int ffs_ready(struct ffs_data *ffs);
+ static void ffs_closed(struct ffs_data *ffs);
++static void ffs_reset_work(struct work_struct *work);
+
+ /* Misc helper functions ****************************************************/
+
+@@ -1774,6 +1775,7 @@ static struct ffs_data *ffs_data_new(con
+ init_waitqueue_head(&ffs->ev.waitq);
+ init_waitqueue_head(&ffs->wait);
+ init_completion(&ffs->ep0req_completion);
++ INIT_WORK(&ffs->reset_work, ffs_reset_work);
+
+ /* XXX REVISIT need to update it in some places, or do we? */
+ ffs->ev.can_stall = 1;
+@@ -3330,7 +3332,6 @@ static int ffs_func_set_alt(struct usb_f
+
+ if (ffs->state == FFS_DEACTIVATED) {
+ ffs->state = FFS_CLOSING;
+- INIT_WORK(&ffs->reset_work, ffs_reset_work);
+ schedule_work(&ffs->reset_work);
+ return -ENODEV;
+ }
--- /dev/null
+From sashal@kernel.org Mon Jul 20 17:56:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:56:40 -0400
+Subject: usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile
+To: stable@vger.kernel.org
+Cc: Neill Kapron <nkapron@google.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720155640.2425938-1-sashal@kernel.org>
+
+From: Neill Kapron <nkapron@google.com>
+
+[ Upstream commit 8bdcf96eb135aebacac319667f87db034fb38406 ]
+
+Currently, ffs_epfile_release unconditionally frees the endpoint's
+read_buffer when a file descriptor is closed. If userspace explicitly
+opens the endpoint multiple times and closes one, the read_buffer is
+destroyed. This can lead to silent data loss if other file descriptors
+are still actively reading from the endpoint.
+
+By tying the lifetime of the read_buffer to the ffs_epfile structure itself
+(which is destroyed when the functionfs instance is torn down in
+ffs_epfiles_destroy), we eliminate the brittle dependency on open/release
+calls while correctly matching the conceptual lifetime of unread data on
+the hardware endpoint.
+
+Fixes: 9353afbbfa7b ("usb: gadget: f_fs: buffer data from ‘oversized’ OUT requests")
+Cc: stable <stable@kernel.org>
+Assisted-by: Antigravity:gemini-3.1-pro
+Signed-off-by: Neill Kapron <nkapron@google.com>
+Link: https://patch.msgid.link/20260619040609.4010746-3-nkapron@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ adjusted context in ffs_epfiles_destroy() since 6.12 lacks the simple_remove_by_name() rework and still uses dentry-based cleanup ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -1279,7 +1279,6 @@ ffs_epfile_release(struct inode *inode,
+
+ ENTER();
+
+- __ffs_epfile_read_buffer_free(epfile);
+ ffs_data_closed(epfile->ffs);
+
+ return 0;
+@@ -1945,6 +1944,7 @@ static void ffs_epfiles_destroy(struct f
+
+ for (; count; --count, ++epfile) {
+ BUG_ON(mutex_is_locked(&epfile->mutex));
++ __ffs_epfile_read_buffer_free(epfile);
+ if (epfile->dentry) {
+ d_delete(epfile->dentry);
+ dput(epfile->dentry);
--- /dev/null
+From stable+bounces-277456-greg=kroah.com@vger.kernel.org Sun Jul 19 16:54:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 10:53:42 -0400
+Subject: usb: gadget: f_printer: take kref only for successful open
+To: stable@vger.kernel.org
+Cc: Xu Rao <raoxu@uniontech.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719145342.5397-2-sashal@kernel.org>
+
+From: Xu Rao <raoxu@uniontech.com>
+
+[ Upstream commit 30adce93d5c4a5a1ec29d9249e3fdfcc391d406b ]
+
+printer_open() returns -EBUSY when the character device is already
+open, but it increments dev->kref regardless of the return value. VFS
+does not call ->release() for a failed open, so every rejected second
+open permanently leaks one reference.
+
+Move kref_get() into the successful-open branch.
+
+Fixes: e8d5f92b8d30 ("usb: gadget: function: printer: fix use-after-free in __lock_acquire")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Xu Rao <raoxu@uniontech.com>
+Link: https://patch.msgid.link/80295742B820DA9B+20260626064617.4090626-1-raoxu@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_printer.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -358,12 +358,11 @@ printer_open(struct inode *inode, struct
+ ret = 0;
+ /* Change the printer status to show that it's on-line. */
+ dev->printer_status |= PRINTER_SELECTED;
++ kref_get(&dev->kref);
+ }
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- kref_get(&dev->kref);
+-
+ return ret;
+ }
+
--- /dev/null
+From stable+bounces-277455-greg=kroah.com@vger.kernel.org Sun Jul 19 16:53:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 10:53:41 -0400
+Subject: usb: gadget: function: Simplify diagnostic messaging in printer
+To: stable@vger.kernel.org
+Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719145342.5397-1-sashal@kernel.org>
+
+From: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+
+[ Upstream commit 57b7b733b1a7aeab25bc2670afff608214284863 ]
+
+Don't issue messages which can be easily achieved with ftrace.
+In case of printer_open() the return code is propagated to other layers
+so the user will know about -EBUSY anyway.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Link: https://lore.kernel.org/r/20221123110746.59611-1-andrzej.p@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 30adce93d5c4 ("usb: gadget: f_printer: take kref only for successful open")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_printer.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -363,7 +363,7 @@ printer_open(struct inode *inode, struct
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ kref_get(&dev->kref);
+- DBG(dev, "printer_open returned %x\n", ret);
++
+ return ret;
+ }
+
+@@ -381,7 +381,6 @@ printer_close(struct inode *inode, struc
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ kref_put(&dev->kref, printer_dev_free);
+- DBG(dev, "printer_close\n");
+
+ return 0;
+ }
+@@ -867,8 +866,6 @@ static void printer_reset_interface(stru
+ if (dev->interface < 0)
+ return;
+
+- DBG(dev, "%s\n", __func__);
+-
+ if (dev->in_ep->desc)
+ usb_ep_disable(dev->in_ep);
+
+@@ -906,8 +903,6 @@ static void printer_soft_reset(struct pr
+ {
+ struct usb_request *req;
+
+- INFO(dev, "Received Printer Reset Request\n");
+-
+ if (usb_ep_disable(dev->in_ep))
+ DBG(dev, "Failed to disable USB in_ep\n");
+ if (usb_ep_disable(dev->out_ep))
+@@ -1204,8 +1199,6 @@ static void printer_func_disable(struct
+ {
+ struct printer_dev *dev = func_to_printer(f);
+
+- DBG(dev, "%s\n", __func__);
+-
+ printer_reset_interface(dev);
+ }
+
--- /dev/null
+From stable+bounces-277503-greg=kroah.com@vger.kernel.org Sun Jul 19 18:39:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 12:39:18 -0400
+Subject: usb: iowarrior: remove inherent race with minor number
+To: stable@vger.kernel.org
+Cc: Oliver Neukum <oneukum@suse.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719163919.650822-1-sashal@kernel.org>
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 56dd29088c9d9510c48a8ebad2465248fde36551 ]
+
+The driver saves the minor number it gets upon registration
+in its descriptor for debugging purposes. However, there is
+inevitably a window between registration and saving the correct
+minor in a descriptor. During this window the debugging output
+will be wrong.
+As wrong debug output is worse than no debug output, just
+remove it.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://patch.msgid.link/20260312094619.1590556-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: c602254ba4c1 ("USB: iowarrior: fix use-after-free on disconnect race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/iowarrior.c | 17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -74,7 +74,6 @@ struct iowarrior {
+ struct mutex mutex; /* locks this structure */
+ struct usb_device *udev; /* save off the usb device pointer */
+ struct usb_interface *interface; /* the interface for this device */
+- unsigned char minor; /* the starting minor number for this device */
+ struct usb_endpoint_descriptor *int_out_endpoint; /* endpoint for reading (needed for IOW56 only) */
+ struct usb_endpoint_descriptor *int_in_endpoint; /* endpoint for reading */
+ struct urb *int_in_urb; /* the urb for reading data */
+@@ -246,7 +245,6 @@ static void iowarrior_write_callback(str
+ */
+ static inline void iowarrior_delete(struct iowarrior *dev)
+ {
+- dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor);
+ kfree(dev->int_in_buffer);
+ usb_free_urb(dev->int_in_urb);
+ kfree(dev->read_queue);
+@@ -297,9 +295,6 @@ static ssize_t iowarrior_read(struct fil
+ goto exit;
+ }
+
+- dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
+- dev->minor, count);
+-
+ /* read count must be packet size (+ time stamp) */
+ if ((count != dev->report_size)
+ && (count != (dev->report_size + 1))) {
+@@ -379,8 +374,6 @@ static ssize_t iowarrior_write(struct fi
+ retval = -ENODEV;
+ goto exit;
+ }
+- dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
+- dev->minor, count);
+ /* if count is 0 we're already done */
+ if (count == 0) {
+ retval = 0;
+@@ -526,9 +519,6 @@ static long iowarrior_ioctl(struct file
+ goto error_out;
+ }
+
+- dev_dbg(&dev->interface->dev, "minor %d, cmd 0x%.4x, arg %ld\n",
+- dev->minor, cmd, arg);
+-
+ retval = 0;
+ io_res = 0;
+ switch (cmd) {
+@@ -675,8 +665,6 @@ static int iowarrior_release(struct inod
+ if (!dev)
+ return -ENODEV;
+
+- dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor);
+-
+ /* lock our device */
+ mutex_lock(&dev->mutex);
+
+@@ -779,6 +767,7 @@ static int iowarrior_probe(struct usb_in
+ struct usb_host_interface *iface_desc;
+ int retval = -ENOMEM;
+ int res;
++ int minor;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
+@@ -894,12 +883,12 @@ static int iowarrior_probe(struct usb_in
+ goto error;
+ }
+
+- dev->minor = interface->minor;
++ minor = interface->minor;
+
+ /* let the user know what node this device is now attached to */
+ dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
+ "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
+- iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
++ iface_desc->desc.bInterfaceNumber, minor - IOWARRIOR_MINOR_BASE);
+ return retval;
+
+ error:
--- /dev/null
+From sashal@kernel.org Sun Jul 19 20:01:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 14:01:28 -0400
+Subject: USB: serial: digi_acceleport: fix write buffer corruption
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719180128.1055268-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 24ca1fea8f2753bf33e1d458ec1ae5d9b7796a65 ]
+
+The digi_write_inb_command() is supposed to wait for the write urb to
+become available or return an error, but instead it updates the transfer
+buffer and tries to resubmit the urb on timeout.
+
+To make things worse, for commands like break control where no timeout
+is used, the driver would corrupt the urb immediately due to a broken
+jiffies comparison (on 32-bit machines this takes five minutes of uptime
+to trigger due to INITIAL_JIFFIES).
+
+Fix this by adding the missing return on timeout and waiting
+indefinitely when no timeout has been specified as intended.
+
+This issue was (sort of) flagged by Sashiko when reviewing an unrelated
+change to the driver.
+
+Link: https://sashiko.dev/#/patchset/20260610132232.356139-1-johan%40kernel.org?part=11
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+[ adjusted context for 5.10's `&port->write_wait` (no `priv->write_wait`) and kept the existing `unsigned long flags = 0;` declaration alongside the new `expire` variable ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/digi_acceleport.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -431,20 +431,22 @@ static int digi_write_inb_command(struct
+ int len;
+ struct digi_port *priv = usb_get_serial_port_data(port);
+ unsigned char *data = port->write_urb->transfer_buffer;
++ unsigned long expire;
+ unsigned long flags = 0;
+
+ dev_dbg(&port->dev, "digi_write_inb_command: TOP: port=%d, count=%d\n",
+ priv->dp_port_num, count);
+
+ if (timeout)
+- timeout += jiffies;
+- else
+- timeout = ULONG_MAX;
++ expire = jiffies + timeout;
+
+ spin_lock_irqsave(&priv->dp_port_lock, flags);
+ while (count > 0 && ret == 0) {
+- while (priv->dp_write_urb_in_use &&
+- time_before(jiffies, timeout)) {
++ while (priv->dp_write_urb_in_use) {
++ if (timeout && time_after(jiffies, expire)) {
++ ret = -ETIMEDOUT;
++ break;
++ }
+ cond_wait_interruptible_timeout_irqrestore(
+ &port->write_wait, DIGI_RETRY_TIMEOUT,
+ &priv->dp_port_lock, flags);
+@@ -453,6 +455,9 @@ static int digi_write_inb_command(struct
+ spin_lock_irqsave(&priv->dp_port_lock, flags);
+ }
+
++ if (ret)
++ break;
++
+ /* len must be a multiple of 4 and small enough to */
+ /* guarantee the write will send buffered data first, */
+ /* so commands are in order with data and not split */
--- /dev/null
+From sashal@kernel.org Mon Jul 20 12:56:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 06:54:58 -0400
+Subject: usb: typec: tcpm: Fix VDM type for Enter Mode commands
+To: stable@vger.kernel.org
+Cc: Andy Yan <andyshrk@163.com>, stable <stable@kernel.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720105458.217218-1-sashal@kernel.org>
+
+From: Andy Yan <andyshrk@163.com>
+
+[ Upstream commit 9cff680e47632b7723cb19f9c5e63669063c3417 ]
+
+VDO() second parameter is VDM type (bit 15): 1 for SVDM, 0 for UVDM.
+Using 'vdo ? 2 : 1' corrupts SVID low bit when vdo is non-NULL
+(2 << 15 = BIT(16)). Enter Mode is always SVDM, hardcode to 1.
+
+Fixes: 8face9aa57c8 ("usb: typec: Add parameter for the VDO to typec_altmode_enter()")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Andy Yan <andyshrk@163.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260604105059.18750-1-andyshrk@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1671,7 +1671,7 @@ static int tcpm_altmode_enter(struct typ
+ struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
+ u32 header;
+
+- header = VDO(altmode->svid, vdo ? 2 : 1, CMD_ENTER_MODE);
++ header = VDO(altmode->svid, 1, CMD_ENTER_MODE);
+ header |= VDO_OPOS(altmode->mode);
+
+ tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0);
--- /dev/null
+From stable+bounces-277540-greg=kroah.com@vger.kernel.org Mon Jul 20 04:36:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:39 -0400
+Subject: usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove
+To: stable@vger.kernel.org
+Cc: Fan Wu <fanwu01@zju.edu.cn>, stable <stable@kernel.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-5-sashal@kernel.org>
+
+From: Fan Wu <fanwu01@zju.edu.cn>
+
+[ Upstream commit 1f0bdc2884b67de337215079bba166df0cdf4ac5 ]
+
+The threaded IRQ handler ccg_irq_handler() calls ucsi_notify_common(),
+which on a connector-change event calls ucsi_connector_change() and
+schedules connector work. In ucsi_ccg_remove(), ucsi_destroy() frees
+uc->ucsi (kfree) before free_irq() is called, so a handler invocation
+already in flight may access the freed object after ucsi_destroy().
+
+ CPU 0 (remove) | CPU 1 (threaded IRQ)
+ ucsi_destroy(uc->ucsi) | ccg_irq_handler()
+ kfree(ucsi) // FREE | ucsi_notify_common(uc->ucsi) // USE
+
+Move free_irq() before ucsi_destroy() in the remove path. It is kept
+after ucsi_unregister(): ucsi_unregister() cancels connector work whose
+handler issues GET_CONNECTOR_STATUS through ucsi_send_command_common(),
+which waits for a completion that is signalled from the IRQ handler, so
+the IRQ must stay active until that work has been cancelled.
+
+The probe error path already orders free_irq() before ucsi_destroy().
+
+This bug was found by static analysis.
+
+Fixes: e32fd989ac1c ("usb: typec: ucsi: ccg: Move to the new API")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260616132011.103279-1-fanwu01@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi_ccg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
+@@ -1418,8 +1418,8 @@ static int ucsi_ccg_remove(struct i2c_cl
+ cancel_work_sync(&uc->work);
+ pm_runtime_disable(uc->dev);
+ ucsi_unregister(uc->ucsi);
+- ucsi_destroy(uc->ucsi);
+ free_irq(uc->irq, uc);
++ ucsi_destroy(uc->ucsi);
+
+ return 0;
+ }
--- /dev/null
+From stable+bounces-274251-greg=kroah.com@vger.kernel.org Tue Jul 14 15:44:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:40:09 -0400
+Subject: vfio/pci: Release the VGA arbiter client on register_device() failure
+To: stable@vger.kernel.org
+Cc: Alex Williamson <alex.williamson@nvidia.com>, Kevin Tian <kevin.tian@intel.com>, Alex Williamson <alex@shazbot.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714134009.2674596-1-sashal@kernel.org>
+
+From: Alex Williamson <alex.williamson@nvidia.com>
+
+[ Upstream commit daedde7f024ecf88bc8e832ed40cf2c795f0796a ]
+
+The re-order in the Fixes commit below displaced vfio_pci_vga_init() as
+the last failure point of what is now vfio_pci_core_register_device()
+without introducing an unwind for the VGA arbiter registration.
+
+In current kernels this is mostly benign because vfio_pci_set_decode()
+only uses pci_dev state, but the original failure path could leave a
+callback with a freed vdev cookie. The stale registration also becomes
+unsafe again once the callback follows drvdata to the vfio device.
+
+Add the required VGA unwind callout.
+
+Fixes: 4aeec3984ddc ("vfio/pci: Re-order vfio_pci_probe()")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20260615191241.688297-3-alex.williamson@nvidia.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vfio/pci/vfio_pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -2094,6 +2094,7 @@ static int vfio_pci_probe(struct pci_dev
+ out_power:
+ if (!disable_idle_d3)
+ vfio_pci_set_power_state(vdev, PCI_D0);
++ vfio_pci_vga_uninit(vdev);
+ out_vf:
+ vfio_pci_vf_uninit(vdev);
+ out_reflck:
--- /dev/null
+From stable+bounces-276823-greg=kroah.com@vger.kernel.org Thu Jul 16 21:49:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 15:49:31 -0400
+Subject: writeback: fix race between cgroup_writeback_umount() and inode_switch_wbs()
+To: stable@vger.kernel.org
+Cc: Baokun Li <libaokun@linux.alibaba.com>, Jan Kara <jack@suse.cz>, Tejun Heo <tj@kernel.org>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716194931.1111583-1-sashal@kernel.org>
+
+From: Baokun Li <libaokun@linux.alibaba.com>
+
+[ Upstream commit cba38ec4cbd3a7b8b942a8d52531a05be8a9ff0d ]
+
+When a container exits, the following BUG_ON() is occasionally triggered:
+
+==================================================================
+ VFS: Busy inodes after unmount of sdb (ext4)
+ ------------[ cut here ]------------
+ kernel BUG at fs/super.c:695!
+ CPU: 3 PID: 6 Comm: containerd-shim Tainted: G OE K 6.6 #1
+ pstate: 63400009 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
+ pc : generic_shutdown_super+0xf0/0x100
+ lr : generic_shutdown_super+0xf0/0x100
+ Call trace:
+ generic_shutdown_super+0xf0/0x100
+ kill_block_super+0x20/0x48
+ ext4_kill_sb+0x28/0x60
+ deactivate_locked_super+0x54/0x130
+ deactivate_super+0x84/0xa0
+ cleanup_mnt+0xa4/0x140
+ __cleanup_mnt+0x18/0x28
+ task_work_run+0x78/0xe0
+ do_notify_resume+0x204/0x240
+==================================================================
+
+The root cause is a race between cgroup_writeback_umount() and
+inode_switch_wbs()/cleanup_offline_cgwb(). There is a window between
+inode_prepare_wbs_switch() returning true and the subsequent
+wb_queue_isw() call. Following is the process that triggers the issue:
+
+ CPU A (umount) | CPU B (writeback)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ inode_switch_wbs/cleanup_offline_cgwb
+ atomic_inc(&isw_nr_in_flight)
+ inode_prepare_wbs_switch
+ -> passes SB_ACTIVE check
+ __iget(inode)
+ generic_shutdown_super
+ sb->s_flags &= ~SB_ACTIVE
+ cgroup_writeback_umount(sb)
+ smp_mb()
+ atomic_read(&isw_nr_in_flight)
+ rcu_barrier()
+ -> no pending RCU callbacks
+ flush_workqueue(isw_wq)
+ -> nothing queued, returns
+ evict_inodes(sb)
+ -> Inode skipped as isw still holds a ref.
+ sop->put_super(sb)
+ /* destroys percpu counters */
+ -> VFS: Busy inodes after unmount!
+ wb_queue_isw()
+ queue_work(isw_wq, ...)
+ /* later in work function */
+ inode_switch_wbs_work_fn
+ process_inode_switch_wbs
+ iput() -> evict
+ percpu_counter_dec() // UAF!
+
+Fix this by extending the RCU read-side critical section in
+inode_switch_wbs() and cleanup_offline_cgwb() to cover from
+inode_prepare_wbs_switch() through wb_queue_isw(). Since there is
+no sleep in this window, rcu_read_lock() can be used. Then add a
+synchronize_rcu() in cgroup_writeback_umount() before the existing
+rcu_barrier(), so that all in-flight switchers that have passed the
+SB_ACTIVE check have completed queue_work() before flush_workqueue()
+is called.
+
+The existing rcu_barrier() is intentionally retained so this fix can
+be backported unchanged to stable kernels (5.10.y, 6.6.y, ...) that
+still queue switches via queue_rcu_work(). It is a no-op on current
+mainline (since commit e1b849cfa6b6 ("writeback: Avoid contention on
+wb->list_lock when switching inodes")) and is removed in a follow-up
+patch.
+
+Fixes: a1a0e23e4903 ("writeback: flush inode cgroup wb switches instead of pinning super_block")
+Cc: stable@vger.kernel.org
+Suggested-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/all/mxnjq2l6guusfchvauxr3v7c4bwjasybxlleqbbh4efloeqspz@iqylk76ohufz
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
+Link: https://patch.msgid.link/20260521095016.2791354-2-libaokun@linux.alibaba.com
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -507,12 +507,18 @@ static void inode_switch_wbs(struct inod
+
+ atomic_inc(&isw_nr_in_flight);
+
+- /* find and pin the new wb */
++ /*
++ * Paired with synchronize_rcu() in cgroup_writeback_umount():
++ * holding rcu_read_lock across the SB_ACTIVE check, the inode
++ * grab and call_rcu() ensures synchronize_rcu() cannot return
++ * until the switch is queued, so the subsequent rcu_barrier()
++ * and flush_workqueue() will wait for the switch.
++ */
+ rcu_read_lock();
++ /* find and pin the new wb */
+ memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys);
+ if (memcg_css && !css_tryget(memcg_css))
+ memcg_css = NULL;
+- rcu_read_unlock();
+ if (!memcg_css)
+ goto out_free;
+
+@@ -542,9 +548,11 @@ static void inode_switch_wbs(struct inod
+ * Let's continue after I_WB_SWITCH is guaranteed to be visible.
+ */
+ call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
++ rcu_read_unlock();
+ return;
+
+ out_free:
++ rcu_read_unlock();
+ atomic_dec(&isw_nr_in_flight);
+ if (isw->new_wb)
+ wb_put(isw->new_wb);
+@@ -1011,6 +1019,14 @@ void cgroup_writeback_umount(void)
+ {
+ if (atomic_read(&isw_nr_in_flight)) {
+ /*
++ * Paired with rcu_read_lock() in inode_switch_wbs().
++ * synchronize_rcu() waits for any in-flight switcher that
++ * already passed the SB_ACTIVE check to finish calling
++ * call_rcu(), so the rcu_barrier() and flush_workqueue()
++ * below will then drain it.
++ */
++ synchronize_rcu();
++ /*
+ * Use rcu_barrier() to wait for all pending callbacks to
+ * ensure that all in-flight wb switches are in the workqueue.
+ */
--- /dev/null
+From stable+bounces-276826-greg=kroah.com@vger.kernel.org Thu Jul 16 21:54:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 15:54:23 -0400
+Subject: X.509: Fix validation of ASN.1 certificate header
+To: stable@vger.kernel.org
+Cc: Lukas Wunner <lukas@wunner.de>, Sashiko <sashiko-bot@kernel.org>, Ignat Korchagin <ignat@linux.win>, Alistair Francis <alistair.francis@wdc.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716195423.1113794-1-sashal@kernel.org>
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 3b626ba431c4501512ad07549310685e07fe4706 ]
+
+x509_load_certificate_list() seeks to enforce that a certificate starts
+with 0x30 0x82 (ASN.1 SEQUENCE tag followed by a length of more than 256
+and less than 65535 bytes).
+
+But it only enforces that *either* of those two byte values are present,
+instead of checking for the *conjunction* of the two values. Fix it.
+
+Fixes: 631cc66eb9ea ("MODSIGN: Provide module signing public keys to the kernel")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://lore.kernel.org/r/20260508033917.B5873C2BCB0@smtp.kernel.org/
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.7+
+Reviewed-by: Ignat Korchagin <ignat@linux.win>
+Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ certs/common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/certs/common.c
++++ b/certs/common.c
+@@ -20,7 +20,7 @@ int load_certificate_list(const u8 cert_
+ */
+ if (end - p < 4)
+ goto dodgy_cert;
+- if (p[0] != 0x30 &&
++ if (p[0] != 0x30 ||
+ p[1] != 0x82)
+ goto dodgy_cert;
+ plen = (p[2] << 8) | p[3];
--- /dev/null
+From stable+bounces-277293-greg=kroah.com@vger.kernel.org Sat Jul 18 13:21:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 07:20:48 -0400
+Subject: xfs: fix unreachable BIGTIME check in dquot flush validation
+To: stable@vger.kernel.org
+Cc: Alexey Nepomnyashih <sdl@nppct.ru>, "Darrick J. Wong" <djwong@kernel.org>, Allison Henderson <achender@kernel.org>, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718112048.2959902-2-sashal@kernel.org>
+
+From: Alexey Nepomnyashih <sdl@nppct.ru>
+
+[ Upstream commit 03866d130ed33ab68cc7faaf4bf2c4abef96d42e ]
+
+The dqp->q_id == 0 check inside the XFS_DQTYPE_BIGTIME block is
+unreachable because root dquots return successfully earlier. Reject root
+dquots with XFS_DQTYPE_BIGTIME before that early return, preserving the
+intended validation and removing the unreachable condition.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 4ea1ff3b4968 ("xfs: widen ondisk quota expiration timestamps to handle y2038+")
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Alexey Nepomnyashih <sdl@nppct.ru>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_dquot.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/fs/xfs/xfs_dquot.c
++++ b/fs/xfs/xfs_dquot.c
+@@ -1201,6 +1201,14 @@ xfs_qm_dqflush_check(
+ type != XFS_DQTYPE_PROJ)
+ return __this_address;
+
++ /* bigtime flag should never be set on root dquots */
++ if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
++ if (!xfs_has_bigtime(dqp->q_mount))
++ return __this_address;
++ if (dqp->q_id == 0)
++ return __this_address;
++ }
++
+ if (dqp->q_id == 0)
+ return NULL;
+
+@@ -1216,14 +1224,6 @@ xfs_qm_dqflush_check(
+ !dqp->q_rtb.timer)
+ return __this_address;
+
+- /* bigtime flag should never be set on root dquots */
+- if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
+- if (!xfs_has_bigtime(dqp->q_mount))
+- return __this_address;
+- if (dqp->q_id == 0)
+- return __this_address;
+- }
+-
+ return NULL;
+ }
+
--- /dev/null
+From stable+bounces-277292-greg=kroah.com@vger.kernel.org Sat Jul 18 13:20:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 07:20:47 -0400
+Subject: xfs: reflect sb features in xfs_mount
+To: stable@vger.kernel.org
+Cc: Dave Chinner <dchinner@redhat.com>, Christoph Hellwig <hch@lst.de>, "Darrick J. Wong" <djwong@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718112048.2959902-1-sashal@kernel.org>
+
+From: Dave Chinner <dchinner@redhat.com>
+
+[ Upstream commit a1d86e8dec8c1325d301c9d5594bb794bc428fc3 ]
+
+Currently on-disk feature checks require decoding the superblock
+fileds and so can be non-trivial. We have almost 400 hundred
+individual feature checks in the XFS code, so this is a significant
+amount of code. To reduce runtime check overhead, pre-process all
+the version flags into a features field in the xfs_mount at mount
+time so we can convert all the feature checks to a simple flag
+check.
+
+There is also a need to convert the dynamic feature flags to update
+the m_features field. This is required for attr, attr2 and quota
+features. New xfs_mount based wrappers are added for this.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Stable-dep-of: 03866d130ed3 ("xfs: fix unreachable BIGTIME check in dquot flush validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_format.h | 2 -
+ fs/xfs/libxfs/xfs_sb.c | 64 ++++++++++++++++++++++++++++++++++++++
+ fs/xfs/libxfs/xfs_sb.h | 1
+ fs/xfs/xfs_dquot.c | 2 -
+ fs/xfs/xfs_log_recover.c | 1
+ fs/xfs/xfs_mount.c | 1
+ fs/xfs/xfs_mount.h | 75 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/xfs/xfs_rtalloc.c | 3 +
+ 8 files changed, 147 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_format.h
++++ b/fs/xfs/libxfs/xfs_format.h
+@@ -412,7 +412,7 @@ static inline bool xfs_sb_version_haspro
+ (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT));
+ }
+
+-static inline void xfs_sb_version_addprojid32bit(struct xfs_sb *sbp)
++static inline void xfs_sb_version_addprojid32(struct xfs_sb *sbp)
+ {
+ sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
+ sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -91,6 +91,70 @@ xfs_perag_put(
+ trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
+ }
+
++uint64_t
++xfs_sb_version_to_features(
++ struct xfs_sb *sbp)
++{
++ uint64_t features = 0;
++
++ /* optional V4 features */
++ if (sbp->sb_rblocks > 0)
++ features |= XFS_FEAT_REALTIME;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT)
++ features |= XFS_FEAT_ATTR;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT)
++ features |= XFS_FEAT_QUOTA;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT)
++ features |= XFS_FEAT_ALIGN;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT)
++ features |= XFS_FEAT_LOGV2;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT)
++ features |= XFS_FEAT_DALIGN;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT)
++ features |= XFS_FEAT_EXTFLG;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT)
++ features |= XFS_FEAT_SECTOR;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT)
++ features |= XFS_FEAT_ASCIICI;
++ if (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) {
++ if (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)
++ features |= XFS_FEAT_LAZYSBCOUNT;
++ if (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT)
++ features |= XFS_FEAT_ATTR2;
++ if (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT)
++ features |= XFS_FEAT_PROJID32;
++ if (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE)
++ features |= XFS_FEAT_FTYPE;
++ }
++
++ if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5)
++ return features;
++
++ /* Always on V5 features */
++ features |= XFS_FEAT_ALIGN | XFS_FEAT_LOGV2 | XFS_FEAT_EXTFLG |
++ XFS_FEAT_LAZYSBCOUNT | XFS_FEAT_ATTR2 | XFS_FEAT_PROJID32 |
++ XFS_FEAT_V3INODES | XFS_FEAT_CRC | XFS_FEAT_PQUOTINO;
++
++ /* Optional V5 features */
++ if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT)
++ features |= XFS_FEAT_FINOBT;
++ if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT)
++ features |= XFS_FEAT_RMAPBT;
++ if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK)
++ features |= XFS_FEAT_REFLINK;
++ if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
++ features |= XFS_FEAT_INOBTCNT;
++ if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_FTYPE)
++ features |= XFS_FEAT_FTYPE;
++ if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_SPINODES)
++ features |= XFS_FEAT_SPINODES;
++ if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID)
++ features |= XFS_FEAT_META_UUID;
++ if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_BIGTIME)
++ features |= XFS_FEAT_BIGTIME;
++ return features;
++}
++
+ /* Check all the superblock fields we care about when reading one in. */
+ STATIC int
+ xfs_validate_sb_read(
+--- a/fs/xfs/libxfs/xfs_sb.h
++++ b/fs/xfs/libxfs/xfs_sb.h
+@@ -29,6 +29,7 @@ extern void xfs_sb_mount_common(struct x
+ extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
+ extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
+ extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp);
++extern uint64_t xfs_sb_version_to_features(struct xfs_sb *sbp);
+
+ extern int xfs_update_secondary_sbs(struct xfs_mount *mp);
+
+--- a/fs/xfs/xfs_dquot.c
++++ b/fs/xfs/xfs_dquot.c
+@@ -1218,7 +1218,7 @@ xfs_qm_dqflush_check(
+
+ /* bigtime flag should never be set on root dquots */
+ if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
+- if (!xfs_sb_version_hasbigtime(&dqp->q_mount->m_sb))
++ if (!xfs_has_bigtime(dqp->q_mount))
+ return __this_address;
+ if (dqp->q_id == 0)
+ return __this_address;
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -3325,6 +3325,7 @@ xlog_do_recover(
+ xfs_buf_relse(bp);
+
+ /* re-initialise in-core superblock and geometry structures */
++ mp->m_features |= xfs_sb_version_to_features(sbp);
+ xfs_reinit_percpu_counters(mp);
+ error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
+ if (error) {
+--- a/fs/xfs/xfs_mount.c
++++ b/fs/xfs/xfs_mount.c
+@@ -345,6 +345,7 @@ reread:
+ goto reread;
+ }
+
++ mp->m_features |= xfs_sb_version_to_features(sbp);
+ xfs_reinit_percpu_counters(mp);
+
+ /* no need to be quiet anymore, so reset the buf ops */
+--- a/fs/xfs/xfs_mount.h
++++ b/fs/xfs/xfs_mount.h
+@@ -131,6 +131,7 @@ typedef struct xfs_mount {
+ int m_fixedfsid[2]; /* unchanged for life of FS */
+ uint m_qflags; /* quota status flags */
+ uint64_t m_flags; /* global mount flags */
++ uint64_t m_features; /* active filesystem features */
+ int64_t m_low_space[XFS_LOWSP_MAX];
+ struct xfs_ino_geometry m_ino_geo; /* inode geometry */
+ struct xfs_trans_resv m_resv; /* precomputed res values */
+@@ -222,6 +223,80 @@ typedef struct xfs_mount {
+ #define M_IGEO(mp) (&(mp)->m_ino_geo)
+
+ /*
++ * Flags for m_features.
++ *
++ * These are all the active features in the filesystem, regardless of how
++ * they are configured.
++ */
++#define XFS_FEAT_ATTR (1ULL << 0) /* xattrs present in fs */
++#define XFS_FEAT_NLINK (1ULL << 1) /* 32 bit link counts */
++#define XFS_FEAT_QUOTA (1ULL << 2) /* quota active */
++#define XFS_FEAT_ALIGN (1ULL << 3) /* inode alignment */
++#define XFS_FEAT_DALIGN (1ULL << 4) /* data alignment */
++#define XFS_FEAT_LOGV2 (1ULL << 5) /* version 2 logs */
++#define XFS_FEAT_SECTOR (1ULL << 6) /* sector size > 512 bytes */
++#define XFS_FEAT_EXTFLG (1ULL << 7) /* unwritten extents */
++#define XFS_FEAT_ASCIICI (1ULL << 8) /* ASCII only case-insens. */
++#define XFS_FEAT_LAZYSBCOUNT (1ULL << 9) /* Superblk counters */
++#define XFS_FEAT_ATTR2 (1ULL << 10) /* dynamic attr fork */
++#define XFS_FEAT_PARENT (1ULL << 11) /* parent pointers */
++#define XFS_FEAT_PROJID32 (1ULL << 12) /* 32 bit project id */
++#define XFS_FEAT_CRC (1ULL << 13) /* metadata CRCs */
++#define XFS_FEAT_V3INODES (1ULL << 14) /* Version 3 inodes */
++#define XFS_FEAT_PQUOTINO (1ULL << 15) /* non-shared proj/grp quotas */
++#define XFS_FEAT_FTYPE (1ULL << 16) /* inode type in dir */
++#define XFS_FEAT_FINOBT (1ULL << 17) /* free inode btree */
++#define XFS_FEAT_RMAPBT (1ULL << 18) /* reverse map btree */
++#define XFS_FEAT_REFLINK (1ULL << 19) /* reflinked files */
++#define XFS_FEAT_SPINODES (1ULL << 20) /* sparse inode chunks */
++#define XFS_FEAT_META_UUID (1ULL << 21) /* metadata UUID */
++#define XFS_FEAT_REALTIME (1ULL << 22) /* realtime device present */
++#define XFS_FEAT_INOBTCNT (1ULL << 23) /* inobt block counts */
++#define XFS_FEAT_BIGTIME (1ULL << 24) /* large timestamps */
++#define XFS_FEAT_NEEDSREPAIR (1ULL << 25) /* needs xfs_repair */
++
++#define __XFS_HAS_FEAT(name, NAME) \
++static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
++{ \
++ return mp->m_features & XFS_FEAT_ ## NAME; \
++}
++
++/* Some features can be added dynamically so they need a set wrapper, too. */
++#define __XFS_ADD_FEAT(name, NAME) \
++ __XFS_HAS_FEAT(name, NAME); \
++static inline void xfs_add_ ## name (struct xfs_mount *mp) \
++{ \
++ mp->m_features |= XFS_FEAT_ ## NAME; \
++ xfs_sb_version_add ## name(&mp->m_sb); \
++}
++
++__XFS_HAS_FEAT(nlink, NLINK)
++__XFS_ADD_FEAT(quota, QUOTA)
++__XFS_HAS_FEAT(align, ALIGN)
++__XFS_HAS_FEAT(dalign, DALIGN)
++__XFS_HAS_FEAT(logv2, LOGV2)
++__XFS_HAS_FEAT(sector, SECTOR)
++__XFS_HAS_FEAT(extflg, EXTFLG)
++__XFS_HAS_FEAT(asciici, ASCIICI)
++__XFS_HAS_FEAT(lazysbcount, LAZYSBCOUNT)
++__XFS_ADD_FEAT(attr2, ATTR2)
++__XFS_HAS_FEAT(parent, PARENT)
++__XFS_ADD_FEAT(projid32, PROJID32)
++__XFS_HAS_FEAT(crc, CRC)
++__XFS_HAS_FEAT(v3inodes, V3INODES)
++__XFS_HAS_FEAT(pquotino, PQUOTINO)
++__XFS_HAS_FEAT(ftype, FTYPE)
++__XFS_HAS_FEAT(finobt, FINOBT)
++__XFS_HAS_FEAT(rmapbt, RMAPBT)
++__XFS_HAS_FEAT(reflink, REFLINK)
++__XFS_HAS_FEAT(sparseinodes, SPINODES)
++__XFS_HAS_FEAT(metauuid, META_UUID)
++__XFS_HAS_FEAT(realtime, REALTIME)
++__XFS_HAS_FEAT(inobtcounts, INOBTCNT)
++__XFS_HAS_FEAT(bigtime, BIGTIME)
++__XFS_HAS_FEAT(needsrepair, NEEDSREPAIR)
++
++/*
+ * Flags for m_flags.
+ */
+ #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops
+--- a/fs/xfs/xfs_rtalloc.c
++++ b/fs/xfs/xfs_rtalloc.c
+@@ -1101,6 +1101,9 @@ error_cancel:
+ error = xfs_trans_commit(tp);
+ if (error)
+ break;
++
++ /* Ensure the mount RT feature flag is now set. */
++ mp->m_features |= XFS_FEAT_REALTIME;
+ }
+ if (error)
+ goto out_free;
--- /dev/null
+From stable+bounces-277294-greg=kroah.com@vger.kernel.org Sat Jul 18 13:21:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 07:21:01 -0400
+Subject: xfs: use null daddr for unset first bad log block
+To: stable@vger.kernel.org
+Cc: Yousef Alhouseen <alhouseenyousef@gmail.com>, "Darrick J. Wong" <djwong@kernel.org>, syzbot+b7dfbed0c6c2b5e9fd34@syzkaller.appspotmail.com, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718112101.2964955-1-sashal@kernel.org>
+
+From: Yousef Alhouseen <alhouseenyousef@gmail.com>
+
+[ Upstream commit cc9af5e461ea5f6e37738f3f1e41c45a9b7f45d6 ]
+
+xlog_do_recovery_pass() may return before setting first_bad. The caller
+must distinguish that case from an error at a valid log block, including
+block zero after the log wraps.
+
+Initialize first_bad to XFS_BUF_DADDR_NULL and test it explicitly before
+treating the error as a torn write.
+
+Fixes: 7088c4136fa1 ("xfs: detect and trim torn writes during log recovery")
+Suggested-by: Darrick J. Wong <djwong@kernel.org>
+Reported-by: syzbot+b7dfbed0c6c2b5e9fd34@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b7dfbed0c6c2b5e9fd34
+Cc: stable@vger.kernel.org # v4.5
+Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+[ adjusted hunk offsets for context drift and dropped an inapplicable whitespace-only end-of-file hunk whose context doesn't exist in 5.10 ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_log_recover.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -1034,7 +1034,7 @@ xlog_verify_head(
+ {
+ struct xlog_rec_header *tmp_rhead;
+ char *tmp_buffer;
+- xfs_daddr_t first_bad;
++ xfs_daddr_t first_bad = XFS_BUF_DADDR_NULL;
+ xfs_daddr_t tmp_rhead_blk;
+ int found;
+ int error;
+@@ -1063,7 +1063,8 @@ xlog_verify_head(
+ */
+ error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk,
+ XLOG_RECOVER_CRCPASS, &first_bad);
+- if ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) {
++ if ((error == -EFSBADCRC || error == -EFSCORRUPTED) &&
++ first_bad != XFS_BUF_DADDR_NULL) {
+ /*
+ * We've hit a potential torn write. Reset the error and warn
+ * about it.