--- /dev/null
+From f3dd093a81040759d0a89719c86da50e14838aa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 May 2024 13:50:09 +0800
+Subject: ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897
+
+From: Jian-Hong Pan <jhp@endlessos.org>
+
+[ Upstream commit 45e37f9ce28d248470bab4376df2687a215d1b22 ]
+
+JP-IK LEAP W502 laptop's headset mic is not enabled until
+ALC897_FIXUP_HEADSET_MIC_PIN3 quirk is applied.
+
+Here is the original pin node values:
+
+0x11 0x40000000
+0x12 0xb7a60130
+0x14 0x90170110
+0x15 0x411111f0
+0x16 0x411111f0
+0x17 0x411111f0
+0x18 0x411111f0
+0x19 0x411111f0
+0x1a 0x411111f0
+0x1b 0x03211020
+0x1c 0x411111f0
+0x1d 0x4026892d
+0x1e 0x411111f0
+0x1f 0x411111f0
+
+Signed-off-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20240520055008.7083-2-jhp@endlessos.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index bf9a4d5f8555d..2c0bfdfcf6410 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9909,6 +9909,7 @@ enum {
+ ALC897_FIXUP_LENOVO_HEADSET_MODE,
+ ALC897_FIXUP_HEADSET_MIC_PIN2,
+ ALC897_FIXUP_UNIS_H3C_X500S,
++ ALC897_FIXUP_HEADSET_MIC_PIN3,
+ };
+
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -10355,10 +10356,18 @@ static const struct hda_fixup alc662_fixups[] = {
+ {}
+ },
+ },
++ [ALC897_FIXUP_HEADSET_MIC_PIN3] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x19, 0x03a11050 }, /* use as headset mic */
++ { }
++ },
++ },
+ };
+
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
++ SND_PCI_QUIRK(0x1019, 0x9859, "JP-IK LEAP W502", ALC897_FIXUP_HEADSET_MIC_PIN3),
+ SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
+ SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
+ SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
+--
+2.43.0
+
--- /dev/null
+From 0926a685827d774b04d4a44f8c49b25fc40e6f76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jun 2024 17:25:42 +0200
+Subject: i2c: pnx: Fix potential deadlock warning from del_timer_sync() call
+ in isr
+
+From: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
+
+[ Upstream commit f63b94be6942ba82c55343e196bd09b53227618e ]
+
+When del_timer_sync() is called in an interrupt context it throws a warning
+because of potential deadlock. The timer is used only to exit from
+wait_for_completion() after a timeout so replacing the call with
+wait_for_completion_timeout() allows to remove the problematic timer and
+its related functions altogether.
+
+Fixes: 41561f28e76a ("i2c: New Philips PNX bus driver")
+Signed-off-by: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-pnx.c | 48 ++++++++----------------------------
+ 1 file changed, 10 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
+index 6e0e546ef83fc..4d09665a72e59 100644
+--- a/drivers/i2c/busses/i2c-pnx.c
++++ b/drivers/i2c/busses/i2c-pnx.c
+@@ -15,7 +15,6 @@
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+-#include <linux/timer.h>
+ #include <linux/completion.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+@@ -32,7 +31,6 @@ struct i2c_pnx_mif {
+ int ret; /* Return value */
+ int mode; /* Interface mode */
+ struct completion complete; /* I/O completion */
+- struct timer_list timer; /* Timeout */
+ u8 * buf; /* Data buffer */
+ int len; /* Length of data buffer */
+ int order; /* RX Bytes to order via TX */
+@@ -117,24 +115,6 @@ static inline int wait_reset(struct i2c_pnx_algo_data *data)
+ return (timeout <= 0);
+ }
+
+-static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
+-{
+- struct timer_list *timer = &alg_data->mif.timer;
+- unsigned long expires = msecs_to_jiffies(alg_data->timeout);
+-
+- if (expires <= 1)
+- expires = 2;
+-
+- del_timer_sync(timer);
+-
+- dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
+- jiffies, expires);
+-
+- timer->expires = jiffies + expires;
+-
+- add_timer(timer);
+-}
+-
+ /**
+ * i2c_pnx_start - start a device
+ * @slave_addr: slave address
+@@ -259,8 +239,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
+ ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
+ I2C_REG_CTL(alg_data));
+
+- del_timer_sync(&alg_data->mif.timer);
+-
+ dev_dbg(&alg_data->adapter.dev,
+ "%s(): Waking up xfer routine.\n",
+ __func__);
+@@ -276,8 +254,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
+ ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
+ I2C_REG_CTL(alg_data));
+
+- /* Stop timer. */
+- del_timer_sync(&alg_data->mif.timer);
+ dev_dbg(&alg_data->adapter.dev,
+ "%s(): Waking up xfer routine after zero-xfer.\n",
+ __func__);
+@@ -364,8 +340,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
+ mcntrl_drmie | mcntrl_daie);
+ iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+- /* Kill timer. */
+- del_timer_sync(&alg_data->mif.timer);
+ complete(&alg_data->mif.complete);
+ }
+ }
+@@ -400,8 +374,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
+ mcntrl_drmie);
+ iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+- /* Stop timer, to prevent timeout. */
+- del_timer_sync(&alg_data->mif.timer);
+ complete(&alg_data->mif.complete);
+ } else if (stat & mstatus_nai) {
+ /* Slave did not acknowledge, generate a STOP */
+@@ -419,8 +391,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
+ /* Our return value. */
+ alg_data->mif.ret = -EIO;
+
+- /* Stop timer, to prevent timeout. */
+- del_timer_sync(&alg_data->mif.timer);
+ complete(&alg_data->mif.complete);
+ } else {
+ /*
+@@ -453,9 +423,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-static void i2c_pnx_timeout(struct timer_list *t)
++static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data)
+ {
+- struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer);
+ u32 ctl;
+
+ dev_err(&alg_data->adapter.dev,
+@@ -472,7 +441,6 @@ static void i2c_pnx_timeout(struct timer_list *t)
+ iowrite32(ctl, I2C_REG_CTL(alg_data));
+ wait_reset(alg_data);
+ alg_data->mif.ret = -EIO;
+- complete(&alg_data->mif.complete);
+ }
+
+ static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
+@@ -514,6 +482,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ struct i2c_msg *pmsg;
+ int rc = 0, completed = 0, i;
+ struct i2c_pnx_algo_data *alg_data = adap->algo_data;
++ unsigned long time_left;
+ u32 stat;
+
+ dev_dbg(&alg_data->adapter.dev,
+@@ -548,7 +517,6 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
+ __func__, alg_data->mif.mode, alg_data->mif.len);
+
+- i2c_pnx_arm_timer(alg_data);
+
+ /* initialize the completion var */
+ init_completion(&alg_data->mif.complete);
+@@ -564,7 +532,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ break;
+
+ /* Wait for completion */
+- wait_for_completion(&alg_data->mif.complete);
++ time_left = wait_for_completion_timeout(&alg_data->mif.complete,
++ alg_data->timeout);
++ if (time_left == 0)
++ i2c_pnx_timeout(alg_data);
+
+ if (!(rc = alg_data->mif.ret))
+ completed++;
+@@ -657,7 +628,10 @@ static int i2c_pnx_probe(struct platform_device *pdev)
+ alg_data->adapter.algo_data = alg_data;
+ alg_data->adapter.nr = pdev->id;
+
+- alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT;
++ alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT);
++ if (alg_data->timeout <= 1)
++ alg_data->timeout = 2;
++
+ #ifdef CONFIG_OF
+ alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
+ if (pdev->dev.of_node) {
+@@ -677,8 +651,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
+ if (IS_ERR(alg_data->clk))
+ return PTR_ERR(alg_data->clk);
+
+- timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0);
+-
+ snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
+ "%s", pdev->name);
+
+--
+2.43.0
+
--- /dev/null
+From ecf538903e565810946daff7f4449bd9c61edc2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 May 2024 17:43:51 +0530
+Subject: nvme-multipath: find NUMA path only for online numa-node
+
+From: Nilay Shroff <nilay@linux.ibm.com>
+
+[ Upstream commit d3a043733f25d743f3aa617c7f82dbcb5ee2211a ]
+
+In current native multipath design when a shared namespace is created,
+we loop through each possible numa-node, calculate the NUMA distance of
+that node from each nvme controller and then cache the optimal IO path
+for future reference while sending IO. The issue with this design is that
+we may refer to the NUMA distance table for an offline node which may not
+be populated at the time and so we may inadvertently end up finding and
+caching a non-optimal path for IO. Then latter when the corresponding
+numa-node becomes online and hence the NUMA distance table entry for that
+node is created, ideally we should re-calculate the multipath node distance
+for the newly added node however that doesn't happen unless we rescan/reset
+the controller. So essentially, we may keep using non-optimal IO path for a
+node which is made online after namespace is created.
+This patch helps fix this issue ensuring that when a shared namespace is
+created, we calculate the multipath node distance for each online numa-node
+instead of each possible numa-node. Then latter when a node becomes online
+and we receive any IO on that newly added node, we would calculate the
+multipath node distance for newly added node but this time NUMA distance
+table would have been already populated for newly added node. Hence we
+would be able to correctly calculate the multipath node distance and choose
+the optimal path for the IO.
+
+Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/multipath.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index 4f3220aef7c47..36d63da71b2f9 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -437,7 +437,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
+ int node, srcu_idx;
+
+ srcu_idx = srcu_read_lock(&head->srcu);
+- for_each_node(node)
++ for_each_online_node(node)
+ __nvme_find_path(head, node);
+ srcu_read_unlock(&head->srcu, srcu_idx);
+ }
+--
+2.43.0
+