--- /dev/null
+From d45888cc876b80e272280f95f44d23dfa8942a7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jan 2024 13:14:46 +0000
+Subject: cifs: handle servers that still advertise multichannel after
+ disabling
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+[ Upstream commit f591062bdbf4742b7f1622173017f19e927057b0 ]
+
+Some servers like Azure SMB servers always advertise multichannel
+capability in server capabilities list. Such servers return error
+STATUS_NOT_IMPLEMENTED for ioctl calls to query server interfaces,
+and expect clients to consider that as a sign that they do not support
+multichannel.
+
+We already handled this at mount time. Soon after the tree connect,
+we query server interfaces. And when server returned STATUS_NOT_IMPLEMENTED,
+we kept interface list as empty. When cifs_try_adding_channels gets
+called, it would not find any interfaces, so will not add channels.
+
+For the case where an active multichannel mount exists, and multichannel
+is disabled by such a server, this change will now allow the client
+to disable secondary channels on the mount. It will check the return
+status of query server interfaces call soon after a tree reconnect.
+If the return status is EOPNOTSUPP, then instead of the check to add
+more channels, we'll disable the secondary channels instead.
+
+For better code reuse, this change also moves the common code for
+disabling multichannel to a helper function.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 78e727e58e54 ("cifs: update iface_last_update on each query-and-update")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 8 +--
+ fs/smb/client/smb2pdu.c | 107 +++++++++++++++++++++++++---------------
+ 2 files changed, 69 insertions(+), 46 deletions(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 14bc745de199..17310f3a9d89 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -614,7 +614,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ "multichannel not available\n"
+ "Empty network interface list returned by server %s\n",
+ ses->server->hostname);
+- rc = -EINVAL;
++ rc = -EOPNOTSUPP;
+ goto out;
+ }
+
+@@ -734,12 +734,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ if ((bytes_left > 8) || p->Next)
+ cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
+
+-
+- if (!ses->iface_count) {
+- rc = -EINVAL;
+- goto out;
+- }
+-
+ out:
+ /*
+ * Go through the list again and put the inactive entries
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 12e41fcd0b46..bfec2ca0f4e6 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -156,6 +156,57 @@ smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd,
+ return;
+ }
+
++/* helper function for code reuse */
++static int
++cifs_chan_skip_or_disable(struct cifs_ses *ses,
++ struct TCP_Server_Info *server,
++ bool from_reconnect)
++{
++ struct TCP_Server_Info *pserver;
++ unsigned int chan_index;
++
++ if (SERVER_IS_CHAN(server)) {
++ cifs_dbg(VFS,
++ "server %s does not support multichannel anymore. Skip secondary channel\n",
++ ses->server->hostname);
++
++ spin_lock(&ses->chan_lock);
++ chan_index = cifs_ses_get_chan_index(ses, server);
++ if (chan_index == CIFS_INVAL_CHAN_INDEX) {
++ spin_unlock(&ses->chan_lock);
++ goto skip_terminate;
++ }
++
++ ses->chans[chan_index].server = NULL;
++ spin_unlock(&ses->chan_lock);
++
++ /*
++ * the above reference of server by channel
++ * needs to be dropped without holding chan_lock
++ * as cifs_put_tcp_session takes a higher lock
++ * i.e. cifs_tcp_ses_lock
++ */
++ cifs_put_tcp_session(server, from_reconnect);
++
++ server->terminate = true;
++ cifs_signal_cifsd_for_reconnect(server, false);
++
++ /* mark primary server as needing reconnect */
++ pserver = server->primary_server;
++ cifs_signal_cifsd_for_reconnect(pserver, false);
++skip_terminate:
++ mutex_unlock(&ses->session_mutex);
++ return -EHOSTDOWN;
++ }
++
++ cifs_server_dbg(VFS,
++ "server does not support multichannel anymore. Disable all other channels\n");
++ cifs_disable_secondary_channels(ses);
++
++
++ return 0;
++}
++
+ static int
+ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
+ struct TCP_Server_Info *server, bool from_reconnect)
+@@ -164,8 +215,6 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
+ struct nls_table *nls_codepage = NULL;
+ struct cifs_ses *ses;
+ int xid;
+- struct TCP_Server_Info *pserver;
+- unsigned int chan_index;
+
+ /*
+ * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so
+@@ -310,44 +359,11 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
+ */
+ if (ses->chan_count > 1 &&
+ !(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
+- if (SERVER_IS_CHAN(server)) {
+- cifs_dbg(VFS, "server %s does not support " \
+- "multichannel anymore. skipping secondary channel\n",
+- ses->server->hostname);
+-
+- spin_lock(&ses->chan_lock);
+- chan_index = cifs_ses_get_chan_index(ses, server);
+- if (chan_index == CIFS_INVAL_CHAN_INDEX) {
+- spin_unlock(&ses->chan_lock);
+- goto skip_terminate;
+- }
+-
+- ses->chans[chan_index].server = NULL;
+- spin_unlock(&ses->chan_lock);
+-
+- /*
+- * the above reference of server by channel
+- * needs to be dropped without holding chan_lock
+- * as cifs_put_tcp_session takes a higher lock
+- * i.e. cifs_tcp_ses_lock
+- */
+- cifs_put_tcp_session(server, from_reconnect);
+-
+- server->terminate = true;
+- cifs_signal_cifsd_for_reconnect(server, false);
+-
+- /* mark primary server as needing reconnect */
+- pserver = server->primary_server;
+- cifs_signal_cifsd_for_reconnect(pserver, false);
+-
+-skip_terminate:
++ rc = cifs_chan_skip_or_disable(ses, server,
++ from_reconnect);
++ if (rc) {
+ mutex_unlock(&ses->session_mutex);
+- rc = -EHOSTDOWN;
+ goto out;
+- } else {
+- cifs_server_dbg(VFS, "does not support " \
+- "multichannel anymore. disabling all other channels\n");
+- cifs_disable_secondary_channels(ses);
+ }
+ }
+
+@@ -395,11 +411,23 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
+ rc = SMB3_request_interfaces(xid, tcon, false);
+ free_xid(xid);
+
+- if (rc)
++ if (rc == -EOPNOTSUPP) {
++ /*
++ * some servers like Azure SMB server do not advertise
++ * that multichannel has been disabled with server
++ * capabilities, rather return STATUS_NOT_IMPLEMENTED.
++ * treat this as server not supporting multichannel
++ */
++
++ rc = cifs_chan_skip_or_disable(ses, server,
++ from_reconnect);
++ goto skip_add_channels;
++ } else if (rc)
+ cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
+ __func__, rc);
+
+ if (ses->chan_max > ses->chan_count &&
++ ses->iface_count &&
+ !SERVER_IS_CHAN(server)) {
+ if (ses->chan_count == 1)
+ cifs_server_dbg(VFS, "supports multichannel now\n");
+@@ -409,6 +437,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
+ } else {
+ mutex_unlock(&ses->session_mutex);
+ }
++skip_add_channels:
+
+ if (smb2_command != SMB2_INTERNAL_CMD)
+ mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
+--
+2.43.0
+
--- /dev/null
+From edd9cd84182713e9f3392baadc56ba8451432e6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 12:51:49 +0000
+Subject: cifs: update iface_last_update on each query-and-update
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+[ Upstream commit 78e727e58e54efca4c23863fbd9e16e9d2d83f81 ]
+
+iface_last_update was an unused field when it was introduced.
+Later, when we had periodic update of server interface list,
+this field was used regularly to decide when to update next.
+
+However, with the new logic of updating the interfaces, it
+becomes crucial that this field be updated whenever
+parse_server_interfaces runs successfully.
+
+This change updates this field when either the server does
+not support query of interfaces; so that we do not query
+the interfaces repeatedly. It also updates the field when
+the function reaches the end.
+
+Fixes: aa45dadd34e4 ("cifs: change iface_list from array to sorted linked list")
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 17310f3a9d89..beb81fa00cff 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -615,6 +615,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ "Empty network interface list returned by server %s\n",
+ ses->server->hostname);
+ rc = -EOPNOTSUPP;
++ ses->iface_last_update = jiffies;
+ goto out;
+ }
+
+@@ -712,7 +713,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+
+ ses->iface_count++;
+ spin_unlock(&ses->iface_lock);
+- ses->iface_last_update = jiffies;
+ next_iface:
+ nb_iface++;
+ next = le32_to_cpu(p->Next);
+@@ -734,6 +734,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ if ((bytes_left > 8) || p->Next)
+ cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
+
++ ses->iface_last_update = jiffies;
++
+ out:
+ /*
+ * Go through the list again and put the inactive entries
+--
+2.43.0
+
--- /dev/null
+From c55b690ab6b922681775db442b3d622b4a1a9640 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 17:04:52 +0100
+Subject: dmaengine: fix NULL pointer in channel unregistration function
+
+From: Amelie Delaunay <amelie.delaunay@foss.st.com>
+
+[ Upstream commit f5c24d94512f1b288262beda4d3dcb9629222fc7 ]
+
+__dma_async_device_channel_register() can fail. In case of failure,
+chan->local is freed (with free_percpu()), and chan->local is nullified.
+When dma_async_device_unregister() is called (because of managed API or
+intentionally by DMA controller driver), channels are unconditionally
+unregistered, leading to this NULL pointer:
+[ 1.318693] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d0
+[...]
+[ 1.484499] Call trace:
+[ 1.486930] device_del+0x40/0x394
+[ 1.490314] device_unregister+0x20/0x7c
+[ 1.494220] __dma_async_device_channel_unregister+0x68/0xc0
+
+Look at dma_async_device_register() function error path, channel device
+unregistration is done only if chan->local is not NULL.
+
+Then add the same condition at the beginning of
+__dma_async_device_channel_unregister() function, to avoid NULL pointer
+issue whatever the API used to reach this function.
+
+Fixes: d2fb0a043838 ("dmaengine: break out channel registration")
+Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20231213160452.2598073-1-amelie.delaunay@foss.st.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/dmaengine.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index b7388ae62d7f..491b22240221 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -1103,6 +1103,9 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_register);
+ static void __dma_async_device_channel_unregister(struct dma_device *device,
+ struct dma_chan *chan)
+ {
++ if (chan->local == NULL)
++ return;
++
+ WARN_ONCE(!device->device_release && chan->client_count,
+ "%s called while %d clients hold a reference\n",
+ __func__, chan->client_count);
+--
+2.43.0
+
--- /dev/null
+From 6717e02a99f5960946a34c2a499f8464b783c16d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Nov 2023 10:48:21 -0500
+Subject: dmaengine: fsl-edma: fix eDMAv4 channel allocation issue
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit dc51b4442dd94ab12c146c1897bbdb40e16d5636 ]
+
+The eDMAv4 channel mux has a limitation where certain requests must use
+even channels, while others must use odd numbers.
+
+Add two flags (ARGS_EVEN_CH and ARGS_ODD_CH) to reflect this limitation.
+The device tree source (dts) files need to be updated accordingly.
+
+This issue was identified by the following commit:
+commit a725990557e7 ("arm64: dts: imx93: Fix the dmas entries order")
+
+Reverting channel orders triggered this problem.
+
+Fixes: 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231114154824.3617255-2-Frank.Li@nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/fsl-edma-main.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
+index 238a69bd0d6f..75cae7ccae27 100644
+--- a/drivers/dma/fsl-edma-main.c
++++ b/drivers/dma/fsl-edma-main.c
+@@ -24,6 +24,8 @@
+ #define ARGS_RX BIT(0)
+ #define ARGS_REMOTE BIT(1)
+ #define ARGS_MULTI_FIFO BIT(2)
++#define ARGS_EVEN_CH BIT(3)
++#define ARGS_ODD_CH BIT(4)
+
+ static void fsl_edma_synchronize(struct dma_chan *chan)
+ {
+@@ -157,6 +159,12 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
+ fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
+ fsl_chan->is_multi_fifo = dma_spec->args[2] & ARGS_MULTI_FIFO;
+
++ if ((dma_spec->args[2] & ARGS_EVEN_CH) && (i & 0x1))
++ continue;
++
++ if ((dma_spec->args[2] & ARGS_ODD_CH) && !(i & 0x1))
++ continue;
++
+ if (!b_chmux && i == dma_spec->args[0]) {
+ chan = dma_get_slave_channel(chan);
+ chan->device->privatecnt++;
+--
+2.43.0
+
--- /dev/null
+From 936bcdb644a572504a83e703d28db08feccdd72b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Dec 2023 10:21:58 +0800
+Subject: dmaengine: idxd: Move dma_free_coherent() out of spinlocked context
+
+From: Rex Zhang <rex.zhang@intel.com>
+
+[ Upstream commit e271c0ba3f919c48e90c64b703538fbb7865cb63 ]
+
+Task may be rescheduled within dma_free_coherent(). So dma_free_coherent()
+can't be called between spin_lock() and spin_unlock() to avoid Call Trace:
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x37/0x50
+ __might_resched+0x16a/0x1c0
+ vunmap+0x2c/0x70
+ __iommu_dma_free+0x96/0x100
+ idxd_device_evl_free+0xd5/0x100 [idxd]
+ device_release_driver_internal+0x197/0x200
+ unbind_store+0xa1/0xb0
+ kernfs_fop_write_iter+0x120/0x1c0
+ vfs_write+0x2d3/0x400
+ ksys_write+0x63/0xe0
+ do_syscall_64+0x44/0xa0
+ entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+Move it out of the context.
+
+Fixes: 244da66cda35 ("dmaengine: idxd: setup event log configuration")
+Signed-off-by: Rex Zhang <rex.zhang@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fenghua Yu <fenghua.yu@intel.com>
+Link: https://lore.kernel.org/r/20231212022158.358619-2-rex.zhang@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index 8f754f922217..fa0f880beae6 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -802,6 +802,9 @@ static int idxd_device_evl_setup(struct idxd_device *idxd)
+
+ static void idxd_device_evl_free(struct idxd_device *idxd)
+ {
++ void *evl_log;
++ unsigned int evl_log_size;
++ dma_addr_t evl_dma;
+ union gencfg_reg gencfg;
+ union genctrl_reg genctrl;
+ struct device *dev = &idxd->pdev->dev;
+@@ -822,11 +825,15 @@ static void idxd_device_evl_free(struct idxd_device *idxd)
+ iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET);
+ iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET + 8);
+
+- dma_free_coherent(dev, evl->log_size, evl->log, evl->dma);
+ bitmap_free(evl->bmap);
++ evl_log = evl->log;
++ evl_log_size = evl->log_size;
++ evl_dma = evl->dma;
+ evl->log = NULL;
+ evl->size = IDXD_EVL_SIZE_MIN;
+ spin_unlock(&evl->lock);
++
++ dma_free_coherent(dev, evl_log_size, evl_log, evl_dma);
+ }
+
+ static void idxd_group_config_write(struct idxd_group *group)
+--
+2.43.0
+
--- /dev/null
+From e5cefb2a9c45fac38aab0e4c9d836c50dad62513 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 12:13:12 +0100
+Subject: dmaengine: xilinx: xdma: Fix the count of elapsed periods in cyclic
+ mode
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 26ee018ff6d1c326ac9b9be36513e35870ed09db ]
+
+Xilinx DMA engine is capable of keeping track of the number of elapsed
+periods and this is an increasing 32-bit counter which is only reset
+when turning off the engine. No need to add this value to our local
+counter.
+
+Fixes: cd8c732ce1a5 ("dmaengine: xilinx: xdma: Support cyclic transfers")
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/r/20231130111315.729430-2-miquel.raynal@bootlin.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/xilinx/xdma.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c
+index 84a88029226f..2c9c72d4b5a2 100644
+--- a/drivers/dma/xilinx/xdma.c
++++ b/drivers/dma/xilinx/xdma.c
+@@ -754,9 +754,9 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id)
+ if (ret)
+ goto out;
+
+- desc->completed_desc_num += complete_desc_num;
+-
+ if (desc->cyclic) {
++ desc->completed_desc_num = complete_desc_num;
++
+ ret = regmap_read(xdev->rmap, xchan->base + XDMA_CHAN_STATUS,
+ &st);
+ if (ret)
+@@ -768,6 +768,8 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id)
+ goto out;
+ }
+
++ desc->completed_desc_num += complete_desc_num;
++
+ /*
+ * if all data blocks are transferred, remove and complete the request
+ */
+--
+2.43.0
+
--- /dev/null
+From f8e7b50db18855db7b51733c8fd23921e6a554eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 17:26:01 -0300
+Subject: iio: adc: ad7091r: Allow users to configure device events
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+[ Upstream commit 020e71c7ffc25dfe29ed9be6c2d39af7bd7f661f ]
+
+AD7091R-5 devices are supported by the ad7091r-5 driver together with
+the ad7091r-base driver. Those drivers declared iio events for notifying
+user space when ADC readings fall bellow the thresholds of low limit
+registers or above the values set in high limit registers.
+However, to configure iio events and their thresholds, a set of callback
+functions must be implemented and those were not present until now.
+The consequence of trying to configure ad7091r-5 events without the
+proper callback functions was a null pointer dereference in the kernel
+because the pointers to the callback functions were not set.
+
+Implement event configuration callbacks allowing users to read/write
+event thresholds and enable/disable event generation.
+
+Since the event spec structs are generic to AD7091R devices, also move
+those from the ad7091r-5 driver the base driver so they can be reused
+when support for ad7091r-2/-4/-8 be added.
+
+Fixes: ca69300173b6 ("iio: adc: Add support for AD7091R5 ADC")
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/59552d3548dabd56adc3107b7b4869afee2b0c3c.1703013352.git.marcelo.schmitt1@gmail.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/adc/ad7091r-base.c | 156 +++++++++++++++++++++++++++++++++
+ drivers/iio/adc/ad7091r-base.h | 6 ++
+ drivers/iio/adc/ad7091r5.c | 28 +-----
+ 3 files changed, 166 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
+index 8aaa854f816f..3d36bcd26b0c 100644
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/bitops.h>
++#include <linux/bitfield.h>
+ #include <linux/iio/events.h>
+ #include <linux/iio/iio.h>
+ #include <linux/interrupt.h>
+@@ -50,6 +51,27 @@ struct ad7091r_state {
+ struct mutex lock; /*lock to prevent concurent reads */
+ };
+
++const struct iio_event_spec ad7091r_events[] = {
++ {
++ .type = IIO_EV_TYPE_THRESH,
++ .dir = IIO_EV_DIR_RISING,
++ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
++ BIT(IIO_EV_INFO_ENABLE),
++ },
++ {
++ .type = IIO_EV_TYPE_THRESH,
++ .dir = IIO_EV_DIR_FALLING,
++ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
++ BIT(IIO_EV_INFO_ENABLE),
++ },
++ {
++ .type = IIO_EV_TYPE_THRESH,
++ .dir = IIO_EV_DIR_EITHER,
++ .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
++ },
++};
++EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R);
++
+ static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
+ {
+ int ret, conf;
+@@ -169,8 +191,142 @@ static int ad7091r_read_raw(struct iio_dev *iio_dev,
+ return ret;
+ }
+
++static int ad7091r_read_event_config(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++ int val, ret;
++
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ &val);
++ if (ret)
++ return ret;
++ return val != AD7091R_HIGH_LIMIT;
++ case IIO_EV_DIR_FALLING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ &val);
++ if (ret)
++ return ret;
++ return val != AD7091R_LOW_LIMIT;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ad7091r_write_event_config(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir, int state)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++
++ if (state) {
++ return regmap_set_bits(st->map, AD7091R_REG_CONF,
++ AD7091R_REG_CONF_ALERT_EN);
++ } else {
++ /*
++ * Set thresholds either to 0 or to 2^12 - 1 as appropriate to
++ * prevent alerts and thus disable event generation.
++ */
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ AD7091R_HIGH_LIMIT);
++ case IIO_EV_DIR_FALLING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ AD7091R_LOW_LIMIT);
++ default:
++ return -EINVAL;
++ }
++ }
++}
++
++static int ad7091r_read_event_value(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir,
++ enum iio_event_info info, int *val, int *val2)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++ int ret;
++
++ switch (info) {
++ case IIO_EV_INFO_VALUE:
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ val);
++ if (ret)
++ return ret;
++ return IIO_VAL_INT;
++ case IIO_EV_DIR_FALLING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ val);
++ if (ret)
++ return ret;
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
++ }
++ case IIO_EV_INFO_HYSTERESIS:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_HYSTERESIS(chan->channel),
++ val);
++ if (ret)
++ return ret;
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ad7091r_write_event_value(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir,
++ enum iio_event_info info, int val, int val2)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++
++ switch (info) {
++ case IIO_EV_INFO_VALUE:
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ val);
++ case IIO_EV_DIR_FALLING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ val);
++ default:
++ return -EINVAL;
++ }
++ case IIO_EV_INFO_HYSTERESIS:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_HYSTERESIS(chan->channel),
++ val);
++ default:
++ return -EINVAL;
++ }
++}
++
+ static const struct iio_info ad7091r_info = {
+ .read_raw = ad7091r_read_raw,
++ .read_event_config = &ad7091r_read_event_config,
++ .write_event_config = &ad7091r_write_event_config,
++ .read_event_value = &ad7091r_read_event_value,
++ .write_event_value = &ad7091r_write_event_value,
+ };
+
+ static irqreturn_t ad7091r_event_handler(int irq, void *private)
+diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h
+index 509748aef9b1..7a78976a2f80 100644
+--- a/drivers/iio/adc/ad7091r-base.h
++++ b/drivers/iio/adc/ad7091r-base.h
+@@ -8,6 +8,10 @@
+ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+
++/* AD7091R_REG_CH_LIMIT */
++#define AD7091R_HIGH_LIMIT 0xFFF
++#define AD7091R_LOW_LIMIT 0x0
++
+ struct device;
+ struct ad7091r_state;
+
+@@ -17,6 +21,8 @@ struct ad7091r_chip_info {
+ unsigned int vref_mV;
+ };
+
++extern const struct iio_event_spec ad7091r_events[3];
++
+ extern const struct regmap_config ad7091r_regmap_config;
+
+ int ad7091r_probe(struct device *dev, const char *name,
+diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c
+index 2f048527b7b7..dae98c95ebb8 100644
+--- a/drivers/iio/adc/ad7091r5.c
++++ b/drivers/iio/adc/ad7091r5.c
+@@ -12,26 +12,6 @@
+
+ #include "ad7091r-base.h"
+
+-static const struct iio_event_spec ad7091r5_events[] = {
+- {
+- .type = IIO_EV_TYPE_THRESH,
+- .dir = IIO_EV_DIR_RISING,
+- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+- BIT(IIO_EV_INFO_ENABLE),
+- },
+- {
+- .type = IIO_EV_TYPE_THRESH,
+- .dir = IIO_EV_DIR_FALLING,
+- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+- BIT(IIO_EV_INFO_ENABLE),
+- },
+- {
+- .type = IIO_EV_TYPE_THRESH,
+- .dir = IIO_EV_DIR_EITHER,
+- .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+- },
+-};
+-
+ #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \
+ .type = IIO_VOLTAGE, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+@@ -44,10 +24,10 @@ static const struct iio_event_spec ad7091r5_events[] = {
+ .scan_type.realbits = bits, \
+ }
+ static const struct iio_chan_spec ad7091r5_channels_irq[] = {
+- AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+- AD7091R_CHANNEL(1, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+- AD7091R_CHANNEL(2, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+- AD7091R_CHANNEL(3, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
++ AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++ AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++ AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++ AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
+ };
+
+ static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
+--
+2.43.0
+
--- /dev/null
+From 27aacd016cfe147308cf205550c79dbe0a6d1e21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 17:26:27 -0300
+Subject: iio: adc: ad7091r: Enable internal vref if external vref is not
+ supplied
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+[ Upstream commit e71c5c89bcb165a02df35325aa13d1ee40112401 ]
+
+The ADC needs a voltage reference to work correctly.
+Users can provide an external voltage reference or use the chip internal
+reference to operate the ADC.
+The availability of an in chip reference for the ADC saves the user from
+having to supply an external voltage reference, which makes the external
+reference an optional property as described in the device tree
+documentation.
+Though, to use the internal reference, it must be enabled by writing to
+the configuration register.
+Enable AD7091R internal voltage reference if no external vref is supplied.
+
+Fixes: 260442cc5be4 ("iio: adc: ad7091r5: Add scale and external VREF support")
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/b865033fa6a4fc4bf2b4a98ec51a6144e0f64f77.1703013352.git.marcelo.schmitt1@gmail.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/adc/ad7091r-base.c | 7 +++++++
+ drivers/iio/adc/ad7091r-base.h | 2 ++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
+index 3d36bcd26b0c..76002b91c86a 100644
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -405,7 +405,14 @@ int ad7091r_probe(struct device *dev, const char *name,
+ if (IS_ERR(st->vref)) {
+ if (PTR_ERR(st->vref) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
++
+ st->vref = NULL;
++ /* Enable internal vref */
++ ret = regmap_set_bits(st->map, AD7091R_REG_CONF,
++ AD7091R_REG_CONF_INT_VREF);
++ if (ret)
++ return dev_err_probe(st->dev, ret,
++ "Error on enable internal reference\n");
+ } else {
+ ret = regulator_enable(st->vref);
+ if (ret)
+diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h
+index 7a78976a2f80..b9e1c8bf3440 100644
+--- a/drivers/iio/adc/ad7091r-base.h
++++ b/drivers/iio/adc/ad7091r-base.h
+@@ -8,6 +8,8 @@
+ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+
++#define AD7091R_REG_CONF_INT_VREF BIT(0)
++
+ /* AD7091R_REG_CH_LIMIT */
+ #define AD7091R_HIGH_LIMIT 0xFFF
+ #define AD7091R_LOW_LIMIT 0x0
+--
+2.43.0
+
--- /dev/null
+From d4d22d908d7dfb28a0c14fdfcd2664e99264fb2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Dec 2023 14:46:37 -0300
+Subject: iio: adc: ad7091r: Set alert bit in config register
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+[ Upstream commit 149694f5e79b0c7a36ceb76e7c0d590db8f151c1 ]
+
+The ad7091r-base driver sets up an interrupt handler for firing events
+when inputs are either above or below a certain threshold.
+However, for the interrupt signal to come from the device it must be
+configured to enable the ALERT/BUSY/GPO pin to be used as ALERT, which
+was not being done until now.
+Enable interrupt signals on the ALERT/BUSY/GPO pin by setting the proper
+bit in the configuration register.
+
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/e8da2ee98d6df88318b14baf3dc9630e20218418.1702746240.git.marcelo.schmitt1@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 020e71c7ffc2 ("iio: adc: ad7091r: Allow users to configure device events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
+index 0e5d3d2e9c98..8aaa854f816f 100644
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -28,6 +28,7 @@
+ #define AD7091R_REG_RESULT_CONV_RESULT(x) ((x) & 0xfff)
+
+ /* AD7091R_REG_CONF */
++#define AD7091R_REG_CONF_ALERT_EN BIT(4)
+ #define AD7091R_REG_CONF_AUTO BIT(8)
+ #define AD7091R_REG_CONF_CMD BIT(10)
+
+@@ -232,6 +233,11 @@ int ad7091r_probe(struct device *dev, const char *name,
+ iio_dev->channels = chip_info->channels;
+
+ if (irq) {
++ ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
++ AD7091R_REG_CONF_ALERT_EN, BIT(4));
++ if (ret)
++ return ret;
++
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ ad7091r_event_handler,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev);
+--
+2.43.0
+
--- /dev/null
+From f8d8ea62f8b0302156bc87502202c0094bce6c6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jan 2024 11:42:48 -0800
+Subject: riscv: Correctly free relocation hashtable on error
+
+From: Charlie Jenkins <charlie@rivosinc.com>
+
+[ Upstream commit 4b38b36bfbd83b23e20c172d08dd85773791e3bd ]
+
+When there is not enough allocatable memory for the relocation
+hashtable, module loading should exit gracefully. Previously, this was
+attempted to be accomplished by checking if an unsigned number is less
+than zero which does not work. Instead have the caller check if the
+hashtable was correctly allocated and add a comment explaining that
+hashtable_bits that is 0 is valid.
+
+Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
+Fixes: d8792a5734b0 ("riscv: Safely remove entries from relocation list")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/202312132019.iYGTwW0L-lkp@intel.com/
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Julia Lawall <julia.lawall@inria.fr>
+Closes: https://lore.kernel.org/r/202312120044.wTI1Uyaa-lkp@intel.com/
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-2-a71f8de6ce0f@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/module.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
+index 5cf3a693482d..91f7cd221afc 100644
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -747,6 +747,10 @@ initialize_relocation_hashtable(unsigned int num_relocations,
+ {
+ /* Can safely assume that bits is not greater than sizeof(long) */
+ unsigned long hashtable_size = roundup_pow_of_two(num_relocations);
++ /*
++ * When hashtable_size == 1, hashtable_bits == 0.
++ * This is valid because the hashing algorithm returns 0 in this case.
++ */
+ unsigned int hashtable_bits = ilog2(hashtable_size);
+
+ /*
+@@ -763,7 +767,7 @@ initialize_relocation_hashtable(unsigned int num_relocations,
+ sizeof(*relocation_hashtable),
+ GFP_KERNEL);
+ if (!*relocation_hashtable)
+- return -ENOMEM;
++ return 0;
+
+ __hash_init(*relocation_hashtable, hashtable_size);
+
+@@ -789,8 +793,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+ hashtable_bits = initialize_relocation_hashtable(num_relocations,
+ &relocation_hashtable);
+
+- if (hashtable_bits < 0)
+- return hashtable_bits;
++ if (!relocation_hashtable)
++ return -ENOMEM;
+
+ INIT_LIST_HEAD(&used_buckets_list);
+
+--
+2.43.0
+
--- /dev/null
+From 085eef692f59cec7cdfb38b7e2cf1930f689179e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 Oct 2023 08:20:40 +0100
+Subject: riscv: Fix an off-by-one in get_early_cmdline()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit adb1f95d388a43c4c564ef3e436f18900dde978e ]
+
+The ending NULL is not taken into account by strncat(), so switch to
+strlcat() to correctly compute the size of the available memory when
+appending CONFIG_CMDLINE to 'early_cmdline'.
+
+Fixes: 26e7aacb83df ("riscv: Allow to downgrade paging mode from the command line")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/9f66d2b58c8052d4055e90b8477ee55d9a0914f9.1698564026.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/pi/cmdline_early.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kernel/pi/cmdline_early.c b/arch/riscv/kernel/pi/cmdline_early.c
+index 68e786c84c94..f6d4dedffb84 100644
+--- a/arch/riscv/kernel/pi/cmdline_early.c
++++ b/arch/riscv/kernel/pi/cmdline_early.c
+@@ -38,8 +38,7 @@ static char *get_early_cmdline(uintptr_t dtb_pa)
+ if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
+ IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
+ fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) {
+- strncat(early_cmdline, CONFIG_CMDLINE,
+- COMMAND_LINE_SIZE - fdt_cmdline_size);
++ strlcat(early_cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+ }
+
+ return early_cmdline;
+--
+2.43.0
+
--- /dev/null
+From efa49097aa1282b80dc6426c84fcb18110590ce6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jan 2024 11:42:47 -0800
+Subject: riscv: Fix module loading free order
+
+From: Charlie Jenkins <charlie@rivosinc.com>
+
+[ Upstream commit 78996eee79ebdfe8b6f0e54cb6dcc792d5129291 ]
+
+Reverse order of kfree calls to resolve use-after-free error.
+
+Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
+Fixes: d8792a5734b0 ("riscv: Safely remove entries from relocation list")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/r/202312132019.iYGTwW0L-lkp@intel.com/
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Julia Lawall <julia.lawall@inria.fr>
+Closes: https://lore.kernel.org/r/202312120044.wTI1Uyaa-lkp@intel.com/
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-1-a71f8de6ce0f@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/module.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
+index 862834bb1d64..5cf3a693482d 100644
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -723,8 +723,8 @@ static int add_relocation_to_accumulate(struct module *me, int type,
+
+ if (!bucket) {
+ kfree(entry);
+- kfree(rel_head);
+ kfree(rel_head->rel_entry);
++ kfree(rel_head);
+ return -ENOMEM;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 462fae6542a015e24de1c01a35c29461c722ddd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jan 2024 11:42:49 -0800
+Subject: riscv: Fix relocation_hashtable size
+
+From: Charlie Jenkins <charlie@rivosinc.com>
+
+[ Upstream commit a35551c7244d9d061643a01eb96cc3ba04eaf45c ]
+
+A second dereference is needed to get the accurate size of the
+relocation_hashtable.
+
+Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
+Fixes: d8792a5734b0 ("riscv: Safely remove entries from relocation list")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Julia Lawall <julia.lawall@inria.fr>
+Closes: https://lore.kernel.org/r/202312120044.wTI1Uyaa-lkp@intel.com/
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-3-a71f8de6ce0f@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/module.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
+index 91f7cd221afc..c9d59a5448b6 100644
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -764,7 +764,7 @@ initialize_relocation_hashtable(unsigned int num_relocations,
+ hashtable_size <<= should_double_size;
+
+ *relocation_hashtable = kmalloc_array(hashtable_size,
+- sizeof(*relocation_hashtable),
++ sizeof(**relocation_hashtable),
+ GFP_KERNEL);
+ if (!*relocation_hashtable)
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From df6aaddf93455da5a777f3a0c2a4b74cd2e5bd72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 13:05:32 +0100
+Subject: scsi: core: Kick the requeue list after inserting when flushing
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 6df0e077d76bd144c533b61d6182676aae6b0a85 ]
+
+When libata calls ata_link_abort() to abort all ata queued commands, it
+calls blk_abort_request() on the SCSI command representing each QC.
+
+This causes scsi_timeout() to be called, which calls scsi_eh_scmd_add() for
+each SCSI command.
+
+scsi_eh_scmd_add() sets the SCSI host to state recovery, and then adds the
+command to shost->eh_cmd_q.
+
+This will wake up the SCSI EH, and eventually the libata EH strategy
+handler will be called, which calls scsi_eh_flush_done_q() to either flush
+retry or flush finish each failed command.
+
+The commands that are flush retried by scsi_eh_flush_done_q() are done so
+using scsi_queue_insert().
+
+Before commit 8b566edbdbfb ("scsi: core: Only kick the requeue list if
+necessary"), __scsi_queue_insert() called blk_mq_requeue_request() with the
+second argument set to true, indicating that it should always kick/run the
+requeue list after inserting.
+
+After commit 8b566edbdbfb ("scsi: core: Only kick the requeue list if
+necessary"), __scsi_queue_insert() does not kick/run the requeue list after
+inserting, if the current SCSI host state is recovery (which is the case in
+the libata example above).
+
+This optimization is probably fine in most cases, as I can only assume that
+most often someone will eventually kick/run the queues.
+
+However, that is not the case for scsi_eh_flush_done_q(), where we can see
+that the request gets inserted to the requeue list, but the queue is never
+started after the request has been inserted, leading to the block layer
+waiting for the completion of command that never gets to run.
+
+Since scsi_eh_flush_done_q() is called by SCSI EH context, the SCSI host
+state is most likely always in recovery when this function is called.
+
+Thus, let scsi_eh_flush_done_q() explicitly kick the requeue list after
+inserting a flush retry command, so that scsi_eh_flush_done_q() keeps the
+same behavior as before commit 8b566edbdbfb ("scsi: core: Only kick the
+requeue list if necessary").
+
+Simple reproducer for the libata example above:
+$ hdparm -Y /dev/sda
+$ echo 1 > /sys/class/scsi_device/0\:0\:0\:0/device/delete
+
+Fixes: 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary")
+Reported-by: Kevin Locke <kevin@kevinlocke.name>
+Closes: https://lore.kernel.org/linux-scsi/ZZw3Th70wUUvCiCY@kevinlocke.name/
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Link: https://lore.kernel.org/r/20240111120533.3612509-1-cassel@kernel.org
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_error.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 1223d34c04da..d983f4a0e9f1 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -2196,15 +2196,18 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
+ struct scsi_cmnd *scmd, *next;
+
+ list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
++ struct scsi_device *sdev = scmd->device;
++
+ list_del_init(&scmd->eh_entry);
+- if (scsi_device_online(scmd->device) &&
+- !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) &&
+- scsi_eh_should_retry_cmd(scmd)) {
++ if (scsi_device_online(sdev) && !scsi_noretry_cmd(scmd) &&
++ scsi_cmd_retry_allowed(scmd) &&
++ scsi_eh_should_retry_cmd(scmd)) {
+ SCSI_LOG_ERROR_RECOVERY(3,
+ scmd_printk(KERN_INFO, scmd,
+ "%s: flush retry cmd\n",
+ current->comm));
+ scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
++ blk_mq_kick_requeue_list(sdev->request_queue);
+ } else {
+ /*
+ * If just we got sense for the device (called
+--
+2.43.0
+
--- /dev/null
+From 365df24c711357012da87438244c4eecdc6d32a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 14:52:15 -0800
+Subject: scsi: ufs: core: Remove the ufshcd_hba_exit() call from
+ ufshcd_async_scan()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit ee36710912b2075c417100a8acc642c9c6496501 ]
+
+Calling ufshcd_hba_exit() from a function that is called asynchronously
+from ufshcd_init() is wrong because this triggers multiple race
+conditions. Instead of calling ufshcd_hba_exit(), log an error message.
+
+Reported-by: Daniel Mentz <danielmentz@google.com>
+Fixes: 1d337ec2f35e ("ufs: improve init sequence")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20231218225229.2542156-3-bvanassche@acm.org
+Reviewed-by: Can Guo <quic_cang@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index ce2f76769fb0..1f8d86b9c4fa 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -8916,12 +8916,9 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
+
+ out:
+ pm_runtime_put_sync(hba->dev);
+- /*
+- * If we failed to initialize the device or the device is not
+- * present, turn off the power/clocks etc.
+- */
++
+ if (ret)
+- ufshcd_hba_exit(hba);
++ dev_err(hba->dev, "%s failed: %d\n", __func__, ret);
+ }
+
+ static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
+--
+2.43.0
+
--- /dev/null
+soundwire-bus-introduce-controller_id.patch
+soundwire-fix-initializing-sysfs-for-same-devices-on.patch
+iio-adc-ad7091r-set-alert-bit-in-config-register.patch
+iio-adc-ad7091r-allow-users-to-configure-device-even.patch
+iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch
+dmaengine-fsl-edma-fix-edmav4-channel-allocation-iss.patch
+dmaengine-fix-null-pointer-in-channel-unregistration.patch
+dmaengine-idxd-move-dma_free_coherent-out-of-spinloc.patch
+dmaengine-xilinx-xdma-fix-the-count-of-elapsed-perio.patch
+scsi-ufs-core-remove-the-ufshcd_hba_exit-call-from-u.patch
+riscv-fix-module-loading-free-order.patch
+riscv-correctly-free-relocation-hashtable-on-error.patch
+riscv-fix-relocation_hashtable-size.patch
+riscv-fix-an-off-by-one-in-get_early_cmdline.patch
+scsi-core-kick-the-requeue-list-after-inserting-when.patch
+sh-ecovec24-rename-missed-backlight-field-from-fbdev.patch
+smb-client-fix-parsing-of-smb3.1.1-posix-create-cont.patch
+cifs-handle-servers-that-still-advertise-multichanne.patch
+cifs-update-iface_last_update-on-each-query-and-upda.patch
--- /dev/null
+From fecb35137549ac352110e73567328f62c5416f7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 13:10:22 +0200
+Subject: sh: ecovec24: Rename missed backlight field from fbdev to dev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit d87123aa9a7920e88633ffc5c5a0a22ab08bdc06 ]
+
+One instance of gpio_backlight_platform_data.fbdev was renamed, but the
+second instance was forgotten, causing a build failure:
+
+ arch/sh/boards/mach-ecovec24/setup.c: In function ‘arch_setup’:
+ arch/sh/boards/mach-ecovec24/setup.c:1223:37: error: ‘struct gpio_backlight_platform_data’ has no member named ‘fbdev’; did you mean ‘dev’?
+ 1223 | gpio_backlight_data.fbdev = NULL;
+ | ^~~~~
+ | dev
+
+Fix this by updating the second instance.
+
+Fixes: ed369def91c1579a ("backlight/gpio_backlight: Rename field 'fbdev' to 'dev'")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202309231601.Uu6qcRnU-lkp@intel.com/
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reviewed-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Link: https://lore.kernel.org/r/20230925111022.3626362-1-geert+renesas@glider.be
+Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sh/boards/mach-ecovec24/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
+index 0f279360838a..30d117f9ad7e 100644
+--- a/arch/sh/boards/mach-ecovec24/setup.c
++++ b/arch/sh/boards/mach-ecovec24/setup.c
+@@ -1220,7 +1220,7 @@ static int __init arch_setup(void)
+ lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_dvi_modes);
+
+ /* No backlight */
+- gpio_backlight_data.fbdev = NULL;
++ gpio_backlight_data.dev = NULL;
+
+ gpio_set_value(GPIO_PTA2, 1);
+ gpio_set_value(GPIO_PTU1, 1);
+--
+2.43.0
+
--- /dev/null
+From 5a2f1d1720ea1db3d356c7b86e2eadd083f698ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jan 2024 01:08:26 -0300
+Subject: smb: client: fix parsing of SMB3.1.1 POSIX create context
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 76025cc2285d9ede3d717fe4305d66f8be2d9346 ]
+
+The data offset for the SMB3.1.1 POSIX create context will always be
+8-byte aligned so having the check 'noff + nlen >= doff' in
+smb2_parse_contexts() is wrong as it will lead to -EINVAL because noff
++ nlen == doff.
+
+Fix the sanity check to correctly handle aligned create context data.
+
+Fixes: af1689a9b770 ("smb: client: fix potential OOBs in smb2_parse_contexts()")
+Signed-off-by: Paulo Alcantara <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2pdu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 4f971c1061f0..12e41fcd0b46 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -2279,7 +2279,7 @@ int smb2_parse_contexts(struct TCP_Server_Info *server,
+
+ noff = le16_to_cpu(cc->NameOffset);
+ nlen = le16_to_cpu(cc->NameLength);
+- if (noff + nlen >= doff)
++ if (noff + nlen > doff)
+ return -EINVAL;
+
+ name = (char *)cc + noff;
+--
+2.43.0
+
--- /dev/null
+From 85fdfe20a0d45477b117956a8aab8b74b67b89e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 11:09:32 -0500
+Subject: soundwire: bus: introduce controller_id
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 6543ac13c623f906200dfd3f1c407d8d333b6995 ]
+
+The existing SoundWire support misses a clear Controller/Manager
+hiearchical definition to deal with all variants across SOC vendors.
+
+a) Intel platforms have one controller with 4 or more Managers.
+b) AMD platforms have two controllers with one Manager each, but due
+to BIOS issues use two different link_id values within the scope of a
+single controller.
+c) QCOM platforms have one or more controller with one Manager each.
+
+This patch adds a 'controller_id' which can be set by higher
+levels. If assigned to -1, the controller_id will be set to the
+system-unique IDA-assigned bus->id.
+
+The main change is that the bus->id is no longer used for any device
+name, which makes the definition completely predictable and not
+dependent on any enumeration order. The bus->id is only used to insert
+the Managers in the stream rt context.
+
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/stable/20231017160933.12624-2-pierre-louis.bossart%40linux.intel.com
+Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20231017160933.12624-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 8a8a9ac8a497 ("soundwire: fix initializing sysfs for same devices on different buses")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/amd_manager.c | 8 ++++++++
+ drivers/soundwire/bus.c | 4 ++++
+ drivers/soundwire/debugfs.c | 2 +-
+ drivers/soundwire/intel_auxdevice.c | 3 +++
+ drivers/soundwire/master.c | 2 +-
+ drivers/soundwire/qcom.c | 3 +++
+ include/linux/soundwire/sdw.h | 4 +++-
+ 7 files changed, 23 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
+index 3a99f6dcdfaf..a3b1f4e6f0f9 100644
+--- a/drivers/soundwire/amd_manager.c
++++ b/drivers/soundwire/amd_manager.c
+@@ -927,6 +927,14 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
+ amd_manager->bus.clk_stop_timeout = 200;
+ amd_manager->bus.link_id = amd_manager->instance;
+
++ /*
++ * Due to BIOS compatibility, the two links are exposed within
++ * the scope of a single controller. If this changes, the
++ * controller_id will have to be updated with drv_data
++ * information.
++ */
++ amd_manager->bus.controller_id = 0;
++
+ switch (amd_manager->instance) {
+ case ACP_SDW0:
+ amd_manager->num_dout_ports = AMD_SDW0_MAX_TX_PORTS;
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 41b0d9adf68e..f3fec15c3112 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -22,6 +22,10 @@ static int sdw_get_id(struct sdw_bus *bus)
+ return rc;
+
+ bus->id = rc;
++
++ if (bus->controller_id == -1)
++ bus->controller_id = rc;
++
+ return 0;
+ }
+
+diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
+index d1553cb77187..67abd7e52f09 100644
+--- a/drivers/soundwire/debugfs.c
++++ b/drivers/soundwire/debugfs.c
+@@ -20,7 +20,7 @@ void sdw_bus_debugfs_init(struct sdw_bus *bus)
+ return;
+
+ /* create the debugfs master-N */
+- snprintf(name, sizeof(name), "master-%d-%d", bus->id, bus->link_id);
++ snprintf(name, sizeof(name), "master-%d-%d", bus->controller_id, bus->link_id);
+ bus->debugfs = debugfs_create_dir(name, sdw_debugfs_root);
+ }
+
+diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c
+index 7f15e3549e53..93698532deac 100644
+--- a/drivers/soundwire/intel_auxdevice.c
++++ b/drivers/soundwire/intel_auxdevice.c
+@@ -234,6 +234,9 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
+ cdns->instance = sdw->instance;
+ cdns->msg_count = 0;
+
++ /* single controller for all SoundWire links */
++ bus->controller_id = 0;
++
+ bus->link_id = auxdev->id;
+ bus->clk_stop_timeout = 1;
+
+diff --git a/drivers/soundwire/master.c b/drivers/soundwire/master.c
+index 9b05c9e25ebe..51abedbbaa66 100644
+--- a/drivers/soundwire/master.c
++++ b/drivers/soundwire/master.c
+@@ -145,7 +145,7 @@ int sdw_master_device_add(struct sdw_bus *bus, struct device *parent,
+ md->dev.fwnode = fwnode;
+ md->dev.dma_mask = parent->dma_mask;
+
+- dev_set_name(&md->dev, "sdw-master-%d", bus->id);
++ dev_set_name(&md->dev, "sdw-master-%d-%d", bus->controller_id, bus->link_id);
+
+ ret = device_register(&md->dev);
+ if (ret) {
+diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
+index a1e2d6c98186..8e027eee8b73 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -1624,6 +1624,9 @@ static int qcom_swrm_probe(struct platform_device *pdev)
+ }
+ }
+
++ /* FIXME: is there a DT-defined value to use ? */
++ ctrl->bus.controller_id = -1;
++
+ ret = sdw_bus_master_add(&ctrl->bus, dev, dev->fwnode);
+ if (ret) {
+ dev_err(dev, "Failed to register Soundwire controller (%d)\n",
+diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
+index 4f3d14bb1538..c383579a008b 100644
+--- a/include/linux/soundwire/sdw.h
++++ b/include/linux/soundwire/sdw.h
+@@ -886,7 +886,8 @@ struct sdw_master_ops {
+ * struct sdw_bus - SoundWire bus
+ * @dev: Shortcut to &bus->md->dev to avoid changing the entire code.
+ * @md: Master device
+- * @link_id: Link id number, can be 0 to N, unique for each Master
++ * @controller_id: system-unique controller ID. If set to -1, the bus @id will be used.
++ * @link_id: Link id number, can be 0 to N, unique for each Controller
+ * @id: bus system-wide unique id
+ * @slaves: list of Slaves on this bus
+ * @assigned: Bitmap for Slave device numbers.
+@@ -918,6 +919,7 @@ struct sdw_master_ops {
+ struct sdw_bus {
+ struct device *dev;
+ struct sdw_master_device *md;
++ int controller_id;
+ unsigned int link_id;
+ int id;
+ struct list_head slaves;
+--
+2.43.0
+
--- /dev/null
+From 954a3e1a5a5e694d8bd39c5088226b1b83bcc6b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 11:09:33 -0500
+Subject: soundwire: fix initializing sysfs for same devices on different buses
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 8a8a9ac8a4972ee69d3dd3d1ae43963ae39cee18 ]
+
+If same devices with same device IDs are present on different soundwire
+buses, the probe fails due to conflicting device names and sysfs
+entries:
+
+ sysfs: cannot create duplicate filename '/bus/soundwire/devices/sdw:0:0217:0204:00:0'
+
+The link ID is 0 for both devices, so they should be differentiated by
+the controller ID. Add the controller ID so, the device names and sysfs entries look
+like:
+
+ sdw:1:0:0217:0204:00:0 -> ../../../devices/platform/soc@0/6ab0000.soundwire-controller/sdw-master-1-0/sdw:1:0:0217:0204:00:0
+ sdw:3:0:0217:0204:00:0 -> ../../../devices/platform/soc@0/6b10000.soundwire-controller/sdw-master-3-0/sdw:3:0:0217:0204:00:0
+
+[PLB changes: use bus->controller_id instead of bus->id]
+
+Fixes: 7c3cd189b86d ("soundwire: Add Master registration")
+Cc: stable@vger.kernel.org
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Co-developed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Mark Brown <broonie@kernel.org>
+Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20231017160933.12624-3-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/slave.c | 12 ++++++------
+ sound/soc/intel/boards/sof_sdw.c | 4 ++--
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
+index c1c1a2ac293a..060c2982e26b 100644
+--- a/drivers/soundwire/slave.c
++++ b/drivers/soundwire/slave.c
+@@ -39,14 +39,14 @@ int sdw_slave_add(struct sdw_bus *bus,
+ slave->dev.fwnode = fwnode;
+
+ if (id->unique_id == SDW_IGNORED_UNIQUE_ID) {
+- /* name shall be sdw:link:mfg:part:class */
+- dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x",
+- bus->link_id, id->mfg_id, id->part_id,
++ /* name shall be sdw:ctrl:link:mfg:part:class */
++ dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x",
++ bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
+ id->class_id);
+ } else {
+- /* name shall be sdw:link:mfg:part:class:unique */
+- dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x:%01x",
+- bus->link_id, id->mfg_id, id->part_id,
++ /* name shall be sdw:ctrl:link:mfg:part:class:unique */
++ dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x:%01x",
++ bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
+ id->class_id, id->unique_id);
+ }
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 4e4284729773..1e788859c863 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -1232,11 +1232,11 @@ static int fill_sdw_codec_dlc(struct device *dev,
+ else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id,
+ class_id, adr_index))
+ codec->name = devm_kasprintf(dev, GFP_KERNEL,
+- "sdw:%01x:%04x:%04x:%02x", link_id,
++ "sdw:0:%01x:%04x:%04x:%02x", link_id,
+ mfg_id, part_id, class_id);
+ else
+ codec->name = devm_kasprintf(dev, GFP_KERNEL,
+- "sdw:%01x:%04x:%04x:%02x:%01x", link_id,
++ "sdw:0:%01x:%04x:%04x:%02x:%01x", link_id,
+ mfg_id, part_id, class_id, unique_id);
+
+ if (!codec->name)
+--
+2.43.0
+