of/address: Fix of_pci_range_parser_one translation of DMA addresses
authorRob Herring <robh@kernel.org>
Thu, 5 Sep 2019 09:47:26 +0000 (10:47 +0100)
committerRob Herring <robh@kernel.org>
Tue, 8 Oct 2019 18:55:26 +0000 (13:55 -0500)
of_pci_range_parser_one() has a bug when parsing dma-ranges. When it
translates the parent address (aka cpu address in the code), 'ranges' is
always being used. This happens to work because most users are just 1:1
translation.

Cc: Robin Murphy <robin.murphy@arm.com>
Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Signed-off-by: Rob Herring <robh@kernel.org>
drivers/of/address.c
include/linux/of_address.h

index 1c291bd..5ce69d0 100644 (file)
@@ -243,6 +243,7 @@ static int parser_init(struct of_pci_range_parser *parser,
        parser->node = node;
        parser->pna = of_n_addr_cells(node);
        parser->np = parser->pna + na + ns;
+       parser->dma = !strcmp(name, "dma-ranges");
 
        parser->range = of_get_property(node, name, &rlen);
        if (parser->range == NULL)
@@ -281,7 +282,11 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
        range->pci_space = be32_to_cpup(parser->range);
        range->flags = of_bus_pci_get_flags(parser->range);
        range->pci_addr = of_read_number(parser->range + 1, ns);
-       range->cpu_addr = of_translate_address(parser->node,
+       if (parser->dma)
+               range->cpu_addr = of_translate_dma_address(parser->node,
+                               parser->range + na);
+       else
+               range->cpu_addr = of_translate_address(parser->node,
                                parser->range + na);
        range->size = of_read_number(parser->range + parser->pna + na, ns);
 
@@ -294,8 +299,12 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 
                flags = of_bus_pci_get_flags(parser->range);
                pci_addr = of_read_number(parser->range + 1, ns);
-               cpu_addr = of_translate_address(parser->node,
-                               parser->range + na);
+               if (parser->dma)
+                       cpu_addr = of_translate_dma_address(parser->node,
+                                       parser->range + na);
+               else
+                       cpu_addr = of_translate_address(parser->node,
+                                       parser->range + na);
                size = of_read_number(parser->range + parser->pna + na, ns);
 
                if (flags != range->flags)
index ddda393..eac7ab1 100644 (file)
@@ -12,6 +12,7 @@ struct of_pci_range_parser {
        const __be32 *end;
        int np;
        int pna;
+       bool dma;
 };
 
 struct of_pci_range {