--- /dev/null
+From a45dad957afacdc339c1bceb10b9274da8afe32e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 13:14:32 +0800
+Subject: ceph: switch to corrected encoding of max_xattr_size in mdsmap
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit 51d31149a88b5c5a8d2d33f06df93f6187a25b4c ]
+
+The addition of bal_rank_mask with encoding version 17 was merged
+into ceph.git in Oct 2022 and made it into v18.2.0 release normally.
+A few months later, the much delayed addition of max_xattr_size got
+merged, also with encoding version 17, placed before bal_rank_mask
+in the encoding -- but it didn't make v18.2.0 release.
+
+The way this ended up being resolved on the MDS side is that
+bal_rank_mask will continue to be encoded in version 17 while
+max_xattr_size is now encoded in version 18. This does mean that
+older kernels will misdecode version 17, but this is also true for
+v18.2.0 and v18.2.1 clients in userspace.
+
+The best we can do is backport this adjustment -- see ceph.git
+commit 78abfeaff27fee343fb664db633de5b221699a73 for details.
+
+[ idryomov: changelog ]
+
+Cc: stable@vger.kernel.org
+Link: https://tracker.ceph.com/issues/64440
+Fixes: d93231a6bc8a ("ceph: prevent a client from exceeding the MDS maximum xattr size")
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Patrick Donnelly <pdonnell@ibm.com>
+Reviewed-by: Venky Shankar <vshankar@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/mdsmap.c | 7 ++++---
+ include/linux/ceph/mdsmap.h | 6 +++++-
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c
+index 7dac21ee6ce76..3bb3b610d403e 100644
+--- a/fs/ceph/mdsmap.c
++++ b/fs/ceph/mdsmap.c
+@@ -379,10 +379,11 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end, bool msgr2)
+ ceph_decode_skip_8(p, end, bad_ext);
+ /* required_client_features */
+ ceph_decode_skip_set(p, end, 64, bad_ext);
++ /* bal_rank_mask */
++ ceph_decode_skip_string(p, end, bad_ext);
++ }
++ if (mdsmap_ev >= 18) {
+ ceph_decode_64_safe(p, end, m->m_max_xattr_size, bad_ext);
+- } else {
+- /* This forces the usage of the (sync) SETXATTR Op */
+- m->m_max_xattr_size = 0;
+ }
+ bad_ext:
+ dout("mdsmap_decode m_enabled: %d, m_damaged: %d, m_num_laggy: %d\n",
+diff --git a/include/linux/ceph/mdsmap.h b/include/linux/ceph/mdsmap.h
+index 4c3e0648dc277..fcc95bff72a57 100644
+--- a/include/linux/ceph/mdsmap.h
++++ b/include/linux/ceph/mdsmap.h
+@@ -25,7 +25,11 @@ struct ceph_mdsmap {
+ u32 m_session_timeout; /* seconds */
+ u32 m_session_autoclose; /* seconds */
+ u64 m_max_file_size;
+- u64 m_max_xattr_size; /* maximum size for xattrs blob */
++ /*
++ * maximum size for xattrs blob.
++ * Zeroed by default to force the usage of the (sync) SETXATTR Op.
++ */
++ u64 m_max_xattr_size;
+ u32 m_max_mds; /* expected up:active mds number */
+ u32 m_num_active_mds; /* actual up:active mds number */
+ u32 possible_max_rank; /* possible max rank index */
+--
+2.43.0
+
--- /dev/null
+From 72948c318780e95ea55bf1cd9fd37a77fd0a0fcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Feb 2024 14:47:32 -0500
+Subject: dmaengine: fsl-edma: correct max_segment_size setting
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit a79f949a5ce1d45329d63742c2a995f2b47f9852 ]
+
+Correcting the previous setting of 0x3fff to the actual value of 0x7fff.
+
+Introduced new macro 'EDMA_TCD_ITER_MASK' for improved code clarity and
+utilization of FIELD_GET to obtain the accurate maximum value.
+
+Cc: stable@vger.kernel.org
+Fixes: e06748539432 ("dmaengine: fsl-edma: support edma memcpy")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20240207194733.2112870-1-Frank.Li@nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/fsl-edma-common.h | 5 +++--
+ drivers/dma/fsl-edma-main.c | 4 +++-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
+index 40d50cc3d75a3..92fe53faa53b1 100644
+--- a/drivers/dma/fsl-edma-common.h
++++ b/drivers/dma/fsl-edma-common.h
+@@ -30,8 +30,9 @@
+ #define EDMA_TCD_ATTR_SSIZE(x) (((x) & GENMASK(2, 0)) << 8)
+ #define EDMA_TCD_ATTR_SMOD(x) (((x) & GENMASK(4, 0)) << 11)
+
+-#define EDMA_TCD_CITER_CITER(x) ((x) & GENMASK(14, 0))
+-#define EDMA_TCD_BITER_BITER(x) ((x) & GENMASK(14, 0))
++#define EDMA_TCD_ITER_MASK GENMASK(14, 0)
++#define EDMA_TCD_CITER_CITER(x) ((x) & EDMA_TCD_ITER_MASK)
++#define EDMA_TCD_BITER_BITER(x) ((x) & EDMA_TCD_ITER_MASK)
+
+ #define EDMA_TCD_CSR_START BIT(0)
+ #define EDMA_TCD_CSR_INT_MAJOR BIT(1)
+diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
+index a56c8a0f2663f..42a338cbe6143 100644
+--- a/drivers/dma/fsl-edma-main.c
++++ b/drivers/dma/fsl-edma-main.c
+@@ -10,6 +10,7 @@
+ */
+
+ #include <dt-bindings/dma/fsl-edma.h>
++#include <linux/bitfield.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/clk.h>
+@@ -589,7 +590,8 @@ static int fsl_edma_probe(struct platform_device *pdev)
+ DMAENGINE_ALIGN_32_BYTES;
+
+ /* Per worst case 'nbytes = 1' take CITER as the max_seg_size */
+- dma_set_max_seg_size(fsl_edma->dma_dev.dev, 0x3fff);
++ dma_set_max_seg_size(fsl_edma->dma_dev.dev,
++ FIELD_GET(EDMA_TCD_ITER_MASK, EDMA_TCD_ITER_MASK));
+
+ fsl_edma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+
+--
+2.43.0
+
--- /dev/null
+From 148c0e7c08d6625c357dc8d7d19fd5cb19eee308 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Nov 2023 10:48:23 -0500
+Subject: dmaengine: fsl-edma: utilize common dt-binding header file
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit d0e217b72f9f5c5ef35e3423d393ea8093ce98ec ]
+
+Refactor the code to use the common dt-binding header file, fsl-edma.h.
+Renaming ARGS* to FSL_EDMA*, ensuring no functional changes.
+
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231114154824.3617255-4-Frank.Li@nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: a79f949a5ce1 ("dmaengine: fsl-edma: correct max_segment_size setting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/fsl-edma-main.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
+index 30df55da4dbb9..a56c8a0f2663f 100644
+--- a/drivers/dma/fsl-edma-main.c
++++ b/drivers/dma/fsl-edma-main.c
+@@ -9,6 +9,7 @@
+ * Vybrid and Layerscape SoCs.
+ */
+
++#include <dt-bindings/dma/fsl-edma.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/clk.h>
+@@ -23,12 +24,6 @@
+
+ #include "fsl-edma-common.h"
+
+-#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)
+ {
+ struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+@@ -157,14 +152,14 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
+ i = fsl_chan - fsl_edma->chans;
+
+ fsl_chan->priority = dma_spec->args[1];
+- fsl_chan->is_rxchan = dma_spec->args[2] & ARGS_RX;
+- fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
+- fsl_chan->is_multi_fifo = dma_spec->args[2] & ARGS_MULTI_FIFO;
++ fsl_chan->is_rxchan = dma_spec->args[2] & FSL_EDMA_RX;
++ fsl_chan->is_remote = dma_spec->args[2] & FSL_EDMA_REMOTE;
++ fsl_chan->is_multi_fifo = dma_spec->args[2] & FSL_EDMA_MULTI_FIFO;
+
+- if ((dma_spec->args[2] & ARGS_EVEN_CH) && (i & 0x1))
++ if ((dma_spec->args[2] & FSL_EDMA_EVEN_CH) && (i & 0x1))
+ continue;
+
+- if ((dma_spec->args[2] & ARGS_ODD_CH) && !(i & 0x1))
++ if ((dma_spec->args[2] & FSL_EDMA_ODD_CH) && !(i & 0x1))
+ continue;
+
+ if (!b_chmux && i == dma_spec->args[0]) {
+--
+2.43.0
+
--- /dev/null
+From 62aa603606683e56c0e967003e07e93b73d8e901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Dec 2023 14:43:28 +0300
+Subject: drm/bridge: add transparent bridge helper
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 2a04739139b2b2761571e18937e2400e71eff664 ]
+
+Define a helper for creating simple transparent bridges which serve the
+only purpose of linking devices into the bridge chain up to the last
+bridge representing the connector. This is especially useful for
+DP/USB-C bridge chains, which can span across several devices, but do
+not require any additional functionality from the intermediate bridges.
+
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231203114333.1305826-2-dmitry.baryshkov@linaro.org
+Stable-dep-of: b979f2d50a09 ("soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/Kconfig | 9 ++
+ drivers/gpu/drm/bridge/Makefile | 1 +
+ drivers/gpu/drm/bridge/aux-bridge.c | 140 ++++++++++++++++++++++++++++
+ include/drm/bridge/aux-bridge.h | 19 ++++
+ 4 files changed, 169 insertions(+)
+ create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c
+ create mode 100644 include/drm/bridge/aux-bridge.h
+
+diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
+index 3e6a4e2044c0e..a22645efe93a0 100644
+--- a/drivers/gpu/drm/bridge/Kconfig
++++ b/drivers/gpu/drm/bridge/Kconfig
+@@ -12,6 +12,15 @@ config DRM_PANEL_BRIDGE
+ help
+ DRM bridge wrapper of DRM panels
+
++config DRM_AUX_BRIDGE
++ tristate
++ depends on DRM_BRIDGE && OF
++ select AUXILIARY_BUS
++ select DRM_PANEL_BRIDGE
++ help
++ Simple transparent bridge that is used by several non-DRM drivers to
++ build bridges chain.
++
+ menu "Display Interface Bridges"
+ depends on DRM && DRM_BRIDGE
+
+diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
+index 2b892b7ed59e8..918e3bfff079c 100644
+--- a/drivers/gpu/drm/bridge/Makefile
++++ b/drivers/gpu/drm/bridge/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
+ obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
+ obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
+ obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
+diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c
+new file mode 100644
+index 0000000000000..49d7c2ab1ecc3
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/aux-bridge.c
+@@ -0,0 +1,140 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (C) 2023 Linaro Ltd.
++ *
++ * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
++ */
++#include <linux/auxiliary_bus.h>
++#include <linux/module.h>
++
++#include <drm/drm_bridge.h>
++#include <drm/bridge/aux-bridge.h>
++
++static DEFINE_IDA(drm_aux_bridge_ida);
++
++static void drm_aux_bridge_release(struct device *dev)
++{
++ struct auxiliary_device *adev = to_auxiliary_dev(dev);
++
++ ida_free(&drm_aux_bridge_ida, adev->id);
++
++ kfree(adev);
++}
++
++static void drm_aux_bridge_unregister_adev(void *_adev)
++{
++ struct auxiliary_device *adev = _adev;
++
++ auxiliary_device_delete(adev);
++ auxiliary_device_uninit(adev);
++}
++
++/**
++ * drm_aux_bridge_register - Create a simple bridge device to link the chain
++ * @parent: device instance providing this bridge
++ *
++ * Creates a simple DRM bridge that doesn't implement any drm_bridge
++ * operations. Such bridges merely fill a place in the bridge chain linking
++ * surrounding DRM bridges.
++ *
++ * Return: zero on success, negative error code on failure
++ */
++int drm_aux_bridge_register(struct device *parent)
++{
++ struct auxiliary_device *adev;
++ int ret;
++
++ adev = kzalloc(sizeof(*adev), GFP_KERNEL);
++ if (!adev)
++ return -ENOMEM;
++
++ ret = ida_alloc(&drm_aux_bridge_ida, GFP_KERNEL);
++ if (ret < 0) {
++ kfree(adev);
++ return ret;
++ }
++
++ adev->id = ret;
++ adev->name = "aux_bridge";
++ adev->dev.parent = parent;
++ adev->dev.of_node = parent->of_node;
++ adev->dev.release = drm_aux_bridge_release;
++
++ ret = auxiliary_device_init(adev);
++ if (ret) {
++ ida_free(&drm_aux_bridge_ida, adev->id);
++ kfree(adev);
++ return ret;
++ }
++
++ ret = auxiliary_device_add(adev);
++ if (ret) {
++ auxiliary_device_uninit(adev);
++ return ret;
++ }
++
++ return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev);
++}
++EXPORT_SYMBOL_GPL(drm_aux_bridge_register);
++
++struct drm_aux_bridge_data {
++ struct drm_bridge bridge;
++ struct drm_bridge *next_bridge;
++ struct device *dev;
++};
++
++static int drm_aux_bridge_attach(struct drm_bridge *bridge,
++ enum drm_bridge_attach_flags flags)
++{
++ struct drm_aux_bridge_data *data;
++
++ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
++ return -EINVAL;
++
++ data = container_of(bridge, struct drm_aux_bridge_data, bridge);
++
++ return drm_bridge_attach(bridge->encoder, data->next_bridge, bridge,
++ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
++}
++
++static const struct drm_bridge_funcs drm_aux_bridge_funcs = {
++ .attach = drm_aux_bridge_attach,
++};
++
++static int drm_aux_bridge_probe(struct auxiliary_device *auxdev,
++ const struct auxiliary_device_id *id)
++{
++ struct drm_aux_bridge_data *data;
++
++ data = devm_kzalloc(&auxdev->dev, sizeof(*data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->dev = &auxdev->dev;
++ data->next_bridge = devm_drm_of_get_bridge(&auxdev->dev, auxdev->dev.of_node, 0, 0);
++ if (IS_ERR(data->next_bridge))
++ return dev_err_probe(&auxdev->dev, PTR_ERR(data->next_bridge),
++ "failed to acquire drm_bridge\n");
++
++ data->bridge.funcs = &drm_aux_bridge_funcs;
++ data->bridge.of_node = data->dev->of_node;
++
++ return devm_drm_bridge_add(data->dev, &data->bridge);
++}
++
++static const struct auxiliary_device_id drm_aux_bridge_table[] = {
++ { .name = KBUILD_MODNAME ".aux_bridge" },
++ {},
++};
++MODULE_DEVICE_TABLE(auxiliary, drm_aux_bridge_table);
++
++static struct auxiliary_driver drm_aux_bridge_drv = {
++ .name = "aux_bridge",
++ .id_table = drm_aux_bridge_table,
++ .probe = drm_aux_bridge_probe,
++};
++module_auxiliary_driver(drm_aux_bridge_drv);
++
++MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
++MODULE_DESCRIPTION("DRM transparent bridge");
++MODULE_LICENSE("GPL");
+diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
+new file mode 100644
+index 0000000000000..b3a9cc9c862fd
+--- /dev/null
++++ b/include/drm/bridge/aux-bridge.h
+@@ -0,0 +1,19 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Copyright (C) 2023 Linaro Ltd.
++ *
++ * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
++ */
++#ifndef DRM_AUX_BRIDGE_H
++#define DRM_AUX_BRIDGE_H
++
++#if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
++int drm_aux_bridge_register(struct device *parent);
++#else
++static inline int drm_aux_bridge_register(struct device *parent)
++{
++ return 0;
++}
++#endif
++
++#endif
+--
+2.43.0
+
--- /dev/null
+From 5987955d65715e06a13a72c145058466f3cf587a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Feb 2024 16:02:24 +0100
+Subject: drm/bridge: aux-hpd: separate allocation and registration
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit e5ca263508f7e9d2cf711edf3258d11ca087885c ]
+
+Combining allocation and registration is an anti-pattern that should be
+avoided. Add two new functions for allocating and registering an dp-hpd
+bridge with a proper 'devm' prefix so that it is clear that these are
+device managed interfaces.
+
+ devm_drm_dp_hpd_bridge_alloc()
+ devm_drm_dp_hpd_bridge_add()
+
+The new interface will be used to fix a use-after-free bug in the
+Qualcomm PMIC GLINK driver and may prevent similar issues from being
+introduced elsewhere.
+
+The existing drm_dp_hpd_bridge_register() is reimplemented using the
+above and left in place for now.
+
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240217150228.5788-3-johan+linaro@kernel.org
+Stable-dep-of: b979f2d50a09 ("soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/aux-hpd-bridge.c | 67 +++++++++++++++++++------
+ include/drm/bridge/aux-bridge.h | 15 ++++++
+ 2 files changed, 67 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+index 5d2ab3a715f9c..44bb771211b82 100644
+--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
++++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+@@ -29,16 +29,13 @@ static void drm_aux_hpd_bridge_release(struct device *dev)
+ kfree(adev);
+ }
+
+-static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
++static void drm_aux_hpd_bridge_free_adev(void *_adev)
+ {
+- struct auxiliary_device *adev = _adev;
+-
+- auxiliary_device_delete(adev);
+- auxiliary_device_uninit(adev);
++ auxiliary_device_uninit(_adev);
+ }
+
+ /**
+- * drm_dp_hpd_bridge_register - Create a simple HPD DisplayPort bridge
++ * devm_drm_dp_hpd_bridge_alloc - allocate a HPD DisplayPort bridge
+ * @parent: device instance providing this bridge
+ * @np: device node pointer corresponding to this bridge instance
+ *
+@@ -46,11 +43,9 @@ static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
+ * DRM_MODE_CONNECTOR_DisplayPort, which terminates the bridge chain and is
+ * able to send the HPD events.
+ *
+- * Return: device instance that will handle created bridge or an error code
+- * encoded into the pointer.
++ * Return: bridge auxiliary device pointer or an error pointer
+ */
+-struct device *drm_dp_hpd_bridge_register(struct device *parent,
+- struct device_node *np)
++struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np)
+ {
+ struct auxiliary_device *adev;
+ int ret;
+@@ -79,13 +74,55 @@ struct device *drm_dp_hpd_bridge_register(struct device *parent,
+ return ERR_PTR(ret);
+ }
+
+- ret = auxiliary_device_add(adev);
+- if (ret) {
+- auxiliary_device_uninit(adev);
++ ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_free_adev, adev);
++ if (ret)
+ return ERR_PTR(ret);
+- }
+
+- ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_unregister_adev, adev);
++ return adev;
++}
++EXPORT_SYMBOL_GPL(devm_drm_dp_hpd_bridge_alloc);
++
++static void drm_aux_hpd_bridge_del_adev(void *_adev)
++{
++ auxiliary_device_delete(_adev);
++}
++
++/**
++ * devm_drm_dp_hpd_bridge_add - register a HDP DisplayPort bridge
++ * @dev: struct device to tie registration lifetime to
++ * @adev: bridge auxiliary device to be registered
++ *
++ * Returns: zero on success or a negative errno
++ */
++int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev)
++{
++ int ret;
++
++ ret = auxiliary_device_add(adev);
++ if (ret)
++ return ret;
++
++ return devm_add_action_or_reset(dev, drm_aux_hpd_bridge_del_adev, adev);
++}
++EXPORT_SYMBOL_GPL(devm_drm_dp_hpd_bridge_add);
++
++/**
++ * drm_dp_hpd_bridge_register - allocate and register a HDP DisplayPort bridge
++ * @parent: device instance providing this bridge
++ * @np: device node pointer corresponding to this bridge instance
++ *
++ * Return: device instance that will handle created bridge or an error pointer
++ */
++struct device *drm_dp_hpd_bridge_register(struct device *parent, struct device_node *np)
++{
++ struct auxiliary_device *adev;
++ int ret;
++
++ adev = devm_drm_dp_hpd_bridge_alloc(parent, np);
++ if (IS_ERR(adev))
++ return ERR_CAST(adev);
++
++ ret = devm_drm_dp_hpd_bridge_add(parent, adev);
+ if (ret)
+ return ERR_PTR(ret);
+
+diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
+index 66249ff0858e7..874f177381e34 100644
+--- a/include/drm/bridge/aux-bridge.h
++++ b/include/drm/bridge/aux-bridge.h
+@@ -9,6 +9,8 @@
+
+ #include <drm/drm_connector.h>
+
++struct auxiliary_device;
++
+ #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
+ int drm_aux_bridge_register(struct device *parent);
+ #else
+@@ -19,10 +21,23 @@ static inline int drm_aux_bridge_register(struct device *parent)
+ #endif
+
+ #if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
++struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np);
++int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev);
+ struct device *drm_dp_hpd_bridge_register(struct device *parent,
+ struct device_node *np);
+ void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
+ #else
++static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent,
++ struct device_node *np)
++{
++ return NULL;
++}
++
++static inline int devm_drm_dp_hpd_bridge_add(struct auxiliary_device *adev)
++{
++ return 0;
++}
++
+ static inline struct device *drm_dp_hpd_bridge_register(struct device *parent,
+ struct device_node *np)
+ {
+--
+2.43.0
+
--- /dev/null
+From 1ddace2b96caf41b5ed5d98e44326187059c8096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Dec 2023 14:43:31 +0300
+Subject: drm/bridge: implement generic DP HPD bridge
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit e560518a6c2e60f1566473c146fddcff3281f617 ]
+
+Several USB-C controllers implement a pretty simple DRM bridge which
+implements just the HPD notification operations. Add special helper
+for creating such simple bridges.
+
+Acked-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231203114333.1305826-5-dmitry.baryshkov@linaro.org
+Stable-dep-of: b979f2d50a09 ("soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/Kconfig | 8 ++
+ drivers/gpu/drm/bridge/Makefile | 1 +
+ drivers/gpu/drm/bridge/aux-hpd-bridge.c | 163 ++++++++++++++++++++++++
+ include/drm/bridge/aux-bridge.h | 18 +++
+ 4 files changed, 190 insertions(+)
+ create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.c
+
+diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
+index a22645efe93a0..efd996f6c1384 100644
+--- a/drivers/gpu/drm/bridge/Kconfig
++++ b/drivers/gpu/drm/bridge/Kconfig
+@@ -21,6 +21,14 @@ config DRM_AUX_BRIDGE
+ Simple transparent bridge that is used by several non-DRM drivers to
+ build bridges chain.
+
++config DRM_AUX_HPD_BRIDGE
++ tristate
++ depends on DRM_BRIDGE && OF
++ select AUXILIARY_BUS
++ help
++ Simple bridge that terminates the bridge chain and provides HPD
++ support.
++
+ menu "Display Interface Bridges"
+ depends on DRM && DRM_BRIDGE
+
+diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
+index 918e3bfff079c..017b5832733b2 100644
+--- a/drivers/gpu/drm/bridge/Makefile
++++ b/drivers/gpu/drm/bridge/Makefile
+@@ -1,5 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
++obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
+ obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
+ obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
+ obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
+diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+new file mode 100644
+index 0000000000000..5d2ab3a715f9c
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+@@ -0,0 +1,163 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (C) 2023 Linaro Ltd.
++ *
++ * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
++ */
++#include <linux/auxiliary_bus.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++
++#include <drm/drm_bridge.h>
++#include <drm/bridge/aux-bridge.h>
++
++static DEFINE_IDA(drm_aux_hpd_bridge_ida);
++
++struct drm_aux_hpd_bridge_data {
++ struct drm_bridge bridge;
++ struct device *dev;
++};
++
++static void drm_aux_hpd_bridge_release(struct device *dev)
++{
++ struct auxiliary_device *adev = to_auxiliary_dev(dev);
++
++ ida_free(&drm_aux_hpd_bridge_ida, adev->id);
++
++ of_node_put(adev->dev.platform_data);
++
++ kfree(adev);
++}
++
++static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
++{
++ struct auxiliary_device *adev = _adev;
++
++ auxiliary_device_delete(adev);
++ auxiliary_device_uninit(adev);
++}
++
++/**
++ * drm_dp_hpd_bridge_register - Create a simple HPD DisplayPort bridge
++ * @parent: device instance providing this bridge
++ * @np: device node pointer corresponding to this bridge instance
++ *
++ * Creates a simple DRM bridge with the type set to
++ * DRM_MODE_CONNECTOR_DisplayPort, which terminates the bridge chain and is
++ * able to send the HPD events.
++ *
++ * Return: device instance that will handle created bridge or an error code
++ * encoded into the pointer.
++ */
++struct device *drm_dp_hpd_bridge_register(struct device *parent,
++ struct device_node *np)
++{
++ struct auxiliary_device *adev;
++ int ret;
++
++ adev = kzalloc(sizeof(*adev), GFP_KERNEL);
++ if (!adev)
++ return ERR_PTR(-ENOMEM);
++
++ ret = ida_alloc(&drm_aux_hpd_bridge_ida, GFP_KERNEL);
++ if (ret < 0) {
++ kfree(adev);
++ return ERR_PTR(ret);
++ }
++
++ adev->id = ret;
++ adev->name = "dp_hpd_bridge";
++ adev->dev.parent = parent;
++ adev->dev.of_node = parent->of_node;
++ adev->dev.release = drm_aux_hpd_bridge_release;
++ adev->dev.platform_data = np;
++
++ ret = auxiliary_device_init(adev);
++ if (ret) {
++ ida_free(&drm_aux_hpd_bridge_ida, adev->id);
++ kfree(adev);
++ return ERR_PTR(ret);
++ }
++
++ ret = auxiliary_device_add(adev);
++ if (ret) {
++ auxiliary_device_uninit(adev);
++ return ERR_PTR(ret);
++ }
++
++ ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_unregister_adev, adev);
++ if (ret)
++ return ERR_PTR(ret);
++
++ return &adev->dev;
++}
++EXPORT_SYMBOL_GPL(drm_dp_hpd_bridge_register);
++
++/**
++ * drm_aux_hpd_bridge_notify - notify hot plug detection events
++ * @dev: device created for the HPD bridge
++ * @status: output connection status
++ *
++ * A wrapper around drm_bridge_hpd_notify() that is used to report hot plug
++ * detection events for bridges created via drm_dp_hpd_bridge_register().
++ *
++ * This function shall be called in a context that can sleep.
++ */
++void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
++{
++ struct auxiliary_device *adev = to_auxiliary_dev(dev);
++ struct drm_aux_hpd_bridge_data *data = auxiliary_get_drvdata(adev);
++
++ if (!data)
++ return;
++
++ drm_bridge_hpd_notify(&data->bridge, status);
++}
++EXPORT_SYMBOL_GPL(drm_aux_hpd_bridge_notify);
++
++static int drm_aux_hpd_bridge_attach(struct drm_bridge *bridge,
++ enum drm_bridge_attach_flags flags)
++{
++ return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
++}
++
++static const struct drm_bridge_funcs drm_aux_hpd_bridge_funcs = {
++ .attach = drm_aux_hpd_bridge_attach,
++};
++
++static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
++ const struct auxiliary_device_id *id)
++{
++ struct drm_aux_hpd_bridge_data *data;
++
++ data = devm_kzalloc(&auxdev->dev, sizeof(*data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->dev = &auxdev->dev;
++ data->bridge.funcs = &drm_aux_hpd_bridge_funcs;
++ data->bridge.of_node = dev_get_platdata(data->dev);
++ data->bridge.ops = DRM_BRIDGE_OP_HPD;
++ data->bridge.type = id->driver_data;
++
++ auxiliary_set_drvdata(auxdev, data);
++
++ return devm_drm_bridge_add(data->dev, &data->bridge);
++}
++
++static const struct auxiliary_device_id drm_aux_hpd_bridge_table[] = {
++ { .name = KBUILD_MODNAME ".dp_hpd_bridge", .driver_data = DRM_MODE_CONNECTOR_DisplayPort, },
++ {},
++};
++MODULE_DEVICE_TABLE(auxiliary, drm_aux_hpd_bridge_table);
++
++static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
++ .name = "aux_hpd_bridge",
++ .id_table = drm_aux_hpd_bridge_table,
++ .probe = drm_aux_hpd_bridge_probe,
++};
++module_auxiliary_driver(drm_aux_hpd_bridge_drv);
++
++MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
++MODULE_DESCRIPTION("DRM HPD bridge");
++MODULE_LICENSE("GPL");
+diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
+index b3a9cc9c862fd..66249ff0858e7 100644
+--- a/include/drm/bridge/aux-bridge.h
++++ b/include/drm/bridge/aux-bridge.h
+@@ -7,6 +7,8 @@
+ #ifndef DRM_AUX_BRIDGE_H
+ #define DRM_AUX_BRIDGE_H
+
++#include <drm/drm_connector.h>
++
+ #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
+ int drm_aux_bridge_register(struct device *parent);
+ #else
+@@ -16,4 +18,20 @@ static inline int drm_aux_bridge_register(struct device *parent)
+ }
+ #endif
+
++#if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
++struct device *drm_dp_hpd_bridge_register(struct device *parent,
++ struct device_node *np);
++void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
++#else
++static inline struct device *drm_dp_hpd_bridge_register(struct device *parent,
++ struct device_node *np)
++{
++ return 0;
++}
++
++static inline void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
++{
++}
++#endif
++
+ #endif
+--
+2.43.0
+
--- /dev/null
+From 8f41cc5863892f914017415a4843bcd9e3da7a5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Nov 2023 10:48:22 -0500
+Subject: dt-bindings: dma: fsl-edma: Add fsl-edma.h to prevent hardcoding in
+ dts
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit 1e9b05258271b76ccc04a4b535009d2cb596506a ]
+
+Introduce a common dt-bindings header file, fsl-edma.h, shared between
+the driver and dts files. This addition aims to eliminate hardcoded values
+in dts files, promoting maintainability and consistency.
+
+DTS header file not support BIT() macro yet. Directly use 2^n number.
+
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20231114154824.3617255-3-Frank.Li@nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: a79f949a5ce1 ("dmaengine: fsl-edma: correct max_segment_size setting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/dma/fsl-edma.h | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+ create mode 100644 include/dt-bindings/dma/fsl-edma.h
+
+diff --git a/include/dt-bindings/dma/fsl-edma.h b/include/dt-bindings/dma/fsl-edma.h
+new file mode 100644
+index 0000000000000..fd11478cfe9cc
+--- /dev/null
++++ b/include/dt-bindings/dma/fsl-edma.h
+@@ -0,0 +1,21 @@
++/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
++
++#ifndef _FSL_EDMA_DT_BINDING_H_
++#define _FSL_EDMA_DT_BINDING_H_
++
++/* Receive Channel */
++#define FSL_EDMA_RX 0x1
++
++/* iMX8 audio remote DMA */
++#define FSL_EDMA_REMOTE 0x2
++
++/* FIFO is continue memory region */
++#define FSL_EDMA_MULTI_FIFO 0x4
++
++/* Channel need stick to even channel */
++#define FSL_EDMA_EVEN_CH 0x8
++
++/* Channel need stick to odd channel */
++#define FSL_EDMA_ODD_CH 0x10
++
++#endif
+--
+2.43.0
+
--- /dev/null
+From 4f2123962d79d1c209c30c367027ec1bdc474f1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 17:51:26 +0800
+Subject: mm: migrate: convert numamigrate_isolate_page() to
+ numamigrate_isolate_folio()
+
+From: Kefeng Wang <wangkefeng.wang@huawei.com>
+
+[ Upstream commit 2ac9e99f3b21b2864305fbfba4bae5913274c409 ]
+
+Rename numamigrate_isolate_page() to numamigrate_isolate_folio(), then
+make it takes a folio and use folio API to save compound_head() calls.
+
+Link: https://lkml.kernel.org/r/20230913095131.2426871-4-wangkefeng.wang@huawei.com
+Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
+Reviewed-by: Zi Yan <ziy@nvidia.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: "Huang, Ying" <ying.huang@intel.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 2774f256e7c0 ("mm/vmscan: fix a bug calling wakeup_kswapd() with a wrong zone index")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/migrate.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/mm/migrate.c b/mm/migrate.c
+index c9fabb960996f..e5f2f7243a659 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -2501,10 +2501,9 @@ static struct folio *alloc_misplaced_dst_folio(struct folio *src,
+ return __folio_alloc_node(gfp, order, nid);
+ }
+
+-static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
++static int numamigrate_isolate_folio(pg_data_t *pgdat, struct folio *folio)
+ {
+- int nr_pages = thp_nr_pages(page);
+- int order = compound_order(page);
++ int nr_pages = folio_nr_pages(folio);
+
+ /* Avoid migrating to a node that is nearly full */
+ if (!migrate_balanced_pgdat(pgdat, nr_pages)) {
+@@ -2516,22 +2515,23 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
+ if (managed_zone(pgdat->node_zones + z))
+ break;
+ }
+- wakeup_kswapd(pgdat->node_zones + z, 0, order, ZONE_MOVABLE);
++ wakeup_kswapd(pgdat->node_zones + z, 0,
++ folio_order(folio), ZONE_MOVABLE);
+ return 0;
+ }
+
+- if (!isolate_lru_page(page))
++ if (!folio_isolate_lru(folio))
+ return 0;
+
+- mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + page_is_file_lru(page),
++ node_stat_mod_folio(folio, NR_ISOLATED_ANON + folio_is_file_lru(folio),
+ nr_pages);
+
+ /*
+- * Isolating the page has taken another reference, so the
+- * caller's reference can be safely dropped without the page
++ * Isolating the folio has taken another reference, so the
++ * caller's reference can be safely dropped without the folio
+ * disappearing underneath us during migration.
+ */
+- put_page(page);
++ folio_put(folio);
+ return 1;
+ }
+
+@@ -2565,7 +2565,7 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
+ if (page_is_file_lru(page) && PageDirty(page))
+ goto out;
+
+- isolated = numamigrate_isolate_page(pgdat, page);
++ isolated = numamigrate_isolate_folio(pgdat, page_folio(page));
+ if (!isolated)
+ goto out;
+
+--
+2.43.0
+
--- /dev/null
+From 33a638a72e8de7db8b0ae986a8c1b06728d757cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 17:51:24 +0800
+Subject: mm: migrate: remove PageTransHuge check in numamigrate_isolate_page()
+
+From: Kefeng Wang <wangkefeng.wang@huawei.com>
+
+[ Upstream commit a8ac4a767dcd9d87d8229045904d9fe15ea5e0e8 ]
+
+Patch series "mm: migrate: more folio conversion and unification", v3.
+
+Convert more migrate functions to use a folio, it is also a preparation
+for large folio migration support when balancing numa.
+
+This patch (of 8):
+
+The assert VM_BUG_ON_PAGE(order && !PageTransHuge(page), page) is not very
+useful,
+
+ 1) for a tail/base page, order = 0, for a head page, the order > 0 &&
+ PageTransHuge() is true
+ 2) there is a PageCompound() check and only base page is handled in
+ do_numa_page(), and do_huge_pmd_numa_page() only handle PMD-mapped
+ THP
+ 3) even though the page is a tail page, isolate_lru_page() will post
+ a warning, and fail to isolate the page
+ 4) if large folio/pte-mapped THP migration supported in the future,
+ we could migrate the entire folio if numa fault on a tail page
+
+so just remove the check.
+
+Link: https://lkml.kernel.org/r/20230913095131.2426871-1-wangkefeng.wang@huawei.com
+Link: https://lkml.kernel.org/r/20230913095131.2426871-2-wangkefeng.wang@huawei.com
+Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
+Suggested-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Huang Ying <ying.huang@intel.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Zi Yan <ziy@nvidia.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 2774f256e7c0 ("mm/vmscan: fix a bug calling wakeup_kswapd() with a wrong zone index")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/migrate.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/mm/migrate.c b/mm/migrate.c
+index b4d972d80b10c..6f8ad6b64c9bc 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -2506,8 +2506,6 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
+ int nr_pages = thp_nr_pages(page);
+ int order = compound_order(page);
+
+- VM_BUG_ON_PAGE(order && !PageTransHuge(page), page);
+-
+ /* Do not migrate THP mapped by multiple processes */
+ if (PageTransHuge(page) && total_mapcount(page) > 1)
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 9429f944b65798873089ce0b50d6f44bddac674b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 17:51:25 +0800
+Subject: mm: migrate: remove THP mapcount check in numamigrate_isolate_page()
+
+From: Kefeng Wang <wangkefeng.wang@huawei.com>
+
+[ Upstream commit 728be28fae8c838d52c91dce4867133798146357 ]
+
+The check of THP mapped by multiple processes was introduced by commit
+04fa5d6a6547 ("mm: migrate: check page_count of THP before migrating") and
+refactor by commit 340ef3902cf2 ("mm: numa: cleanup flow of transhuge page
+migration"), which is out of date, since migrate_misplaced_page() is now
+using the standard migrate_pages() for small pages and THPs, the reference
+count checking is in folio_migrate_mapping(), so let's remove the special
+check for THP.
+
+Link: https://lkml.kernel.org/r/20230913095131.2426871-3-wangkefeng.wang@huawei.com
+Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
+Suggested-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reviewed-by: "Huang, Ying" <ying.huang@intel.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Zi Yan <ziy@nvidia.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 2774f256e7c0 ("mm/vmscan: fix a bug calling wakeup_kswapd() with a wrong zone index")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/migrate.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 6f8ad6b64c9bc..c9fabb960996f 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -2506,10 +2506,6 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
+ int nr_pages = thp_nr_pages(page);
+ int order = compound_order(page);
+
+- /* Do not migrate THP mapped by multiple processes */
+- if (PageTransHuge(page) && total_mapcount(page) > 1)
+- return 0;
+-
+ /* Avoid migrating to a node that is nearly full */
+ if (!migrate_balanced_pgdat(pgdat, nr_pages)) {
+ int z;
+--
+2.43.0
+
--- /dev/null
+From 8b6bc15674905f185c644d93e48f6b7437c0d184 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 20:15:02 +0900
+Subject: mm/vmscan: fix a bug calling wakeup_kswapd() with a wrong zone index
+
+From: Byungchul Park <byungchul@sk.com>
+
+[ Upstream commit 2774f256e7c0219e2b0a0894af1c76bdabc4f974 ]
+
+With numa balancing on, when a numa system is running where a numa node
+doesn't have its local memory so it has no managed zones, the following
+oops has been observed. It's because wakeup_kswapd() is called with a
+wrong zone index, -1. Fixed it by checking the index before calling
+wakeup_kswapd().
+
+> BUG: unable to handle page fault for address: 00000000000033f3
+> #PF: supervisor read access in kernel mode
+> #PF: error_code(0x0000) - not-present page
+> PGD 0 P4D 0
+> Oops: 0000 [#1] PREEMPT SMP NOPTI
+> CPU: 2 PID: 895 Comm: masim Not tainted 6.6.0-dirty #255
+> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+> rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+> RIP: 0010:wakeup_kswapd (./linux/mm/vmscan.c:7812)
+> Code: (omitted)
+> RSP: 0000:ffffc90004257d58 EFLAGS: 00010286
+> RAX: ffffffffffffffff RBX: ffff88883fff0480 RCX: 0000000000000003
+> RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88883fff0480
+> RBP: ffffffffffffffff R08: ff0003ffffffffff R09: ffffffffffffffff
+> R10: ffff888106c95540 R11: 0000000055555554 R12: 0000000000000003
+> R13: 0000000000000000 R14: 0000000000000000 R15: ffff88883fff0940
+> FS: 00007fc4b8124740(0000) GS:ffff888827c00000(0000) knlGS:0000000000000000
+> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+> CR2: 00000000000033f3 CR3: 000000026cc08004 CR4: 0000000000770ee0
+> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+> PKRU: 55555554
+> Call Trace:
+> <TASK>
+> ? __die
+> ? page_fault_oops
+> ? __pte_offset_map_lock
+> ? exc_page_fault
+> ? asm_exc_page_fault
+> ? wakeup_kswapd
+> migrate_misplaced_page
+> __handle_mm_fault
+> handle_mm_fault
+> do_user_addr_fault
+> exc_page_fault
+> asm_exc_page_fault
+> RIP: 0033:0x55b897ba0808
+> Code: (omitted)
+> RSP: 002b:00007ffeefa821a0 EFLAGS: 00010287
+> RAX: 000055b89983acd0 RBX: 00007ffeefa823f8 RCX: 000055b89983acd0
+> RDX: 00007fc2f8122010 RSI: 0000000000020000 RDI: 000055b89983acd0
+> RBP: 00007ffeefa821a0 R08: 0000000000000037 R09: 0000000000000075
+> R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000
+> R13: 00007ffeefa82410 R14: 000055b897ba5dd8 R15: 00007fc4b8340000
+> </TASK>
+
+Link: https://lkml.kernel.org/r/20240216111502.79759-1-byungchul@sk.com
+Signed-off-by: Byungchul Park <byungchul@sk.com>
+Reported-by: Hyeongtak Ji <hyeongtak.ji@sk.com>
+Fixes: c574bbe917036 ("NUMA balancing: optimize page placement for memory tiering system")
+Reviewed-by: Oscar Salvador <osalvador@suse.de>
+Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: "Huang, Ying" <ying.huang@intel.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/migrate.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/mm/migrate.c b/mm/migrate.c
+index e5f2f7243a659..d69b4556cc15f 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -2515,6 +2515,14 @@ static int numamigrate_isolate_folio(pg_data_t *pgdat, struct folio *folio)
+ if (managed_zone(pgdat->node_zones + z))
+ break;
+ }
++
++ /*
++ * If there are no managed zones, it should not proceed
++ * further.
++ */
++ if (z < 0)
++ return 0;
++
+ wakeup_kswapd(pgdat->node_zones + z, 0,
+ folio_order(folio), ZONE_MOVABLE);
+ return 0;
+--
+2.43.0
+
--- /dev/null
+drm-bridge-add-transparent-bridge-helper.patch
+drm-bridge-implement-generic-dp-hpd-bridge.patch
+soc-qcom-pmic-glink-switch-to-drm_aux_hpd_bridge.patch
+drm-bridge-aux-hpd-separate-allocation-and-registrat.patch
+soc-qcom-pmic_glink_altmode-fix-drm-bridge-use-after.patch
+dt-bindings-dma-fsl-edma-add-fsl-edma.h-to-prevent-h.patch
+dmaengine-fsl-edma-utilize-common-dt-binding-header-.patch
+dmaengine-fsl-edma-correct-max_segment_size-setting.patch
+ceph-switch-to-corrected-encoding-of-max_xattr_size-.patch
+mm-migrate-remove-pagetranshuge-check-in-numamigrate.patch
+mm-migrate-remove-thp-mapcount-check-in-numamigrate_.patch
+mm-migrate-convert-numamigrate_isolate_page-to-numam.patch
+mm-vmscan-fix-a-bug-calling-wakeup_kswapd-with-a-wro.patch
--- /dev/null
+From bb14b6982fe054b9297263c12201143bc1732d73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Dec 2023 14:43:32 +0300
+Subject: soc: qcom: pmic-glink: switch to DRM_AUX_HPD_BRIDGE
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 2bcca96abfbf89d26fc10fc92e40532bb2ae8891 ]
+
+Use the freshly defined DRM_AUX_HPD_BRIDGE instead of open-coding the
+same functionality for the DRM bridge chain termination.
+
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Acked-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231203114333.1305826-6-dmitry.baryshkov@linaro.org
+Stable-dep-of: b979f2d50a09 ("soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/Kconfig | 1 +
+ drivers/soc/qcom/pmic_glink_altmode.c | 33 ++++++++-------------------
+ 2 files changed, 10 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
+index 715348869d048..a4a201404d09f 100644
+--- a/drivers/soc/qcom/Kconfig
++++ b/drivers/soc/qcom/Kconfig
+@@ -102,6 +102,7 @@ config QCOM_PMIC_GLINK
+ depends on OF
+ select AUXILIARY_BUS
+ select QCOM_PDR_HELPERS
++ select DRM_AUX_HPD_BRIDGE
+ help
+ The Qualcomm PMIC GLINK driver provides access, over GLINK, to the
+ USB and battery firmware running on one of the coprocessors in
+diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
+index 9b0000b5f064c..c07cddecc85e9 100644
+--- a/drivers/soc/qcom/pmic_glink_altmode.c
++++ b/drivers/soc/qcom/pmic_glink_altmode.c
+@@ -11,7 +11,7 @@
+ #include <linux/mutex.h>
+ #include <linux/property.h>
+ #include <linux/soc/qcom/pdr.h>
+-#include <drm/drm_bridge.h>
++#include <drm/bridge/aux-bridge.h>
+
+ #include <linux/usb/typec_altmode.h>
+ #include <linux/usb/typec_dp.h>
+@@ -76,7 +76,7 @@ struct pmic_glink_altmode_port {
+
+ struct work_struct work;
+
+- struct drm_bridge bridge;
++ struct device *bridge;
+
+ enum typec_orientation orientation;
+ u16 svid;
+@@ -230,10 +230,10 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
+ else
+ pmic_glink_altmode_enable_usb(altmode, alt_port);
+
+- if (alt_port->hpd_state)
+- drm_bridge_hpd_notify(&alt_port->bridge, connector_status_connected);
+- else
+- drm_bridge_hpd_notify(&alt_port->bridge, connector_status_disconnected);
++ drm_aux_hpd_bridge_notify(alt_port->bridge,
++ alt_port->hpd_state ?
++ connector_status_connected :
++ connector_status_disconnected);
+
+ pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index);
+ };
+@@ -365,16 +365,6 @@ static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv
+ }
+ }
+
+-static int pmic_glink_altmode_attach(struct drm_bridge *bridge,
+- enum drm_bridge_attach_flags flags)
+-{
+- return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
+-}
+-
+-static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = {
+- .attach = pmic_glink_altmode_attach,
+-};
+-
+ static void pmic_glink_altmode_put_retimer(void *data)
+ {
+ typec_retimer_put(data);
+@@ -464,15 +454,10 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
+ alt_port->index = port;
+ INIT_WORK(&alt_port->work, pmic_glink_altmode_worker);
+
+- alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs;
+- alt_port->bridge.of_node = to_of_node(fwnode);
+- alt_port->bridge.ops = DRM_BRIDGE_OP_HPD;
+- alt_port->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+-
+- ret = devm_drm_bridge_add(dev, &alt_port->bridge);
+- if (ret) {
++ alt_port->bridge = drm_dp_hpd_bridge_register(dev, to_of_node(fwnode));
++ if (IS_ERR(alt_port->bridge)) {
+ fwnode_handle_put(fwnode);
+- return ret;
++ return PTR_ERR(alt_port->bridge);
+ }
+
+ alt_port->dp_alt.svid = USB_TYPEC_DP_SID;
+--
+2.43.0
+
--- /dev/null
+From 67a4099fba7bfae3544f7d85c0fb4e9e47c744b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Feb 2024 16:02:25 +0100
+Subject: soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit b979f2d50a099f3402418d7ff5f26c3952fb08bb ]
+
+A recent DRM series purporting to simplify support for "transparent
+bridges" and handling of probe deferrals ironically exposed a
+use-after-free issue on pmic_glink_altmode probe deferral.
+
+This has manifested itself as the display subsystem occasionally failing
+to initialise and NULL-pointer dereferences during boot of machines like
+the Lenovo ThinkPad X13s.
+
+Specifically, the dp-hpd bridge is currently registered before all
+resources have been acquired which means that it can also be
+deregistered on probe deferrals.
+
+In the meantime there is a race window where the new aux bridge driver
+(or PHY driver previously) may have looked up the dp-hpd bridge and
+stored a (non-reference-counted) pointer to the bridge which is about to
+be deallocated.
+
+When the display controller is later initialised, this triggers a
+use-after-free when attaching the bridges:
+
+ dp -> aux -> dp-hpd (freed)
+
+which may, for example, result in the freed bridge failing to attach:
+
+ [drm:drm_bridge_attach [drm]] *ERROR* failed to attach bridge /soc@0/phy@88eb000 to encoder TMDS-31: -16
+
+or a NULL-pointer dereference:
+
+ Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+ ...
+ Call trace:
+ drm_bridge_attach+0x70/0x1a8 [drm]
+ drm_aux_bridge_attach+0x24/0x38 [aux_bridge]
+ drm_bridge_attach+0x80/0x1a8 [drm]
+ dp_bridge_init+0xa8/0x15c [msm]
+ msm_dp_modeset_init+0x28/0xc4 [msm]
+
+The DRM bridge implementation is clearly fragile and implicitly built on
+the assumption that bridges may never go away. In this case, the fix is
+to move the bridge registration in the pmic_glink_altmode driver to
+after all resources have been looked up.
+
+Incidentally, with the new dp-hpd bridge implementation, which registers
+child devices, this is also a requirement due to a long-standing issue
+in driver core that can otherwise lead to a probe deferral loop (see
+commit fbc35b45f9f6 ("Add documentation on meaning of -EPROBE_DEFER")).
+
+[DB: slightly fixed commit message by adding the word 'commit']
+Fixes: 080b4e24852b ("soc: qcom: pmic_glink: Introduce altmode support")
+Fixes: 2bcca96abfbf ("soc: qcom: pmic-glink: switch to DRM_AUX_HPD_BRIDGE")
+Cc: <stable@vger.kernel.org> # 6.3
+Cc: Bjorn Andersson <andersson@kernel.org>
+Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240217150228.5788-4-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/pmic_glink_altmode.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
+index c07cddecc85e9..0b869de665101 100644
+--- a/drivers/soc/qcom/pmic_glink_altmode.c
++++ b/drivers/soc/qcom/pmic_glink_altmode.c
+@@ -76,7 +76,7 @@ struct pmic_glink_altmode_port {
+
+ struct work_struct work;
+
+- struct device *bridge;
++ struct auxiliary_device *bridge;
+
+ enum typec_orientation orientation;
+ u16 svid;
+@@ -230,7 +230,7 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
+ else
+ pmic_glink_altmode_enable_usb(altmode, alt_port);
+
+- drm_aux_hpd_bridge_notify(alt_port->bridge,
++ drm_aux_hpd_bridge_notify(&alt_port->bridge->dev,
+ alt_port->hpd_state ?
+ connector_status_connected :
+ connector_status_disconnected);
+@@ -454,7 +454,7 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
+ alt_port->index = port;
+ INIT_WORK(&alt_port->work, pmic_glink_altmode_worker);
+
+- alt_port->bridge = drm_dp_hpd_bridge_register(dev, to_of_node(fwnode));
++ alt_port->bridge = devm_drm_dp_hpd_bridge_alloc(dev, to_of_node(fwnode));
+ if (IS_ERR(alt_port->bridge)) {
+ fwnode_handle_put(fwnode);
+ return PTR_ERR(alt_port->bridge);
+@@ -510,6 +510,16 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
+ }
+ }
+
++ for (port = 0; port < ARRAY_SIZE(altmode->ports); port++) {
++ alt_port = &altmode->ports[port];
++ if (!alt_port->bridge)
++ continue;
++
++ ret = devm_drm_dp_hpd_bridge_add(dev, alt_port->bridge);
++ if (ret)
++ return ret;
++ }
++
+ altmode->client = devm_pmic_glink_register_client(dev,
+ altmode->owner_id,
+ pmic_glink_altmode_callback,
+--
+2.43.0
+