Commit 645c1386 authored by Rob Herring's avatar Rob Herring

of/address: Fix of_pci_range_parser_one translation of DMA addresses

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: default avatarNicolas Saenz Julienne <nsaenzjulienne@suse.de>
Reviewed-by: default avatarNicolas Saenz Julienne <nsaenzjulienne@suse.de>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 81db12ee
...@@ -243,6 +243,7 @@ static int parser_init(struct of_pci_range_parser *parser, ...@@ -243,6 +243,7 @@ static int parser_init(struct of_pci_range_parser *parser,
parser->node = node; parser->node = node;
parser->pna = of_n_addr_cells(node); parser->pna = of_n_addr_cells(node);
parser->np = parser->pna + na + ns; parser->np = parser->pna + na + ns;
parser->dma = !strcmp(name, "dma-ranges");
parser->range = of_get_property(node, name, &rlen); parser->range = of_get_property(node, name, &rlen);
if (parser->range == NULL) if (parser->range == NULL)
...@@ -281,7 +282,11 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, ...@@ -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->pci_space = be32_to_cpup(parser->range);
range->flags = of_bus_pci_get_flags(parser->range); range->flags = of_bus_pci_get_flags(parser->range);
range->pci_addr = of_read_number(parser->range + 1, ns); 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); parser->range + na);
range->size = of_read_number(parser->range + parser->pna + na, ns); 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, ...@@ -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); flags = of_bus_pci_get_flags(parser->range);
pci_addr = of_read_number(parser->range + 1, ns); pci_addr = of_read_number(parser->range + 1, ns);
cpu_addr = of_translate_address(parser->node, if (parser->dma)
parser->range + na); 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); size = of_read_number(parser->range + parser->pna + na, ns);
if (flags != range->flags) if (flags != range->flags)
......
...@@ -12,6 +12,7 @@ struct of_pci_range_parser { ...@@ -12,6 +12,7 @@ struct of_pci_range_parser {
const __be32 *end; const __be32 *end;
int np; int np;
int pna; int pna;
bool dma;
}; };
struct of_pci_range { struct of_pci_range {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment