Commit 73ae3088 authored by Rob Herring's avatar Rob Herring

of: address: Consolidate bus .map() functions

The bus .map() functions vary only by checking the flag cells values
and skipping over any flag cells to read the addresses. Otherwise they
all do the same reading 'ranges' address and size and returning the
address's offset if it is within the 'ranges' entry.

Refactor all the .map() functions to pass in the flag cell size so that
each bus can check the bus specific flags and then call a common
function to do everything else.
Acked-by: default avatarHerve Codina <herve.codina@bootlin.com>
Link: https://lore.kernel.org/r/20231026135358.3564307-3-robh@kernel.orgSigned-off-by: default avatarRob Herring <robh@kernel.org>
parent 88696db0
...@@ -43,7 +43,7 @@ struct of_bus { ...@@ -43,7 +43,7 @@ struct of_bus {
void (*count_cells)(struct device_node *child, void (*count_cells)(struct device_node *child,
int *addrc, int *sizec); int *addrc, int *sizec);
u64 (*map)(__be32 *addr, const __be32 *range, u64 (*map)(__be32 *addr, const __be32 *range,
int na, int ns, int pna); int na, int ns, int pna, int fna);
int (*translate)(__be32 *addr, u64 offset, int na); int (*translate)(__be32 *addr, u64 offset, int na);
int flag_cells; int flag_cells;
unsigned int (*get_flags)(const __be32 *addr); unsigned int (*get_flags)(const __be32 *addr);
...@@ -63,13 +63,13 @@ static void of_bus_default_count_cells(struct device_node *dev, ...@@ -63,13 +63,13 @@ static void of_bus_default_count_cells(struct device_node *dev,
} }
static u64 of_bus_default_map(__be32 *addr, const __be32 *range, static u64 of_bus_default_map(__be32 *addr, const __be32 *range,
int na, int ns, int pna) int na, int ns, int pna, int fna)
{ {
u64 cp, s, da; u64 cp, s, da;
cp = of_read_number(range, na); cp = of_read_number(range + fna, na - fna);
s = of_read_number(range + na + pna, ns); s = of_read_number(range + na + pna, ns);
da = of_read_number(addr, na); da = of_read_number(addr + fna, na - fna);
pr_debug("default map, cp=%llx, s=%llx, da=%llx\n", cp, s, da); pr_debug("default map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
...@@ -101,24 +101,13 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr) ...@@ -101,24 +101,13 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
} }
static u64 of_bus_default_flags_map(__be32 *addr, const __be32 *range, int na, static u64 of_bus_default_flags_map(__be32 *addr, const __be32 *range, int na,
int ns, int pna) int ns, int pna, int fna)
{ {
u64 cp, s, da;
/* Check that flags match */ /* Check that flags match */
if (*addr != *range) if (*addr != *range)
return OF_BAD_ADDR; return OF_BAD_ADDR;
/* Read address values, skipping high cell */ return of_bus_default_map(addr, range, na, ns, pna, fna);
cp = of_read_number(range + 1, na - 1);
s = of_read_number(range + na + pna, ns);
da = of_read_number(addr + 1, na - 1);
pr_debug("default flags map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
return da - cp;
} }
static int of_bus_default_flags_translate(__be32 *addr, u64 offset, int na) static int of_bus_default_flags_translate(__be32 *addr, u64 offset, int na)
...@@ -192,9 +181,8 @@ static void of_bus_pci_count_cells(struct device_node *np, ...@@ -192,9 +181,8 @@ static void of_bus_pci_count_cells(struct device_node *np,
} }
static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns,
int pna) int pna, int fna)
{ {
u64 cp, s, da;
unsigned int af, rf; unsigned int af, rf;
af = of_bus_pci_get_flags(addr); af = of_bus_pci_get_flags(addr);
...@@ -204,16 +192,7 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, ...@@ -204,16 +192,7 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns,
if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO)) if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
return OF_BAD_ADDR; return OF_BAD_ADDR;
/* Read address values, skipping high cell */ return of_bus_default_map(addr, range, na, ns, pna, fna);
cp = of_read_number(range + 1, na - 1);
s = of_read_number(range + na + pna, ns);
da = of_read_number(addr + 1, na - 1);
pr_debug("PCI map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
return da - cp;
} }
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
...@@ -319,24 +298,13 @@ static void of_bus_isa_count_cells(struct device_node *child, ...@@ -319,24 +298,13 @@ static void of_bus_isa_count_cells(struct device_node *child,
} }
static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns, static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns,
int pna) int pna, int fna)
{ {
u64 cp, s, da;
/* Check address type match */ /* Check address type match */
if ((addr[0] ^ range[0]) & cpu_to_be32(1)) if ((addr[0] ^ range[0]) & cpu_to_be32(1))
return OF_BAD_ADDR; return OF_BAD_ADDR;
/* Read address values, skipping high cell */ return of_bus_default_map(addr, range, na, ns, pna, fna);
cp = of_read_number(range + 1, na - 1);
s = of_read_number(range + na + pna, ns);
da = of_read_number(addr + 1, na - 1);
pr_debug("ISA map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
return da - cp;
} }
static unsigned int of_bus_isa_get_flags(const __be32 *addr) static unsigned int of_bus_isa_get_flags(const __be32 *addr)
...@@ -486,7 +454,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, ...@@ -486,7 +454,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
rlen /= 4; rlen /= 4;
rone = na + pna + ns; rone = na + pna + ns;
for (; rlen >= rone; rlen -= rone, ranges += rone) { for (; rlen >= rone; rlen -= rone, ranges += rone) {
offset = bus->map(addr, ranges, na, ns, pna); offset = bus->map(addr, ranges, na, ns, pna, bus->flag_cells);
if (offset != OF_BAD_ADDR) if (offset != OF_BAD_ADDR)
break; break;
} }
......
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