--- /dev/null
+From 0f9242b08ecf66d505597300e879774795c4f441 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 09:31:04 +0200
+Subject: ALSA: sh: SND_AICA should depend on SH_DMA_API
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 66e48ef6ef506c89ec1b3851c6f9f5f80b5835ff ]
+
+If CONFIG_SH_DMA_API=n:
+
+ WARNING: unmet direct dependencies detected for G2_DMA
+ Depends on [n]: SH_DREAMCAST [=y] && SH_DMA_API [=n]
+ Selected by [y]:
+ - SND_AICA [=y] && SOUND [=y] && SND [=y] && SND_SUPERH [=y] && SH_DREAMCAST [=y]
+
+SND_AICA selects G2_DMA. As the latter depends on SH_DMA_API, the
+former should depend on SH_DMA_API, too.
+
+Fixes: f477a538c14d07f8 ("sh: dma: fix kconfig dependency for G2_DMA")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202505131320.PzgTtl9H-lkp@intel.com/
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/b90625f8a9078d0d304bafe862cbe3a3fab40082.1747121335.git.geert+renesas@glider.be
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/sh/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig
+index b75fbb3236a7b..f5fa09d740b4c 100644
+--- a/sound/sh/Kconfig
++++ b/sound/sh/Kconfig
+@@ -14,7 +14,7 @@ if SND_SUPERH
+
+ config SND_AICA
+ tristate "Dreamcast Yamaha AICA sound"
+- depends on SH_DREAMCAST
++ depends on SH_DREAMCAST && SH_DMA_API
+ select SND_PCM
+ select G2_DMA
+ help
+--
+2.39.5
+
--- /dev/null
+From 0ed4a5c266093f42710f33991d79877f455a6f03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Apr 2025 11:34:25 +0100
+Subject: iio: adc: ad7768-1: Fix insufficient alignment of timestamp.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ffbc26bc91c1f1eb3dcf5d8776e74cbae21ee13a ]
+
+On architectures where an s64 is not 64-bit aligned, this may result
+insufficient alignment of the timestamp and the structure being too small.
+Use aligned_s64 to force the alignment.
+
+Fixes: a1caeebab07e ("iio: adc: ad7768-1: Fix too small buffer passed to iio_push_to_buffers_with_timestamp()") # aligned_s64 newer
+Reported-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250413103443.2420727-3-jic23@kernel.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7768-1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index c1adb95f2a464..fd9aea1453201 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -168,7 +168,7 @@ struct ad7768_state {
+ union {
+ struct {
+ __be32 chan;
+- s64 timestamp;
++ aligned_s64 timestamp;
+ } scan;
+ __be32 d32;
+ u8 d8[2];
+--
+2.39.5
+
--- /dev/null
+From 136ffa9ffa6232d733356e9c4608de4b4f2c3844 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 11:52:37 -0500
+Subject: iio: chemical: sps30: use aligned_s64 for timestamp
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: David Lechner <dlechner@baylibre.com>
+
+[ Upstream commit bb49d940344bcb8e2b19e69d7ac86f567887ea9a ]
+
+Follow the pattern of other drivers and use aligned_s64 for the
+timestamp. This will ensure that the timestamp is correctly aligned on
+all architectures.
+
+Fixes: a5bf6fdd19c3 ("iio:chemical:sps30: Fix timestamp alignment")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250417-iio-more-timestamp-alignment-v1-5-eafac1e22318@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/chemical/sps30.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c
+index c0845d892faad..0e466106becb4 100644
+--- a/drivers/iio/chemical/sps30.c
++++ b/drivers/iio/chemical/sps30.c
+@@ -232,7 +232,7 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p)
+ int ret;
+ struct {
+ s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
+- s64 ts;
++ aligned_s64 ts;
+ } scan;
+
+ mutex_lock(&state->lock);
+--
+2.39.5
+
--- /dev/null
+From 386ab7ac3886f796009ef09da76014df6ee4b179 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 14:38:16 +0300
+Subject: net: dsa: sja1105: discard incoming frames in BR_STATE_LISTENING
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 498625a8ab2c8e1c9ab5105744310e8d6952cc01 ]
+
+It has been reported that when under a bridge with stp_state=1, the logs
+get spammed with this message:
+
+[ 251.734607] fsl_dpaa2_eth dpni.5 eth0: Couldn't decode source port
+
+Further debugging shows the following info associated with packets:
+source_port=-1, switch_id=-1, vid=-1, vbid=1
+
+In other words, they are data plane packets which are supposed to be
+decoded by dsa_tag_8021q_find_port_by_vbid(), but the latter (correctly)
+refuses to do so, because no switch port is currently in
+BR_STATE_LEARNING or BR_STATE_FORWARDING - so the packet is effectively
+unexpected.
+
+The error goes away after the port progresses to BR_STATE_LEARNING in 15
+seconds (the default forward_time of the bridge), because then,
+dsa_tag_8021q_find_port_by_vbid() can correctly associate the data plane
+packets with a plausible bridge port in a plausible STP state.
+
+Re-reading IEEE 802.1D-1990, I see the following:
+
+"4.4.2 Learning: (...) The Forwarding Process shall discard received
+frames."
+
+IEEE 802.1D-2004 further clarifies:
+
+"DISABLED, BLOCKING, LISTENING, and BROKEN all correspond to the
+DISCARDING port state. While those dot1dStpPortStates serve to
+distinguish reasons for discarding frames, the operation of the
+Forwarding and Learning processes is the same for all of them. (...)
+LISTENING represents a port that the spanning tree algorithm has
+selected to be part of the active topology (computing a Root Port or
+Designated Port role) but is temporarily discarding frames to guard
+against loops or incorrect learning."
+
+Well, this is not what the driver does - instead it sets
+mac[port].ingress = true.
+
+To get rid of the log spam, prevent unexpected data plane packets to
+be received by software by discarding them on ingress in the LISTENING
+state.
+
+In terms of blame attribution: the prints only date back to commit
+d7f9787a763f ("net: dsa: tag_8021q: add support for imprecise RX based
+on the VBID"). However, the settings would permit a LISTENING port to
+forward to a FORWARDING port, and the standard suggests that's not OK.
+
+Fixes: 640f763f98c2 ("net: dsa: sja1105: Add support for Spanning Tree Protocol")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250509113816.2221992-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index eab861352bf23..007eb05ed659f 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1390,6 +1390,7 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
+ switch (state) {
+ case BR_STATE_DISABLED:
+ case BR_STATE_BLOCKING:
++ case BR_STATE_LISTENING:
+ /* From UM10944 description of DRPDTAG (why put this there?):
+ * "Management traffic flows to the port regardless of the state
+ * of the INGRESS flag". So BPDUs are still be allowed to pass.
+@@ -1399,11 +1400,6 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
+ mac[port].egress = false;
+ mac[port].dyn_learn = false;
+ break;
+- case BR_STATE_LISTENING:
+- mac[port].ingress = true;
+- mac[port].egress = false;
+- mac[port].dyn_learn = false;
+- break;
+ case BR_STATE_LEARNING:
+ mac[port].ingress = true;
+ mac[port].egress = false;
+--
+2.39.5
+
--- /dev/null
+From bff46f3446358d126f30a5be496428102b12edac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 15:25:08 +0800
+Subject: nfs: handle failure of nfs_get_lock_context in unlock path
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit c457dc1ec770a22636b473ce5d35614adfe97636 ]
+
+When memory is insufficient, the allocation of nfs_lock_context in
+nfs_get_lock_context() fails and returns -ENOMEM. If we mistakenly treat
+an nfs4_unlockdata structure (whose l_ctx member has been set to -ENOMEM)
+as valid and proceed to execute rpc_run_task(), this will trigger a NULL
+pointer dereference in nfs4_locku_prepare. For example:
+
+BUG: kernel NULL pointer dereference, address: 000000000000000c
+PGD 0 P4D 0
+Oops: Oops: 0000 [#1] SMP PTI
+CPU: 15 UID: 0 PID: 12 Comm: kworker/u64:0 Not tainted 6.15.0-rc2-dirty #60
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40
+Workqueue: rpciod rpc_async_schedule
+RIP: 0010:nfs4_locku_prepare+0x35/0xc2
+Code: 89 f2 48 89 fd 48 c7 c7 68 69 ef b5 53 48 8b 8e 90 00 00 00 48 89 f3
+RSP: 0018:ffffbbafc006bdb8 EFLAGS: 00010246
+RAX: 000000000000004b RBX: ffff9b964fc1fa00 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: fffffffffffffff4 RDI: ffff9ba53fddbf40
+RBP: ffff9ba539934000 R08: 0000000000000000 R09: ffffbbafc006bc38
+R10: ffffffffb6b689c8 R11: 0000000000000003 R12: ffff9ba539934030
+R13: 0000000000000001 R14: 0000000004248060 R15: ffffffffb56d1c30
+FS: 0000000000000000(0000) GS:ffff9ba5881f0000(0000) knlGS:00000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000000000c CR3: 000000093f244000 CR4: 00000000000006f0
+Call Trace:
+ <TASK>
+ __rpc_execute+0xbc/0x480
+ rpc_async_schedule+0x2f/0x40
+ process_one_work+0x232/0x5d0
+ worker_thread+0x1da/0x3d0
+ ? __pfx_worker_thread+0x10/0x10
+ kthread+0x10d/0x240
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x34/0x50
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+Modules linked in:
+CR2: 000000000000000c
+---[ end trace 0000000000000000 ]---
+
+Free the allocated nfs4_unlockdata when nfs_get_lock_context() fails and
+return NULL to terminate subsequent rpc_run_task, preventing NULL pointer
+dereference.
+
+Fixes: f30cb757f680 ("NFS: Always wait for I/O completion before unlock")
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Link: https://lore.kernel.org/r/20250417072508.3850532-1-lilingfeng3@huawei.com
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 632cea3fb91da..3477da3c2190e 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6573,10 +6573,18 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
+ struct nfs4_unlockdata *p;
+ struct nfs4_state *state = lsp->ls_state;
+ struct inode *inode = state->inode;
++ struct nfs_lock_context *l_ctx;
+
+ p = kzalloc(sizeof(*p), GFP_NOFS);
+ if (p == NULL)
+ return NULL;
++ l_ctx = nfs_get_lock_context(ctx);
++ if (!IS_ERR(l_ctx)) {
++ p->l_ctx = l_ctx;
++ } else {
++ kfree(p);
++ return NULL;
++ }
+ p->arg.fh = NFS_FH(inode);
+ p->arg.fl = &p->fl;
+ p->arg.seqid = seqid;
+@@ -6584,7 +6592,6 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
+ p->lsp = lsp;
+ /* Ensure we don't close file until we're done freeing locks! */
+ p->ctx = get_nfs_open_context(ctx);
+- p->l_ctx = nfs_get_lock_context(ctx);
+ locks_init_lock(&p->fl);
+ locks_copy_lock(&p->fl, fl);
+ p->server = NFS_SERVER(inode);
+--
+2.39.5
+
--- /dev/null
+From fbe767e4e91e409e6c2be2ce01901b76b2ce5e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2020 13:07:26 -0500
+Subject: NFSv4/pnfs: pnfs_set_layout_stateid() should update the layout cred
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 59b5639490f51aa604d18064dcf0c2d72eb1decf ]
+
+If the cred assigned to the layout that we're updating differs from
+the one used to retrieve the new layout segment, then we need to
+update the layout plh_lc_cred field.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 6d6d7f91cc8c ("NFSv4/pnfs: Reset the layout state after a layoutreturn")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/callback_proc.c | 2 +-
+ fs/nfs/pnfs.c | 20 ++++++++++++++++----
+ fs/nfs/pnfs.h | 1 +
+ 3 files changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
+index 31922657e836e..1397e0816ba09 100644
+--- a/fs/nfs/callback_proc.c
++++ b/fs/nfs/callback_proc.c
+@@ -284,7 +284,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
+ goto unlock;
+ }
+
+- pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
++ pnfs_set_layout_stateid(lo, &args->cbl_stateid, NULL, true);
+ switch (pnfs_mark_matching_lsegs_return(lo, &free_me_list,
+ &args->cbl_range,
+ be32_to_cpu(args->cbl_stateid.seqid))) {
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index 90961dae4dc3b..a6362c07cff63 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -943,10 +943,21 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
+ pnfs_destroy_layouts_byclid(clp, false);
+ }
+
++static void
++pnfs_set_layout_cred(struct pnfs_layout_hdr *lo, const struct cred *cred)
++{
++ const struct cred *old;
++
++ if (cred && cred_fscmp(lo->plh_lc_cred, cred) != 0) {
++ old = xchg(&lo->plh_lc_cred, get_cred(cred));
++ put_cred(old);
++ }
++}
++
+ /* update lo->plh_stateid with new if is more recent */
+ void
+ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
+- bool update_barrier)
++ const struct cred *cred, bool update_barrier)
+ {
+ u32 oldseq, newseq, new_barrier = 0;
+
+@@ -954,6 +965,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
+ newseq = be32_to_cpu(new->seqid);
+
+ if (!pnfs_layout_is_valid(lo)) {
++ pnfs_set_layout_cred(lo, cred);
+ nfs4_stateid_copy(&lo->plh_stateid, new);
+ lo->plh_barrier = newseq;
+ pnfs_clear_layoutreturn_info(lo);
+@@ -1149,7 +1161,7 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
+
+ pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);
+ pnfs_free_returned_lsegs(lo, &freeme, range, seq);
+- pnfs_set_layout_stateid(lo, stateid, true);
++ pnfs_set_layout_stateid(lo, stateid, NULL, true);
+ } else
+ pnfs_mark_layout_stateid_invalid(lo, &freeme);
+ out_unlock:
+@@ -2382,14 +2394,14 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
+
+ if (!pnfs_layout_is_valid(lo)) {
+ /* We have a completely new layout */
+- pnfs_set_layout_stateid(lo, &res->stateid, true);
++ pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
+ } else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
+ /* existing state ID, make sure the sequence number matches. */
+ if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
+ dprintk("%s forget reply due to sequence\n", __func__);
+ goto out_forget;
+ }
+- pnfs_set_layout_stateid(lo, &res->stateid, false);
++ pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, false);
+ } else {
+ /*
+ * We got an entirely new state ID. Mark all segments for the
+diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
+index 68339680bb7d1..b0f91a4592cb5 100644
+--- a/fs/nfs/pnfs.h
++++ b/fs/nfs/pnfs.h
+@@ -270,6 +270,7 @@ bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
+ void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
+ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
+ const nfs4_stateid *new,
++ const struct cred *cred,
+ bool update_barrier);
+ int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
+ struct list_head *tmp_list,
+--
+2.39.5
+
--- /dev/null
+From 162452f8f30ab3825cd2ec6f477a1dde3a5db9bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 10:50:13 -0400
+Subject: NFSv4/pnfs: Reset the layout state after a layoutreturn
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 6d6d7f91cc8c111d40416ac9240a3bb9396c5235 ]
+
+If there are still layout segments in the layout plh_return_lsegs list
+after a layout return, we should be resetting the state to ensure they
+eventually get returned as well.
+
+Fixes: 68f744797edd ("pNFS: Do not free layout segments that are marked for return")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/pnfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index a6362c07cff63..d91576a587e4e 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -710,6 +710,14 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
+ return remaining;
+ }
+
++static void pnfs_reset_return_info(struct pnfs_layout_hdr *lo)
++{
++ struct pnfs_layout_segment *lseg;
++
++ list_for_each_entry(lseg, &lo->plh_return_segs, pls_list)
++ pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0);
++}
++
+ static void
+ pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
+ struct list_head *free_me,
+@@ -1162,6 +1170,7 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
+ pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);
+ pnfs_free_returned_lsegs(lo, &freeme, range, seq);
+ pnfs_set_layout_stateid(lo, stateid, NULL, true);
++ pnfs_reset_return_info(lo);
+ } else
+ pnfs_mark_layout_stateid_invalid(lo, &freeme);
+ out_unlock:
+--
+2.39.5
+
--- /dev/null
+From f4af9011d15c4f36dd16614859b204eae66fe90e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 15:17:02 +0200
+Subject: platform/x86: asus-wmi: Fix wlan_ctrl_by_user detection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit bfcfe6d335a967f8ea0c1980960e6f0205b5de6e ]
+
+The wlan_ctrl_by_user detection was introduced by commit a50bd128f28c
+("asus-wmi: record wlan status while controlled by userapp").
+
+Quoting from that commit's commit message:
+
+"""
+When you call WMIMethod(DSTS, 0x00010011) to get WLAN status, it may return
+
+(1) 0x00050001 (On)
+(2) 0x00050000 (Off)
+(3) 0x00030001 (On)
+(4) 0x00030000 (Off)
+(5) 0x00000002 (Unknown)
+
+(1), (2) means that the model has hardware GPIO for WLAN, you can call
+WMIMethod(DEVS, 0x00010011, 1 or 0) to turn WLAN on/off.
+(3), (4) means that the model doesn’t have hardware GPIO, you need to use
+API or driver library to turn WLAN on/off, and call
+WMIMethod(DEVS, 0x00010012, 1 or 0) to set WLAN LED status.
+After you set WLAN LED status, you can see the WLAN status is changed with
+WMIMethod(DSTS, 0x00010011). Because the status is recorded lastly
+(ex: Windows), you can use it for synchronization.
+(5) means that the model doesn’t have WLAN device.
+
+WLAN is the ONLY special case with upper rule.
+"""
+
+The wlan_ctrl_by_user flag should be set on 0x0003000? ((3), (4) above)
+return values, but the flag mistakenly also gets set on laptops with
+0x0005000? ((1), (2)) return values. This is causing rfkill problems on
+laptops where 0x0005000? is returned.
+
+Fix the check to only set the wlan_ctrl_by_user flag for 0x0003000?
+return values.
+
+Fixes: a50bd128f28c ("asus-wmi: record wlan status while controlled by userapp")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219786
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20250501131702.103360-2-hdegoede@redhat.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/asus-wmi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index 761cab698c750..9e8be6c52e3d3 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -2458,7 +2458,8 @@ static int asus_wmi_add(struct platform_device *pdev)
+ goto fail_leds;
+
+ asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
+- if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
++ if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ==
++ (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
+ asus->driver->wlan_ctrl_by_user = 1;
+
+ if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {
+--
+2.39.5
+
--- /dev/null
+From e74cb0cb067b381897c1729cb7722ed361a83996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 10:18:27 +0530
+Subject: qlcnic: fix memory leak in qlcnic_sriov_channel_cfg_cmd()
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit 9d8a99c5a7c7f4f7eca2c168a4ec254409670035 ]
+
+In one of the error paths in qlcnic_sriov_channel_cfg_cmd(), the memory
+allocated in qlcnic_sriov_alloc_bc_mbx_args() for mailbox arguments is
+not freed. Fix that by jumping to the error path that frees them, by
+calling qlcnic_free_mbx_args(). This was found using static analysis.
+
+Fixes: f197a7aa6288 ("qlcnic: VF-PF communication channel implementation")
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250512044829.36400-1-abdun.nihaal@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+index 5d8b9e10ddf84..d6fcef1651a7e 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+@@ -1486,8 +1486,11 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_o
+ }
+
+ cmd_op = (cmd.rsp.arg[0] & 0xff);
+- if (cmd.rsp.arg[0] >> 25 == 2)
+- return 2;
++ if (cmd.rsp.arg[0] >> 25 == 2) {
++ ret = 2;
++ goto out;
++ }
++
+ if (cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
+ set_bit(QLC_BC_VF_STATE, &vf->state);
+ else
+--
+2.39.5
+
--- /dev/null
+From 38e852239fef17b19ae64dcaa190ca70582e938c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Apr 2025 09:57:14 +0200
+Subject: RDMA/rxe: Fix slab-use-after-free Read in rxe_queue_cleanup bug
+
+From: Zhu Yanjun <yanjun.zhu@linux.dev>
+
+[ Upstream commit f81b33582f9339d2dc17c69b92040d3650bb4bae ]
+
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0x7d/0xa0 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xcf/0x610 mm/kasan/report.c:489
+ kasan_report+0xb5/0xe0 mm/kasan/report.c:602
+ rxe_queue_cleanup+0xd0/0xe0 drivers/infiniband/sw/rxe/rxe_queue.c:195
+ rxe_cq_cleanup+0x3f/0x50 drivers/infiniband/sw/rxe/rxe_cq.c:132
+ __rxe_cleanup+0x168/0x300 drivers/infiniband/sw/rxe/rxe_pool.c:232
+ rxe_create_cq+0x22e/0x3a0 drivers/infiniband/sw/rxe/rxe_verbs.c:1109
+ create_cq+0x658/0xb90 drivers/infiniband/core/uverbs_cmd.c:1052
+ ib_uverbs_create_cq+0xc7/0x120 drivers/infiniband/core/uverbs_cmd.c:1095
+ ib_uverbs_write+0x969/0xc90 drivers/infiniband/core/uverbs_main.c:679
+ vfs_write fs/read_write.c:677 [inline]
+ vfs_write+0x26a/0xcc0 fs/read_write.c:659
+ ksys_write+0x1b8/0x200 fs/read_write.c:731
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xaa/0x1b0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+In the function rxe_create_cq, when rxe_cq_from_init fails, the function
+rxe_cleanup will be called to handle the allocated resources. In fact,
+some memory resources have already been freed in the function
+rxe_cq_from_init. Thus, this problem will occur.
+
+The solution is to let rxe_cleanup do all the work.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://paste.ubuntu.com/p/tJgC42wDf6/
+Tested-by: liuyi <liuy22@mails.tsinghua.edu.cn>
+Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Link: https://patch.msgid.link/20250412075714.3257358-1-yanjun.zhu@linux.dev
+Reviewed-by: Daisuke Matsuda <matsuda-daisuke@fujitsu.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_cq.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c
+index ad30901311268..81f66ba6bf359 100644
+--- a/drivers/infiniband/sw/rxe/rxe_cq.c
++++ b/drivers/infiniband/sw/rxe/rxe_cq.c
+@@ -96,11 +96,8 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
+
+ err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata,
+ cq->queue->buf, cq->queue->buf_size, &cq->queue->ip);
+- if (err) {
+- vfree(cq->queue->buf);
+- kfree(cq->queue);
++ if (err)
+ return err;
+- }
+
+ if (uresp)
+ cq->is_user = 1;
+--
+2.39.5
+
mips-fix-max_reg_offset.patch
nvme-unblock-ctrl-state-transition-for-firmware-upda.patch
do_umount-add-missing-barrier-before-refcount-checks.patch
+platform-x86-asus-wmi-fix-wlan_ctrl_by_user-detectio.patch
+staging-axis-fifo-replace-spinlock-with-mutex.patch
+staging-axis-fifo-remove-hardware-resets-for-user-er.patch
+staging-axis-fifo-avoid-parsing-ignored-device-tree-.patch
+staging-axis-fifo-correct-handling-of-tx_fifo_depth-.patch
+iio-adc-ad7768-1-fix-insufficient-alignment-of-times.patch
+iio-chemical-sps30-use-aligned_s64-for-timestamp.patch
+rdma-rxe-fix-slab-use-after-free-read-in-rxe_queue_c.patch
+nfs-handle-failure-of-nfs_get_lock_context-in-unlock.patch
+spi-loopback-test-do-not-split-1024-byte-hexdumps.patch
+net-dsa-sja1105-discard-incoming-frames-in-br_state_.patch
+alsa-sh-snd_aica-should-depend-on-sh_dma_api.patch
+qlcnic-fix-memory-leak-in-qlcnic_sriov_channel_cfg_c.patch
+nfsv4-pnfs-pnfs_set_layout_stateid-should-update-the.patch
+nfsv4-pnfs-reset-the-layout-state-after-a-layoutretu.patch
--- /dev/null
+From cfd870ccd4aeb0131e7f9395aa5eb15a5e37efe9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 13:10:35 +0200
+Subject: spi: loopback-test: Do not split 1024-byte hexdumps
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit a73fa3690a1f3014d6677e368dce4e70767a6ba2 ]
+
+spi_test_print_hex_dump() prints buffers holding less than 1024 bytes in
+full. Larger buffers are truncated: only the first 512 and the last 512
+bytes are printed, separated by a truncation message. The latter is
+confusing in case the buffer holds exactly 1024 bytes, as all data is
+printed anyway.
+
+Fix this by printing buffers holding up to and including 1024 bytes in
+full.
+
+Fixes: 84e0c4e5e2c4ef42 ("spi: add loopback test driver to allow for spi_master regression tests")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/37ee1bc90c6554c9347040adabf04188c8f704aa.1746184171.git.geert+renesas@glider.be
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-loopback-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c
+index 69a9df2cbbcf2..0f571ff132377 100644
+--- a/drivers/spi/spi-loopback-test.c
++++ b/drivers/spi/spi-loopback-test.c
+@@ -377,7 +377,7 @@ MODULE_LICENSE("GPL");
+ static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len)
+ {
+ /* limit the hex_dump */
+- if (len < 1024) {
++ if (len <= 1024) {
+ print_hex_dump(KERN_INFO, pre,
+ DUMP_PREFIX_OFFSET, 16, 1,
+ ptr, len, 0);
+--
+2.39.5
+
--- /dev/null
+From d52c382add71f0fe0becd2ac551edcba72b3913b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Nov 2019 21:42:50 +0000
+Subject: staging: axis-fifo: avoid parsing ignored device tree properties
+
+From: Quentin Deslandes <quentin.deslandes@itdev.co.uk>
+
+[ Upstream commit ed6daf2b2832d9b07582a6ff884039afa9063206 ]
+
+Some properties were parsed from the device tree and then ignored by the
+driver. Some would return an error if absent from the device tree, then
+return an error if they were found because they are unsupported by the
+driver.
+
+Avoid parsing unused properties and clearly explain in the documentation
+the ignored / unsupported properties.
+
+Signed-off-by: Quentin Deslandes <quentin.deslandes@itdev.co.uk>
+Link: https://lore.kernel.org/r/20191101214232.16960-2-quentin.deslandes@itdev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2ca34b508774 ("staging: axis-fifo: Correct handling of tx_fifo_depth for size validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/axis-fifo/axis-fifo.c | 247 ++++++------------------
+ drivers/staging/axis-fifo/axis-fifo.txt | 18 +-
+ 2 files changed, 74 insertions(+), 191 deletions(-)
+
+diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
+index 42528d4593b83..08f9990ab499a 100644
+--- a/drivers/staging/axis-fifo/axis-fifo.c
++++ b/drivers/staging/axis-fifo/axis-fifo.c
+@@ -738,6 +738,68 @@ static int get_dts_property(struct axis_fifo *fifo,
+ return 0;
+ }
+
++static int axis_fifo_parse_dt(struct axis_fifo *fifo)
++{
++ int ret;
++ unsigned int value;
++
++ ret = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width", &value);
++ if (ret) {
++ dev_err(fifo->dt_device, "missing xlnx,axi-str-rxd-tdata-width property\n");
++ goto end;
++ } else if (value != 32) {
++ dev_err(fifo->dt_device, "xlnx,axi-str-rxd-tdata-width only supports 32 bits\n");
++ ret = -EIO;
++ goto end;
++ }
++
++ ret = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width", &value);
++ if (ret) {
++ dev_err(fifo->dt_device, "missing xlnx,axi-str-txd-tdata-width property\n");
++ goto end;
++ } else if (value != 32) {
++ dev_err(fifo->dt_device, "xlnx,axi-str-txd-tdata-width only supports 32 bits\n");
++ ret = -EIO;
++ goto end;
++ }
++
++ ret = get_dts_property(fifo, "xlnx,rx-fifo-depth",
++ &fifo->rx_fifo_depth);
++ if (ret) {
++ dev_err(fifo->dt_device, "missing xlnx,rx-fifo-depth property\n");
++ ret = -EIO;
++ goto end;
++ }
++
++ ret = get_dts_property(fifo, "xlnx,tx-fifo-depth",
++ &fifo->tx_fifo_depth);
++ if (ret) {
++ dev_err(fifo->dt_device, "missing xlnx,tx-fifo-depth property\n");
++ ret = -EIO;
++ goto end;
++ }
++
++ /* IP sets TDFV to fifo depth - 4 so we will do the same */
++ fifo->tx_fifo_depth -= 4;
++
++ ret = get_dts_property(fifo, "xlnx,use-rx-data", &fifo->has_rx_fifo);
++ if (ret) {
++ dev_err(fifo->dt_device, "missing xlnx,use-rx-data property\n");
++ ret = -EIO;
++ goto end;
++ }
++
++ ret = get_dts_property(fifo, "xlnx,use-tx-data", &fifo->has_tx_fifo);
++ if (ret) {
++ dev_err(fifo->dt_device, "missing xlnx,use-tx-data property\n");
++ ret = -EIO;
++ goto end;
++ }
++
++end:
++ return ret;
++}
++
+ static int axis_fifo_probe(struct platform_device *pdev)
+ {
+ struct resource *r_irq; /* interrupt resources */
+@@ -749,34 +811,6 @@ static int axis_fifo_probe(struct platform_device *pdev)
+
+ int rc = 0; /* error return value */
+
+- /* IP properties from device tree */
+- unsigned int rxd_tdata_width;
+- unsigned int txc_tdata_width;
+- unsigned int txd_tdata_width;
+- unsigned int tdest_width;
+- unsigned int tid_width;
+- unsigned int tuser_width;
+- unsigned int data_interface_type;
+- unsigned int has_tdest;
+- unsigned int has_tid;
+- unsigned int has_tkeep;
+- unsigned int has_tstrb;
+- unsigned int has_tuser;
+- unsigned int rx_fifo_depth;
+- unsigned int rx_programmable_empty_threshold;
+- unsigned int rx_programmable_full_threshold;
+- unsigned int axi_id_width;
+- unsigned int axi4_data_width;
+- unsigned int select_xpm;
+- unsigned int tx_fifo_depth;
+- unsigned int tx_programmable_empty_threshold;
+- unsigned int tx_programmable_full_threshold;
+- unsigned int use_rx_cut_through;
+- unsigned int use_rx_data;
+- unsigned int use_tx_control;
+- unsigned int use_tx_cut_through;
+- unsigned int use_tx_data;
+-
+ /* ----------------------------
+ * init wrapper device
+ * ----------------------------
+@@ -843,164 +877,9 @@ static int axis_fifo_probe(struct platform_device *pdev)
+ * ----------------------------
+ */
+
+- /* retrieve device tree properties */
+- rc = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width",
+- &rxd_tdata_width);
++ rc = axis_fifo_parse_dt(fifo);
+ if (rc)
+ goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,axi-str-txc-tdata-width",
+- &txc_tdata_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width",
+- &txd_tdata_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,axis-tdest-width", &tdest_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,axis-tid-width", &tid_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,axis-tuser-width", &tuser_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,data-interface-type",
+- &data_interface_type);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,has-axis-tdest", &has_tdest);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,has-axis-tid", &has_tid);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,has-axis-tkeep", &has_tkeep);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,has-axis-tstrb", &has_tstrb);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,has-axis-tuser", &has_tuser);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,rx-fifo-depth", &rx_fifo_depth);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,rx-fifo-pe-threshold",
+- &rx_programmable_empty_threshold);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,rx-fifo-pf-threshold",
+- &rx_programmable_full_threshold);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,s-axi-id-width", &axi_id_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,s-axi4-data-width", &axi4_data_width);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,select-xpm", &select_xpm);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,tx-fifo-depth", &tx_fifo_depth);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,tx-fifo-pe-threshold",
+- &tx_programmable_empty_threshold);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,tx-fifo-pf-threshold",
+- &tx_programmable_full_threshold);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,use-rx-cut-through",
+- &use_rx_cut_through);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,use-rx-data", &use_rx_data);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,use-tx-ctrl", &use_tx_control);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,use-tx-cut-through",
+- &use_tx_cut_through);
+- if (rc)
+- goto err_unmap;
+- rc = get_dts_property(fifo, "xlnx,use-tx-data", &use_tx_data);
+- if (rc)
+- goto err_unmap;
+-
+- /* check validity of device tree properties */
+- if (rxd_tdata_width != 32) {
+- dev_err(fifo->dt_device,
+- "rxd_tdata_width width [%u] unsupported\n",
+- rxd_tdata_width);
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (txd_tdata_width != 32) {
+- dev_err(fifo->dt_device,
+- "txd_tdata_width width [%u] unsupported\n",
+- txd_tdata_width);
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (has_tdest) {
+- dev_err(fifo->dt_device, "tdest not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (has_tid) {
+- dev_err(fifo->dt_device, "tid not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (has_tkeep) {
+- dev_err(fifo->dt_device, "tkeep not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (has_tstrb) {
+- dev_err(fifo->dt_device, "tstrb not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (has_tuser) {
+- dev_err(fifo->dt_device, "tuser not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (use_rx_cut_through) {
+- dev_err(fifo->dt_device, "rx cut-through not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (use_tx_cut_through) {
+- dev_err(fifo->dt_device, "tx cut-through not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+- if (use_tx_control) {
+- dev_err(fifo->dt_device, "tx control not supported\n");
+- rc = -EIO;
+- goto err_unmap;
+- }
+-
+- /* TODO
+- * these exist in the device tree but it's unclear what they do
+- * - select-xpm
+- * - data-interface-type
+- */
+-
+- /* set device wrapper properties based on IP config */
+- fifo->rx_fifo_depth = rx_fifo_depth;
+- /* IP sets TDFV to fifo depth - 4 so we will do the same */
+- fifo->tx_fifo_depth = tx_fifo_depth - 4;
+- fifo->has_rx_fifo = use_rx_data;
+- fifo->has_tx_fifo = use_tx_data;
+
+ reset_ip_core(fifo);
+
+diff --git a/drivers/staging/axis-fifo/axis-fifo.txt b/drivers/staging/axis-fifo/axis-fifo.txt
+index 85d88c010e724..5828e1b8e8223 100644
+--- a/drivers/staging/axis-fifo/axis-fifo.txt
++++ b/drivers/staging/axis-fifo/axis-fifo.txt
+@@ -25,10 +25,10 @@ Required properties:
+ - xlnx,axi-str-txc-tdata-width: Should be <0x20>
+ - xlnx,axi-str-txd-protocol: Should be "XIL_AXI_STREAM_ETH_DATA"
+ - xlnx,axi-str-txd-tdata-width: Should be <0x20>
+-- xlnx,axis-tdest-width: AXI-Stream TDEST width
+-- xlnx,axis-tid-width: AXI-Stream TID width
+-- xlnx,axis-tuser-width: AXI-Stream TUSER width
+-- xlnx,data-interface-type: Should be <0x0>
++- xlnx,axis-tdest-width: AXI-Stream TDEST width (ignored by the driver)
++- xlnx,axis-tid-width: AXI-Stream TID width (ignored by the driver)
++- xlnx,axis-tuser-width: AXI-Stream TUSER width (ignored by the driver)
++- xlnx,data-interface-type: Should be <0x0> (ignored by the driver)
+ - xlnx,has-axis-tdest: Should be <0x0> (this feature isn't supported)
+ - xlnx,has-axis-tid: Should be <0x0> (this feature isn't supported)
+ - xlnx,has-axis-tkeep: Should be <0x0> (this feature isn't supported)
+@@ -36,13 +36,17 @@ Required properties:
+ - xlnx,has-axis-tuser: Should be <0x0> (this feature isn't supported)
+ - xlnx,rx-fifo-depth: Depth of RX FIFO in words
+ - xlnx,rx-fifo-pe-threshold: RX programmable empty interrupt threshold
++ (ignored by the driver)
+ - xlnx,rx-fifo-pf-threshold: RX programmable full interrupt threshold
+-- xlnx,s-axi-id-width: Should be <0x4>
+-- xlnx,s-axi4-data-width: Should be <0x20>
+-- xlnx,select-xpm: Should be <0x0>
++ (ignored by the driver)
++- xlnx,s-axi-id-width: Should be <0x4> (ignored by the driver)
++- xlnx,s-axi4-data-width: Should be <0x20> (ignored by the driver)
++- xlnx,select-xpm: Should be <0x0> (ignored by the driver)
+ - xlnx,tx-fifo-depth: Depth of TX FIFO in words
+ - xlnx,tx-fifo-pe-threshold: TX programmable empty interrupt threshold
++ (ignored by the driver)
+ - xlnx,tx-fifo-pf-threshold: TX programmable full interrupt threshold
++ (ignored by the driver)
+ - xlnx,use-rx-cut-through: Should be <0x0> (this feature isn't supported)
+ - xlnx,use-rx-data: <0x1> if RX FIFO is enabled, <0x0> otherwise
+ - xlnx,use-tx-ctrl: Should be <0x0> (this feature isn't supported)
+--
+2.39.5
+
--- /dev/null
+From 7a36666f1f82bfd2ed2bf0fb9316e7e2e79cc173 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 21:29:37 -0400
+Subject: staging: axis-fifo: Correct handling of tx_fifo_depth for size
+ validation
+
+From: Gabriel Shahrouzi <gshahrouzi@gmail.com>
+
+[ Upstream commit 2ca34b508774aaa590fc3698a54204706ecca4ba ]
+
+Remove erroneous subtraction of 4 from the total FIFO depth read from
+device tree. The stored depth is for checking against total capacity,
+not initial vacancy. This prevented writes near the FIFO's full size.
+
+The check performed just before data transfer, which uses live reads of
+the TDFV register to determine current vacancy, correctly handles the
+initial Depth - 4 hardware state and subsequent FIFO fullness.
+
+Fixes: 4a965c5f89de ("staging: add driver for Xilinx AXI-Stream FIFO v4.1 IP core")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gabriel Shahrouzi <gshahrouzi@gmail.com>
+Link: https://lore.kernel.org/r/20250419012937.674924-1-gshahrouzi@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/axis-fifo/axis-fifo.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
+index 08f9990ab499a..4dd2c8e9b7878 100644
+--- a/drivers/staging/axis-fifo/axis-fifo.c
++++ b/drivers/staging/axis-fifo/axis-fifo.c
+@@ -779,9 +779,6 @@ static int axis_fifo_parse_dt(struct axis_fifo *fifo)
+ goto end;
+ }
+
+- /* IP sets TDFV to fifo depth - 4 so we will do the same */
+- fifo->tx_fifo_depth -= 4;
+-
+ ret = get_dts_property(fifo, "xlnx,use-rx-data", &fifo->has_rx_fifo);
+ if (ret) {
+ dev_err(fifo->dt_device, "missing xlnx,use-rx-data property\n");
+--
+2.39.5
+
--- /dev/null
+From 57f1ce28b04d2446bc62d89619be023c4449f312 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 20:43:06 -0400
+Subject: staging: axis-fifo: Remove hardware resets for user errors
+
+From: Gabriel Shahrouzi <gshahrouzi@gmail.com>
+
+[ Upstream commit c6e8d85fafa7193613db37da29c0e8d6e2515b13 ]
+
+The axis-fifo driver performs a full hardware reset (via
+reset_ip_core()) in several error paths within the read and write
+functions. This reset flushes both TX and RX FIFOs and resets the
+AXI-Stream links.
+
+Allow the user to handle the error without causing hardware disruption
+or data loss in other FIFO paths.
+
+Fixes: 4a965c5f89de ("staging: add driver for Xilinx AXI-Stream FIFO v4.1 IP core")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gabriel Shahrouzi <gshahrouzi@gmail.com>
+Link: https://lore.kernel.org/r/20250419004306.669605-1-gshahrouzi@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/axis-fifo/axis-fifo.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
+index c1dd01c5c9ea6..42528d4593b83 100644
+--- a/drivers/staging/axis-fifo/axis-fifo.c
++++ b/drivers/staging/axis-fifo/axis-fifo.c
+@@ -401,16 +401,14 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+
+ bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
+ if (!bytes_available) {
+- dev_err(fifo->dt_device, "received a packet of length 0 - fifo core will be reset\n");
+- reset_ip_core(fifo);
++ dev_err(fifo->dt_device, "received a packet of length 0\n");
+ ret = -EIO;
+ goto end_unlock;
+ }
+
+ if (bytes_available > len) {
+- dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n",
++ dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n",
+ bytes_available, len);
+- reset_ip_core(fifo);
+ ret = -EINVAL;
+ goto end_unlock;
+ }
+@@ -419,8 +417,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ /* this probably can't happen unless IP
+ * registers were previously mishandled
+ */
+- dev_err(fifo->dt_device, "received a packet that isn't word-aligned - fifo core will be reset\n");
+- reset_ip_core(fifo);
++ dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n");
+ ret = -EIO;
+ goto end_unlock;
+ }
+@@ -441,7 +438,6 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+
+ if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
+ copy * sizeof(u32))) {
+- reset_ip_core(fifo);
+ ret = -EFAULT;
+ goto end_unlock;
+ }
+@@ -551,7 +547,6 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+
+ if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
+ copy * sizeof(u32))) {
+- reset_ip_core(fifo);
+ ret = -EFAULT;
+ goto end_unlock;
+ }
+--
+2.39.5
+
--- /dev/null
+From c65bf2163673387bf03785f4fa2439c981eab5c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jan 2020 10:40:24 +0000
+Subject: staging: axis-fifo: replace spinlock with mutex
+
+From: Quentin Deslandes <quentin.deslandes@itdev.co.uk>
+
+[ Upstream commit 0443b3f4436321e1098fdf74432c8867016339da ]
+
+Following the device's documentation guidance, reading a packet from the
+device or writing a packet to it must be atomic. Previously, only
+reading device's vacancy (before writing on it) or occupancy (before
+reading from it) was locked. Hence, effectively reading the packet or
+writing the packet wasn't locked at all. However, reading a packet (and
+writing one, to a lesser extent) requires to read 3 different registers
+in a specific order, without missing one or else we should reset the
+device.
+
+This patch fixes the device's locking mechanism on the FIFO character
+device. As the device was using copy_from_user() and copy_to_user(), we
+need to replace spinlocks with mutexes.
+
+Signed-off-by: Quentin Deslandes <quentin.deslandes@itdev.co.uk>
+Link: https://lore.kernel.org/r/20200121103958.12941-1-quentin.deslandes@itdev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: c6e8d85fafa7 ("staging: axis-fifo: Remove hardware resets for user errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/axis-fifo/axis-fifo.c | 160 ++++++++++++++++----------
+ 1 file changed, 101 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
+index 805437fa249a9..c1dd01c5c9ea6 100644
+--- a/drivers/staging/axis-fifo/axis-fifo.c
++++ b/drivers/staging/axis-fifo/axis-fifo.c
+@@ -16,7 +16,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/wait.h>
+-#include <linux/spinlock_types.h>
++#include <linux/mutex.h>
+ #include <linux/device.h>
+ #include <linux/cdev.h>
+ #include <linux/init.h>
+@@ -134,9 +134,9 @@ struct axis_fifo {
+ int has_tx_fifo; /* whether the IP has the tx fifo enabled */
+
+ wait_queue_head_t read_queue; /* wait queue for asynchronos read */
+- spinlock_t read_queue_lock; /* lock for reading waitqueue */
++ struct mutex read_lock; /* lock for reading */
+ wait_queue_head_t write_queue; /* wait queue for asynchronos write */
+- spinlock_t write_queue_lock; /* lock for writing waitqueue */
++ struct mutex write_lock; /* lock for writing */
+ unsigned int write_flags; /* write file flags */
+ unsigned int read_flags; /* read file flags */
+
+@@ -337,7 +337,21 @@ static void reset_ip_core(struct axis_fifo *fifo)
+ iowrite32(XLLF_INT_ALL_MASK, fifo->base_addr + XLLF_ISR_OFFSET);
+ }
+
+-/* reads a single packet from the fifo as dictated by the tlast signal */
++/**
++ * axis_fifo_write() - Read a packet from AXIS-FIFO character device.
++ * @f Open file.
++ * @buf User space buffer to read to.
++ * @len User space buffer length.
++ * @off Buffer offset.
++ *
++ * As defined by the device's documentation, we need to check the device's
++ * occupancy before reading the length register and then the data. All these
++ * operations must be executed atomically, in order and one after the other
++ * without missing any.
++ *
++ * Returns the number of bytes read from the device or negative error code
++ * on failure.
++ */
+ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ size_t len, loff_t *off)
+ {
+@@ -351,36 +365,37 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ u32 tmp_buf[READ_BUF_SIZE];
+
+ if (fifo->read_flags & O_NONBLOCK) {
+- /* opened in non-blocking mode
+- * return if there are no packets available
++ /*
++ * Device opened in non-blocking mode. Try to lock it and then
++ * check if any packet is available.
+ */
+- if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET))
++ if (!mutex_trylock(&fifo->read_lock))
+ return -EAGAIN;
++
++ if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET)) {
++ ret = -EAGAIN;
++ goto end_unlock;
++ }
+ } else {
+ /* opened in blocking mode
+ * wait for a packet available interrupt (or timeout)
+ * if nothing is currently available
+ */
+- spin_lock_irq(&fifo->read_queue_lock);
+- ret = wait_event_interruptible_lock_irq_timeout
+- (fifo->read_queue,
+- ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
+- fifo->read_queue_lock,
+- (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
++ mutex_lock(&fifo->read_lock);
++ ret = wait_event_interruptible_timeout(fifo->read_queue,
++ ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
++ (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
+ MAX_SCHEDULE_TIMEOUT);
+- spin_unlock_irq(&fifo->read_queue_lock);
+
+- if (ret == 0) {
+- /* timeout occurred */
+- dev_dbg(fifo->dt_device, "read timeout");
+- return -EAGAIN;
+- } else if (ret == -ERESTARTSYS) {
+- /* signal received */
+- return -ERESTARTSYS;
+- } else if (ret < 0) {
+- dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
+- ret);
+- return ret;
++ if (ret <= 0) {
++ if (ret == 0) {
++ ret = -EAGAIN;
++ } else if (ret != -ERESTARTSYS) {
++ dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
++ ret);
++ }
++
++ goto end_unlock;
+ }
+ }
+
+@@ -388,14 +403,16 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ if (!bytes_available) {
+ dev_err(fifo->dt_device, "received a packet of length 0 - fifo core will be reset\n");
+ reset_ip_core(fifo);
+- return -EIO;
++ ret = -EIO;
++ goto end_unlock;
+ }
+
+ if (bytes_available > len) {
+ dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n",
+ bytes_available, len);
+ reset_ip_core(fifo);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto end_unlock;
+ }
+
+ if (bytes_available % sizeof(u32)) {
+@@ -404,7 +421,8 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ */
+ dev_err(fifo->dt_device, "received a packet that isn't word-aligned - fifo core will be reset\n");
+ reset_ip_core(fifo);
+- return -EIO;
++ ret = -EIO;
++ goto end_unlock;
+ }
+
+ words_available = bytes_available / sizeof(u32);
+@@ -424,16 +442,37 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
+ copy * sizeof(u32))) {
+ reset_ip_core(fifo);
+- return -EFAULT;
++ ret = -EFAULT;
++ goto end_unlock;
+ }
+
+ copied += copy;
+ words_available -= copy;
+ }
+
+- return bytes_available;
++ ret = bytes_available;
++
++end_unlock:
++ mutex_unlock(&fifo->read_lock);
++
++ return ret;
+ }
+
++/**
++ * axis_fifo_write() - Write buffer to AXIS-FIFO character device.
++ * @f Open file.
++ * @buf User space buffer to write to the device.
++ * @len User space buffer length.
++ * @off Buffer offset.
++ *
++ * As defined by the device's documentation, we need to write to the device's
++ * data buffer then to the device's packet length register atomically. Also,
++ * we need to lock before checking if the device has available space to avoid
++ * any concurrency issue.
++ *
++ * Returns the number of bytes written to the device or negative error code
++ * on failure.
++ */
+ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+ size_t len, loff_t *off)
+ {
+@@ -466,12 +505,17 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+ }
+
+ if (fifo->write_flags & O_NONBLOCK) {
+- /* opened in non-blocking mode
+- * return if there is not enough room available in the fifo
++ /*
++ * Device opened in non-blocking mode. Try to lock it and then
++ * check if there is any room to write the given buffer.
+ */
++ if (!mutex_trylock(&fifo->write_lock))
++ return -EAGAIN;
++
+ if (words_to_write > ioread32(fifo->base_addr +
+ XLLF_TDFV_OFFSET)) {
+- return -EAGAIN;
++ ret = -EAGAIN;
++ goto end_unlock;
+ }
+ } else {
+ /* opened in blocking mode */
+@@ -479,30 +523,22 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+ /* wait for an interrupt (or timeout) if there isn't
+ * currently enough room in the fifo
+ */
+- spin_lock_irq(&fifo->write_queue_lock);
+- ret = wait_event_interruptible_lock_irq_timeout
+- (fifo->write_queue,
+- ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
++ mutex_lock(&fifo->write_lock);
++ ret = wait_event_interruptible_timeout(fifo->write_queue,
++ ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
+ >= words_to_write,
+- fifo->write_queue_lock,
+- (write_timeout >= 0) ?
+- msecs_to_jiffies(write_timeout) :
++ (write_timeout >= 0) ? msecs_to_jiffies(write_timeout) :
+ MAX_SCHEDULE_TIMEOUT);
+- spin_unlock_irq(&fifo->write_queue_lock);
+
+- if (ret == 0) {
+- /* timeout occurred */
+- dev_dbg(fifo->dt_device, "write timeout\n");
+- return -EAGAIN;
+- } else if (ret == -ERESTARTSYS) {
+- /* signal received */
+- return -ERESTARTSYS;
+- } else if (ret < 0) {
+- /* unknown error */
+- dev_err(fifo->dt_device,
+- "wait_event_interruptible_timeout() error in write (ret=%i)\n",
+- ret);
+- return ret;
++ if (ret <= 0) {
++ if (ret == 0) {
++ ret = -EAGAIN;
++ } else if (ret != -ERESTARTSYS) {
++ dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in write (ret=%i)\n",
++ ret);
++ }
++
++ goto end_unlock;
+ }
+ }
+
+@@ -516,7 +552,8 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+ if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
+ copy * sizeof(u32))) {
+ reset_ip_core(fifo);
+- return -EFAULT;
++ ret = -EFAULT;
++ goto end_unlock;
+ }
+
+ for (i = 0; i < copy; i++)
+@@ -527,10 +564,15 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+ words_to_write -= copy;
+ }
+
++ ret = copied * sizeof(u32);
++
+ /* write packet size to fifo */
+- iowrite32(copied * sizeof(u32), fifo->base_addr + XLLF_TLR_OFFSET);
++ iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET);
++
++end_unlock:
++ mutex_unlock(&fifo->write_lock);
+
+- return (ssize_t)copied * sizeof(u32);
++ return ret;
+ }
+
+ static irqreturn_t axis_fifo_irq(int irq, void *dw)
+@@ -756,8 +798,8 @@ static int axis_fifo_probe(struct platform_device *pdev)
+ init_waitqueue_head(&fifo->read_queue);
+ init_waitqueue_head(&fifo->write_queue);
+
+- spin_lock_init(&fifo->read_queue_lock);
+- spin_lock_init(&fifo->write_queue_lock);
++ mutex_init(&fifo->read_lock);
++ mutex_init(&fifo->write_lock);
+
+ /* ----------------------------
+ * init device memory space
+--
+2.39.5
+