diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch | 107 |
1 files changed, 0 insertions, 107 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch deleted file mode 100644 index 1cac2dfcd8..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7631cb95056f03136c9e0a35484e8bebe7b52650 Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Wed, 3 Jul 2019 18:42:20 +0100 -Subject: [PATCH] of: Make of_dma_get_range() work on bus nodes - -commit 951d48855d86e72e0d6de73440fe09d363168064 upstream. - -Since the "dma-ranges" property is only valid for a node representing a -bus, of_dma_get_range() currently assumes the node passed in is a leaf -representing a device, and starts the walk from its parent. In cases -like PCI host controllers on typical FDT systems, however, where the PCI -endpoints are probed dynamically the initial leaf node represents the -'bus' itself, and this logic means we fail to consider any "dma-ranges" -describing the host bridge itself. Rework the logic such that -of_dma_get_range() also works correctly starting from a bus node -containing "dma-ranges". - -While this does mean "dma-ranges" could incorrectly be in a device leaf -node, there isn't really any way in this function to ensure that a leaf -node is or isn't a bus node. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -[robh: Allow for the bus child node to still be passed in] -Signed-off-by: Rob Herring <robh@kernel.org> -Reviewed-by: Robin Murphy <robin.murphy@arm.com> -Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> -Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> ---- - drivers/of/address.c | 44 ++++++++++++++++++-------------------------- - 1 file changed, 18 insertions(+), 26 deletions(-) - ---- a/drivers/of/address.c -+++ b/drivers/of/address.c -@@ -940,47 +940,39 @@ int of_dma_get_range(struct device_node - const __be32 *ranges = NULL; - int len, naddr, nsize, pna; - int ret = 0; -+ bool found_dma_ranges = false; - u64 dmaaddr; - -- if (!node) -- return -EINVAL; -- -- while (1) { -- struct device_node *parent; -- -- naddr = of_n_addr_cells(node); -- nsize = of_n_size_cells(node); -- -- parent = __of_get_dma_parent(node); -- of_node_put(node); -- -- node = parent; -- if (!node) -- break; -- -+ while (node) { - ranges = of_get_property(node, "dma-ranges", &len); - - /* Ignore empty ranges, they imply no translation required */ - if (ranges && len > 0) - break; - -- /* -- * At least empty ranges has to be defined for parent node if -- * DMA is supported -- */ -- if (!ranges) -- break; -+ /* Once we find 'dma-ranges', then a missing one is an error */ -+ if (found_dma_ranges && !ranges) { -+ ret = -ENODEV; -+ goto out; -+ } -+ found_dma_ranges = true; -+ -+ node = of_get_next_dma_parent(node); - } - -- if (!ranges) { -+ if (!node || !ranges) { - pr_debug("no dma-ranges found for node(%pOF)\n", np); - ret = -ENODEV; - goto out; - } - -- len /= sizeof(u32); -- -+ naddr = of_bus_n_addr_cells(node); -+ nsize = of_bus_n_size_cells(node); - pna = of_n_addr_cells(node); -+ if ((len / sizeof(__be32)) % (pna + naddr + nsize)) { -+ ret = -EINVAL; -+ goto out; -+ } - - /* dma-ranges format: - * DMA addr : naddr cells -@@ -988,7 +980,7 @@ int of_dma_get_range(struct device_node - * size : nsize cells - */ - dmaaddr = of_read_number(ranges, naddr); -- *paddr = of_translate_dma_address(np, ranges); -+ *paddr = of_translate_dma_address(node, ranges + naddr); - if (*paddr == OF_BAD_ADDR) { - pr_err("translation of DMA address(%pad) to CPU address failed node(%pOF)\n", - dma_addr, np); |