--- /dev/null
+From 923ff2cab90e59991db251dfcf3029e878f6c8f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:03 +0100
+Subject: ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit d1718a1b7a86743b9c517bf9521695ba909c734f ]
+
+iort_get_device_domain() is PCI specific but it need not be,
+since it can be used to retrieve IRQ domain nexus of any kind
+by adding an irq_domain_bus_token input to it.
+
+Make it PCI agnostic by also renaming the requestor ID input
+to a more generic ID name.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com> # pci/msi.c
+Cc: Will Deacon <will@kernel.org>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Link: https://lore.kernel.org/r/20200619082013.13661-3-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/arm64/iort.c | 14 +++++++-------
+ drivers/pci/msi.c | 3 ++-
+ include/linux/acpi_iort.h | 7 ++++---
+ 3 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index 09eb170f26d27..0428e74b6002b 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -503,7 +503,6 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
+ node = iort_get_iort_node(dev->fwnode);
+ if (node)
+ return node;
+-
+ /*
+ * if not, then it should be a platform device defined in
+ * DSDT/SSDT (with Named Component node in IORT)
+@@ -594,13 +593,13 @@ static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base)
+ /**
+ * iort_dev_find_its_id() - Find the ITS identifier for a device
+ * @dev: The device.
+- * @req_id: Device's requester ID
++ * @id: Device's ID
+ * @idx: Index of the ITS identifier list.
+ * @its_id: ITS identifier.
+ *
+ * Returns: 0 on success, appropriate error value otherwise
+ */
+-static int iort_dev_find_its_id(struct device *dev, u32 req_id,
++static int iort_dev_find_its_id(struct device *dev, u32 id,
+ unsigned int idx, int *its_id)
+ {
+ struct acpi_iort_its_group *its;
+@@ -610,7 +609,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
+ if (!node)
+ return -ENXIO;
+
+- node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
++ node = iort_node_map_id(node, id, NULL, IORT_MSI_TYPE);
+ if (!node)
+ return -ENXIO;
+
+@@ -633,19 +632,20 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
+ *
+ * Returns: the MSI domain for this device, NULL otherwise
+ */
+-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
++struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
++ enum irq_domain_bus_token bus_token)
+ {
+ struct fwnode_handle *handle;
+ int its_id;
+
+- if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
++ if (iort_dev_find_its_id(dev, id, 0, &its_id))
+ return NULL;
+
+ handle = iort_find_domain_token(its_id);
+ if (!handle)
+ return NULL;
+
+- return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
++ return irq_find_matching_fwnode(handle, bus_token);
+ }
+
+ static void iort_set_device_domain(struct device *dev,
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index 715c85d4e688d..6336316c37932 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1626,7 +1626,8 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
+ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+ dom = of_msi_map_get_device_domain(&pdev->dev, rid);
+ if (!dom)
+- dom = iort_get_device_domain(&pdev->dev, rid);
++ dom = iort_get_device_domain(&pdev->dev, rid,
++ DOMAIN_BUS_PCI_MSI);
+ return dom;
+ }
+ #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
+diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
+index 64f700254ca0f..6bf603a4e6d2c 100644
+--- a/include/linux/acpi_iort.h
++++ b/include/linux/acpi_iort.h
+@@ -30,7 +30,8 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
+ #ifdef CONFIG_ACPI_IORT
+ void acpi_iort_init(void);
+ u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
++struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
++ enum irq_domain_bus_token bus_token);
+ void acpi_configure_pmsi_domain(struct device *dev);
+ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
+ /* IOMMU interface */
+@@ -41,8 +42,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
+ static inline void acpi_iort_init(void) { }
+ static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+ { return req_id; }
+-static inline struct irq_domain *iort_get_device_domain(struct device *dev,
+- u32 req_id)
++static inline struct irq_domain *iort_get_device_domain(
++ struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
+ { return NULL; }
+ static inline void acpi_configure_pmsi_domain(struct device *dev) { }
+ /* IOMMU interface */
+--
+2.42.0
+
--- /dev/null
+From bba4d6d770955f88463130f210fbd3a408693f27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:04 +0100
+Subject: ACPI/IORT: Make iort_msi_map_rid() PCI agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit 39c3cf566ceafa7c1ae331a5f26fbb685d670001 ]
+
+There is nothing PCI specific in iort_msi_map_rid().
+
+Rename the function using a bus protocol agnostic name,
+iort_msi_map_id(), and convert current callers to it.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Link: https://lore.kernel.org/r/20200619082013.13661-4-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/arm64/iort.c | 12 ++++++------
+ drivers/pci/msi.c | 2 +-
+ include/linux/acpi_iort.h | 6 +++---
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index 0428e74b6002b..13ae2ce9f50dd 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -521,22 +521,22 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
+ }
+
+ /**
+- * iort_msi_map_rid() - Map a MSI requester ID for a device
++ * iort_msi_map_id() - Map a MSI input ID for a device
+ * @dev: The device for which the mapping is to be done.
+- * @req_id: The device requester ID.
++ * @input_id: The device input ID.
+ *
+- * Returns: mapped MSI RID on success, input requester ID otherwise
++ * Returns: mapped MSI ID on success, input ID otherwise
+ */
+-u32 iort_msi_map_rid(struct device *dev, u32 req_id)
++u32 iort_msi_map_id(struct device *dev, u32 input_id)
+ {
+ struct acpi_iort_node *node;
+ u32 dev_id;
+
+ node = iort_find_dev_node(dev);
+ if (!node)
+- return req_id;
++ return input_id;
+
+- iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE);
++ iort_node_map_id(node, input_id, &dev_id, IORT_MSI_TYPE);
+ return dev_id;
+ }
+
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index 6336316c37932..cc863cdd5cc74 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1604,7 +1604,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
+
+ of_node = irq_domain_get_of_node(domain);
+ rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) :
+- iort_msi_map_rid(&pdev->dev, rid);
++ iort_msi_map_id(&pdev->dev, rid);
+
+ return rid;
+ }
+diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
+index 6bf603a4e6d2c..cce2cbd4f3018 100644
+--- a/include/linux/acpi_iort.h
++++ b/include/linux/acpi_iort.h
+@@ -29,7 +29,7 @@ void iort_deregister_domain_token(int trans_id);
+ struct fwnode_handle *iort_find_domain_token(int trans_id);
+ #ifdef CONFIG_ACPI_IORT
+ void acpi_iort_init(void);
+-u32 iort_msi_map_rid(struct device *dev, u32 req_id);
++u32 iort_msi_map_id(struct device *dev, u32 id);
+ struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
+ enum irq_domain_bus_token bus_token);
+ void acpi_configure_pmsi_domain(struct device *dev);
+@@ -40,8 +40,8 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev);
+ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
+ #else
+ static inline void acpi_iort_init(void) { }
+-static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+-{ return req_id; }
++static inline u32 iort_msi_map_id(struct device *dev, u32 id)
++{ return id; }
+ static inline struct irq_domain *iort_get_device_domain(
+ struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
+ { return NULL; }
+--
+2.42.0
+
--- /dev/null
+From 10654aa2b57ab75495499ab3d2c94a9b2a763f53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 12:35:03 +0100
+Subject: arcnet: restoring support for multiple Sohard Arcnet cards
+
+From: Thomas Reichinger <thomas.reichinger@sohard.de>
+
+[ Upstream commit 6b17a597fc2f13aaaa0a2780eb7edb9ae7ac9aea ]
+
+Probe of Sohard Arcnet cards fails,
+if 2 or more cards are installed in a system.
+See kernel log:
+[ 2.759203] arcnet: arcnet loaded
+[ 2.763648] arcnet:com20020: COM20020 chipset support (by David Woodhouse et al.)
+[ 2.770585] arcnet:com20020_pci: COM20020 PCI support
+[ 2.772295] com20020 0000:02:00.0: enabling device (0000 -> 0003)
+[ 2.772354] (unnamed net_device) (uninitialized): PLX-PCI Controls
+...
+[ 3.071301] com20020 0000:02:00.0 arc0-0 (uninitialized): PCI COM20020: station FFh found at F080h, IRQ 101.
+[ 3.071305] com20020 0000:02:00.0 arc0-0 (uninitialized): Using CKP 64 - data rate 2.5 Mb/s
+[ 3.071534] com20020 0000:07:00.0: enabling device (0000 -> 0003)
+[ 3.071581] (unnamed net_device) (uninitialized): PLX-PCI Controls
+...
+[ 3.369501] com20020 0000:07:00.0: Led pci:green:tx:0-0 renamed to pci:green:tx:0-0_1 due to name collision
+[ 3.369535] com20020 0000:07:00.0: Led pci:red:recon:0-0 renamed to pci:red:recon:0-0_1 due to name collision
+[ 3.370586] com20020 0000:07:00.0 arc0-0 (uninitialized): PCI COM20020: station E1h found at C000h, IRQ 35.
+[ 3.370589] com20020 0000:07:00.0 arc0-0 (uninitialized): Using CKP 64 - data rate 2.5 Mb/s
+[ 3.370608] com20020: probe of 0000:07:00.0 failed with error -5
+
+commit 5ef216c1f848 ("arcnet: com20020-pci: add rotary index support")
+changes the device name of all COM20020 based PCI cards,
+even if only some cards support this:
+ snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
+
+The error happens because all Sohard Arcnet cards would be called arc0-0,
+since the Sohard Arcnet cards don't have a PLX rotary coder.
+I.e. EAE Arcnet cards have a PLX rotary coder,
+which sets the first decimal, ensuring unique devices names.
+
+This patch adds two new card feature flags to indicate
+which cards support LEDs and the PLX rotary coder.
+For EAE based cards the names still depend on the PLX rotary coder
+(untested, since missing EAE hardware).
+For Sohard based cards, this patch will result in devices
+being called arc0, arc1, ... (tested).
+
+Signed-off-by: Thomas Reichinger <thomas.reichinger@sohard.de>
+Fixes: 5ef216c1f848 ("arcnet: com20020-pci: add rotary index support")
+Link: https://lore.kernel.org/r/20231130113503.6812-1-thomas.reichinger@sohard.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/arcdevice.h | 2 +
+ drivers/net/arcnet/com20020-pci.c | 89 ++++++++++++++++---------------
+ 2 files changed, 48 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
+index 7178f5349fa8f..7b783ee918346 100644
+--- a/drivers/net/arcnet/arcdevice.h
++++ b/drivers/net/arcnet/arcdevice.h
+@@ -186,6 +186,8 @@ do { \
+ #define ARC_IS_5MBIT 1 /* card default speed is 5MBit */
+ #define ARC_CAN_10MBIT 2 /* card uses COM20022, supporting 10MBit,
+ but default is 2.5MBit. */
++#define ARC_HAS_LED 4 /* card has software controlled LEDs */
++#define ARC_HAS_ROTARY 8 /* card has rotary encoder */
+
+ /* information needed to define an encapsulation driver */
+ struct ArcProto {
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index 28dccbc0e8d8f..9d9e4200064f9 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15))
+ lp->backplane = 1;
+
+- /* Get the dev_id from the PLX rotary coder */
+- if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
+- dev_id_mask = 0x3;
+- dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
+-
+- snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
++ if (ci->flags & ARC_HAS_ROTARY) {
++ /* Get the dev_id from the PLX rotary coder */
++ if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
++ dev_id_mask = 0x3;
++ dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
++ snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
++ }
+
+ if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
+ pr_err("IO address %Xh is empty!\n", ioaddr);
+@@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ goto err_free_arcdev;
+ }
+
++ ret = com20020_found(dev, IRQF_SHARED);
++ if (ret)
++ goto err_free_arcdev;
++
+ card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
+ GFP_KERNEL);
+ if (!card) {
+@@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev,
+
+ card->index = i;
+ card->pci_priv = priv;
+- card->tx_led.brightness_set = led_tx_set;
+- card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
+- GFP_KERNEL, "arc%d-%d-tx",
+- dev->dev_id, i);
+- card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+- "pci:green:tx:%d-%d",
+- dev->dev_id, i);
+-
+- card->tx_led.dev = &dev->dev;
+- card->recon_led.brightness_set = led_recon_set;
+- card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
+- GFP_KERNEL, "arc%d-%d-recon",
+- dev->dev_id, i);
+- card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+- "pci:red:recon:%d-%d",
+- dev->dev_id, i);
+- card->recon_led.dev = &dev->dev;
+- card->dev = dev;
+-
+- ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+- if (ret)
+- goto err_free_arcdev;
+
+- ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
+- if (ret)
+- goto err_free_arcdev;
+-
+- dev_set_drvdata(&dev->dev, card);
+-
+- ret = com20020_found(dev, IRQF_SHARED);
+- if (ret)
+- goto err_free_arcdev;
+-
+- devm_arcnet_led_init(dev, dev->dev_id, i);
++ if (ci->flags & ARC_HAS_LED) {
++ card->tx_led.brightness_set = led_tx_set;
++ card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
++ GFP_KERNEL, "arc%d-%d-tx",
++ dev->dev_id, i);
++ card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
++ "pci:green:tx:%d-%d",
++ dev->dev_id, i);
++
++ card->tx_led.dev = &dev->dev;
++ card->recon_led.brightness_set = led_recon_set;
++ card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
++ GFP_KERNEL, "arc%d-%d-recon",
++ dev->dev_id, i);
++ card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
++ "pci:red:recon:%d-%d",
++ dev->dev_id, i);
++ card->recon_led.dev = &dev->dev;
++
++ ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
++ if (ret)
++ goto err_free_arcdev;
++
++ ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
++ if (ret)
++ goto err_free_arcdev;
++
++ dev_set_drvdata(&dev->dev, card);
++ devm_arcnet_led_init(dev, dev->dev_id, i);
++ }
+
++ card->dev = dev;
+ list_add(&card->list, &priv->list_dev);
+ continue;
+
+@@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = {
+ };
+
+ static struct com20020_pci_card_info card_info_sohard = {
+- .name = "PLX-PCI",
++ .name = "SOHARD SH ARC-PCI",
+ .devcount = 1,
+ /* SOHARD needs PCI base addr 4 */
+ .chan_map_tbl = {
+@@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
+ },
+ },
+ .rotary = 0x0,
+- .flags = ARC_CAN_10MBIT,
++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
+ };
+
+ static struct com20020_pci_card_info card_info_eae_ma1 = {
+@@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
+ },
+ },
+ .rotary = 0x0,
+- .flags = ARC_CAN_10MBIT,
++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
+ };
+
+ static struct com20020_pci_card_info card_info_eae_fb2 = {
+@@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = {
+ },
+ },
+ .rotary = 0x0,
+- .flags = ARC_CAN_10MBIT,
++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
+ };
+
+ static const struct pci_device_id com20020pci_id_table[] = {
+--
+2.42.0
+
--- /dev/null
+From f25918361336972575caf2fbee637ec22cb475a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 15:27:06 -0800
+Subject: bpf: sockmap, updating the sg structure should also update curr
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit bb9aefde5bbaf6c168c77ba635c155b4980c2287 ]
+
+Curr pointer should be updated when the sg structure is shifted.
+
+Fixes: 7246d8ed4dcce ("bpf: helper to pop data from messages")
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20231206232706.374377-3-john.fastabend@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index d866e1c5970cc..3c4dcdc7217e0 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2219,6 +2219,22 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes)
+ return 0;
+ }
+
++static void sk_msg_reset_curr(struct sk_msg *msg)
++{
++ u32 i = msg->sg.start;
++ u32 len = 0;
++
++ do {
++ len += sk_msg_elem(msg, i)->length;
++ sk_msg_iter_var_next(i);
++ if (len >= msg->sg.size)
++ break;
++ } while (i != msg->sg.end);
++
++ msg->sg.curr = i;
++ msg->sg.copybreak = 0;
++}
++
+ static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
+ .func = bpf_msg_cork_bytes,
+ .gpl_only = false,
+@@ -2338,6 +2354,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
+ msg->sg.end - shift + NR_MSG_FRAG_IDS :
+ msg->sg.end - shift;
+ out:
++ sk_msg_reset_curr(msg);
+ msg->data = sg_virt(&msg->sg.data[first_sge]) + start - offset;
+ msg->data_end = msg->data + bytes;
+ return 0;
+@@ -2471,6 +2488,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+ msg->sg.data[new] = rsge;
+ }
+
++ sk_msg_reset_curr(msg);
+ sk_msg_compute_data_pointers(msg);
+ return 0;
+ }
+@@ -2642,6 +2660,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+
+ sk_mem_uncharge(msg->sk, len - pop);
+ msg->sg.size -= (len - pop);
++ sk_msg_reset_curr(msg);
+ sk_msg_compute_data_pointers(msg);
+ return 0;
+ }
+--
+2.42.0
+
--- /dev/null
+From 25c4f058b04a5cfe78869fb292c86b1ee324be73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 21:58:53 -0800
+Subject: hv_netvsc: rndis_filter needs to select NLS
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 6c89f49964375c904cea33c0247467873f4daf2c ]
+
+rndis_filter uses utf8s_to_utf16s() which is provided by setting
+NLS, so select NLS to fix the build error:
+
+ERROR: modpost: "utf8s_to_utf16s" [drivers/net/hyperv/hv_netvsc.ko] undefined!
+
+Fixes: 1ce09e899d28 ("hyperv: Add support for setting MAC from within guests")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Wei Liu <wei.liu@kernel.org>
+Cc: Dexuan Cui <decui@microsoft.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Simon Horman <horms@kernel.org> # build-tested
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20231130055853.19069-1-rdunlap@infradead.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig
+index ca7bf7f897d36..c8cbd85adcf99 100644
+--- a/drivers/net/hyperv/Kconfig
++++ b/drivers/net/hyperv/Kconfig
+@@ -3,5 +3,6 @@ config HYPERV_NET
+ tristate "Microsoft Hyper-V virtual network driver"
+ depends on HYPERV
+ select UCS2_STRING
++ select NLS
+ help
+ Select this option to enable the Hyper-V virtual network driver.
+--
+2.42.0
+
--- /dev/null
+From 3eb8cb022ac5e64bf5a872ede5079c0b753f355f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Dec 2023 01:14:41 +0900
+Subject: ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit()
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit 80d875cfc9d3711a029f234ef7d680db79e8fa4b ]
+
+In ipgre_xmit(), skb_pull() may fail even if pskb_inet_may_pull() returns
+true. For example, applications can use PF_PACKET to create a malformed
+packet with no IP header. This type of packet causes a problem such as
+uninit-value access.
+
+This patch ensures that skb_pull() can pull the required size by checking
+the skb with pskb_network_may_pull() before skb_pull().
+
+Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.")
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Suman Ghosh <sumang@marvell.com>
+Link: https://lore.kernel.org/r/20231202161441.221135-1-syoshida@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_gre.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index f8f008344273e..db48dec61f305 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -607,15 +607,18 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
+ }
+
+ if (dev->header_ops) {
++ int pull_len = tunnel->hlen + sizeof(struct iphdr);
++
+ if (skb_cow_head(skb, 0))
+ goto free_skb;
+
+ tnl_params = (const struct iphdr *)skb->data;
+
+- /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
+- * to gre header.
+- */
+- skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
++ if (!pskb_network_may_pull(skb, pull_len))
++ goto free_skb;
++
++ /* ip_tunnel_xmit() needs skb->data pointing to gre header. */
++ skb_pull(skb, pull_len);
+ skb_reset_mac_header(skb);
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
+--
+2.42.0
+
--- /dev/null
+From 2712197797e463a75a003b549c3c252c3a47e073 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 16:06:30 +0000
+Subject: ipv6: fix potential NULL deref in fib6_add()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 75475bb51e78a3f54ad2f69380f2a1c985e85f2d ]
+
+If fib6_find_prefix() returns NULL, we should silently fallback
+using fib6_null_entry regardless of RT6_DEBUG value.
+
+syzbot reported:
+
+WARNING: CPU: 0 PID: 5477 at net/ipv6/ip6_fib.c:1516 fib6_add+0x310d/0x3fa0 net/ipv6/ip6_fib.c:1516
+Modules linked in:
+CPU: 0 PID: 5477 Comm: syz-executor.0 Not tainted 6.7.0-rc2-syzkaller-00029-g9b6de136b5f0 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/10/2023
+RIP: 0010:fib6_add+0x310d/0x3fa0 net/ipv6/ip6_fib.c:1516
+Code: 00 48 8b 54 24 68 e8 42 22 00 00 48 85 c0 74 14 49 89 c6 e8 d5 d3 c2 f7 eb 5d e8 ce d3 c2 f7 e9 ca 00 00 00 e8 c4 d3 c2 f7 90 <0f> 0b 90 48 b8 00 00 00 00 00 fc ff df 48 8b 4c 24 38 80 3c 01 00
+RSP: 0018:ffffc90005067740 EFLAGS: 00010293
+RAX: ffffffff89cba5bc RBX: ffffc90005067ab0 RCX: ffff88801a2e9dc0
+RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
+RBP: ffffc90005067980 R08: ffffffff89cbca85 R09: 1ffff110040d4b85
+R10: dffffc0000000000 R11: ffffed10040d4b86 R12: 00000000ffffffff
+R13: 1ffff110051c3904 R14: ffff8880206a5c00 R15: ffff888028e1c820
+FS: 00007f763783c6c0(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f763783bff8 CR3: 000000007f74d000 CR4: 00000000003506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+<TASK>
+__ip6_ins_rt net/ipv6/route.c:1303 [inline]
+ip6_route_add+0x88/0x120 net/ipv6/route.c:3847
+ipv6_route_ioctl+0x525/0x7b0 net/ipv6/route.c:4467
+inet6_ioctl+0x21a/0x270 net/ipv6/af_inet6.c:575
+sock_do_ioctl+0x152/0x460 net/socket.c:1220
+sock_ioctl+0x615/0x8c0 net/socket.c:1339
+vfs_ioctl fs/ioctl.c:51 [inline]
+__do_sys_ioctl fs/ioctl.c:871 [inline]
+__se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857
+do_syscall_x64 arch/x86/entry/common.c:51 [inline]
+do_syscall_64+0x45/0x110 arch/x86/entry/common.c:82
+
+Fixes: 7bbfe00e0252 ("ipv6: fix general protection fault in fib6_add()")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Wei Wang <weiwan@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20231129160630.3509216-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_fib.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index ef55489651f87..d74a825c50f0c 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1433,13 +1433,9 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt,
+ if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) {
+ pn_leaf = fib6_find_prefix(info->nl_net, table,
+ pn);
+-#if RT6_DEBUG >= 2
+- if (!pn_leaf) {
+- WARN_ON(!pn_leaf);
++ if (!pn_leaf)
+ pn_leaf =
+ info->nl_net->ipv6.fib6_null_entry;
+- }
+-#endif
+ fib6_info_hold(pn_leaf);
+ rcu_assign_pointer(pn->leaf, pn_leaf);
+ }
+--
+2.42.0
+
--- /dev/null
+From c33a40189dcbd1ac546ce01ec12faf78bc6e8e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Mar 2021 14:08:36 -0400
+Subject: net: arcnet: com20020 fix error handling
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit 6577b9a551aedb86bca6d4438c28386361845108 ]
+
+There are two issues when handling error case in com20020pci_probe()
+
+1. priv might be not initialized yet when calling com20020pci_remove()
+from com20020pci_probe(), since the priv is set at the very last but it
+can jump to error handling in the middle and priv remains NULL.
+2. memory leak - the net device is allocated in alloc_arcdev but not
+properly released if error happens in the middle of the big for loop
+
+[ 1.529110] BUG: kernel NULL pointer dereference, address: 0000000000000008
+[ 1.531447] RIP: 0010:com20020pci_remove+0x15/0x60 [com20020_pci]
+[ 1.536805] Call Trace:
+[ 1.536939] com20020pci_probe+0x3f2/0x48c [com20020_pci]
+[ 1.537226] local_pci_probe+0x48/0x80
+[ 1.539918] com20020pci_init+0x3f/0x1000 [com20020_pci]
+
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/com20020-pci.c | 34 +++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index b4f8798d8c509..28dccbc0e8d8f 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -127,6 +127,8 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ int i, ioaddr, ret;
+ struct resource *r;
+
++ ret = 0;
++
+ if (pci_enable_device(pdev))
+ return -EIO;
+
+@@ -142,6 +144,8 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ priv->ci = ci;
+ mm = &ci->misc_map;
+
++ pci_set_drvdata(pdev, priv);
++
+ INIT_LIST_HEAD(&priv->list_dev);
+
+ if (mm->size) {
+@@ -164,7 +168,7 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ dev = alloc_arcdev(device);
+ if (!dev) {
+ ret = -ENOMEM;
+- goto out_port;
++ break;
+ }
+ dev->dev_port = i;
+
+@@ -181,7 +185,7 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ pr_err("IO region %xh-%xh already allocated\n",
+ ioaddr, ioaddr + cm->size - 1);
+ ret = -EBUSY;
+- goto out_port;
++ goto err_free_arcdev;
+ }
+
+ /* Dummy access after Reset
+@@ -219,18 +223,18 @@ static int com20020pci_probe(struct pci_dev *pdev,
+ if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
+ pr_err("IO address %Xh is empty!\n", ioaddr);
+ ret = -EIO;
+- goto out_port;
++ goto err_free_arcdev;
+ }
+ if (com20020_check(dev)) {
+ ret = -EIO;
+- goto out_port;
++ goto err_free_arcdev;
+ }
+
+ card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
+ GFP_KERNEL);
+ if (!card) {
+ ret = -ENOMEM;
+- goto out_port;
++ goto err_free_arcdev;
+ }
+
+ card->index = i;
+@@ -256,29 +260,29 @@ static int com20020pci_probe(struct pci_dev *pdev,
+
+ ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+ if (ret)
+- goto out_port;
++ goto err_free_arcdev;
+
+ ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
+ if (ret)
+- goto out_port;
++ goto err_free_arcdev;
+
+ dev_set_drvdata(&dev->dev, card);
+
+ ret = com20020_found(dev, IRQF_SHARED);
+ if (ret)
+- goto out_port;
++ goto err_free_arcdev;
+
+ devm_arcnet_led_init(dev, dev->dev_id, i);
+
+ list_add(&card->list, &priv->list_dev);
+- }
++ continue;
+
+- pci_set_drvdata(pdev, priv);
+-
+- return 0;
+-
+-out_port:
+- com20020pci_remove(pdev);
++err_free_arcdev:
++ free_arcdev(dev);
++ break;
++ }
++ if (ret)
++ com20020pci_remove(pdev);
+ return ret;
+ }
+
+--
+2.42.0
+
--- /dev/null
+From fd32bea442d3d892bb83f873fc7e5a5bf1fffca2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Jan 2021 20:48:02 +0100
+Subject: net: arcnet: Fix RESET flag handling
+
+From: Ahmed S. Darwish <a.darwish@linutronix.de>
+
+[ Upstream commit 01365633bd1c836240f9bbf86bbeee749795480a ]
+
+The main arcnet interrupt handler calls arcnet_close() then
+arcnet_open(), if the RESET status flag is encountered.
+
+This is invalid:
+
+ 1) In general, interrupt handlers should never call ->ndo_stop() and
+ ->ndo_open() functions. They are usually full of blocking calls and
+ other methods that are expected to be called only from drivers
+ init and exit code paths.
+
+ 2) arcnet_close() contains a del_timer_sync(). If the irq handler
+ interrupts the to-be-deleted timer, del_timer_sync() will just loop
+ forever.
+
+ 3) arcnet_close() also calls tasklet_kill(), which has a warning if
+ called from irq context.
+
+ 4) For device reset, the sequence "arcnet_close(); arcnet_open();" is
+ not complete. Some children arcnet drivers have special init/exit
+ code sequences, which then embed a call to arcnet_open() and
+ arcnet_close() accordingly. Check drivers/net/arcnet/com20020.c.
+
+Run the device RESET sequence from a scheduled workqueue instead.
+
+Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/r/20210128194802.727770-1-a.darwish@linutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/arc-rimi.c | 4 +-
+ drivers/net/arcnet/arcdevice.h | 6 +++
+ drivers/net/arcnet/arcnet.c | 66 +++++++++++++++++++++++++++++--
+ drivers/net/arcnet/com20020-isa.c | 4 +-
+ drivers/net/arcnet/com20020-pci.c | 2 +-
+ drivers/net/arcnet/com20020_cs.c | 2 +-
+ drivers/net/arcnet/com90io.c | 4 +-
+ drivers/net/arcnet/com90xx.c | 4 +-
+ 8 files changed, 78 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
+index 14a5fb3781453..313b636edf239 100644
+--- a/drivers/net/arcnet/arc-rimi.c
++++ b/drivers/net/arcnet/arc-rimi.c
+@@ -332,7 +332,7 @@ static int __init arc_rimi_init(void)
+ dev->irq = 9;
+
+ if (arcrimi_probe(dev)) {
+- free_netdev(dev);
++ free_arcdev(dev);
+ return -EIO;
+ }
+
+@@ -349,7 +349,7 @@ static void __exit arc_rimi_exit(void)
+ iounmap(lp->mem_start);
+ release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ free_irq(dev->irq, dev);
+- free_netdev(dev);
++ free_arcdev(dev);
+ }
+
+ #ifndef MODULE
+diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
+index b0f5bc07aef5b..7178f5349fa8f 100644
+--- a/drivers/net/arcnet/arcdevice.h
++++ b/drivers/net/arcnet/arcdevice.h
+@@ -298,6 +298,10 @@ struct arcnet_local {
+
+ int excnak_pending; /* We just got an excesive nak interrupt */
+
++ /* RESET flag handling */
++ int reset_in_progress;
++ struct work_struct reset_work;
++
+ struct {
+ uint16_t sequence; /* sequence number (incs with each packet) */
+ __be16 aborted_seq;
+@@ -350,7 +354,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
+
+ void arcnet_unregister_proto(struct ArcProto *proto);
+ irqreturn_t arcnet_interrupt(int irq, void *dev_id);
++
+ struct net_device *alloc_arcdev(const char *name);
++void free_arcdev(struct net_device *dev);
+
+ int arcnet_open(struct net_device *dev);
+ int arcnet_close(struct net_device *dev);
+diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
+index 2b112d3d85409..cf652c76af85e 100644
+--- a/drivers/net/arcnet/arcnet.c
++++ b/drivers/net/arcnet/arcnet.c
+@@ -387,10 +387,44 @@ static void arcnet_timer(struct timer_list *t)
+ struct arcnet_local *lp = from_timer(lp, t, timer);
+ struct net_device *dev = lp->dev;
+
+- if (!netif_carrier_ok(dev)) {
++ spin_lock_irq(&lp->lock);
++
++ if (!lp->reset_in_progress && !netif_carrier_ok(dev)) {
+ netif_carrier_on(dev);
+ netdev_info(dev, "link up\n");
+ }
++
++ spin_unlock_irq(&lp->lock);
++}
++
++static void reset_device_work(struct work_struct *work)
++{
++ struct arcnet_local *lp;
++ struct net_device *dev;
++
++ lp = container_of(work, struct arcnet_local, reset_work);
++ dev = lp->dev;
++
++ /* Do not bring the network interface back up if an ifdown
++ * was already done.
++ */
++ if (!netif_running(dev) || !lp->reset_in_progress)
++ return;
++
++ rtnl_lock();
++
++ /* Do another check, in case of an ifdown that was triggered in
++ * the small race window between the exit condition above and
++ * acquiring RTNL.
++ */
++ if (!netif_running(dev) || !lp->reset_in_progress)
++ goto out;
++
++ dev_close(dev);
++ dev_open(dev, NULL);
++
++out:
++ rtnl_unlock();
+ }
+
+ static void arcnet_reply_tasklet(unsigned long data)
+@@ -452,12 +486,25 @@ struct net_device *alloc_arcdev(const char *name)
+ lp->dev = dev;
+ spin_lock_init(&lp->lock);
+ timer_setup(&lp->timer, arcnet_timer, 0);
++ INIT_WORK(&lp->reset_work, reset_device_work);
+ }
+
+ return dev;
+ }
+ EXPORT_SYMBOL(alloc_arcdev);
+
++void free_arcdev(struct net_device *dev)
++{
++ struct arcnet_local *lp = netdev_priv(dev);
++
++ /* Do not cancel this at ->ndo_close(), as the workqueue itself
++ * indirectly calls the ifdown path through dev_close().
++ */
++ cancel_work_sync(&lp->reset_work);
++ free_netdev(dev);
++}
++EXPORT_SYMBOL(free_arcdev);
++
+ /* Open/initialize the board. This is called sometime after booting when
+ * the 'ifconfig' program is run.
+ *
+@@ -587,6 +634,10 @@ int arcnet_close(struct net_device *dev)
+
+ /* shut down the card */
+ lp->hw.close(dev);
++
++ /* reset counters */
++ lp->reset_in_progress = 0;
++
+ module_put(lp->hw.owner);
+ return 0;
+ }
+@@ -820,6 +871,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
+
+ spin_lock_irqsave(&lp->lock, flags);
+
++ if (lp->reset_in_progress)
++ goto out;
++
+ /* RESET flag was enabled - if device is not running, we must
+ * clear it right away (but nothing else).
+ */
+@@ -852,11 +906,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
+ if (status & RESETflag) {
+ arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n",
+ status);
+- arcnet_close(dev);
+- arcnet_open(dev);
++
++ lp->reset_in_progress = 1;
++ netif_stop_queue(dev);
++ netif_carrier_off(dev);
++ schedule_work(&lp->reset_work);
+
+ /* get out of the interrupt handler! */
+- break;
++ goto out;
+ }
+ /* RX is inhibited - we must have received something.
+ * Prepare to receive into the next buffer.
+@@ -1052,6 +1109,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
+ udelay(1);
+ lp->hw.intmask(dev, lp->intmask);
+
++out:
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return retval;
+ }
+diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
+index cd27fdc1059b9..141b05451252e 100644
+--- a/drivers/net/arcnet/com20020-isa.c
++++ b/drivers/net/arcnet/com20020-isa.c
+@@ -169,7 +169,7 @@ static int __init com20020_init(void)
+ dev->irq = 9;
+
+ if (com20020isa_probe(dev)) {
+- free_netdev(dev);
++ free_arcdev(dev);
+ return -EIO;
+ }
+
+@@ -182,7 +182,7 @@ static void __exit com20020_exit(void)
+ unregister_netdev(my_dev);
+ free_irq(my_dev->irq, my_dev);
+ release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
+- free_netdev(my_dev);
++ free_arcdev(my_dev);
+ }
+
+ #ifndef MODULE
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index 9f44e2e458df1..b4f8798d8c509 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -294,7 +294,7 @@ static void com20020pci_remove(struct pci_dev *pdev)
+
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+- free_netdev(dev);
++ free_arcdev(dev);
+ }
+ }
+
+diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
+index cf607ffcf358e..9cc5eb6a8e905 100644
+--- a/drivers/net/arcnet/com20020_cs.c
++++ b/drivers/net/arcnet/com20020_cs.c
+@@ -177,7 +177,7 @@ static void com20020_detach(struct pcmcia_device *link)
+ dev = info->dev;
+ if (dev) {
+ dev_dbg(&link->dev, "kfree...\n");
+- free_netdev(dev);
++ free_arcdev(dev);
+ }
+ dev_dbg(&link->dev, "kfree2...\n");
+ kfree(info);
+diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
+index 186bbf87bc849..5843b8976fd19 100644
+--- a/drivers/net/arcnet/com90io.c
++++ b/drivers/net/arcnet/com90io.c
+@@ -396,7 +396,7 @@ static int __init com90io_init(void)
+ err = com90io_probe(dev);
+
+ if (err) {
+- free_netdev(dev);
++ free_arcdev(dev);
+ return err;
+ }
+
+@@ -419,7 +419,7 @@ static void __exit com90io_exit(void)
+
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+- free_netdev(dev);
++ free_arcdev(dev);
+ }
+
+ module_init(com90io_init)
+diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
+index bd75d06ad7dfc..5e40ecf189b15 100644
+--- a/drivers/net/arcnet/com90xx.c
++++ b/drivers/net/arcnet/com90xx.c
+@@ -554,7 +554,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem,
+ err_release_mem:
+ release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ err_free_dev:
+- free_netdev(dev);
++ free_arcdev(dev);
+ return -EIO;
+ }
+
+@@ -672,7 +672,7 @@ static void __exit com90xx_exit(void)
+ release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ release_mem_region(dev->mem_start,
+ dev->mem_end - dev->mem_start + 1);
+- free_netdev(dev);
++ free_arcdev(dev);
+ }
+ }
+
+--
+2.42.0
+
--- /dev/null
+From 825a0ae8dd0c9904ee7e26b1cbec0714451951f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 22:32:32 +0800
+Subject: net: hns: fix fake link up on xge port
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ Upstream commit f708aba40f9c1eeb9c7e93ed4863b5f85b09b288 ]
+
+If a xge port just connect with an optical module and no fiber,
+it may have a fake link up because there may be interference on
+the hardware. This patch adds an anti-shake to avoid the problem.
+And the time of anti-shake is base on tests.
+
+Fixes: b917078c1c10 ("net: hns: Add ACPI support to check SFP present")
+Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 29 +++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+index 8aace2de0cc91..e34245649057e 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+@@ -66,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb)
+ }
+ }
+
++static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv)
++{
++#define HNS_MAC_LINK_WAIT_TIME 5
++#define HNS_MAC_LINK_WAIT_CNT 40
++
++ u32 link_status = 0;
++ int i;
++
++ if (!mac_ctrl_drv->get_link_status)
++ return link_status;
++
++ for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) {
++ msleep(HNS_MAC_LINK_WAIT_TIME);
++ mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status);
++ if (!link_status)
++ break;
++ }
++
++ return link_status;
++}
++
+ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
+ {
+ struct mac_driver *mac_ctrl_drv;
+@@ -83,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
+ &sfp_prsnt);
+ if (!ret)
+ *link_status = *link_status && sfp_prsnt;
++
++ /* for FIBER port, it may have a fake link up.
++ * when the link status changes from down to up, we need to do
++ * anti-shake. the anti-shake time is base on tests.
++ * only FIBER port need to do this.
++ */
++ if (*link_status && !mac_cb->link)
++ *link_status = hns_mac_link_anti_shake(mac_ctrl_drv);
+ }
+
+ mac_cb->link = *link_status;
+--
+2.42.0
+
--- /dev/null
+From 7861d807c7bd847121a26b55cb66c30b62b3b718 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 21:58:12 +0100
+Subject: netfilter: xt_owner: Fix for unsafe access of sk->sk_socket
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 7ae836a3d630e146b732fe8ef7d86b243748751f ]
+
+A concurrently running sock_orphan() may NULL the sk_socket pointer in
+between check and deref. Follow other users (like nft_meta.c for
+instance) and acquire sk_callback_lock before dereferencing sk_socket.
+
+Fixes: 0265ab44bacc ("[NETFILTER]: merge ipt_owner/ip6t_owner in xt_owner")
+Reported-by: Jann Horn <jannh@google.com>
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_owner.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
+index e85ce69924aee..50332888c8d23 100644
+--- a/net/netfilter/xt_owner.c
++++ b/net/netfilter/xt_owner.c
+@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ */
+ return false;
+
+- filp = sk->sk_socket->file;
+- if (filp == NULL)
++ read_lock_bh(&sk->sk_callback_lock);
++ filp = sk->sk_socket ? sk->sk_socket->file : NULL;
++ if (filp == NULL) {
++ read_unlock_bh(&sk->sk_callback_lock);
+ return ((info->match ^ info->invert) &
+ (XT_OWNER_UID | XT_OWNER_GID)) == 0;
++ }
+
+ if (info->match & XT_OWNER_UID) {
+ kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
+ kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
+ if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
+ uid_lte(filp->f_cred->fsuid, uid_max)) ^
+- !(info->invert & XT_OWNER_UID))
++ !(info->invert & XT_OWNER_UID)) {
++ read_unlock_bh(&sk->sk_callback_lock);
+ return false;
++ }
+ }
+
+ if (info->match & XT_OWNER_GID) {
+@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ }
+ }
+
+- if (match ^ !(info->invert & XT_OWNER_GID))
++ if (match ^ !(info->invert & XT_OWNER_GID)) {
++ read_unlock_bh(&sk->sk_callback_lock);
+ return false;
++ }
+ }
+
++ read_unlock_bh(&sk->sk_callback_lock);
+ return true;
+ }
+
+--
+2.42.0
+
--- /dev/null
+From 0d4adf4c5580c4abf8fd489ba7f9585ea7ce9271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 10:47:12 -0600
+Subject: of: Add missing 'Return' section in kerneldoc comments
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 8c8239c2c1fb82f171cb22a707f3bb88a2f22109 ]
+
+Many of the DT kerneldoc comments are lacking a 'Return' section. Let's
+add the section in cases we have a description of return values. There's
+still some cases where the return values are not documented.
+
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Link: https://lore.kernel.org/r/20210325164713.1296407-8-robh@kernel.org
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c | 39 +++++++++++++------------
+ drivers/of/dynamic.c | 19 ++++++++-----
+ drivers/of/fdt.c | 8 +++---
+ drivers/of/irq.c | 14 ++++-----
+ drivers/of/overlay.c | 16 +++++------
+ drivers/of/platform.c | 10 +++----
+ drivers/of/property.c | 66 +++++++++++++++++++++++++++----------------
+ include/linux/of.h | 63 ++++++++++++++++++++++++++---------------
+ 8 files changed, 140 insertions(+), 95 deletions(-)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index c4c64ef5fb7a8..c8af9a65f98b0 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -306,7 +306,7 @@ struct device_node *__of_find_all_nodes(struct device_node *prev)
+ * @prev: Previous node or NULL to start iteration
+ * of_node_put() will be called on it
+ *
+- * Returns a node pointer with refcount incremented, use
++ * Return: A node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_all_nodes(struct device_node *prev)
+@@ -436,7 +436,7 @@ bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+- * Returns a node pointer for the logical cpu with refcount incremented, use
++ * Return: A node pointer for the logical cpu with refcount incremented, use
+ * of_node_put() on it when done. Returns NULL if not found.
+ */
+ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+@@ -456,8 +456,8 @@ EXPORT_SYMBOL(of_get_cpu_node);
+ *
+ * @cpu_node: Pointer to the device_node for CPU.
+ *
+- * Returns the logical CPU number of the given CPU device_node.
+- * Returns -ENODEV if the CPU is not found.
++ * Return: The logical CPU number of the given CPU device_node or -ENODEV if the
++ * CPU is not found.
+ */
+ int of_cpu_node_to_id(struct device_node *cpu_node)
+ {
+@@ -489,7 +489,7 @@ EXPORT_SYMBOL(of_cpu_node_to_id);
+ * bindings. This function check for both and returns the idle state node for
+ * the requested index.
+ *
+- * In case an idle state node is found at @index, the refcount is incremented
++ * Return: An idle state node if found at @index. The refcount is incremented
+ * for it, so call of_node_put() on it when done. Returns NULL if not found.
+ */
+ struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
+@@ -623,7 +623,7 @@ int of_device_compatible_match(struct device_node *device,
+ * of_machine_is_compatible - Test root of device tree for a given compatible value
+ * @compat: compatible string to look for in root node's compatible property.
+ *
+- * Returns a positive integer if the root node has the given value in its
++ * Return: A positive integer if the root node has the given value in its
+ * compatible property.
+ */
+ int of_machine_is_compatible(const char *compat)
+@@ -645,7 +645,7 @@ EXPORT_SYMBOL(of_machine_is_compatible);
+ *
+ * @device: Node to check for availability, with locks already held
+ *
+- * Returns true if the status property is absent or set to "okay" or "ok",
++ * Return: True if the status property is absent or set to "okay" or "ok",
+ * false otherwise
+ */
+ static bool __of_device_is_available(const struct device_node *device)
+@@ -673,7 +673,7 @@ static bool __of_device_is_available(const struct device_node *device)
+ *
+ * @device: Node to check for availability
+ *
+- * Returns true if the status property is absent or set to "okay" or "ok",
++ * Return: True if the status property is absent or set to "okay" or "ok",
+ * false otherwise
+ */
+ bool of_device_is_available(const struct device_node *device)
+@@ -694,7 +694,7 @@ EXPORT_SYMBOL(of_device_is_available);
+ *
+ * @device: Node to check for endianness
+ *
+- * Returns true if the device has a "big-endian" property, or if the kernel
++ * Return: True if the device has a "big-endian" property, or if the kernel
+ * was compiled for BE *and* the device has a "native-endian" property.
+ * Returns false otherwise.
+ *
+@@ -878,7 +878,7 @@ EXPORT_SYMBOL(of_get_next_cpu_node);
+ * Lookup child node whose compatible property contains the given compatible
+ * string.
+ *
+- * Returns a node pointer with refcount incremented, use of_node_put() on it
++ * Return: a node pointer with refcount incremented, use of_node_put() on it
+ * when done; or NULL if not found.
+ */
+ struct device_node *of_get_compatible_child(const struct device_node *parent,
+@@ -1232,7 +1232,7 @@ EXPORT_SYMBOL(of_find_matching_node_and_match);
+ * It does this by stripping the manufacturer prefix (as delimited by a ',')
+ * from the first entry in the compatible list property.
+ *
+- * This routine returns 0 on success, <0 on failure.
++ * Return: This routine returns 0 on success, <0 on failure.
+ */
+ int of_modalias_node(struct device_node *node, char *modalias, int len)
+ {
+@@ -1252,7 +1252,7 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ *
+- * Returns a node pointer with refcount incremented, use
++ * Return: A node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_node_by_phandle(phandle handle)
+@@ -1505,7 +1505,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
+ * @index: For properties holding a table of phandles, this is the index into
+ * the table
+ *
+- * Returns the device_node pointer with refcount incremented. Use
++ * Return: The device_node pointer with refcount incremented. Use
+ * of_node_put() on it when done.
+ */
+ struct device_node *of_parse_phandle(const struct device_node *np,
+@@ -1805,7 +1805,7 @@ EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
+ * @list_name: property name that contains a list
+ * @cells_name: property name that specifies phandles' arguments count
+ *
+- * Returns the number of phandle + argument tuples within a property. It
++ * Return: The number of phandle + argument tuples within a property. It
+ * is a typical pattern to encode a list of phandle and variable
+ * arguments into a single property. The number of arguments is encoded
+ * by a property in the phandle-target node. For example, a gpios
+@@ -2104,7 +2104,9 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
+ * @stem: Alias stem of the given device_node
+ *
+ * The function travels the lookup table to get the alias id for the given
+- * device_node and alias stem. It returns the alias id if found.
++ * device_node and alias stem.
++ *
++ * Return: The alias id if found.
+ */
+ int of_alias_get_id(struct device_node *np, const char *stem)
+ {
+@@ -2213,8 +2215,9 @@ EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
+ * @index: Index to use for preferred console.
+ *
+ * Check if the given device node matches the stdout-path property in the
+- * /chosen node. If it does then register it as the preferred console and return
+- * TRUE. Otherwise return FALSE.
++ * /chosen node. If it does then register it as the preferred console.
++ *
++ * Return: TRUE if console successfully setup. Otherwise return FALSE.
+ */
+ bool of_console_check(struct device_node *dn, char *name, int index)
+ {
+@@ -2265,7 +2268,7 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
+ *
+ * @cpu: cpu number(logical index) for which the last cache level is needed
+ *
+- * Returns the the level at which the last cache is present. It is exactly
++ * Return: The the level at which the last cache is present. It is exactly
+ * same as the total number of cache levels for the given logical cpu.
+ */
+ int of_find_last_cache_level(unsigned int cpu)
+diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
+index 49b16f76d78e8..92ee15be78d43 100644
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -27,7 +27,7 @@ static struct device_node *kobj_to_device_node(struct kobject *kobj)
+ * @node: Node to inc refcount, NULL is supported to simplify writing of
+ * callers
+ *
+- * Returns node.
++ * Return: The node with refcount incremented.
+ */
+ struct device_node *of_node_get(struct device_node *node)
+ {
+@@ -104,7 +104,8 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
+ * @arg - argument of the of notifier
+ *
+ * Returns the new state of a device based on the notifier used.
+- * Returns 0 on device going from enabled to disabled, 1 on device
++ *
++ * Return: 0 on device going from enabled to disabled, 1 on device
+ * going from disabled to enabled and -1 on no change.
+ */
+ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
+@@ -372,7 +373,8 @@ void of_node_release(struct kobject *kobj)
+ * property structure and the property name & contents. The property's
+ * flags have the OF_DYNAMIC bit set so that we can differentiate between
+ * dynamically allocated properties and not.
+- * Returns the newly allocated property or NULL on out of memory error.
++ *
++ * Return: The newly allocated property or NULL on out of memory error.
+ */
+ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
+ {
+@@ -415,7 +417,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
+ * another node. The node data are dynamically allocated and all the node
+ * flags have the OF_DYNAMIC & OF_DETACHED bits set.
+ *
+- * Returns the newly allocated node or NULL on out of memory error.
++ * Return: The newly allocated node or NULL on out of memory error.
+ */
+ struct device_node *__of_node_dup(const struct device_node *np,
+ const char *full_name)
+@@ -781,7 +783,8 @@ static int __of_changeset_apply(struct of_changeset *ocs)
+ * Any side-effects of live tree state changes are applied here on
+ * success, like creation/destruction of devices and side-effects
+ * like creation of sysfs properties and directories.
+- * Returns 0 on success, a negative error value in case of an error.
++ *
++ * Return: 0 on success, a negative error value in case of an error.
+ * On error the partially applied effects are reverted.
+ */
+ int of_changeset_apply(struct of_changeset *ocs)
+@@ -875,7 +878,8 @@ static int __of_changeset_revert(struct of_changeset *ocs)
+ * was before the application.
+ * Any side-effects like creation/destruction of devices and
+ * removal of sysfs properties and directories are applied.
+- * Returns 0 on success, a negative error value in case of an error.
++ *
++ * Return: 0 on success, a negative error value in case of an error.
+ */
+ int of_changeset_revert(struct of_changeset *ocs)
+ {
+@@ -903,7 +907,8 @@ EXPORT_SYMBOL_GPL(of_changeset_revert);
+ * + OF_RECONFIG_ADD_PROPERTY
+ * + OF_RECONFIG_REMOVE_PROPERTY,
+ * + OF_RECONFIG_UPDATE_PROPERTY
+- * Returns 0 on success, a negative error value in case of an error.
++ *
++ * Return: 0 on success, a negative error value in case of an error.
+ */
+ int of_changeset_action(struct of_changeset *ocs, unsigned long action,
+ struct device_node *np, struct property *prop)
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 09a98668e7db0..1db951f433538 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -282,7 +282,7 @@ static void reverse_nodes(struct device_node *parent)
+ * @dad: Parent struct device_node
+ * @nodepp: The device_node tree created by the call
+ *
+- * It returns the size of unflattened device tree or error code
++ * Return: The size of unflattened device tree or error code
+ */
+ static int unflatten_dt_nodes(const void *blob,
+ void *mem,
+@@ -360,7 +360,7 @@ static int unflatten_dt_nodes(const void *blob,
+ * fills the "name" and "type" pointers of the nodes so the normal device-tree
+ * walking functions can be used.
+ *
+- * Returns NULL on failure or the memory chunk containing the unflattened
++ * Return: NULL on failure or the memory chunk containing the unflattened
+ * device tree on success.
+ */
+ void *__unflatten_device_tree(const void *blob,
+@@ -441,7 +441,7 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex);
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ *
+- * Returns NULL on failure or the memory chunk containing the unflattened
++ * Return: NULL on failure or the memory chunk containing the unflattened
+ * device tree on success.
+ */
+ void *of_fdt_unflatten_tree(const unsigned long *blob,
+@@ -719,7 +719,7 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ *
+- * On match, returns a non-zero value with smaller values returned for more
++ * Return: a non-zero value on match with smaller values returned for more
+ * specific compatible values.
+ */
+ static int of_fdt_is_compatible(const void *blob,
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index 25d17b8a1a1aa..352e14b007e78 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -48,7 +48,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+ * of_irq_find_parent - Given a device node, find its interrupt parent node
+ * @child: pointer to device node
+ *
+- * Returns a pointer to the interrupt parent node, or NULL if the interrupt
++ * Return: A pointer to the interrupt parent node, or NULL if the interrupt
+ * parent could not be determined.
+ */
+ struct device_node *of_irq_find_parent(struct device_node *child)
+@@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
+ * @addr: address specifier (start of "reg" property of the device) in be32 format
+ * @out_irq: structure of_phandle_args updated by this function
+ *
+- * Returns 0 on success and a negative number on error
+- *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent. It takes an interrupt specifier structure as
+ * input, walks the tree looking for any interrupt-map properties, translates
+ * the specifier for each map, and then returns the translated map.
++ *
++ * Return: 0 on success and a negative number on error
+ */
+ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
+ {
+@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource);
+ * @dev: pointer to device tree node
+ * @index: zero-based index of the IRQ
+ *
+- * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
++ * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+ * of any other failure.
+ */
+@@ -407,7 +407,7 @@ EXPORT_SYMBOL_GPL(of_irq_get);
+ * @dev: pointer to device tree node
+ * @name: IRQ name
+ *
+- * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
++ * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+ * of any other failure.
+ */
+@@ -447,7 +447,7 @@ int of_irq_count(struct device_node *dev)
+ * @res: array of resources to fill in
+ * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
+ *
+- * Returns the size of the filled in table (up to @nr_irqs).
++ * Return: The size of the filled in table (up to @nr_irqs).
+ */
+ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
+ int nr_irqs)
+@@ -602,7 +602,7 @@ static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+ * property. If found, apply the mapping to @id_in.
+ *
+- * Returns the mapped MSI ID.
++ * Return: The mapped MSI ID.
+ */
+ u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
+ {
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index dc298775f7620..b551fe44f2f95 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -296,7 +296,7 @@ static struct property *dup_and_fixup_symbol_prop(
+ *
+ * Update of property in symbols node is not allowed.
+ *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid @overlay.
+ */
+ static int add_changeset_property(struct overlay_changeset *ovcs,
+@@ -401,7 +401,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
+ *
+ * NOTE_2: Multiple mods of created nodes not supported.
+ *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid @overlay.
+ */
+ static int add_changeset_node(struct overlay_changeset *ovcs,
+@@ -473,7 +473,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
+ *
+ * Do not allow symbols node to have any children.
+ *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid @overlay_node.
+ */
+ static int build_changeset_next_level(struct overlay_changeset *ovcs,
+@@ -604,7 +604,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs,
+ * the same node or duplicate {add, delete, or update} properties entries
+ * for the same property.
+ *
+- * Returns 0 on success, or -EINVAL if duplicate changeset entry found.
++ * Return: 0 on success, or -EINVAL if duplicate changeset entry found.
+ */
+ static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
+ {
+@@ -628,7 +628,7 @@ static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
+ * any portions of the changeset that were successfully created will remain
+ * in @ovcs->cset.
+ *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid overlay in @ovcs->fragments[].
+ */
+ static int build_changeset(struct overlay_changeset *ovcs)
+@@ -724,7 +724,7 @@ static struct device_node *find_target(struct device_node *info_node)
+ * the top level of @tree. The relevant top level nodes are the fragment
+ * nodes and the __symbols__ node. Any other top level node will be ignored.
+ *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
++ * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
+ * detected in @tree, or -ENOSPC if idr_alloc() error.
+ */
+ static int init_overlay_changeset(struct overlay_changeset *ovcs,
+@@ -1180,7 +1180,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
+ * If an error is returned by an overlay changeset post-remove notifier
+ * then no further overlay changeset post-remove notifier will be called.
+ *
+- * Returns 0 on success, or a negative error number. *ovcs_id is set to
++ * Return: 0 on success, or a negative error number. *ovcs_id is set to
+ * zero after reverting the changeset, even if a subsequent error occurs.
+ */
+ int of_overlay_remove(int *ovcs_id)
+@@ -1267,7 +1267,7 @@ EXPORT_SYMBOL_GPL(of_overlay_remove);
+ *
+ * Removes all overlays from the system in the correct order.
+ *
+- * Returns 0 on success, or a negative error number
++ * Return: 0 on success, or a negative error number
+ */
+ int of_overlay_remove_all(void)
+ {
+diff --git a/drivers/of/platform.c b/drivers/of/platform.c
+index b47a2292fe8e8..cf5dbc9536f20 100644
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -44,7 +44,7 @@ static const struct of_device_id of_skipped_node_table[] = {
+ * Takes a reference to the embedded struct device which needs to be dropped
+ * after use.
+ *
+- * Returns platform_device pointer, or NULL if not found
++ * Return: platform_device pointer, or NULL if not found
+ */
+ struct platform_device *of_find_device_by_node(struct device_node *np)
+ {
+@@ -160,7 +160,7 @@ EXPORT_SYMBOL(of_device_alloc);
+ * @platform_data: pointer to populate platform_data pointer with
+ * @parent: Linux device model parent device.
+ *
+- * Returns pointer to created platform device, or NULL if a device was not
++ * Return: Pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+ static struct platform_device *of_platform_device_create_pdata(
+@@ -204,7 +204,7 @@ static struct platform_device *of_platform_device_create_pdata(
+ * @bus_id: name to assign device
+ * @parent: Linux device model parent device.
+ *
+- * Returns pointer to created platform device, or NULL if a device was not
++ * Return: Pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+ struct platform_device *of_platform_device_create(struct device_node *np,
+@@ -463,7 +463,7 @@ EXPORT_SYMBOL(of_platform_bus_probe);
+ * New board support should be using this function instead of
+ * of_platform_bus_probe().
+ *
+- * Returns 0 on success, < 0 on failure.
++ * Return: 0 on success, < 0 on failure.
+ */
+ int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+@@ -594,7 +594,7 @@ static void devm_of_platform_populate_release(struct device *dev, void *res)
+ * Similar to of_platform_populate(), but will automatically call
+ * of_platform_depopulate() when the device is unbound from the bus.
+ *
+- * Returns 0 on success, < 0 on failure.
++ * Return: 0 on success, < 0 on failure.
+ */
+ int devm_of_platform_populate(struct device *dev)
+ {
+diff --git a/drivers/of/property.c b/drivers/of/property.c
+index f6010ec0f67b1..28ea326d102f9 100644
+--- a/drivers/of/property.c
++++ b/drivers/of/property.c
+@@ -36,9 +36,11 @@
+ * @elem_size: size of the individual element
+ *
+ * Search for a property in a device node and count the number of elements of
+- * size elem_size in it. Returns number of elements on sucess, -EINVAL if the
+- * property does not exist or its length does not match a multiple of elem_size
+- * and -ENODATA if the property does not have a value.
++ * size elem_size in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does not
++ * exist or its length does not match a multiple of elem_size and -ENODATA if
++ * the property does not have a value.
+ */
+ int of_property_count_elems_of_size(const struct device_node *np,
+ const char *propname, int elem_size)
+@@ -70,8 +72,9 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
+ * @len: if !=NULL, actual length is written to here
+ *
+ * Search for a property in a device node and valid the requested size.
+- * Returns the property value on success, -EINVAL if the property does not
+- * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
++ *
++ * Return: The property value on success, -EINVAL if the property does not
++ * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data is too small or too large.
+ *
+ */
+@@ -104,7 +107,9 @@ static void *of_find_property_value_of_size(const struct device_node *np,
+ * @out_value: pointer to return value, modified only if no error.
+ *
+ * Search for a property in a device node and read nth 32-bit value from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+@@ -136,7 +141,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
+ * @out_value: pointer to return value, modified only if no error.
+ *
+ * Search for a property in a device node and read nth 64-bit value from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+@@ -171,12 +178,14 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_index);
+ * sz_min will be read.
+ *
+ * Search for a property in a device node and read 8-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
+- * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+- * if the property data is smaller than sz_min or longer than sz_max.
++ * it.
+ *
+ * dts entry of array should be like:
+- * property = /bits/ 8 <0x50 0x60 0x70>;
++ * ``property = /bits/ 8 <0x50 0x60 0x70>;``
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
++ * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
++ * if the property data is smaller than sz_min or longer than sz_max.
+ *
+ * The out_values is modified only if a valid u8 value can be decoded.
+ */
+@@ -219,12 +228,14 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
+ * sz_min will be read.
+ *
+ * Search for a property in a device node and read 16-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
+- * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+- * if the property data is smaller than sz_min or longer than sz_max.
++ * it.
+ *
+ * dts entry of array should be like:
+- * property = /bits/ 16 <0x5000 0x6000 0x7000>;
++ * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
++ * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
++ * if the property data is smaller than sz_min or longer than sz_max.
+ *
+ * The out_values is modified only if a valid u16 value can be decoded.
+ */
+@@ -267,7 +278,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
+ * sz_min will be read.
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
++ * it.
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
+ * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+ * if the property data is smaller than sz_min or longer than sz_max.
+ *
+@@ -306,7 +319,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);
+ * @out_value: pointer to return value, modified only if return value is 0.
+ *
+ * Search for a property in a device node and read a 64-bit value from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+@@ -341,7 +356,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u64);
+ * sz_min will be read.
+ *
+ * Search for a property in a device node and read 64-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
++ * it.
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
+ * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+ * if the property data is smaller than sz_min or longer than sz_max.
+ *
+@@ -383,10 +400,11 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);
+ * return value is 0.
+ *
+ * Search for a property in a device tree node and retrieve a null
+- * terminated string value (pointer to data, not a copy). Returns 0 on
+- * success, -EINVAL if the property does not exist, -ENODATA if property
+- * does not have a value, and -EILSEQ if the string is not null-terminated
+- * within the length of the property data.
++ * terminated string value (pointer to data, not a copy).
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if
++ * property does not have a value, and -EILSEQ if the string is not
++ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+@@ -750,7 +768,7 @@ EXPORT_SYMBOL(of_graph_get_remote_port_parent);
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote port node associated with remote endpoint node linked
+- * to @node. Use of_node_put() on it when done.
++ * to @node. Use of_node_put() on it when done.
+ */
+ struct device_node *of_graph_get_remote_port(const struct device_node *node)
+ {
+@@ -783,7 +801,7 @@ EXPORT_SYMBOL(of_graph_get_endpoint_count);
+ * @endpoint: identifier (value of reg property) of the endpoint node
+ *
+ * Return: Remote device node associated with remote endpoint node linked
+- * to @node. Use of_node_put() on it when done.
++ * to @node. Use of_node_put() on it when done.
+ */
+ struct device_node *of_graph_get_remote_node(const struct device_node *node,
+ u32 port, u32 endpoint)
+diff --git a/include/linux/of.h b/include/linux/of.h
+index e070c5ed62a09..8681277af9c6f 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -424,12 +424,14 @@ extern int of_detach_node(struct device_node *);
+ * @sz: number of array elements to read
+ *
+ * Search for a property in a device node and read 8-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
+- * -ENODATA if property does not have a value, and -EOVERFLOW if the
+- * property data isn't large enough.
++ * it.
+ *
+ * dts entry of array should be like:
+- * property = /bits/ 8 <0x50 0x60 0x70>;
++ * ``property = /bits/ 8 <0x50 0x60 0x70>;``
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
++ * -ENODATA if property does not have a value, and -EOVERFLOW if the
++ * property data isn't large enough.
+ *
+ * The out_values is modified only if a valid u8 value can be decoded.
+ */
+@@ -454,12 +456,14 @@ static inline int of_property_read_u8_array(const struct device_node *np,
+ * @sz: number of array elements to read
+ *
+ * Search for a property in a device node and read 16-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
+- * -ENODATA if property does not have a value, and -EOVERFLOW if the
+- * property data isn't large enough.
++ * it.
+ *
+ * dts entry of array should be like:
+- * property = /bits/ 16 <0x5000 0x6000 0x7000>;
++ * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
++ * -ENODATA if property does not have a value, and -EOVERFLOW if the
++ * property data isn't large enough.
+ *
+ * The out_values is modified only if a valid u16 value can be decoded.
+ */
+@@ -485,7 +489,9 @@ static inline int of_property_read_u16_array(const struct device_node *np,
+ * @sz: number of array elements to read
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+@@ -513,7 +519,9 @@ static inline int of_property_read_u32_array(const struct device_node *np,
+ * @sz: number of array elements to read
+ *
+ * Search for a property in a device node and read 64-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+@@ -1046,7 +1054,9 @@ static inline bool of_node_is_type(const struct device_node *np, const char *typ
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device node and count the number of u8 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+ * not exist or its length does not match a multiple of u8 and -ENODATA if the
+ * property does not have a value.
+ */
+@@ -1063,7 +1073,9 @@ static inline int of_property_count_u8_elems(const struct device_node *np,
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device node and count the number of u16 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+ * not exist or its length does not match a multiple of u16 and -ENODATA if the
+ * property does not have a value.
+ */
+@@ -1080,7 +1092,9 @@ static inline int of_property_count_u16_elems(const struct device_node *np,
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device node and count the number of u32 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+ * not exist or its length does not match a multiple of u32 and -ENODATA if the
+ * property does not have a value.
+ */
+@@ -1097,7 +1111,9 @@ static inline int of_property_count_u32_elems(const struct device_node *np,
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device node and count the number of u64 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+ * not exist or its length does not match a multiple of u64 and -ENODATA if the
+ * property does not have a value.
+ */
+@@ -1118,7 +1134,7 @@ static inline int of_property_count_u64_elems(const struct device_node *np,
+ * Search for a property in a device tree node and retrieve a list of
+ * terminated string values (pointer to data, not a copy) in that property.
+ *
+- * If @out_strs is NULL, the number of strings in the property is returned.
++ * Return: If @out_strs is NULL, the number of strings in the property is returned.
+ */
+ static inline int of_property_read_string_array(const struct device_node *np,
+ const char *propname, const char **out_strs,
+@@ -1134,10 +1150,11 @@ static inline int of_property_read_string_array(const struct device_node *np,
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device tree node and retrieve the number of null
+- * terminated string contain in it. Returns the number of strings on
+- * success, -EINVAL if the property does not exist, -ENODATA if property
+- * does not have a value, and -EILSEQ if the string is not null-terminated
+- * within the length of the property data.
++ * terminated string contain in it.
++ *
++ * Return: The number of strings on success, -EINVAL if the property does not
++ * exist, -ENODATA if property does not have a value, and -EILSEQ if the string
++ * is not null-terminated within the length of the property data.
+ */
+ static inline int of_property_count_strings(const struct device_node *np,
+ const char *propname)
+@@ -1157,7 +1174,8 @@ static inline int of_property_count_strings(const struct device_node *np,
+ * Search for a property in a device tree node and retrieve a null
+ * terminated string value (pointer to data, not a copy) in the list of strings
+ * contained in that property.
+- * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EILSEQ if the string is not
+ * null-terminated within the length of the property data.
+ *
+@@ -1177,7 +1195,8 @@ static inline int of_property_read_string_index(const struct device_node *np,
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device node.
+- * Returns true if the property exists false otherwise.
++ *
++ * Return: true if the property exists false otherwise.
+ */
+ static inline bool of_property_read_bool(const struct device_node *np,
+ const char *propname)
+@@ -1423,7 +1442,7 @@ static inline int of_reconfig_get_state_change(unsigned long action,
+ * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node
+ * @np: Pointer to the given device_node
+ *
+- * return true if present false otherwise
++ * Return: true if present false otherwise
+ */
+ static inline bool of_device_is_system_power_controller(const struct device_node *np)
+ {
+--
+2.42.0
+
--- /dev/null
+From e8f906090506040660495eb0f530a35318533ba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2019 12:01:48 +0200
+Subject: of: base: Add of_get_cpu_state_node() to get idle states for a CPU
+ node
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit b9f8c26afc405a4a616e765e949bdd551151e41d ]
+
+The CPU's idle state nodes are currently parsed at the common cpuidle DT
+library, but also when initializing data for specific CPU idle operations,
+as in the PSCI cpuidle driver case and qcom-spm cpuidle case.
+
+To avoid open-coding, let's introduce of_get_cpu_state_node(), which takes
+the device node for the CPU and the index to the requested idle state node,
+as in-parameters. In case a corresponding idle state node is found, it
+returns the node with the refcount incremented for it, else it returns
+NULL.
+
+Moreover, for PSCI there are two options to describe the CPU's idle states
+[1], either via a flattened description or a hierarchical layout. Hence,
+let's take both options into account.
+
+[1] Documentation/devicetree/bindings/arm/psci.yaml
+
+Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
+Co-developed-by: Lina Iyer <lina.iyer@linaro.org>
+Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c | 36 ++++++++++++++++++++++++++++++++++++
+ include/linux/of.h | 8 ++++++++
+ 2 files changed, 44 insertions(+)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index b5c84607a74bf..3f13b982e8b53 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -477,6 +477,42 @@ int of_cpu_node_to_id(struct device_node *cpu_node)
+ }
+ EXPORT_SYMBOL(of_cpu_node_to_id);
+
++/**
++ * of_get_cpu_state_node - Get CPU's idle state node at the given index
++ *
++ * @cpu_node: The device node for the CPU
++ * @index: The index in the list of the idle states
++ *
++ * Two generic methods can be used to describe a CPU's idle states, either via
++ * a flattened description through the "cpu-idle-states" binding or via the
++ * hierarchical layout, using the "power-domains" and the "domain-idle-states"
++ * bindings. This function check for both and returns the idle state node for
++ * the requested index.
++ *
++ * In case an idle state node is found at @index, the refcount is incremented
++ * for it, so call of_node_put() on it when done. Returns NULL if not found.
++ */
++struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
++ int index)
++{
++ struct of_phandle_args args;
++ int err;
++
++ err = of_parse_phandle_with_args(cpu_node, "power-domains",
++ "#power-domain-cells", 0, &args);
++ if (!err) {
++ struct device_node *state_node =
++ of_parse_phandle(args.np, "domain-idle-states", index);
++
++ of_node_put(args.np);
++ if (state_node)
++ return state_node;
++ }
++
++ return of_parse_phandle(cpu_node, "cpu-idle-states", index);
++}
++EXPORT_SYMBOL(of_get_cpu_state_node);
++
+ /**
+ * __of_device_is_compatible() - Check if the node matches given constraints
+ * @device: pointer to node
+diff --git a/include/linux/of.h b/include/linux/of.h
+index a7621e2b440ad..e29b341598e99 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -351,6 +351,8 @@ extern const void *of_get_property(const struct device_node *node,
+ int *lenp);
+ extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+ extern struct device_node *of_get_next_cpu_node(struct device_node *prev);
++extern struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
++ int index);
+
+ #define for_each_property_of_node(dn, pp) \
+ for (pp = dn->properties; pp != NULL; pp = pp->next)
+@@ -765,6 +767,12 @@ static inline struct device_node *of_get_next_cpu_node(struct device_node *prev)
+ return NULL;
+ }
+
++static inline struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
++ int index)
++{
++ return NULL;
++}
++
+ static inline int of_n_addr_cells(struct device_node *np)
+ {
+ return 0;
+--
+2.42.0
+
--- /dev/null
+From 538e78aea655244d2819a4745898f149e1b99a98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Mar 2021 10:40:30 +0000
+Subject: of: base: Fix some formatting issues and provide missing descriptions
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 3637d49e11219512920aca8b8ccd0994be33fa8b ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/of/base.c:315: warning: Function parameter or member 'cpun' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: Function parameter or member 'prop_name' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: Function parameter or member 'cpu' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: Function parameter or member 'thread' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: expecting prototype for property holds the physical id of the(). Prototype was for __of_find_n_match_cpu_property() instead
+ drivers/of/base.c:1139: warning: Function parameter or member 'match' not described in 'of_find_matching_node_and_match'
+ drivers/of/base.c:1779: warning: Function parameter or member 'np' not described in '__of_add_property'
+ drivers/of/base.c:1779: warning: Function parameter or member 'prop' not described in '__of_add_property'
+ drivers/of/base.c:1800: warning: Function parameter or member 'np' not described in 'of_add_property'
+ drivers/of/base.c:1800: warning: Function parameter or member 'prop' not described in 'of_add_property'
+ drivers/of/base.c:1849: warning: Function parameter or member 'np' not described in 'of_remove_property'
+ drivers/of/base.c:1849: warning: Function parameter or member 'prop' not described in 'of_remove_property'
+ drivers/of/base.c:2137: warning: Function parameter or member 'dn' not described in 'of_console_check'
+ drivers/of/base.c:2137: warning: Function parameter or member 'name' not described in 'of_console_check'
+ drivers/of/base.c:2137: warning: Function parameter or member 'index' not described in 'of_console_check'
+
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210318104036.3175910-5-lee.jones@linaro.org
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 5c97366628b13..4032814133fe6 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -367,7 +367,7 @@ bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+ return (u32)phys_id == cpu;
+ }
+
+-/**
++/*
+ * Checks if the given "prop_name" property holds the physical id of the
+ * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
+ * NULL, local thread number within the core is returned in it.
+@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(of_match_node);
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @matches: array of of device match structures to search in
+- * @match Updated to point at the matches entry which matched
++ * @match: Updated to point at the matches entry which matched
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+@@ -1853,6 +1853,8 @@ EXPORT_SYMBOL(of_count_phandle_with_args);
+
+ /**
+ * __of_add_property - Add a property to a node without lock operations
++ * @np: Caller's Device Node
++ * @prob: Property to add
+ */
+ int __of_add_property(struct device_node *np, struct property *prop)
+ {
+@@ -1874,6 +1876,8 @@ int __of_add_property(struct device_node *np, struct property *prop)
+
+ /**
+ * of_add_property - Add a property to a node
++ * @np: Caller's Device Node
++ * @prob: Property to add
+ */
+ int of_add_property(struct device_node *np, struct property *prop)
+ {
+@@ -1918,6 +1922,8 @@ int __of_remove_property(struct device_node *np, struct property *prop)
+
+ /**
+ * of_remove_property - Remove a property from a node.
++ * @np: Caller's Device Node
++ * @prob: Property to remove
+ *
+ * Note that we don't actually remove it, since we have given out
+ * who-knows-how-many pointers to the data using get-property.
+@@ -2203,9 +2209,9 @@ EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
+
+ /**
+ * of_console_check() - Test and setup console for DT setup
+- * @dn - Pointer to device node
+- * @name - Name to use for preferred console without index. ex. "ttyS"
+- * @index - Index to use for preferred console.
++ * @dn: Pointer to device node
++ * @name: Name to use for preferred console without index. ex. "ttyS"
++ * @index: Index to use for preferred console.
+ *
+ * Check if the given device node matches the stdout-path property in the
+ * /chosen node. If it does then register it as the preferred console and return
+--
+2.42.0
+
--- /dev/null
+From 8cf8ba72543852f7312e8388fc5f22a995d5eba3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Nov 2023 15:47:18 +0100
+Subject: of: dynamic: Fix of_reconfig_get_state_change() return value
+ documentation
+
+From: Luca Ceresoli <luca.ceresoli@bootlin.com>
+
+[ Upstream commit d79972789d17499b6091ded2fc0c6763c501a5ba ]
+
+The documented numeric return values do not match the actual returned
+values. Fix them by using the enum names instead of raw numbers.
+
+Fixes: b53a2340d0d3 ("of/reconfig: Add of_reconfig_get_state_change() of notifier helper.")
+Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://lore.kernel.org/r/20231123-fix-of_reconfig_get_state_change-docs-v1-1-f51892050ff9@bootlin.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/dynamic.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
+index 92ee15be78d43..ae969630958cd 100644
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -105,8 +105,9 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
+ *
+ * Returns the new state of a device based on the notifier used.
+ *
+- * Return: 0 on device going from enabled to disabled, 1 on device
+- * going from disabled to enabled and -1 on no change.
++ * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to
++ * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to
++ * enabled and OF_RECONFIG_NO_CHANGE on no change.
+ */
+ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
+ {
+--
+2.42.0
+
--- /dev/null
+From 19c581a873796822ddf355a4544dfa6550739ede Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 13:26:06 -0600
+Subject: of: Fix kerneldoc output formatting
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 62f026f082e4d762a47b43ea693b38f025122332 ]
+
+The indentation of the kerneldoc comments affects the output formatting.
+Leading tabs in particular don't work, sections need to be indented
+under the section header, and several code blocks are reformatted.
+
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Link: https://lore.kernel.org/r/20210326192606.3702739-1-robh@kernel.org
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c | 275 +++++++++++++++++++++++-----------------------
+ drivers/of/fdt.c | 9 +-
+ 2 files changed, 141 insertions(+), 143 deletions(-)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 4032814133fe6..c4c64ef5fb7a8 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -713,11 +713,11 @@ bool of_device_is_big_endian(const struct device_node *device)
+ EXPORT_SYMBOL(of_device_is_big_endian);
+
+ /**
+- * of_get_parent - Get a node's parent if any
+- * @node: Node to get parent
++ * of_get_parent - Get a node's parent if any
++ * @node: Node to get parent
+ *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_get_parent(const struct device_node *node)
+ {
+@@ -735,15 +735,15 @@ struct device_node *of_get_parent(const struct device_node *node)
+ EXPORT_SYMBOL(of_get_parent);
+
+ /**
+- * of_get_next_parent - Iterate to a node's parent
+- * @node: Node to get parent of
++ * of_get_next_parent - Iterate to a node's parent
++ * @node: Node to get parent of
+ *
+- * This is like of_get_parent() except that it drops the
+- * refcount on the passed node, making it suitable for iterating
+- * through a node's parents.
++ * This is like of_get_parent() except that it drops the
++ * refcount on the passed node, making it suitable for iterating
++ * through a node's parents.
+ *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_get_next_parent(struct device_node *node)
+ {
+@@ -781,13 +781,13 @@ static struct device_node *__of_get_next_child(const struct device_node *node,
+ child = __of_get_next_child(parent, child))
+
+ /**
+- * of_get_next_child - Iterate a node childs
+- * @node: parent node
+- * @prev: previous child of the parent node, or NULL to get first
++ * of_get_next_child - Iterate a node childs
++ * @node: parent node
++ * @prev: previous child of the parent node, or NULL to get first
+ *
+- * Returns a node pointer with refcount incremented, use of_node_put() on
+- * it when done. Returns NULL when prev is the last child. Decrements the
+- * refcount of prev.
++ * Return: A node pointer with refcount incremented, use of_node_put() on
++ * it when done. Returns NULL when prev is the last child. Decrements the
++ * refcount of prev.
+ */
+ struct device_node *of_get_next_child(const struct device_node *node,
+ struct device_node *prev)
+@@ -803,12 +803,12 @@ struct device_node *of_get_next_child(const struct device_node *node,
+ EXPORT_SYMBOL(of_get_next_child);
+
+ /**
+- * of_get_next_available_child - Find the next available child node
+- * @node: parent node
+- * @prev: previous child of the parent node, or NULL to get first
++ * of_get_next_available_child - Find the next available child node
++ * @node: parent node
++ * @prev: previous child of the parent node, or NULL to get first
+ *
+- * This function is like of_get_next_child(), except that it
+- * automatically skips any disabled nodes (i.e. status = "disabled").
++ * This function is like of_get_next_child(), except that it
++ * automatically skips any disabled nodes (i.e. status = "disabled").
+ */
+ struct device_node *of_get_next_available_child(const struct device_node *node,
+ struct device_node *prev)
+@@ -834,12 +834,12 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
+ EXPORT_SYMBOL(of_get_next_available_child);
+
+ /**
+- * of_get_next_cpu_node - Iterate on cpu nodes
+- * @prev: previous child of the /cpus node, or NULL to get first
++ * of_get_next_cpu_node - Iterate on cpu nodes
++ * @prev: previous child of the /cpus node, or NULL to get first
+ *
+- * Returns a cpu node pointer with refcount incremented, use of_node_put()
+- * on it when done. Returns NULL when prev is the last child. Decrements
+- * the refcount of prev.
++ * Return: A cpu node pointer with refcount incremented, use of_node_put()
++ * on it when done. Returns NULL when prev is the last child. Decrements
++ * the refcount of prev.
+ */
+ struct device_node *of_get_next_cpu_node(struct device_node *prev)
+ {
+@@ -896,15 +896,15 @@ struct device_node *of_get_compatible_child(const struct device_node *parent,
+ EXPORT_SYMBOL(of_get_compatible_child);
+
+ /**
+- * of_get_child_by_name - Find the child node by name for a given parent
+- * @node: parent node
+- * @name: child name to look for.
++ * of_get_child_by_name - Find the child node by name for a given parent
++ * @node: parent node
++ * @name: child name to look for.
+ *
+- * This function looks for child node for given matching name
++ * This function looks for child node for given matching name
+ *
+- * Returns a node pointer if found, with refcount incremented, use
+- * of_node_put() on it when done.
+- * Returns NULL if node is not found.
++ * Return: A node pointer if found, with refcount incremented, use
++ * of_node_put() on it when done.
++ * Returns NULL if node is not found.
+ */
+ struct device_node *of_get_child_by_name(const struct device_node *node,
+ const char *name)
+@@ -955,22 +955,22 @@ struct device_node *__of_find_node_by_full_path(struct device_node *node,
+ }
+
+ /**
+- * of_find_node_opts_by_path - Find a node matching a full OF path
+- * @path: Either the full path to match, or if the path does not
+- * start with '/', the name of a property of the /aliases
+- * node (an alias). In the case of an alias, the node
+- * matching the alias' value will be returned.
+- * @opts: Address of a pointer into which to store the start of
+- * an options string appended to the end of the path with
+- * a ':' separator.
+- *
+- * Valid paths:
+- * /foo/bar Full path
+- * foo Valid alias
+- * foo/bar Valid alias + relative path
+- *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * of_find_node_opts_by_path - Find a node matching a full OF path
++ * @path: Either the full path to match, or if the path does not
++ * start with '/', the name of a property of the /aliases
++ * node (an alias). In the case of an alias, the node
++ * matching the alias' value will be returned.
++ * @opts: Address of a pointer into which to store the start of
++ * an options string appended to the end of the path with
++ * a ':' separator.
++ *
++ * Valid paths:
++ * * /foo/bar Full path
++ * * foo Valid alias
++ * * foo/bar Valid alias + relative path
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
+ {
+@@ -1020,15 +1020,15 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt
+ EXPORT_SYMBOL(of_find_node_opts_by_path);
+
+ /**
+- * of_find_node_by_name - Find a node by its "name" property
+- * @from: The node to start searching from or NULL; the node
++ * of_find_node_by_name - Find a node by its "name" property
++ * @from: The node to start searching from or NULL; the node
+ * you pass will not be searched, only the next one
+ * will. Typically, you pass what the previous call
+ * returned. of_node_put() will be called on @from.
+- * @name: The name string to match against
++ * @name: The name string to match against
+ *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name)
+@@ -1047,16 +1047,16 @@ struct device_node *of_find_node_by_name(struct device_node *from,
+ EXPORT_SYMBOL(of_find_node_by_name);
+
+ /**
+- * of_find_node_by_type - Find a node by its "device_type" property
+- * @from: The node to start searching from, or NULL to start searching
++ * of_find_node_by_type - Find a node by its "device_type" property
++ * @from: The node to start searching from, or NULL to start searching
+ * the entire device tree. The node you pass will not be
+ * searched, only the next one will; typically, you pass
+ * what the previous call returned. of_node_put() will be
+ * called on from for you.
+- * @type: The type string to match against
++ * @type: The type string to match against
+ *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_node_by_type(struct device_node *from,
+ const char *type)
+@@ -1075,18 +1075,18 @@ struct device_node *of_find_node_by_type(struct device_node *from,
+ EXPORT_SYMBOL(of_find_node_by_type);
+
+ /**
+- * of_find_compatible_node - Find a node based on type and one of the
++ * of_find_compatible_node - Find a node based on type and one of the
+ * tokens in its "compatible" property
+- * @from: The node to start searching from or NULL, the node
+- * you pass will not be searched, only the next one
+- * will; typically, you pass what the previous call
+- * returned. of_node_put() will be called on it
+- * @type: The type string to match "device_type" or NULL to ignore
+- * @compatible: The string to match to one of the tokens in the device
+- * "compatible" list.
+- *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * @from: The node to start searching from or NULL, the node
++ * you pass will not be searched, only the next one
++ * will; typically, you pass what the previous call
++ * returned. of_node_put() will be called on it
++ * @type: The type string to match "device_type" or NULL to ignore
++ * @compatible: The string to match to one of the tokens in the device
++ * "compatible" list.
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_compatible_node(struct device_node *from,
+ const char *type, const char *compatible)
+@@ -1106,16 +1106,16 @@ struct device_node *of_find_compatible_node(struct device_node *from,
+ EXPORT_SYMBOL(of_find_compatible_node);
+
+ /**
+- * of_find_node_with_property - Find a node which has a property with
+- * the given name.
+- * @from: The node to start searching from or NULL, the node
+- * you pass will not be searched, only the next one
+- * will; typically, you pass what the previous call
+- * returned. of_node_put() will be called on it
+- * @prop_name: The name of the property to look for.
+- *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * of_find_node_with_property - Find a node which has a property with
++ * the given name.
++ * @from: The node to start searching from or NULL, the node
++ * you pass will not be searched, only the next one
++ * will; typically, you pass what the previous call
++ * returned. of_node_put() will be called on it
++ * @prop_name: The name of the property to look for.
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_node_with_property(struct device_node *from,
+ const char *prop_name)
+@@ -1164,10 +1164,10 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
+
+ /**
+ * of_match_node - Tell if a device_node has a matching of_match structure
+- * @matches: array of of device match structures to search in
+- * @node: the of device structure to match against
++ * @matches: array of of device match structures to search in
++ * @node: the of device structure to match against
+ *
+- * Low level utility function used by device matching.
++ * Low level utility function used by device matching.
+ */
+ const struct of_device_id *of_match_node(const struct of_device_id *matches,
+ const struct device_node *node)
+@@ -1183,17 +1183,17 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
+ EXPORT_SYMBOL(of_match_node);
+
+ /**
+- * of_find_matching_node_and_match - Find a node based on an of_device_id
+- * match table.
+- * @from: The node to start searching from or NULL, the node
+- * you pass will not be searched, only the next one
+- * will; typically, you pass what the previous call
+- * returned. of_node_put() will be called on it
+- * @matches: array of of device match structures to search in
+- * @match: Updated to point at the matches entry which matched
+- *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done.
++ * of_find_matching_node_and_match - Find a node based on an of_device_id
++ * match table.
++ * @from: The node to start searching from or NULL, the node
++ * you pass will not be searched, only the next one
++ * will; typically, you pass what the previous call
++ * returned. of_node_put() will be called on it
++ * @matches: array of of device match structures to search in
++ * @match: Updated to point at the matches entry which matched
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+ */
+ struct device_node *of_find_matching_node_and_match(struct device_node *from,
+ const struct of_device_id *matches,
+@@ -1539,21 +1539,21 @@ EXPORT_SYMBOL(of_parse_phandle);
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+- * Example:
++ * Example::
+ *
+- * phandle1: node1 {
++ * phandle1: node1 {
+ * #list-cells = <2>;
+- * }
++ * };
+ *
+- * phandle2: node2 {
++ * phandle2: node2 {
+ * #list-cells = <1>;
+- * }
++ * };
+ *
+- * node3 {
++ * node3 {
+ * list = <&phandle1 1 2 &phandle2 3>;
+- * }
++ * };
+ *
+- * To get a device_node of the `node2' node you may call this:
++ * To get a device_node of the ``node2`` node you may call this:
+ * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
+ */
+ int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
+@@ -1591,29 +1591,29 @@ EXPORT_SYMBOL(of_parse_phandle_with_args);
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+- * Example:
++ * Example::
+ *
+- * phandle1: node1 {
+- * #list-cells = <2>;
+- * }
++ * phandle1: node1 {
++ * #list-cells = <2>;
++ * };
+ *
+- * phandle2: node2 {
+- * #list-cells = <1>;
+- * }
++ * phandle2: node2 {
++ * #list-cells = <1>;
++ * };
+ *
+- * phandle3: node3 {
+- * #list-cells = <1>;
+- * list-map = <0 &phandle2 3>,
+- * <1 &phandle2 2>,
+- * <2 &phandle1 5 1>;
+- * list-map-mask = <0x3>;
+- * };
++ * phandle3: node3 {
++ * #list-cells = <1>;
++ * list-map = <0 &phandle2 3>,
++ * <1 &phandle2 2>,
++ * <2 &phandle1 5 1>;
++ * list-map-mask = <0x3>;
++ * };
+ *
+- * node4 {
+- * list = <&phandle1 1 2 &phandle3 0>;
+- * }
++ * node4 {
++ * list = <&phandle1 1 2 &phandle3 0>;
++ * };
+ *
+- * To get a device_node of the `node2' node you may call this:
++ * To get a device_node of the ``node2`` node you may call this:
+ * of_parse_phandle_with_args(node4, "list", "list", 1, &args);
+ */
+ int of_parse_phandle_with_args_map(const struct device_node *np,
+@@ -1773,19 +1773,19 @@ EXPORT_SYMBOL(of_parse_phandle_with_args_map);
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+- * Example:
++ * Example::
+ *
+- * phandle1: node1 {
+- * }
++ * phandle1: node1 {
++ * };
+ *
+- * phandle2: node2 {
+- * }
++ * phandle2: node2 {
++ * };
+ *
+- * node3 {
+- * list = <&phandle1 0 2 &phandle2 2 3>;
+- * }
++ * node3 {
++ * list = <&phandle1 0 2 &phandle2 2 3>;
++ * };
+ *
+- * To get a device_node of the `node2' node you may call this:
++ * To get a device_node of the ``node2`` node you may call this:
+ * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
+ */
+ int of_parse_phandle_with_fixed_args(const struct device_node *np,
+@@ -2030,13 +2030,12 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+
+ /**
+ * of_alias_scan - Scan all properties of the 'aliases' node
++ * @dt_alloc: An allocator that provides a virtual address to memory
++ * for storing the resulting tree
+ *
+ * The function scans all the properties of the 'aliases' node and populates
+ * the global lookup table with the properties. It returns the
+ * number of alias properties found, or an error code in case of failure.
+- *
+- * @dt_alloc: An allocator that provides a virtual address to memory
+- * for storing the resulting tree
+ */
+ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
+ {
+@@ -2231,12 +2230,12 @@ bool of_console_check(struct device_node *dn, char *name, int index)
+ EXPORT_SYMBOL_GPL(of_console_check);
+
+ /**
+- * of_find_next_cache_node - Find a node's subsidiary cache
+- * @np: node of type "cpu" or "cache"
++ * of_find_next_cache_node - Find a node's subsidiary cache
++ * @np: node of type "cpu" or "cache"
+ *
+- * Returns a node pointer with refcount incremented, use
+- * of_node_put() on it when done. Caller should hold a reference
+- * to np.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done. Caller should hold a reference
++ * to np.
+ */
+ struct device_node *of_find_next_cache_node(const struct device_node *np)
+ {
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 6d519ef3c5da4..09a98668e7db0 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -349,11 +349,6 @@ static int unflatten_dt_nodes(const void *blob,
+
+ /**
+ * __unflatten_device_tree - create tree of device_nodes from flat blob
+- *
+- * unflattens a device-tree, creating the
+- * tree of struct device_node. It also fills the "name" and "type"
+- * pointers of the nodes so the normal device-tree walking functions
+- * can be used.
+ * @blob: The blob to expand
+ * @dad: Parent device node
+ * @mynodes: The device_node tree created by the call
+@@ -361,6 +356,10 @@ static int unflatten_dt_nodes(const void *blob,
+ * for the resulting tree
+ * @detached: if true set OF_DETACHED on @mynodes
+ *
++ * unflattens a device-tree, creating the tree of struct device_node. It also
++ * fills the "name" and "type" pointers of the nodes so the normal device-tree
++ * walking functions can be used.
++ *
+ * Returns NULL on failure or the memory chunk containing the unflattened
+ * device tree on success.
+ */
+--
+2.42.0
+
--- /dev/null
+From 2b931bcceb369affc55fb9f9c80d13f8be41ed1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:07 +0100
+Subject: of/iommu: Make of_map_rid() PCI agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit 746a71d02b5d15817fcb13c956ba999a87773952 ]
+
+There is nothing PCI specific (other than the RID - requester ID)
+in the of_map_rid() implementation, so the same function can be
+reused for input/output IDs mapping for other busses just as well.
+
+Rename the RID instances/names to a generic "id" tag.
+
+No functionality change intended.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Joerg Roedel <jroedel@suse.de>
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Joerg Roedel <joro@8bytes.org>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200619082013.13661-7-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/of_iommu.c | 4 ++--
+ drivers/of/base.c | 42 ++++++++++++++++++++--------------------
+ drivers/of/irq.c | 2 +-
+ include/linux/of.h | 4 ++--
+ 4 files changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
+index 614a93aa5305a..656939ed842e7 100644
+--- a/drivers/iommu/of_iommu.c
++++ b/drivers/iommu/of_iommu.c
+@@ -121,7 +121,7 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
+ struct of_phandle_args iommu_spec = { .args_count = 1 };
+ int err;
+
+- err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask",
++ err = of_map_id(info->np, alias, "iommu-map", "iommu-map-mask",
+ &iommu_spec.np, iommu_spec.args);
+ if (err)
+ return err == -ENODEV ? NO_IOMMU : err;
+@@ -137,7 +137,7 @@ static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
+ struct of_phandle_args iommu_spec = { .args_count = 1 };
+ int err;
+
+- err = of_map_rid(master_np, mc_dev->icid, "iommu-map",
++ err = of_map_id(master_np, mc_dev->icid, "iommu-map",
+ "iommu-map-mask", &iommu_spec.np,
+ iommu_spec.args);
+ if (err)
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 3f13b982e8b53..5c97366628b13 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -2280,15 +2280,15 @@ int of_find_last_cache_level(unsigned int cpu)
+ }
+
+ /**
+- * of_map_rid - Translate a requester ID through a downstream mapping.
++ * of_map_id - Translate an ID through a downstream mapping.
+ * @np: root complex device node.
+- * @rid: device requester ID to map.
++ * @id: device ID to map.
+ * @map_name: property name of the map to use.
+ * @map_mask_name: optional property name of the mask to use.
+ * @target: optional pointer to a target device node.
+ * @id_out: optional pointer to receive the translated ID.
+ *
+- * Given a device requester ID, look up the appropriate implementation-defined
++ * Given a device ID, look up the appropriate implementation-defined
+ * platform ID and/or the target device which receives transactions on that
+ * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
+ * @id_out may be NULL if only the other is required. If @target points to
+@@ -2298,11 +2298,11 @@ int of_find_last_cache_level(unsigned int cpu)
+ *
+ * Return: 0 on success or a standard error code on failure.
+ */
+-int of_map_rid(struct device_node *np, u32 rid,
++int of_map_id(struct device_node *np, u32 id,
+ const char *map_name, const char *map_mask_name,
+ struct device_node **target, u32 *id_out)
+ {
+- u32 map_mask, masked_rid;
++ u32 map_mask, masked_id;
+ int map_len;
+ const __be32 *map = NULL;
+
+@@ -2314,7 +2314,7 @@ int of_map_rid(struct device_node *np, u32 rid,
+ if (target)
+ return -ENODEV;
+ /* Otherwise, no map implies no translation */
+- *id_out = rid;
++ *id_out = id;
+ return 0;
+ }
+
+@@ -2334,22 +2334,22 @@ int of_map_rid(struct device_node *np, u32 rid,
+ if (map_mask_name)
+ of_property_read_u32(np, map_mask_name, &map_mask);
+
+- masked_rid = map_mask & rid;
++ masked_id = map_mask & id;
+ for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
+ struct device_node *phandle_node;
+- u32 rid_base = be32_to_cpup(map + 0);
++ u32 id_base = be32_to_cpup(map + 0);
+ u32 phandle = be32_to_cpup(map + 1);
+ u32 out_base = be32_to_cpup(map + 2);
+- u32 rid_len = be32_to_cpup(map + 3);
++ u32 id_len = be32_to_cpup(map + 3);
+
+- if (rid_base & ~map_mask) {
+- pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
++ if (id_base & ~map_mask) {
++ pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
+ np, map_name, map_name,
+- map_mask, rid_base);
++ map_mask, id_base);
+ return -EFAULT;
+ }
+
+- if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
++ if (masked_id < id_base || masked_id >= id_base + id_len)
+ continue;
+
+ phandle_node = of_find_node_by_phandle(phandle);
+@@ -2367,20 +2367,20 @@ int of_map_rid(struct device_node *np, u32 rid,
+ }
+
+ if (id_out)
+- *id_out = masked_rid - rid_base + out_base;
++ *id_out = masked_id - id_base + out_base;
+
+- pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
+- np, map_name, map_mask, rid_base, out_base,
+- rid_len, rid, masked_rid - rid_base + out_base);
++ pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
++ np, map_name, map_mask, id_base, out_base,
++ id_len, id, masked_id - id_base + out_base);
+ return 0;
+ }
+
+- pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name,
+- rid, target && *target ? *target : NULL);
++ pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name,
++ id, target && *target ? *target : NULL);
+
+ /* Bypasses translation */
+ if (id_out)
+- *id_out = rid;
++ *id_out = id;
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(of_map_rid);
++EXPORT_SYMBOL_GPL(of_map_id);
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index a296eaf52a5b2..d632bc5b3a2de 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -587,7 +587,7 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
+ * "msi-map" property.
+ */
+ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
+- if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
++ if (!of_map_id(parent_dev->of_node, rid_in, "msi-map",
+ "msi-map-mask", np, &rid_out))
+ break;
+ return rid_out;
+diff --git a/include/linux/of.h b/include/linux/of.h
+index e29b341598e99..e070c5ed62a09 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -554,7 +554,7 @@ bool of_console_check(struct device_node *dn, char *name, int index);
+
+ extern int of_cpu_node_to_id(struct device_node *np);
+
+-int of_map_rid(struct device_node *np, u32 rid,
++int of_map_id(struct device_node *np, u32 id,
+ const char *map_name, const char *map_mask_name,
+ struct device_node **target, u32 *id_out);
+
+@@ -978,7 +978,7 @@ static inline int of_cpu_node_to_id(struct device_node *np)
+ return -ENODEV;
+ }
+
+-static inline int of_map_rid(struct device_node *np, u32 rid,
++static inline int of_map_id(struct device_node *np, u32 id,
+ const char *map_name, const char *map_mask_name,
+ struct device_node **target, u32 *id_out)
+ {
+--
+2.42.0
+
--- /dev/null
+From de174d191aecc6a69cf5c44bec20c17a5dc931f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:10 +0100
+Subject: of/irq: make of_msi_map_get_device_domain() bus agnostic
+
+From: Diana Craciun <diana.craciun@oss.nxp.com>
+
+[ Upstream commit 6f881aba01109a01a43e4f135673c19190f61133 ]
+
+of_msi_map_get_device_domain() is PCI specific but it need not be and
+can be easily changed to be bus agnostic in order to be used by other
+busses by adding an IRQ domain bus token as an input parameter.
+
+Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com> # pci/msi.c
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200619082013.13661-10-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/irq.c | 8 +++++---
+ drivers/pci/msi.c | 2 +-
+ include/linux/of_irq.h | 5 +++--
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index d632bc5b3a2de..1005e4f349ef6 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -613,18 +613,20 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
+ * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
+ * @dev: device for which the mapping is to be done.
+ * @rid: Requester ID for the device.
++ * @bus_token: Bus token
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+ * property.
+ *
+ * Returns: the MSI domain for this device (or NULL on failure)
+ */
+-struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)
++struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
++ u32 bus_token)
+ {
+ struct device_node *np = NULL;
+
+- __of_msi_map_rid(dev, &np, rid);
+- return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
++ __of_msi_map_rid(dev, &np, id);
++ return irq_find_matching_host(np, bus_token);
+ }
+
+ /**
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index cc863cdd5cc74..392d2ecf7dc89 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1624,7 +1624,7 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
+ u32 rid = pci_dev_id(pdev);
+
+ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+- dom = of_msi_map_get_device_domain(&pdev->dev, rid);
++ dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI);
+ if (!dom)
+ dom = iort_get_device_domain(&pdev->dev, rid,
+ DOMAIN_BUS_PCI_MSI);
+diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
+index 1214cabb22479..7142a37227584 100644
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -52,7 +52,8 @@ extern struct irq_domain *of_msi_get_domain(struct device *dev,
+ struct device_node *np,
+ enum irq_domain_bus_token token);
+ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+- u32 rid);
++ u32 id,
++ u32 bus_token);
+ extern void of_msi_configure(struct device *dev, struct device_node *np);
+ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
+ #else
+@@ -85,7 +86,7 @@ static inline struct irq_domain *of_msi_get_domain(struct device *dev,
+ return NULL;
+ }
+ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+- u32 rid)
++ u32 id, u32 bus_token)
+ {
+ return NULL;
+ }
+--
+2.42.0
+
--- /dev/null
+From 43feea6bf296097366432b53034ab33b6901773a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:11 +0100
+Subject: of/irq: Make of_msi_map_rid() PCI bus agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit 2bcdd8f2c07f1aa1bfd34fa0dab8e06949e34846 ]
+
+There is nothing PCI bus specific in the of_msi_map_rid()
+implementation other than the requester ID tag for the input
+ID space. Rename requester ID to a more generic ID so that
+the translation code can be used by all busses that require
+input/output ID translations.
+
+No functional change intended.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200619082013.13661-11-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/irq.c | 28 ++++++++++++++--------------
+ drivers/pci/msi.c | 2 +-
+ include/linux/of_irq.h | 8 ++++----
+ 3 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index 1005e4f349ef6..25d17b8a1a1aa 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -576,43 +576,43 @@ void __init of_irq_init(const struct of_device_id *matches)
+ }
+ }
+
+-static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
+- u32 rid_in)
++static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
++ u32 id_in)
+ {
+ struct device *parent_dev;
+- u32 rid_out = rid_in;
++ u32 id_out = id_in;
+
+ /*
+ * Walk up the device parent links looking for one with a
+ * "msi-map" property.
+ */
+ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
+- if (!of_map_id(parent_dev->of_node, rid_in, "msi-map",
+- "msi-map-mask", np, &rid_out))
++ if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
++ "msi-map-mask", np, &id_out))
+ break;
+- return rid_out;
++ return id_out;
+ }
+
+ /**
+- * of_msi_map_rid - Map a MSI requester ID for a device.
++ * of_msi_map_id - Map a MSI ID for a device.
+ * @dev: device for which the mapping is to be done.
+ * @msi_np: device node of the expected msi controller.
+- * @rid_in: unmapped MSI requester ID for the device.
++ * @id_in: unmapped MSI ID for the device.
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+- * property. If found, apply the mapping to @rid_in.
++ * property. If found, apply the mapping to @id_in.
+ *
+- * Returns the mapped MSI requester ID.
++ * Returns the mapped MSI ID.
+ */
+-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
++u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
+ {
+- return __of_msi_map_rid(dev, &msi_np, rid_in);
++ return __of_msi_map_id(dev, &msi_np, id_in);
+ }
+
+ /**
+ * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
+ * @dev: device for which the mapping is to be done.
+- * @rid: Requester ID for the device.
++ * @id: Device ID.
+ * @bus_token: Bus token
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+@@ -625,7 +625,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
+ {
+ struct device_node *np = NULL;
+
+- __of_msi_map_rid(dev, &np, id);
++ __of_msi_map_id(dev, &np, id);
+ return irq_find_matching_host(np, bus_token);
+ }
+
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index 392d2ecf7dc89..c4f4a8a3bf8fa 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1603,7 +1603,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
+ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+
+ of_node = irq_domain_get_of_node(domain);
+- rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) :
++ rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) :
+ iort_msi_map_id(&pdev->dev, rid);
+
+ return rid;
+diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
+index 7142a37227584..e8b78139f78c5 100644
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -55,7 +55,7 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+ u32 id,
+ u32 bus_token);
+ extern void of_msi_configure(struct device *dev, struct device_node *np);
+-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
++u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
+ #else
+ static inline int of_irq_count(struct device_node *dev)
+ {
+@@ -93,10 +93,10 @@ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev
+ static inline void of_msi_configure(struct device *dev, struct device_node *np)
+ {
+ }
+-static inline u32 of_msi_map_rid(struct device *dev,
+- struct device_node *msi_np, u32 rid_in)
++static inline u32 of_msi_map_id(struct device *dev,
++ struct device_node *msi_np, u32 id_in)
+ {
+- return rid_in;
++ return id_in;
+ }
+ #endif
+
+--
+2.42.0
+
tg3-increment-tx_dropped-in-tg3_tso_bug.patch
kconfig-fix-memory-leak-from-range-properties.patch
drm-amdgpu-correct-chunk_ptr-to-a-pointer-to-chunk.patch
+of-base-add-of_get_cpu_state_node-to-get-idle-states.patch
+acpi-iort-make-iort_get_device_domain-irq-domain-agn.patch
+acpi-iort-make-iort_msi_map_rid-pci-agnostic.patch
+of-iommu-make-of_map_rid-pci-agnostic.patch
+of-irq-make-of_msi_map_get_device_domain-bus-agnosti.patch
+of-irq-make-of_msi_map_rid-pci-bus-agnostic.patch
+of-base-fix-some-formatting-issues-and-provide-missi.patch
+of-fix-kerneldoc-output-formatting.patch
+of-add-missing-return-section-in-kerneldoc-comments.patch
+of-dynamic-fix-of_reconfig_get_state_change-return-v.patch
+ipv6-fix-potential-null-deref-in-fib6_add.patch
+hv_netvsc-rndis_filter-needs-to-select-nls.patch
+net-arcnet-fix-reset-flag-handling.patch
+net-arcnet-com20020-fix-error-handling.patch
+arcnet-restoring-support-for-multiple-sohard-arcnet-.patch
+ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch
+net-hns-fix-fake-link-up-on-xge-port.patch
+netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch
+tcp-do-not-accept-ack-of-bytes-we-never-sent.patch
+bpf-sockmap-updating-the-sg-structure-should-also-up.patch
--- /dev/null
+From 6ed64c74adf1266ed9d54c2d0ec702181db3072d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 16:18:41 +0000
+Subject: tcp: do not accept ACK of bytes we never sent
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 3d501dd326fb1c73f1b8206d4c6e1d7b15c07e27 ]
+
+This patch is based on a detailed report and ideas from Yepeng Pan
+and Christian Rossow.
+
+ACK seq validation is currently following RFC 5961 5.2 guidelines:
+
+ The ACK value is considered acceptable only if
+ it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <=
+ SND.NXT). All incoming segments whose ACK value doesn't satisfy the
+ above condition MUST be discarded and an ACK sent back. It needs to
+ be noted that RFC 793 on page 72 (fifth check) says: "If the ACK is a
+ duplicate (SEG.ACK < SND.UNA), it can be ignored. If the ACK
+ acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an
+ ACK, drop the segment, and return". The "ignored" above implies that
+ the processing of the incoming data segment continues, which means
+ the ACK value is treated as acceptable. This mitigation makes the
+ ACK check more stringent since any ACK < SND.UNA wouldn't be
+ accepted, instead only ACKs that are in the range ((SND.UNA -
+ MAX.SND.WND) <= SEG.ACK <= SND.NXT) get through.
+
+This can be refined for new (and possibly spoofed) flows,
+by not accepting ACK for bytes that were never sent.
+
+This greatly improves TCP security at a little cost.
+
+I added a Fixes: tag to make sure this patch will reach stable trees,
+even if the 'blamed' patch was adhering to the RFC.
+
+tp->bytes_acked was added in linux-4.2
+
+Following packetdrill test (courtesy of Yepeng Pan) shows
+the issue at hand:
+
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
++0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
++0 bind(3, ..., ...) = 0
++0 listen(3, 1024) = 0
+
+// ---------------- Handshake ------------------- //
+
+// when window scale is set to 14 the window size can be extended to
+// 65535 * (2^14) = 1073725440. Linux would accept an ACK packet
+// with ack number in (Server_ISN+1-1073725440. Server_ISN+1)
+// ,though this ack number acknowledges some data never
+// sent by the server.
+
++0 < S 0:0(0) win 65535 <mss 1400,nop,wscale 14>
++0 > S. 0:0(0) ack 1 <...>
++0 < . 1:1(0) ack 1 win 65535
++0 accept(3, ..., ...) = 4
+
+// For the established connection, we send an ACK packet,
+// the ack packet uses ack number 1 - 1073725300 + 2^32,
+// where 2^32 is used to wrap around.
+// Note: we used 1073725300 instead of 1073725440 to avoid possible
+// edge cases.
+// 1 - 1073725300 + 2^32 = 3221241997
+
+// Oops, old kernels happily accept this packet.
++0 < . 1:1001(1000) ack 3221241997 win 65535
+
+// After the kernel fix the following will be replaced by a challenge ACK,
+// and prior malicious frame would be dropped.
++0 > . 1:1(0) ack 1001
+
+Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Yepeng Pan <yepeng.pan@cispa.de>
+Reported-by: Christian Rossow <rossow@cispa.de>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Link: https://lore.kernel.org/r/20231205161841.2702925-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index fe5ef114beba5..982fe464156a4 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -3657,8 +3657,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
+ * then we can probably ignore it.
+ */
+ if (before(ack, prior_snd_una)) {
++ u32 max_window;
++
++ /* do not accept ACK for bytes we never sent. */
++ max_window = min_t(u64, tp->max_window, tp->bytes_acked);
+ /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */
+- if (before(ack, prior_snd_una - tp->max_window)) {
++ if (before(ack, prior_snd_una - max_window)) {
+ if (!(flag & FLAG_NO_CHALLENGE_ACK))
+ tcp_send_challenge_ack(sk, skb);
+ return -1;
+--
+2.42.0
+