Add functions to access addresses in the device tree. These are brought
in from Linux 4.10.
Also fix up the header guard for fdtaddr.h to avoid confusion.
Signed-off-by: Simon Glass
---
Changes in v3:
- Fix up the fdtaddr.h header guard to avoid conflicts
Changes in v2: None
drivers/core/Makefile | 2 +-
drivers/core/of_addr.c | 359 +
include/dm/fdtaddr.h | 4 +-
include/dm/of_addr.h | 64 +
4 files changed, 426 insertions(+), 3 deletions(-)
create mode 100644 drivers/core/of_addr.c
create mode 100644 include/dm/of_addr.h
diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index c25288e464..1c6795af13 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -11,5 +11,5 @@ obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o
obj-$(CONFIG_DM) += dump.o
obj-$(CONFIG_$(SPL_)REGMAP)+= regmap.o
obj-$(CONFIG_$(SPL_)SYSCON)+= syscon-uclass.o
-obj-$(CONFIG_OF_LIVE) += of_access.o
+obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
obj-$(CONFIG_OF_CONTROL) += ofnode.o
diff --git a/drivers/core/of_addr.c b/drivers/core/of_addr.c
new file mode 100644
index 00..4757066967
--- /dev/null
+++ b/drivers/core/of_addr.c
@@ -0,0 +1,359 @@
+/*
+ * Taken from Linux v4.9 drivers/of/address.c
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS 4
+#define OF_CHECK_ADDR_COUNT(na)((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+#define OF_CHECK_COUNTS(na, ns)(OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
+{
+ debug("%s", s);
+ while (na--)
+ pr_cont(" %08x", be32_to_cpu(*(addr++)));
+ pr_cont("\n");
+}
+#else
+static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+ const char *name;
+ const char *addresses;
+ int (*match)(struct device_node *parent);
+ void (*count_cells)(const struct device_node *child, int *addrc,
+ int *sizec);
+ u64 (*map)(__be32 *addr, const __be32 *range, int na, int ns, int pna);
+ int (*translate)(__be32 *addr, u64 offset, int na);
+ unsigned int (*get_flags)(const __be32 *addr);
+};
+
+static void of_bus_default_count_cells(const struct device_node *np,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(np);
+ if (sizec)
+ *sizec = of_n_size_cells(np);
+}
+
+static u64 of_bus_default_map(__be32 *addr, const __be32 *range,
+ int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = of_read_number(range, na);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr, na);
+
+ debug("default map, cp=%llx, s=%llx, da=%llx\n",
+ (unsigned long long)cp, (unsigned long long)s,
+ (unsigned long long)da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_default_translate(__be32 *addr, u64 offset, int na)
+{
+ u64 a = of_read_number(addr, na);
+ memset(addr, 0, na * 4);
+ a += offset;
+ if (na > 1)
+ addr[na - 2] = cpu_to_be32(a >> 32);
+ addr[na - 1] = cpu_to_be32(a & 0xu);
+
+ return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const __be32 *addr)
+{
+ return IORESOURCE_MEM;
+}
+
+/*
+ * Array of bus-specific translators
+ */
+static struct of_bus of_busses[] = {
+ /* Default */
+ {
+ .name = "default",
+ .addresses = "reg",
+ .match = NULL,
+ .count_cells = of_bus_default_count_cells,
+ .map = of_bus_default_map,
+ .translate = of_bus_default_translate,
+ .get_flags = of_bus_default_get_flags,
+ },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+ if (!of_busses[i].match || of_busses[i].match(np))
+ return _busses[i];
+ BUG();
+ return NULL;
+}
+
+static void dev_count_cells(const struct device_node *np, int *nap, int *nsp)
+{
+ of_bus_default_count_cells(np, nap, nsp);
+}
+
+const __be32 *of_get_address(const struct device_node *dev, int index,
+u64 *size, unsigned int *flags)
+{
+ const __be32 *prop;
+ int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /*