* [PATCH 0/9] OF: address and device related sync and cleanup
@ 2013-06-25 9:20 Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 1/9] OF: import address related functions from Linux OF API Sebastian Hesselbarth
` (20 more replies)
0 siblings, 21 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This patch set comprises a quite unsorted bunch of patches to further
improve and cleanup OF API. With address and device related functions,
two more API sets of Linux OF API are imported and modified to match
barebox driver core.
With above API improvements, device and resource pointer are removed
from struct device_node. Futher, of_translate_address, of_probe, and
of_add_memory are converted to recently introduced OF API.
At last, of_free is renamed to of_delete_node, which gives a better
impression of what the function is doing.
Sebastian Hesselbarth (9):
OF: import address related functions from Linux OF API
OF: convert of_translate_address to new API
OF: base: move OF_ROOT_NODE_ defines to local OF code
OF: import bus/device related functions from Linux OF API
OF: base: use of_platform_populate for probing
OF: base: remove dead device related functions
OF: remove device and resource pointer from struct device_node
OF: base: convert of_add_memory to OF API
OF: base: rename of_free to of_delete_node
commands/of_node.c | 2 +-
commands/oftree.c | 4 +-
drivers/of/Makefile | 2 +-
drivers/of/address.c | 437 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/of/base.c | 339 +++++---------------------------------
drivers/of/fdt.c | 2 +-
drivers/of/gpio.c | 6 +-
drivers/of/platform.c | 294 +++++++++++++++++++++++++++++++++
include/of.h | 30 +++-
include/of_address.h | 72 ++++++++
10 files changed, 879 insertions(+), 309 deletions(-)
create mode 100644 drivers/of/address.c
create mode 100644 drivers/of/platform.c
create mode 100644 include/of_address.h
---
Cc: barebox@lists.infradead.org
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 1/9] OF: import address related functions from Linux OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 2/9] OF: convert of_translate_address to new API Sebastian Hesselbarth
` (19 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This imports drivers/of/address.c from Linux with some minor modifications.
of_translate_address is not yet enabled and PCI and ISA related bus translations
have not been imported. Also, a corresponding include header is created with
prototypes and non-OF function stubs.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/Makefile | 2 +-
drivers/of/address.c | 431 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/of_address.h | 64 ++++++++
3 files changed, 496 insertions(+), 1 deletions(-)
create mode 100644 drivers/of/address.c
create mode 100644 include/of_address.h
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index c81bbec..b8add0b 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,4 @@
-obj-y += base.o fdt.o
+obj-y += address.o base.o fdt.o
obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-y += partition.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
new file mode 100644
index 0000000..3e5387a
--- /dev/null
+++ b/drivers/of/address.c
@@ -0,0 +1,431 @@
+/*
+ * address.c - address related devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <of.h>
+#include <of_address.h>
+
+/* 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)
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
+{
+ printk(KERN_DEBUG "%s", s);
+ while (na--)
+ printk(" %08x", be32_to_cpu(*(addr++)));
+ printk("\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)(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);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(dev);
+ if (sizec)
+ *sizec = of_n_size_cells(dev);
+}
+
+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);
+
+ pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
+ (unsigned long long)cp, (unsigned long long)s,
+ (unsigned long long)da);
+
+ /*
+ * If the number of address cells is larger than 2 we assume the
+ * mapping doesn't specify a physical address. Rather, the address
+ * specifies an identifier that must match exactly.
+ */
+ if (na > 2 && memcmp(range, addr, na * 4) != 0)
+ return OF_BAD_ADDR;
+
+ 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 & 0xffffffffu);
+
+ 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 &of_busses[i];
+ BUG();
+ return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+ struct of_bus *pbus, __be32 *addr,
+ int na, int ns, int pna, const char *rprop)
+{
+ const __be32 *ranges;
+ unsigned int rlen;
+ int rone;
+ u64 offset = OF_BAD_ADDR;
+
+ /* Normally, an absence of a "ranges" property means we are
+ * crossing a non-translatable boundary, and thus the addresses
+ * below the current not cannot be converted to CPU physical ones.
+ * Unfortunately, while this is very clear in the spec, it's not
+ * what Apple understood, and they do have things like /uni-n or
+ * /ht nodes with no "ranges" property and a lot of perfectly
+ * useable mapped devices below them. Thus we treat the absence of
+ * "ranges" as equivalent to an empty "ranges" property which means
+ * a 1:1 translation at that level. It's up to the caller not to try
+ * to translate addresses that aren't supposed to be translated in
+ * the first place. --BenH.
+ *
+ * As far as we know, this damage only exists on Apple machines, so
+ * This code is only enabled on powerpc. --gcl
+ */
+ ranges = of_get_property(parent, rprop, &rlen);
+#if !defined(CONFIG_PPC)
+ if (ranges == NULL) {
+ pr_err("OF: no ranges; cannot translate\n");
+ return 1;
+ }
+#endif /* !defined(CONFIG_PPC) */
+ if (ranges == NULL || rlen == 0) {
+ offset = of_read_number(addr, na);
+ memset(addr, 0, pna * 4);
+ pr_debug("OF: empty ranges; 1:1 translation\n");
+ goto finish;
+ }
+
+ pr_debug("OF: walking ranges...\n");
+
+ /* Now walk through the ranges */
+ rlen /= 4;
+ rone = na + pna + ns;
+ for (; rlen >= rone; rlen -= rone, ranges += rone) {
+ offset = bus->map(addr, ranges, na, ns, pna);
+ if (offset != OF_BAD_ADDR)
+ break;
+ }
+ if (offset == OF_BAD_ADDR) {
+ pr_debug("OF: not found !\n");
+ return 1;
+ }
+ memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+ of_dump_addr("OF: parent translation for:", addr, pna);
+ pr_debug("OF: with offset: %llx\n", (unsigned long long)offset);
+
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+static u64 __of_translate_address(struct device_node *dev,
+ const __be32 *in_addr, const char *rprop)
+{
+ struct device_node *parent = NULL;
+ struct of_bus *bus, *pbus;
+ __be32 addr[OF_MAX_ADDR_CELLS];
+ int na, ns, pna, pns;
+ u64 result = OF_BAD_ADDR;
+
+ pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return OF_BAD_ADDR;
+ bus = of_match_bus(parent);
+
+ /* Count address cells & copy address locally */
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_COUNTS(na, ns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ return OF_BAD_ADDR;
+ }
+ memcpy(addr, in_addr, na * 4);
+
+ pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+ bus->name, na, ns, parent->full_name);
+ of_dump_addr("OF: translating address:", addr, na);
+
+ /* Translate */
+ for (;;) {
+ /* Switch to parent bus */
+ dev = parent;
+ parent = of_get_parent(dev);
+
+ /* If root, we have finished */
+ if (parent == NULL) {
+ pr_debug("OF: reached root node\n");
+ result = of_read_number(addr, na);
+ break;
+ }
+
+ /* Get new parent bus and counts */
+ pbus = of_match_bus(parent);
+ pbus->count_cells(dev, &pna, &pns);
+ if (!OF_CHECK_COUNTS(pna, pns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ break;
+ }
+
+ pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+ pbus->name, pna, pns, parent->full_name);
+
+ /* Apply bus translation */
+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+ break;
+
+ /* Complete the move up one level */
+ na = pna;
+ ns = pns;
+ bus = pbus;
+
+ of_dump_addr("OF: one level translation:", addr, na);
+ }
+
+ return result;
+}
+
+u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
+{
+ return __of_translate_address(dev, in_addr, "dma-ranges");
+}
+EXPORT_SYMBOL(of_translate_dma_address);
+
+bool of_can_translate_address(struct device_node *dev)
+{
+ struct device_node *parent;
+ struct of_bus *bus;
+ int na, ns;
+
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return false;
+
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+
+ return OF_CHECK_COUNTS(na, ns);
+}
+EXPORT_SYMBOL(of_can_translate_address);
+
+const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
+ unsigned int *flags)
+{
+ const __be32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_ADDR_COUNT(na))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, bus->addresses, &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if (i == index) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev,
+ const __be32 *addrp, u64 size, unsigned int flags,
+ const char *name, struct resource *r)
+{
+ u64 taddr;
+
+ if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+ return -EINVAL;
+ taddr = of_translate_address(dev, addrp);
+ if (taddr == OF_BAD_ADDR)
+ return -EINVAL;
+ memset(r, 0, sizeof(struct resource));
+ if (flags & IORESOURCE_IO) {
+ unsigned long port;
+ port = pci_address_to_pio(taddr);
+ if (port == (unsigned long)-1)
+ return -EINVAL;
+ r->start = port;
+ r->end = port + size - 1;
+ } else {
+ r->start = taddr;
+ r->end = taddr + size - 1;
+ }
+ r->flags = flags;
+ r->name = name ? name : dev->full_name;
+
+ return 0;
+}
+
+/**
+ * of_address_to_resource - Translate device tree address and return as resource
+ *
+ * Note that if your address is a PIO address, the conversion will fail if
+ * the physical address can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early or it
+ * can't be matched to any host bridge IO space
+ */
+int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ const __be32 *addrp;
+ u64 size;
+ unsigned int flags;
+ const char *name = NULL;
+
+ addrp = of_get_address(dev, index, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+
+ /* Get optional "reg-names" property to add a name to a resource */
+ of_property_read_string_index(dev, "reg-names", index, &name);
+
+ return __of_address_to_resource(dev, addrp, size, flags, name, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+struct device_node *of_find_matching_node_by_address(struct device_node *from,
+ const struct of_device_id *matches,
+ u64 base_address)
+{
+ struct device_node *dn = of_find_matching_node(from, matches);
+ struct resource res;
+
+ while (dn) {
+ if (of_address_to_resource(dn, 0, &res))
+ continue;
+ if (res.start == base_address)
+ return dn;
+ dn = of_find_matching_node(dn, matches);
+ }
+
+ return NULL;
+}
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return IOMEM(res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/include/of_address.h b/include/of_address.h
new file mode 100644
index 0000000..a82e2e5
--- /dev/null
+++ b/include/of_address.h
@@ -0,0 +1,64 @@
+#ifndef __OF_ADDRESS_H
+#define __OF_ADDRESS_H
+
+#include <common.h>
+#include <of.h>
+
+#ifndef pci_address_to_pio
+static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
+#endif
+
+#ifdef CONFIG_OFTREE
+
+extern u64 of_translate_dma_address(struct device_node *dev,
+ const __be32 *in_addr);
+extern bool of_can_translate_address(struct device_node *dev);
+extern const __be32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags);
+extern int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+extern struct device_node *of_find_matching_node_by_address(
+ struct device_node *from, const struct of_device_id *matches,
+ u64 base_address);
+extern void __iomem *of_iomap(struct device_node *np, int index);
+
+#else /* CONFIG_OFTREE */
+
+static inline u64 of_translate_dma_address(struct device_node *dev,
+ const __be32 *in_addr)
+{
+ return OF_BAD_ADDR;
+}
+
+static inline bool of_can_translate_address(struct device_node *dev)
+{
+ return false;
+}
+
+static inline const __be32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags)
+{
+ return 0;
+}
+
+static inline int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ return -ENOSYS;
+}
+
+static inline struct device_node *of_find_matching_node_by_address(
+ struct device_node *from, const struct of_device_id *matches,
+ u64 base_address)
+{
+ return NULL;
+}
+
+static inline void __iomem *of_iomap(struct device_node *np, int index)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_OFTREE */
+
+#endif /* __OF_ADDRESS_H */
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 2/9] OF: convert of_translate_address to new API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 1/9] OF: import address related functions from Linux OF API Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 3/9] OF: base: move OF_ROOT_NODE_ defines to local OF code Sebastian Hesselbarth
` (18 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This converts existing of_translate_address to recently added API. In
contrast to existing behavior, the new function honors ranges properties
properly. It now allows reg properties to be set as offset with respect
to the correspoding parent node.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/address.c | 6 ++++++
drivers/of/base.c | 26 +-------------------------
include/of.h | 2 --
include/of_address.h | 8 ++++++++
4 files changed, 15 insertions(+), 27 deletions(-)
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 3e5387a..4cacdb1 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -278,6 +278,12 @@ static u64 __of_translate_address(struct device_node *dev,
return result;
}
+u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
+{
+ return __of_translate_address(dev, in_addr, "ranges");
+}
+EXPORT_SYMBOL(of_translate_address);
+
u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
{
return __of_translate_address(dev, in_addr, "dma-ranges");
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 63ff647..2778230 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -19,6 +19,7 @@
*/
#include <common.h>
#include <of.h>
+#include <of_address.h>
#include <errno.h>
#include <malloc.h>
#include <init.h>
@@ -242,31 +243,6 @@ const char *of_alias_get(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_alias_get);
-u64 of_translate_address(struct device_node *node, const __be32 *in_addr)
-{
- struct property *p;
- u64 addr = be32_to_cpu(*in_addr);
-
- while (1) {
- int na, nc;
-
- if (!node->parent)
- return addr;
-
- node = node->parent;
- p = of_find_property(node, "ranges", NULL);
- if (!p && node->parent)
- return OF_BAD_ADDR;
- of_bus_count_cells(node, &na, &nc);
- if (na != 1 || nc != 1) {
- printk("%s: #size-cells != 1 or #address-cells != 1 "
- "currently not supported\n", node->name);
- return OF_BAD_ADDR;
- }
- }
-}
-EXPORT_SYMBOL(of_translate_address);
-
/*
* of_find_node_by_phandle - Find a node given a phandle
* @handle: phandle of the node to find
diff --git a/include/of.h b/include/of.h
index b392ca9..e091326 100644
--- a/include/of.h
+++ b/include/of.h
@@ -101,8 +101,6 @@ int of_get_named_gpio(struct device_node *np,
void of_print_property(const void *data, int len);
void of_print_cmdline(struct device_node *root);
-u64 of_translate_address(struct device_node *node, const __be32 *in_addr);
-
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
diff --git a/include/of_address.h b/include/of_address.h
index a82e2e5..9022ab7 100644
--- a/include/of_address.h
+++ b/include/of_address.h
@@ -10,6 +10,8 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
#ifdef CONFIG_OFTREE
+extern u64 of_translate_address(struct device_node *dev,
+ const __be32 *in_addr);
extern u64 of_translate_dma_address(struct device_node *dev,
const __be32 *in_addr);
extern bool of_can_translate_address(struct device_node *dev);
@@ -24,6 +26,12 @@ extern void __iomem *of_iomap(struct device_node *np, int index);
#else /* CONFIG_OFTREE */
+static inline u64 of_translate_address(struct device_node *dev,
+ const __be32 *in_addr)
+{
+ return OF_BAD_ADDR;
+}
+
static inline u64 of_translate_dma_address(struct device_node *dev,
const __be32 *in_addr)
{
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 3/9] OF: base: move OF_ROOT_NODE_ defines to local OF code
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 1/9] OF: import address related functions from Linux OF API Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 2/9] OF: convert of_translate_address to new API Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 4/9] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
` (17 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
OF_ROOT_NODE_* defines should not be used outside of base.c. Move them
to drivers/of/base.c to ensure they will not be used elsewhere.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 3 +++
include/of.h | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 2778230..429f924 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -64,6 +64,9 @@ struct device_node *root_node;
struct device_node *of_aliases;
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+
int of_n_addr_cells(struct device_node *np)
{
const __be32 *ip;
diff --git a/include/of.h b/include/of.h
index e091326..8cab797 100644
--- a/include/of.h
+++ b/include/of.h
@@ -101,9 +101,6 @@ int of_get_named_gpio(struct device_node *np,
void of_print_property(const void *data, int len);
void of_print_cmdline(struct device_node *root);
-#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
-#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
-
void of_print_nodes(struct device_node *node, int indent);
int of_probe(void);
int of_parse_dtb(struct fdt_header *fdt);
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 4/9] OF: import bus/device related functions from Linux OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (2 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 3/9] OF: base: move OF_ROOT_NODE_ defines to local OF code Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-25 12:55 ` Sebastian Hesselbarth
` (2 more replies)
2013-06-25 9:20 ` [PATCH 5/9] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
` (16 subsequent siblings)
20 siblings, 3 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This imports some bus and device related functions from Linux OF API
with some modifcations for Barebox.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/Makefile | 2 +-
drivers/of/platform.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++
include/of.h | 18 +++
3 files changed, 313 insertions(+), 1 deletions(-)
create mode 100644 drivers/of/platform.c
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b8add0b..186074e 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,4 @@
-obj-y += address.o base.o fdt.o
+obj-y += address.o base.o fdt.o platform.o
obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-y += partition.o
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
new file mode 100644
index 0000000..450d770
--- /dev/null
+++ b/drivers/of/platform.c
@@ -0,0 +1,294 @@
+/*
+ * platform.c - bus/device related devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <malloc.h>
+#include <of.h>
+#include <of_address.h>
+#include <linux/amba/bus.h>
+
+/**
+ * of_find_device_by_node - Find the platform_device associated with a node
+ * @np: Pointer to device tree node
+ *
+ * Returns platform_device pointer, or NULL if not found
+ */
+struct device_d *of_find_device_by_node(struct device_node *np)
+{
+ struct device_d *dev;
+
+ for_each_device(dev)
+ if (dev->device_node == np)
+ return dev;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+/**
+ * of_device_make_bus_id - Use the device node data to assign a unique name
+ * @dev: pointer to device structure that is linked to a device tree node
+ *
+ * This routine will first try using either the dcr-reg or the reg property
+ * value to derive a unique name. As a last resort it will use the node
+ * name followed by a unique number.
+ */
+static void of_device_make_bus_id(struct device_d *dev)
+{
+ static int bus_no_reg_magic;
+ struct device_node *np = dev->device_node;
+ const __be32 *reg, *addrp;
+ u64 addr;
+ char *name, *at;
+
+ name = xstrdup(np->name);
+ at = strchr(name, '@');
+ if (at)
+ *at = '\0';
+
+#ifdef CONFIG_PPC_DCR
+ /*
+ * If it's a DCR based device, use 'd' for native DCRs
+ * and 'D' for MMIO DCRs.
+ */
+ reg = of_get_property(np, "dcr-reg", NULL);
+ if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+ snprintf(dev->name, MAX_DRIVER_NAME, "d%x.%s", *reg, name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+ u64 addr = of_translate_dcr_address(np, *reg, NULL);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(dev->name, MAX_DRIVER_NAME, "D%llx.%s",
+ (unsigned long long)addr, name);
+ free(name);
+ return;
+ }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+ }
+#endif /* CONFIG_PPC_DCR */
+
+ /*
+ * For MMIO, get the physical address
+ */
+ reg = of_get_property(np, "reg", NULL);
+ if (reg) {
+ if (of_can_translate_address(np)) {
+ addr = of_translate_address(np, reg);
+ } else {
+ addrp = of_get_address(np, 0, NULL, NULL);
+ if (addrp)
+ addr = of_read_number(addrp, 1);
+ else
+ addr = OF_BAD_ADDR;
+ }
+ if (addr != OF_BAD_ADDR) {
+ snprintf(dev->name, MAX_DRIVER_NAME, "%llx.%s",
+ (unsigned long long)addr, name);
+ free(name);
+ return;
+ }
+ }
+
+ /*
+ * No BusID, use the node name and add a globally incremented counter
+ */
+ snprintf(dev->name, MAX_DRIVER_NAME, "%s.%d", name, bus_no_reg_magic++);
+ free(name);
+}
+
+/**
+ * of_platform_device_create - Alloc, initialize and register an of_device
+ * @np: pointer to node to create device for
+ * @parent: device model parent device.
+ *
+ * Returns pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+static struct device_d *of_platform_device_create(struct device_node *np,
+ struct device_d *parent)
+{
+ struct device_d *dev;
+ struct resource *res, temp_res;
+ int i, ret, num_reg = 0;
+
+ if (!of_device_is_available(np))
+ return NULL;
+
+ dev = xzalloc(sizeof(*dev));
+
+ /* setup generic device info */
+ dev->id = DEVICE_ID_SINGLE;
+ dev->device_node = np;
+ dev->parent = parent;
+ of_device_make_bus_id(dev);
+
+ /* count the io resources */
+ if (of_can_translate_address(np))
+ while (of_address_to_resource(np, num_reg, &temp_res) == 0)
+ num_reg++;
+
+ /* Populate the resource table */
+ if (num_reg) {
+ res = xzalloc(sizeof(*res) * num_reg);
+
+ dev->num_resources = num_reg;
+ dev->resource = res;
+ for (i = 0; i < num_reg; i++, res++) {
+ ret = of_address_to_resource(np, i, res);
+ if (ret)
+ goto err_free;
+ }
+ }
+
+ debug("register device 0x%08x\n", (num_reg) ? dev->resource[0].start : (-1));
+
+ ret = platform_device_register(dev);
+ if (ret)
+ goto err_free;
+
+ return dev;
+
+err_free:
+ free(dev);
+ return NULL;
+}
+
+#ifdef CONFIG_ARM_AMBA
+static struct device_d *of_amba_device_create(struct device_node *np)
+{
+ struct amba_device *dev;
+ int ret;
+
+ debug("Creating amba device %s\n", np->full_name);
+
+ if (!of_device_is_available(np))
+ return NULL;
+
+ dev = xzalloc(sizeof(*dev));
+
+ /* setup generic device info */
+ dev->dev.id = DEVICE_ID_SINGLE;
+ dev->dev.device_node = np;
+ of_device_make_bus_id(&dev->dev);
+
+ ret = of_address_to_resource(np, 0, &dev->res);
+ if (ret)
+ goto amba_err_free;
+
+ dev->dev.resource = &dev->res;
+ dev->dev.num_resources = 1;
+
+ /* Allow the HW Peripheral ID to be overridden */
+ of_property_read_u32(np, "arm,primecell-periphid", &dev->periphid);
+
+ debug("register device 0x%08x\n", dev->dev.resource[0].start);
+
+ ret = amba_device_add(dev);
+ if (ret)
+ goto amba_err_free;
+
+ return &dev->dev;
+
+amba_err_free:
+ free(dev);
+ return NULL;
+}
+#else /* CONFIG_ARM_AMBA */
+static inline struct amba_device *of_amba_device_create(struct device_node *np)
+{
+ return NULL;
+}
+#endif /* CONFIG_ARM_AMBA */
+
+/**
+ * of_platform_bus_create() - Create a device for a node and its children.
+ * @bus: device node of the bus to instantiate
+ * @matches: match table for bus nodes
+ * @parent: parent for new device, or NULL for top level.
+ *
+ * Creates a platform_device for the provided device_node, and optionally
+ * recursively create devices for all the child nodes.
+ */
+static int of_platform_bus_create(struct device_node *bus,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ struct device_node *child;
+ struct device_d *dev;
+ int rc = 0;
+
+ /* Make sure it has a compatible property */
+ if (!of_get_property(bus, "compatible", NULL)) {
+ pr_debug("%s() - skipping %s, no compatible prop\n",
+ __func__, bus->full_name);
+ return 0;
+ }
+
+ if (of_device_is_compatible(bus, "arm,primecell")) {
+ of_amba_device_create(bus);
+ return 0;
+ }
+
+ dev = of_platform_device_create(bus, parent);
+ if (!dev || !of_match_node(matches, bus))
+ return 0;
+
+ for_each_child_of_node(bus, child) {
+ pr_debug(" create child: %s\n", child->full_name);
+ rc = of_platform_bus_create(child, matches, dev);
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+/**
+ * of_platform_populate() - Populate platform_devices from device tree data
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @lookup: auxdata table for matching id and platform_data with device nodes
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * This function walks the device tree given by @root node and creates devices
+ * from nodes. It requires all device nodes to have a 'compatible' property,
+ * and it is suitable for creating devices which are children of the root
+ * node.
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ struct device_node *child;
+ int rc = 0;
+
+ if (!root)
+ root = of_find_node_by_path("/");
+ if (!root)
+ return -EINVAL;
+
+ for_each_child_of_node(root, child) {
+ rc = of_platform_bus_create(child, matches, parent);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(of_platform_populate);
diff --git a/include/of.h b/include/of.h
index 8cab797..f1f555f 100644
--- a/include/of.h
+++ b/include/of.h
@@ -61,6 +61,7 @@ struct of_reserve_map *of_get_reserve_map(void);
void of_clean_reserve_map(void);
void fdt_add_reserve_map(void *fdt);
+struct device_d;
struct driver_d;
int of_fix_tree(struct device_node *);
@@ -221,6 +222,11 @@ extern int of_modalias_node(struct device_node *node, char *modalias, int len);
extern struct device_node *of_get_root_node(void);
extern int of_set_root_node(struct device_node *node);
+extern int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent);
+extern struct device_d *of_find_device_by_node(struct device_node *np);
+
int of_parse_partitions(struct cdev *cdev, struct device_node *node);
int of_device_is_stdout_path(struct device_d *dev);
const char *of_get_model(void);
@@ -547,6 +553,18 @@ static inline int of_modalias_node(struct device_node *node, char *modalias,
{
return -ENOSYS;
}
+
+static inline int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ return -ENOSYS;
+}
+
+static inline struct device_d *of_find_device_by_node(struct device_node *np)
+{
+ return NULL;
+}
#endif
#define for_each_node_by_name(dn, name) \
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 5/9] OF: base: use of_platform_populate for probing
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (3 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 4/9] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-29 14:22 ` Sascha Hauer
2013-06-25 9:20 ` [PATCH 6/9] OF: base: remove dead device related functions Sebastian Hesselbarth
` (15 subsequent siblings)
20 siblings, 1 reply; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
With recent bus/device related functions in OF API, we can now
convert to use of_platform_populate.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 429f924..eb9ac84 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1840,7 +1840,7 @@ const struct of_device_id of_default_bus_match_table[] = {
int of_probe(void)
{
- struct device_node *memory, *n;
+ struct device_node *memory;
if(!root_node)
return -ENODEV;
@@ -1854,8 +1854,7 @@ int of_probe(void)
if (memory)
of_add_memory(memory, false);
- list_for_each_entry(n, &root_node->children, parent_list)
- __of_probe(n, of_default_bus_match_table, NULL);
+ of_platform_populate(root_node, of_default_bus_match_table, NULL);
return 0;
}
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 6/9] OF: base: remove dead device related functions
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (4 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 5/9] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 7/9] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
` (14 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
With recent conversion to of_platfrom_populate_some functions are now
dead code and can be removed.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 183 -----------------------------------------------------
1 files changed, 0 insertions(+), 183 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index eb9ac84..9d63127 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1543,94 +1543,6 @@ int of_set_property(struct device_node *np, const char *name, const void *val, i
return 0;
}
-static struct device_d *add_of_amba_device(struct device_node *node)
-{
- struct amba_device *dev;
- char *name, *at;
-
- dev = xzalloc(sizeof(*dev));
-
- name = xstrdup(node->name);
- at = strchr(name, '@');
- if (at) {
- *at = 0;
- snprintf(dev->dev.name, MAX_DRIVER_NAME, "%s.%s", at + 1, name);
- } else {
- strncpy(dev->dev.name, node->name, MAX_DRIVER_NAME);
- }
-
- dev->dev.id = DEVICE_ID_SINGLE;
- memcpy(&dev->res, &node->resource[0], sizeof(struct resource));
- dev->dev.resource = node->resource;
- dev->dev.num_resources = 1;
- dev->dev.device_node = node;
- node->device = &dev->dev;
-
- of_property_read_u32(node, "arm,primecell-periphid", &dev->periphid);
-
- debug("register device 0x%08x\n", node->resource[0].start);
-
- amba_device_add(dev);
-
- free(name);
-
- return &dev->dev;
-}
-
-static struct device_d *add_of_platform_device(struct device_node *node,
- struct device_d *parent)
-{
- struct device_d *dev;
- char *name, *at;
-
- dev = xzalloc(sizeof(*dev));
-
- dev->parent = parent;
-
- name = xstrdup(node->name);
- at = strchr(name, '@');
- if (at) {
- *at = 0;
- snprintf(dev->name, MAX_DRIVER_NAME, "%s.%s", at + 1, name);
- } else {
- strncpy(dev->name, node->name, MAX_DRIVER_NAME);
- }
-
- dev->id = DEVICE_ID_SINGLE;
- dev->resource = node->resource;
- dev->num_resources = node->num_resource;
- dev->device_node = node;
- node->device = dev;
-
- debug("register device 0x%08x\n", node->resource[0].start);
-
- platform_device_register(dev);
-
- free(name);
-
- return dev;
-}
-
-static struct device_d *add_of_device(struct device_node *node,
- struct device_d *parent)
-{
- const struct property *cp;
-
- if (!of_device_is_available(node))
- return NULL;
-
- cp = of_get_property(node, "compatible", NULL);
- if (!cp)
- return NULL;
-
- if (IS_ENABLED(CONFIG_ARM_AMBA) &&
- of_device_is_compatible(node, "arm,primecell") == 1)
- return add_of_amba_device(node);
- else
- return add_of_platform_device(node, parent);
-}
-EXPORT_SYMBOL(add_of_device);
-
static u64 dt_mem_next_cell(int s, const __be32 **cellp)
{
const __be32 *p = *cellp;
@@ -1678,82 +1590,6 @@ int of_add_memory(struct device_node *node, bool dump)
return 0;
}
-static struct device_d *add_of_device_resource(struct device_node *node,
- struct device_d *parent)
-{
- u64 address = 0, size;
- struct resource *res, *resp;
- struct device_d *dev;
- const __be32 *endp, *reg;
- const char *resname;
- int na, nc, n_resources;
- int ret, len, index;
-
- reg = of_get_property(node, "reg", &len);
- if (!reg)
- return add_of_device(node, parent);
-
- of_bus_count_cells(node, &na, &nc);
-
- n_resources = (len / sizeof(__be32)) / (na + nc);
-
- res = resp = xzalloc(sizeof(*res) * n_resources);
-
- endp = reg + (len / sizeof(__be32));
-
- index = 0;
-
- while ((endp - reg) >= (na + nc)) {
- address = of_translate_address(node, reg);
- if (address == OF_BAD_ADDR) {
- ret = -EINVAL;
- goto err_free;
- }
-
- reg += na;
- size = dt_mem_next_cell(nc, ®);
-
- resp->start = address;
- resp->end = address + size - 1;
- resname = NULL;
- of_property_read_string_index(node, "reg-names", index, &resname);
- if (resname)
- resp->name = xstrdup(resname);
- resp->flags = IORESOURCE_MEM;
- resp++;
- index++;
- }
-
- /*
- * A device may already be registered as platform_device.
- * Instead of registering the same device again, just
- * add this node to the existing device.
- */
- for_each_device(dev) {
- if (!dev->resource)
- continue;
- if (dev->resource->start == res->start &&
- dev->resource->end == res->end) {
- debug("connecting %s to %s\n", node->name, dev_name(dev));
- node->device = dev;
- dev->device_node = node;
- node->resource = dev->resource;
- ret = 0;
- goto err_free;
- }
- }
-
- node->resource = res;
- node->num_resource = n_resources;
-
- return add_of_device(node, parent);
-
-err_free:
- free(res);
-
- return NULL;
-}
-
void of_free(struct device_node *node)
{
struct device_node *n, *nt;
@@ -1787,25 +1623,6 @@ void of_free(struct device_node *node)
of_set_root_node(NULL);
}
-static void __of_probe(struct device_node *node,
- const struct of_device_id *matches,
- struct device_d *parent)
-{
- struct device_node *n;
- struct device_d *dev;
-
- if (node->device)
- return;
-
- dev = add_of_device_resource(node, parent);
-
- if (!of_match_node(matches, node))
- return;
-
- list_for_each_entry(n, &node->children, parent_list)
- __of_probe(n, matches, dev);
-}
-
static void __of_parse_phandles(struct device_node *node)
{
struct device_node *n;
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 7/9] OF: remove device and resource pointer from struct device_node
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (5 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 6/9] OF: base: remove dead device related functions Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-29 14:28 ` Sascha Hauer
2013-06-25 9:20 ` [PATCH 8/9] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
` (13 subsequent siblings)
20 siblings, 1 reply; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
struct device_node has its own resources and a pointer to associated
device_d. With recent platform related OF code, we can convert the
only user of it and remove those pointers from struct device_node.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 8 ++++----
drivers/of/gpio.c | 6 +++++-
include/of.h | 3 ---
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 9d63127..0244281 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1594,6 +1594,7 @@ void of_free(struct device_node *node)
{
struct device_node *n, *nt;
struct property *p, *pt;
+ struct device_d *dev;
if (!node)
return;
@@ -1610,10 +1611,9 @@ void of_free(struct device_node *node)
list_del(&node->list);
}
- if (node->device)
- node->device->device_node = NULL;
- else
- free(node->resource);
+ dev = of_find_device_by_node(node);
+ if (dev)
+ dev->device_node = NULL;
free(node->name);
free(node->full_name);
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 41e91ec..7f6d99c 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -10,6 +10,10 @@ int of_get_named_gpio(struct device_node *np,
{
int ret;
struct of_phandle_args out_args;
+ struct device_d *dev = of_find_device_by_node(np);
+
+ if (!dev)
+ return -EINVAL;
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
index, &out_args);
@@ -18,7 +22,7 @@ int of_get_named_gpio(struct device_node *np,
return -EINVAL;
}
- ret = gpio_get_num(out_args.np->device, out_args.args[0]);
+ ret = gpio_get_num(dev, out_args.args[0]);
if (ret < 0)
return ret;
diff --git a/include/of.h b/include/of.h
index f1f555f..0298189 100644
--- a/include/of.h
+++ b/include/of.h
@@ -30,9 +30,6 @@ struct device_node {
struct list_head children;
struct list_head parent_list;
struct list_head list;
- struct resource *resource;
- int num_resource;
- struct device_d *device;
struct list_head phandles;
phandle phandle;
};
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 8/9] OF: base: convert of_add_memory to OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (6 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 7/9] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-25 19:48 ` Sascha Hauer
2013-06-26 8:43 ` [PATCH v2 " Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 9/9] OF: base: rename of_free to of_delete_node Sebastian Hesselbarth
` (12 subsequent siblings)
20 siblings, 2 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
Convert of_add_memory parsing to make use of of_address_to_resource
instead of parsing memory ranges itself. This makes some functions
dead code which are also removed.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 57 +++++++---------------------------------------------
1 files changed, 8 insertions(+), 49 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 0244281..6fc962d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -99,21 +99,6 @@ int of_n_size_cells(struct device_node *np)
}
EXPORT_SYMBOL(of_n_size_cells);
-static void of_bus_default_count_cells(struct device_node *dev,
- int *addrc, int *sizec)
-{
- if (addrc)
- *addrc = of_n_addr_cells(dev);
- if (sizec)
- *sizec = of_n_size_cells(dev);
-}
-
-static void of_bus_count_cells(struct device_node *dev,
- int *addrc, int *sizec)
-{
- of_bus_default_count_cells(dev, addrc, sizec);
-}
-
struct property *of_find_property(const struct device_node *np,
const char *name, int *lenp)
{
@@ -1543,48 +1528,22 @@ int of_set_property(struct device_node *np, const char *name, const void *val, i
return 0;
}
-static u64 dt_mem_next_cell(int s, const __be32 **cellp)
-{
- const __be32 *p = *cellp;
-
- *cellp = p + s;
- return of_read_number(p, s);
-}
-
int of_add_memory(struct device_node *node, bool dump)
{
- int na, nc;
- const __be32 *reg, *endp;
- int len, r = 0, ret;
const char *device_type;
+ struct resource res;
+ int n = 0, ret;
ret = of_property_read_string(node, "device_type", &device_type);
- if (ret)
+ if (ret || of_node_cmp(device_type, "memory"))
return -ENXIO;
- if (of_node_cmp(device_type, "memory"))
- return -ENXIO;
-
- of_bus_count_cells(node, &na, &nc);
-
- reg = of_get_property(node, "reg", &len);
- if (!reg)
- return -EINVAL;
-
- endp = reg + (len / sizeof(__be32));
-
- while ((endp - reg) >= (na + nc)) {
- u64 base, size;
-
- base = dt_mem_next_cell(na, ®);
- size = dt_mem_next_cell(nc, ®);
-
- if (size == 0)
+ while (of_address_to_resource(node, n, &res)) {
+ if (!resource_size(&res))
continue;
-
- of_add_memory_bank(node, dump, r, base, size);
-
- r++;
+ of_add_memory_bank(node, dump, n,
+ res.start, resource_size(&res));
+ n++;
}
return 0;
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 9/9] OF: base: rename of_free to of_delete_node
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (7 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 8/9] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
@ 2013-06-25 9:20 ` Sebastian Hesselbarth
2013-06-27 6:51 ` [PATCH 0/9] OF: address and device related sync and cleanup Sascha Hauer
` (11 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 9:20 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
of_free is misleading about the actual purpose of the function. There is
already a of_create_node counterpart, so rename of_free to of_create_node
and update all users accordingly.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
commands/of_node.c | 2 +-
commands/oftree.c | 4 +-
drivers/of/base.c | 65 +++++++++++++++++++++++++--------------------------
drivers/of/fdt.c | 2 +-
include/of.h | 4 +-
5 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/commands/of_node.c b/commands/of_node.c
index e60ef66..b1894b1 100644
--- a/commands/of_node.c
+++ b/commands/of_node.c
@@ -87,7 +87,7 @@ static int do_of_node(int argc, char *argv[])
return -ENOENT;
}
- of_free(node);
+ of_delete_node(node);
}
return 0;
diff --git a/commands/oftree.c b/commands/oftree.c
index 9149517..00e54dc 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -86,7 +86,7 @@ static int do_oftree(int argc, char *argv[])
struct device_node *root = of_get_root_node();
if (root)
- of_free(root);
+ of_delete_node(root);
return 0;
}
@@ -162,7 +162,7 @@ static int do_oftree(int argc, char *argv[])
goto out;
}
of_print_nodes(root, 0);
- of_free(root);
+ of_delete_node(root);
} else {
struct device_node *n = of_find_node_by_path(node);
if (!n) {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6fc962d..d077335 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1549,39 +1549,6 @@ int of_add_memory(struct device_node *node, bool dump)
return 0;
}
-void of_free(struct device_node *node)
-{
- struct device_node *n, *nt;
- struct property *p, *pt;
- struct device_d *dev;
-
- if (!node)
- return;
-
- list_for_each_entry_safe(p, pt, &node->properties, list)
- of_delete_property(p);
-
- list_for_each_entry_safe(n, nt, &node->children, parent_list) {
- of_free(n);
- }
-
- if (node->parent) {
- list_del(&node->parent_list);
- list_del(&node->list);
- }
-
- dev = of_find_device_by_node(node);
- if (dev)
- dev->device_node = NULL;
-
- free(node->name);
- free(node->full_name);
- free(node);
-
- if (node == root_node)
- of_set_root_node(NULL);
-}
-
static void __of_parse_phandles(struct device_node *node)
{
struct device_node *n;
@@ -1679,6 +1646,38 @@ out:
return dn;
}
+void of_delete_node(struct device_node *node)
+{
+ struct device_node *n, *nt;
+ struct property *p, *pt;
+ struct device_d *dev;
+
+ if (!node)
+ return;
+
+ list_for_each_entry_safe(p, pt, &node->properties, list)
+ of_delete_property(p);
+
+ list_for_each_entry_safe(n, nt, &node->children, parent_list)
+ of_delete_node(n);
+
+ if (node->parent) {
+ list_del(&node->parent_list);
+ list_del(&node->list);
+ }
+
+ dev = of_find_device_by_node(node);
+ if (dev)
+ dev->device_node = NULL;
+
+ free(node->name);
+ free(node->full_name);
+ free(node);
+
+ if (node == root_node)
+ of_set_root_node(NULL);
+}
+
int of_device_is_stdout_path(struct device_d *dev)
{
struct device_node *dn;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index afaa4e0..76d6bb1 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -211,7 +211,7 @@ struct device_node *of_unflatten_dtb(struct device_node *root, void *infdt)
}
}
err:
- of_free(root);
+ of_delete_node(root);
return ERR_PTR(ret);
}
diff --git a/include/of.h b/include/of.h
index 0298189..e832a78 100644
--- a/include/of.h
+++ b/include/of.h
@@ -142,7 +142,7 @@ extern struct device_node *of_new_node(struct device_node *parent,
const char *name);
extern struct device_node *of_create_node(struct device_node *root,
const char *path);
-extern void of_free(struct device_node *node);
+extern void of_delete_node(struct device_node *node);
extern int of_machine_is_compatible(const char *compat);
extern int of_device_is_compatible(const struct device_node *device,
@@ -511,7 +511,7 @@ static inline struct device_node *of_create_node(struct device_node *root,
return NULL;
}
-static inline void of_free(struct device_node *node)
+static inline void of_delete_node(struct device_node *node)
{
}
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 4/9] OF: import bus/device related functions from Linux OF API
2013-06-25 9:20 ` [PATCH 4/9] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
@ 2013-06-25 12:55 ` Sebastian Hesselbarth
2013-06-26 6:11 ` Sascha Hauer
2013-06-26 8:43 ` [PATCH v2 " Sebastian Hesselbarth
2 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 12:55 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On 06/25/13 11:20, Sebastian Hesselbarth wrote:
> This imports some bus and device related functions from Linux OF API
> with some modifcations for Barebox.
>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> ---
> Cc: barebox@lists.infradead.org
> ---
> drivers/of/Makefile | 2 +-
> drivers/of/platform.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++
> include/of.h | 18 +++
> 3 files changed, 313 insertions(+), 1 deletions(-)
> create mode 100644 drivers/of/platform.c
[...]
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> new file mode 100644
> index 0000000..450d770
> --- /dev/null
> +++ b/drivers/of/platform.c
> @@ -0,0 +1,294 @@
> +/*
> + * platform.c - bus/device related devicetree functions
> + *
> + * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> + *
> + * based on Linux devicetree support
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
[...]
> +/**
> + * of_platform_device_create - Alloc, initialize and register an of_device
> + * @np: pointer to node to create device for
> + * @parent: device model parent device.
> + *
> + * Returns pointer to created platform device, or NULL if a device was not
> + * registered. Unavailable devices will not get registered.
> + */
> +static struct device_d *of_platform_device_create(struct device_node *np,
> + struct device_d *parent)
> +{
> + struct device_d *dev;
> + struct resource *res, temp_res;
> + int i, ret, num_reg = 0;
> +
> + if (!of_device_is_available(np))
> + return NULL;
> +
> + dev = xzalloc(sizeof(*dev));
> +
> + /* setup generic device info */
> + dev->id = DEVICE_ID_SINGLE;
> + dev->device_node = np;
> + dev->parent = parent;
> + of_device_make_bus_id(dev);
> +
> + /* count the io resources */
> + if (of_can_translate_address(np))
> + while (of_address_to_resource(np, num_reg, &temp_res) == 0)
> + num_reg++;
> +
> + /* Populate the resource table */
> + if (num_reg) {
> + res = xzalloc(sizeof(*res) * num_reg);
> +
> + dev->num_resources = num_reg;
> + dev->resource = res;
> + for (i = 0; i < num_reg; i++, res++) {
> + ret = of_address_to_resource(np, i, res);
> + if (ret)
> + goto err_free;
> + }
> + }
> +
> + debug("register device 0x%08x\n", (num_reg) ? dev->resource[0].start : (-1));
> +
> + ret = platform_device_register(dev);
> + if (ret)
> + goto err_free;
> +
> + return dev;
> +
> +err_free:
> + free(dev);
> + return NULL;
> +}
of_platform_device_create is missing a check for already existing
devices. I have added a check that tries to match all mem resources
of the node with existing devices.
[...]
> +/**
> + * of_platform_populate() - Populate platform_devices from device tree data
> + * @root: parent of the first level to probe or NULL for the root of the tree
> + * @matches: match table, NULL to use the default
> + * @lookup: auxdata table for matching id and platform_data with device nodes
Removed the line above, as lookup auxdata is not used on barebox.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 8/9] OF: base: convert of_add_memory to OF API
2013-06-25 9:20 ` [PATCH 8/9] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
@ 2013-06-25 19:48 ` Sascha Hauer
2013-06-25 19:57 ` Sebastian Hesselbarth
2013-06-25 21:38 ` Sebastian Hesselbarth
2013-06-26 8:43 ` [PATCH v2 " Sebastian Hesselbarth
1 sibling, 2 replies; 41+ messages in thread
From: Sascha Hauer @ 2013-06-25 19:48 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Tue, Jun 25, 2013 at 11:20:46AM +0200, Sebastian Hesselbarth wrote:
> Convert of_add_memory parsing to make use of of_address_to_resource
> instead of parsing memory ranges itself. This makes some functions
> dead code which are also removed.
>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Haven't investigated further yet, but this one breaks my loco board
with:
mmu: Error: Can't request SDRAM region for ttb
prefetch abort
pc : [<00000004>] lr : [<7ff20563>]
sp : 8fffff30 ip : 7ff20563 fp : 8fff4000
r10: 8fff4000 r9 : 00000000 r8 : 000298ec
r7 : 20000000 r6 : 7ff43e74 r5 : 7ff37824 r4 : 7ff37824
r3 : 7ff205a1 r2 : 00000000 r1 : ffffffff r0 : 00000000
Flags: nzCv IRQs off FIQs off Mode SVC_32
[<7ff20563>] (__mmu_cache_on+0xb/0x10) from [<7ff202d3>] (mmu_init+0x7b/0x1f4)
[<7ff202d3>] (mmu_init+0x7b/0x1f4) from [<7ff049f3>] (start_barebox+0x17/0xc4)
[<7ff049f3>] (start_barebox+0x17/0xc4) from [<7ff1ff09>] (__start+0x51/0x5c)
[<7ff1ff09>] (__start+0x51/0x5c) from [<7ff00005>] (__bare_init_start+0x1/0xc)
It looks like the memory cannot be found anymore.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 8/9] OF: base: convert of_add_memory to OF API
2013-06-25 19:48 ` Sascha Hauer
@ 2013-06-25 19:57 ` Sebastian Hesselbarth
2013-06-25 21:38 ` Sebastian Hesselbarth
1 sibling, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 19:57 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/25/2013 09:48 PM, Sascha Hauer wrote:
> On Tue, Jun 25, 2013 at 11:20:46AM +0200, Sebastian Hesselbarth wrote:
>> Convert of_add_memory parsing to make use of of_address_to_resource
>> instead of parsing memory ranges itself. This makes some functions
>> dead code which are also removed.
>>
>> Signed-off-by: Sebastian Hesselbarth<sebastian.hesselbarth@gmail.com>
>
> Haven't investigated further yet, but this one breaks my loco board
> with:
>
> mmu: Error: Can't request SDRAM region for ttb
> prefetch abort
> pc : [<00000004>] lr : [<7ff20563>]
> sp : 8fffff30 ip : 7ff20563 fp : 8fff4000
> r10: 8fff4000 r9 : 00000000 r8 : 000298ec
> r7 : 20000000 r6 : 7ff43e74 r5 : 7ff37824 r4 : 7ff37824
> r3 : 7ff205a1 r2 : 00000000 r1 : ffffffff r0 : 00000000
> Flags: nzCv IRQs off FIQs off Mode SVC_32
> [<7ff20563>] (__mmu_cache_on+0xb/0x10) from [<7ff202d3>] (mmu_init+0x7b/0x1f4)
> [<7ff202d3>] (mmu_init+0x7b/0x1f4) from [<7ff049f3>] (start_barebox+0x17/0xc4)
> [<7ff049f3>] (start_barebox+0x17/0xc4) from [<7ff1ff09>] (__start+0x51/0x5c)
> [<7ff1ff09>] (__start+0x51/0x5c) from [<7ff00005>] (__bare_init_start+0x1/0xc)
>
> It looks like the memory cannot be found anymore.
Ok, I just reworked Marvell Dove to boot from DT. I will have a look at
loco code to get an impression of how of_add_memory should be called
and add that to Dove. Maybe I can reproduce it there too.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 8/9] OF: base: convert of_add_memory to OF API
2013-06-25 19:48 ` Sascha Hauer
2013-06-25 19:57 ` Sebastian Hesselbarth
@ 2013-06-25 21:38 ` Sebastian Hesselbarth
1 sibling, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-25 21:38 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/25/2013 09:48 PM, Sascha Hauer wrote:
> On Tue, Jun 25, 2013 at 11:20:46AM +0200, Sebastian Hesselbarth wrote:
>> Convert of_add_memory parsing to make use of of_address_to_resource
>> instead of parsing memory ranges itself. This makes some functions
>> dead code which are also removed.
>>
>> Signed-off-by: Sebastian Hesselbarth<sebastian.hesselbarth@gmail.com>
>
> Haven't investigated further yet, but this one breaks my loco board
> with:
The check on the return value from of_address_to_resource in the while
loop is wrong and should be
while (!of_address_to_resource(...))
I'll update for a v2.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 4/9] OF: import bus/device related functions from Linux OF API
2013-06-25 9:20 ` [PATCH 4/9] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
2013-06-25 12:55 ` Sebastian Hesselbarth
@ 2013-06-26 6:11 ` Sascha Hauer
2013-06-26 8:23 ` Sebastian Hesselbarth
2013-06-26 8:43 ` [PATCH v2 " Sebastian Hesselbarth
2 siblings, 1 reply; 41+ messages in thread
From: Sascha Hauer @ 2013-06-26 6:11 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Tue, Jun 25, 2013 at 11:20:42AM +0200, Sebastian Hesselbarth wrote:
> +struct device_d *of_find_device_by_node(struct device_node *np)
> +{
> + struct device_d *dev;
> +
> + for_each_device(dev)
> + if (dev->device_node == np)
> + return dev;
> + return NULL;
> +}
There's some whitespace damage in this function.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 4/9] OF: import bus/device related functions from Linux OF API
2013-06-26 6:11 ` Sascha Hauer
@ 2013-06-26 8:23 ` Sebastian Hesselbarth
0 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-26 8:23 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/26/13 08:11, Sascha Hauer wrote:
> On Tue, Jun 25, 2013 at 11:20:42AM +0200, Sebastian Hesselbarth wrote:
>> +struct device_d *of_find_device_by_node(struct device_node *np)
>> +{
>> + struct device_d *dev;
>> +
>> + for_each_device(dev)
>> + if (dev->device_node == np)
>> + return dev;
>> + return NULL;
>> +}
>
> There's some whitespace damage in this function.
True, and again I am wondering why my pre-commit checkpatch hook didn't
catch it.
Queued for v2.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v2 4/9] OF: import bus/device related functions from Linux OF API
2013-06-25 9:20 ` [PATCH 4/9] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
2013-06-25 12:55 ` Sebastian Hesselbarth
2013-06-26 6:11 ` Sascha Hauer
@ 2013-06-26 8:43 ` Sebastian Hesselbarth
2 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-26 8:43 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This imports some bus and device related functions from Linux OF API
with some modifcations for Barebox.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- check for existing devices on of_platform_device_create
- remove auxdata lookup from doxygen header
- fix whitespace damage (Reported by Sascha Hauer)
Cc: barebox@lists.infradead.org
Cc: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/of/Makefile | 2 +-
drivers/of/platform.c | 320 +++++++++++++++++++++++++++++++++++++++++++++++++
include/of.h | 18 +++
3 files changed, 339 insertions(+), 1 deletions(-)
create mode 100644 drivers/of/platform.c
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b8add0b..186074e 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,4 @@
-obj-y += address.o base.o fdt.o
+obj-y += address.o base.o fdt.o platform.o
obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-y += partition.o
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
new file mode 100644
index 0000000..0d87ef4
--- /dev/null
+++ b/drivers/of/platform.c
@@ -0,0 +1,320 @@
+/*
+ * platform.c - bus/device related devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <malloc.h>
+#include <of.h>
+#include <of_address.h>
+#include <linux/amba/bus.h>
+
+/**
+ * of_find_device_by_node - Find the platform_device associated with a node
+ * @np: Pointer to device tree node
+ *
+ * Returns platform_device pointer, or NULL if not found
+ */
+struct device_d *of_find_device_by_node(struct device_node *np)
+{
+ struct device_d *dev;
+ for_each_device(dev)
+ if (dev->device_node == np)
+ return dev;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+/**
+ * of_device_make_bus_id - Use the device node data to assign a unique name
+ * @dev: pointer to device structure that is linked to a device tree node
+ *
+ * This routine will first try using either the dcr-reg or the reg property
+ * value to derive a unique name. As a last resort it will use the node
+ * name followed by a unique number.
+ */
+static void of_device_make_bus_id(struct device_d *dev)
+{
+ static int bus_no_reg_magic;
+ struct device_node *np = dev->device_node;
+ const __be32 *reg, *addrp;
+ u64 addr;
+ char *name, *at;
+
+ name = xstrdup(np->name);
+ at = strchr(name, '@');
+ if (at)
+ *at = '\0';
+
+#ifdef CONFIG_PPC_DCR
+ /*
+ * If it's a DCR based device, use 'd' for native DCRs
+ * and 'D' for MMIO DCRs.
+ */
+ reg = of_get_property(np, "dcr-reg", NULL);
+ if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+ snprintf(dev->name, MAX_DRIVER_NAME, "d%x.%s", *reg, name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+ u64 addr = of_translate_dcr_address(np, *reg, NULL);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(dev->name, MAX_DRIVER_NAME, "D%llx.%s",
+ (unsigned long long)addr, name);
+ free(name);
+ return;
+ }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+ }
+#endif /* CONFIG_PPC_DCR */
+
+ /*
+ * For MMIO, get the physical address
+ */
+ reg = of_get_property(np, "reg", NULL);
+ if (reg) {
+ if (of_can_translate_address(np)) {
+ addr = of_translate_address(np, reg);
+ } else {
+ addrp = of_get_address(np, 0, NULL, NULL);
+ if (addrp)
+ addr = of_read_number(addrp, 1);
+ else
+ addr = OF_BAD_ADDR;
+ }
+ if (addr != OF_BAD_ADDR) {
+ snprintf(dev->name, MAX_DRIVER_NAME, "%llx.%s",
+ (unsigned long long)addr, name);
+ free(name);
+ return;
+ }
+ }
+
+ /*
+ * No BusID, use the node name and add a globally incremented counter
+ */
+ snprintf(dev->name, MAX_DRIVER_NAME, "%s.%d", name, bus_no_reg_magic++);
+ free(name);
+}
+
+/**
+ * of_platform_device_create - Alloc, initialize and register an of_device
+ * @np: pointer to node to create device for
+ * @parent: device model parent device.
+ *
+ * Returns pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+static struct device_d *of_platform_device_create(struct device_node *np,
+ struct device_d *parent)
+{
+ struct device_d *dev;
+ struct resource *res = NULL, temp_res;
+ int i, j, ret, num_reg = 0, match;
+
+ if (!of_device_is_available(np))
+ return NULL;
+
+ /* count the io resources */
+ if (of_can_translate_address(np))
+ while (of_address_to_resource(np, num_reg, &temp_res) == 0)
+ num_reg++;
+
+ /* Populate the resource table */
+ if (num_reg) {
+ res = xzalloc(sizeof(*res) * num_reg);
+ for (i = 0; i < num_reg; i++) {
+ ret = of_address_to_resource(np, i, &res[i]);
+ if (ret) {
+ free(res);
+ return NULL;
+ }
+ }
+
+ /*
+ * A device may already be registered as platform_device.
+ * Instead of registering the same device again, just
+ * add this node to the existing device.
+ */
+ for_each_device(dev) {
+ if (!dev->resource)
+ continue;
+
+ for (i = 0, match = 0; i < num_reg; i++)
+ for (j = 0; j < dev->num_resources; j++)
+ if (dev->resource[j].start ==
+ res[i].start &&
+ dev->resource[j].end ==
+ res[i].end) {
+ match++;
+ break;
+ }
+
+ /* check if all address resources match */
+ if (match == num_reg) {
+ debug("connecting %s to %s\n",
+ np->name, dev_name(dev));
+ dev->device_node = np;
+ free(res);
+ return dev;
+ }
+ }
+ }
+
+ debug("register device 0x%08x\n", (num_reg) ? dev->resource[0].start : (-1));
+
+ /* setup generic device info */
+ dev = xzalloc(sizeof(*dev));
+ dev->id = DEVICE_ID_SINGLE;
+ dev->device_node = np;
+ dev->parent = parent;
+ dev->resource = res;
+ dev->num_resources = num_reg;
+ of_device_make_bus_id(dev);
+
+ ret = platform_device_register(dev);
+ if (!ret)
+ return dev;
+
+ free(dev);
+ if (num_reg)
+ free(res);
+ return NULL;
+}
+
+#ifdef CONFIG_ARM_AMBA
+static struct device_d *of_amba_device_create(struct device_node *np)
+{
+ struct amba_device *dev;
+ int ret;
+
+ debug("Creating amba device %s\n", np->full_name);
+
+ if (!of_device_is_available(np))
+ return NULL;
+
+ dev = xzalloc(sizeof(*dev));
+
+ /* setup generic device info */
+ dev->dev.id = DEVICE_ID_SINGLE;
+ dev->dev.device_node = np;
+ of_device_make_bus_id(&dev->dev);
+
+ ret = of_address_to_resource(np, 0, &dev->res);
+ if (ret)
+ goto amba_err_free;
+
+ dev->dev.resource = &dev->res;
+ dev->dev.num_resources = 1;
+
+ /* Allow the HW Peripheral ID to be overridden */
+ of_property_read_u32(np, "arm,primecell-periphid", &dev->periphid);
+
+ debug("register device 0x%08x\n", dev->dev.resource[0].start);
+
+ ret = amba_device_add(dev);
+ if (ret)
+ goto amba_err_free;
+
+ return &dev->dev;
+
+amba_err_free:
+ free(dev);
+ return NULL;
+}
+#else /* CONFIG_ARM_AMBA */
+static inline struct amba_device *of_amba_device_create(struct device_node *np)
+{
+ return NULL;
+}
+#endif /* CONFIG_ARM_AMBA */
+
+/**
+ * of_platform_bus_create() - Create a device for a node and its children.
+ * @bus: device node of the bus to instantiate
+ * @matches: match table for bus nodes
+ * @parent: parent for new device, or NULL for top level.
+ *
+ * Creates a platform_device for the provided device_node, and optionally
+ * recursively create devices for all the child nodes.
+ */
+static int of_platform_bus_create(struct device_node *bus,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ struct device_node *child;
+ struct device_d *dev;
+ int rc = 0;
+
+ /* Make sure it has a compatible property */
+ if (!of_get_property(bus, "compatible", NULL)) {
+ pr_debug("%s() - skipping %s, no compatible prop\n",
+ __func__, bus->full_name);
+ return 0;
+ }
+
+ if (of_device_is_compatible(bus, "arm,primecell")) {
+ of_amba_device_create(bus);
+ return 0;
+ }
+
+ dev = of_platform_device_create(bus, parent);
+ if (!dev || !of_match_node(matches, bus))
+ return 0;
+
+ for_each_child_of_node(bus, child) {
+ pr_debug(" create child: %s\n", child->full_name);
+ rc = of_platform_bus_create(child, matches, dev);
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+/**
+ * of_platform_populate() - Populate platform_devices from device tree data
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * This function walks the device tree given by @root node and creates devices
+ * from nodes. It requires all device nodes to have a 'compatible' property,
+ * and it is suitable for creating devices which are children of the root
+ * node.
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ struct device_node *child;
+ int rc = 0;
+
+ if (!root)
+ root = of_find_node_by_path("/");
+ if (!root)
+ return -EINVAL;
+
+ for_each_child_of_node(root, child) {
+ rc = of_platform_bus_create(child, matches, parent);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(of_platform_populate);
diff --git a/include/of.h b/include/of.h
index 8cab797..f1f555f 100644
--- a/include/of.h
+++ b/include/of.h
@@ -61,6 +61,7 @@ struct of_reserve_map *of_get_reserve_map(void);
void of_clean_reserve_map(void);
void fdt_add_reserve_map(void *fdt);
+struct device_d;
struct driver_d;
int of_fix_tree(struct device_node *);
@@ -221,6 +222,11 @@ extern int of_modalias_node(struct device_node *node, char *modalias, int len);
extern struct device_node *of_get_root_node(void);
extern int of_set_root_node(struct device_node *node);
+extern int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent);
+extern struct device_d *of_find_device_by_node(struct device_node *np);
+
int of_parse_partitions(struct cdev *cdev, struct device_node *node);
int of_device_is_stdout_path(struct device_d *dev);
const char *of_get_model(void);
@@ -547,6 +553,18 @@ static inline int of_modalias_node(struct device_node *node, char *modalias,
{
return -ENOSYS;
}
+
+static inline int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ return -ENOSYS;
+}
+
+static inline struct device_d *of_find_device_by_node(struct device_node *np)
+{
+ return NULL;
+}
#endif
#define for_each_node_by_name(dn, name) \
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v2 8/9] OF: base: convert of_add_memory to OF API
2013-06-25 9:20 ` [PATCH 8/9] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
2013-06-25 19:48 ` Sascha Hauer
@ 2013-06-26 8:43 ` Sebastian Hesselbarth
1 sibling, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-26 8:43 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
Convert of_add_memory parsing to make use of of_address_to_resource
instead of parsing memory ranges itself. This makes some functions
dead code which are also removed.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- fix check for return value of of_address_to_resource (Reported by
Sascha Hauer)
Cc: barebox@lists.infradead.org
Cc: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/of/base.c | 57 +++++++---------------------------------------------
1 files changed, 8 insertions(+), 49 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 0244281..1cf7a5f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -99,21 +99,6 @@ int of_n_size_cells(struct device_node *np)
}
EXPORT_SYMBOL(of_n_size_cells);
-static void of_bus_default_count_cells(struct device_node *dev,
- int *addrc, int *sizec)
-{
- if (addrc)
- *addrc = of_n_addr_cells(dev);
- if (sizec)
- *sizec = of_n_size_cells(dev);
-}
-
-static void of_bus_count_cells(struct device_node *dev,
- int *addrc, int *sizec)
-{
- of_bus_default_count_cells(dev, addrc, sizec);
-}
-
struct property *of_find_property(const struct device_node *np,
const char *name, int *lenp)
{
@@ -1543,48 +1528,22 @@ int of_set_property(struct device_node *np, const char *name, const void *val, i
return 0;
}
-static u64 dt_mem_next_cell(int s, const __be32 **cellp)
-{
- const __be32 *p = *cellp;
-
- *cellp = p + s;
- return of_read_number(p, s);
-}
-
int of_add_memory(struct device_node *node, bool dump)
{
- int na, nc;
- const __be32 *reg, *endp;
- int len, r = 0, ret;
const char *device_type;
+ struct resource res;
+ int n = 0, ret;
ret = of_property_read_string(node, "device_type", &device_type);
- if (ret)
+ if (ret || of_node_cmp(device_type, "memory"))
return -ENXIO;
- if (of_node_cmp(device_type, "memory"))
- return -ENXIO;
-
- of_bus_count_cells(node, &na, &nc);
-
- reg = of_get_property(node, "reg", &len);
- if (!reg)
- return -EINVAL;
-
- endp = reg + (len / sizeof(__be32));
-
- while ((endp - reg) >= (na + nc)) {
- u64 base, size;
-
- base = dt_mem_next_cell(na, ®);
- size = dt_mem_next_cell(nc, ®);
-
- if (size == 0)
+ while (!of_address_to_resource(node, n, &res)) {
+ if (!resource_size(&res))
continue;
-
- of_add_memory_bank(node, dump, r, base, size);
-
- r++;
+ of_add_memory_bank(node, dump, n,
+ res.start, resource_size(&res));
+ n++;
}
return 0;
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 0/9] OF: address and device related sync and cleanup
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (8 preceding siblings ...)
2013-06-25 9:20 ` [PATCH 9/9] OF: base: rename of_free to of_delete_node Sebastian Hesselbarth
@ 2013-06-27 6:51 ` Sascha Hauer
2013-06-27 7:50 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 00/10] " Sebastian Hesselbarth
` (10 subsequent siblings)
20 siblings, 1 reply; 41+ messages in thread
From: Sascha Hauer @ 2013-06-27 6:51 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Tue, Jun 25, 2013 at 11:20:38AM +0200, Sebastian Hesselbarth wrote:
> This patch set comprises a quite unsorted bunch of patches to further
> improve and cleanup OF API. With address and device related functions,
> two more API sets of Linux OF API are imported and modified to match
> barebox driver core.
>
> With above API improvements, device and resource pointer are removed
> from struct device_node. Futher, of_translate_address, of_probe, and
> of_add_memory are converted to recently introduced OF API.
>
> At last, of_free is renamed to of_delete_node, which gives a better
> impression of what the function is doing.
>
> Sebastian Hesselbarth (9):
> OF: import address related functions from Linux OF API
> OF: convert of_translate_address to new API
> OF: base: move OF_ROOT_NODE_ defines to local OF code
> OF: import bus/device related functions from Linux OF API
> OF: base: use of_platform_populate for probing
> OF: base: remove dead device related functions
> OF: remove device and resource pointer from struct device_node
> OF: base: convert of_add_memory to OF API
> OF: base: rename of_free to of_delete_node
Applied this series with the change that I removed the dead code
ifdeffed with CONFIG_PPC_DCR.
Thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 0/9] OF: address and device related sync and cleanup
2013-06-27 6:51 ` [PATCH 0/9] OF: address and device related sync and cleanup Sascha Hauer
@ 2013-06-27 7:50 ` Sebastian Hesselbarth
2013-06-27 8:58 ` Sascha Hauer
0 siblings, 1 reply; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-27 7:50 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/27/13 08:51, Sascha Hauer wrote:
> On Tue, Jun 25, 2013 at 11:20:38AM +0200, Sebastian Hesselbarth wrote:
>> This patch set comprises a quite unsorted bunch of patches to further
>> improve and cleanup OF API. With address and device related functions,
>> two more API sets of Linux OF API are imported and modified to match
>> barebox driver core.
>>
>> With above API improvements, device and resource pointer are removed
>> from struct device_node. Futher, of_translate_address, of_probe, and
>> of_add_memory are converted to recently introduced OF API.
>>
>> At last, of_free is renamed to of_delete_node, which gives a better
>> impression of what the function is doing.
>>
>> Sebastian Hesselbarth (9):
>> OF: import address related functions from Linux OF API
>> OF: convert of_translate_address to new API
>> OF: base: move OF_ROOT_NODE_ defines to local OF code
>> OF: import bus/device related functions from Linux OF API
>> OF: base: use of_platform_populate for probing
>> OF: base: remove dead device related functions
>> OF: remove device and resource pointer from struct device_node
>> OF: base: convert of_add_memory to OF API
>> OF: base: rename of_free to of_delete_node
>
> Applied this series with the change that I removed the dead code
> ifdeffed with CONFIG_PPC_DCR.
Ok, great! Next patch sets will be focused on actually using the
DT improvements. I have an SPI driver for MACH_MVEBU ready and
running, and I am working on importing generic SDHCI from Linux.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 0/9] OF: address and device related sync and cleanup
2013-06-27 7:50 ` Sebastian Hesselbarth
@ 2013-06-27 8:58 ` Sascha Hauer
2013-06-27 9:00 ` Sebastian Hesselbarth
0 siblings, 1 reply; 41+ messages in thread
From: Sascha Hauer @ 2013-06-27 8:58 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Thu, Jun 27, 2013 at 09:50:10AM +0200, Sebastian Hesselbarth wrote:
> On 06/27/13 08:51, Sascha Hauer wrote:
> >On Tue, Jun 25, 2013 at 11:20:38AM +0200, Sebastian Hesselbarth wrote:
> >>This patch set comprises a quite unsorted bunch of patches to further
> >>improve and cleanup OF API. With address and device related functions,
> >>two more API sets of Linux OF API are imported and modified to match
> >>barebox driver core.
> >>
> >>With above API improvements, device and resource pointer are removed
> >>from struct device_node. Futher, of_translate_address, of_probe, and
> >>of_add_memory are converted to recently introduced OF API.
> >>
> >>At last, of_free is renamed to of_delete_node, which gives a better
> >>impression of what the function is doing.
> >>
> >>Sebastian Hesselbarth (9):
> >> OF: import address related functions from Linux OF API
> >> OF: convert of_translate_address to new API
> >> OF: base: move OF_ROOT_NODE_ defines to local OF code
> >> OF: import bus/device related functions from Linux OF API
> >> OF: base: use of_platform_populate for probing
> >> OF: base: remove dead device related functions
> >> OF: remove device and resource pointer from struct device_node
> >> OF: base: convert of_add_memory to OF API
> >> OF: base: rename of_free to of_delete_node
> >
> >Applied this series with the change that I removed the dead code
> >ifdeffed with CONFIG_PPC_DCR.
>
> Ok, great! Next patch sets will be focused on actually using the
> DT improvements. I have an SPI driver for MACH_MVEBU ready and
> running, and I am working on importing generic SDHCI from Linux.
The sdhc driver in Linux is a big piece of shit which uses the wrong
abstraction model. This is shown by the fact that 32bits are not enough
to abstract the quirks. Even with all these quirks the i.MX part of this
driver has to implement driver logic in the register access functions.
That just insane. I'm not really looking forward to add this driver
to barebox.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 0/9] OF: address and device related sync and cleanup
2013-06-27 8:58 ` Sascha Hauer
@ 2013-06-27 9:00 ` Sebastian Hesselbarth
2013-06-27 18:19 ` Sascha Hauer
0 siblings, 1 reply; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-27 9:00 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/27/13 10:58, Sascha Hauer wrote:
> On Thu, Jun 27, 2013 at 09:50:10AM +0200, Sebastian Hesselbarth wrote:
>> On 06/27/13 08:51, Sascha Hauer wrote:
>>> Applied this series with the change that I removed the dead code
>>> ifdeffed with CONFIG_PPC_DCR.
>>
>> Ok, great! Next patch sets will be focused on actually using the
>> DT improvements. I have an SPI driver for MACH_MVEBU ready and
>> running, and I am working on importing generic SDHCI from Linux.
>
> The sdhc driver in Linux is a big piece of shit which uses the wrong
> abstraction model. This is shown by the fact that 32bits are not enough
> to abstract the quirks. Even with all these quirks the i.MX part of this
> driver has to implement driver logic in the register access functions.
> That just insane. I'm not really looking forward to add this driver
> to barebox.
Ok, fair enough. Then I'll be adding the required callbacks to Dove
SDHCI driver directly based on current barebox i.MX driver.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 0/9] OF: address and device related sync and cleanup
2013-06-27 9:00 ` Sebastian Hesselbarth
@ 2013-06-27 18:19 ` Sascha Hauer
2013-06-27 18:27 ` Sebastian Hesselbarth
0 siblings, 1 reply; 41+ messages in thread
From: Sascha Hauer @ 2013-06-27 18:19 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Thu, Jun 27, 2013 at 11:00:46AM +0200, Sebastian Hesselbarth wrote:
> On 06/27/13 10:58, Sascha Hauer wrote:
> >On Thu, Jun 27, 2013 at 09:50:10AM +0200, Sebastian Hesselbarth wrote:
> >>On 06/27/13 08:51, Sascha Hauer wrote:
> >>>Applied this series with the change that I removed the dead code
> >>>ifdeffed with CONFIG_PPC_DCR.
> >>
> >>Ok, great! Next patch sets will be focused on actually using the
> >>DT improvements. I have an SPI driver for MACH_MVEBU ready and
> >>running, and I am working on importing generic SDHCI from Linux.
> >
> >The sdhc driver in Linux is a big piece of shit which uses the wrong
> >abstraction model. This is shown by the fact that 32bits are not enough
> >to abstract the quirks. Even with all these quirks the i.MX part of this
> >driver has to implement driver logic in the register access functions.
> >That just insane. I'm not really looking forward to add this driver
> >to barebox.
>
> Ok, fair enough. Then I'll be adding the required callbacks to Dove
> SDHCI driver directly based on current barebox i.MX driver.
I think for the SDHC a library approach would be good: Add a new driver
and share common code/helper functions. I recently factored out the
register defines as a start so that these can be shared.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 0/9] OF: address and device related sync and cleanup
2013-06-27 18:19 ` Sascha Hauer
@ 2013-06-27 18:27 ` Sebastian Hesselbarth
0 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-27 18:27 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/27/13 20:19, Sascha Hauer wrote:
> On Thu, Jun 27, 2013 at 11:00:46AM +0200, Sebastian Hesselbarth wrote:
>> On 06/27/13 10:58, Sascha Hauer wrote:
>>> On Thu, Jun 27, 2013 at 09:50:10AM +0200, Sebastian Hesselbarth wrote:
>>>> On 06/27/13 08:51, Sascha Hauer wrote:
>>>>> Applied this series with the change that I removed the dead code
>>>>> ifdeffed with CONFIG_PPC_DCR.
>>>>
>>>> Ok, great! Next patch sets will be focused on actually using the
>>>> DT improvements. I have an SPI driver for MACH_MVEBU ready and
>>>> running, and I am working on importing generic SDHCI from Linux.
>>>
>>> The sdhc driver in Linux is a big piece of shit which uses the wrong
>>> abstraction model. This is shown by the fact that 32bits are not enough
>>> to abstract the quirks. Even with all these quirks the i.MX part of this
>>> driver has to implement driver logic in the register access functions.
>>> That just insane. I'm not really looking forward to add this driver
>>> to barebox.
>>
>> Ok, fair enough. Then I'll be adding the required callbacks to Dove
>> SDHCI driver directly based on current barebox i.MX driver.
>
> I think for the SDHC a library approach would be good: Add a new driver
> and share common code/helper functions. I recently factored out the
> register defines as a start so that these can be shared.
Yeah, I just working at SDHCI driver for Dove and wonder if I start
to wrap my brain around readl/writel or go with readb/w/l as it is
supposed to be.
As soon as I got some valid responses back from the usdcard, I have
another look at sdhci.h and a generic approach.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/9] OF: base: use of_platform_populate for probing
2013-06-25 9:20 ` [PATCH 5/9] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
@ 2013-06-29 14:22 ` Sascha Hauer
0 siblings, 0 replies; 41+ messages in thread
From: Sascha Hauer @ 2013-06-29 14:22 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Tue, Jun 25, 2013 at 11:20:43AM +0200, Sebastian Hesselbarth wrote:
> With recent bus/device related functions in OF API, we can now
> convert to use of_platform_populate.
>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> ---
> Cc: barebox@lists.infradead.org
> ---
> drivers/of/base.c | 5 ++---
> 1 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 429f924..eb9ac84 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -1840,7 +1840,7 @@ const struct of_device_id of_default_bus_match_table[] = {
>
> int of_probe(void)
> {
> - struct device_node *memory, *n;
> + struct device_node *memory;
>
> if(!root_node)
> return -ENODEV;
> @@ -1854,8 +1854,7 @@ int of_probe(void)
> if (memory)
> of_add_memory(memory, false);
>
> - list_for_each_entry(n, &root_node->children, parent_list)
> - __of_probe(n, of_default_bus_match_table, NULL);
> + of_platform_populate(root_node, of_default_bus_match_table, NULL);
This patch breaks the SPI chip select gpios on my efikasb. Problem is
that of_get_named_gpio depends on the device pointer in struct
device_node which of_platform_populate doesn't set. A quick test adding
the pointer in of_platform_device_create fixed this.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 7/9] OF: remove device and resource pointer from struct device_node
2013-06-25 9:20 ` [PATCH 7/9] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
@ 2013-06-29 14:28 ` Sascha Hauer
2013-06-29 14:31 ` Sascha Hauer
0 siblings, 1 reply; 41+ messages in thread
From: Sascha Hauer @ 2013-06-29 14:28 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Tue, Jun 25, 2013 at 11:20:45AM +0200, Sebastian Hesselbarth wrote:
> diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
> index 41e91ec..7f6d99c 100644
> --- a/drivers/of/gpio.c
> +++ b/drivers/of/gpio.c
> @@ -10,6 +10,10 @@ int of_get_named_gpio(struct device_node *np,
> {
> int ret;
> struct of_phandle_args out_args;
> + struct device_d *dev = of_find_device_by_node(np);
> +
> + if (!dev)
> + return -EINVAL;
>
> ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
> index, &out_args);
> @@ -18,7 +22,7 @@ int of_get_named_gpio(struct device_node *np,
> return -EINVAL;
> }
>
> - ret = gpio_get_num(out_args.np->device, out_args.args[0]);
> + ret = gpio_get_num(dev, out_args.args[0]);
This doesn't work. What gpio_get_num needs is the device pointer from
the gpio device, not from the device from the node we pass to this
function. You would have to use of_find_device_by_node(out_args.np) here
I guess.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 7/9] OF: remove device and resource pointer from struct device_node
2013-06-29 14:28 ` Sascha Hauer
@ 2013-06-29 14:31 ` Sascha Hauer
2013-06-29 16:03 ` Sebastian Hesselbarth
0 siblings, 1 reply; 41+ messages in thread
From: Sascha Hauer @ 2013-06-29 14:31 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Sat, Jun 29, 2013 at 04:28:57PM +0200, Sascha Hauer wrote:
> On Tue, Jun 25, 2013 at 11:20:45AM +0200, Sebastian Hesselbarth wrote:
> > diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
> > index 41e91ec..7f6d99c 100644
> > --- a/drivers/of/gpio.c
> > +++ b/drivers/of/gpio.c
> > @@ -10,6 +10,10 @@ int of_get_named_gpio(struct device_node *np,
> > {
> > int ret;
> > struct of_phandle_args out_args;
> > + struct device_d *dev = of_find_device_by_node(np);
> > +
> > + if (!dev)
> > + return -EINVAL;
> >
> > ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
> > index, &out_args);
> > @@ -18,7 +22,7 @@ int of_get_named_gpio(struct device_node *np,
> > return -EINVAL;
> > }
> >
> > - ret = gpio_get_num(out_args.np->device, out_args.args[0]);
> > + ret = gpio_get_num(dev, out_args.args[0]);
>
> This doesn't work. What gpio_get_num needs is the device pointer from
> the gpio device, not from the device from the node we pass to this
> function. You would have to use of_find_device_by_node(out_args.np) here
> I guess.
Apart from this of_find_device_by_node() only works on platform_devices,
so this will break calling of_get_named_gpio on i2c gpio expanders.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 7/9] OF: remove device and resource pointer from struct device_node
2013-06-29 14:31 ` Sascha Hauer
@ 2013-06-29 16:03 ` Sebastian Hesselbarth
2013-06-29 16:09 ` Sascha Hauer
0 siblings, 1 reply; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-29 16:03 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 06/29/2013 04:31 PM, Sascha Hauer wrote:
> On Sat, Jun 29, 2013 at 04:28:57PM +0200, Sascha Hauer wrote:
>> On Tue, Jun 25, 2013 at 11:20:45AM +0200, Sebastian Hesselbarth wrote:
>>> diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
>>> index 41e91ec..7f6d99c 100644
>>> --- a/drivers/of/gpio.c
>>> +++ b/drivers/of/gpio.c
>>> @@ -10,6 +10,10 @@ int of_get_named_gpio(struct device_node *np,
>>> {
>>> int ret;
>>> struct of_phandle_args out_args;
>>> + struct device_d *dev = of_find_device_by_node(np);
>>> +
>>> + if (!dev)
>>> + return -EINVAL;
>>>
>>> ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
>>> index,&out_args);
>>> @@ -18,7 +22,7 @@ int of_get_named_gpio(struct device_node *np,
>>> return -EINVAL;
>>> }
>>>
>>> - ret = gpio_get_num(out_args.np->device, out_args.args[0]);
>>> + ret = gpio_get_num(dev, out_args.args[0]);
>>
>> This doesn't work. What gpio_get_num needs is the device pointer from
>> the gpio device, not from the device from the node we pass to this
>> function. You would have to use of_find_device_by_node(out_args.np) here
>> I guess.
>
> Apart from this of_find_device_by_node() only works on platform_devices,
> so this will break calling of_get_named_gpio on i2c gpio expanders.
Ok, to work on this I would have to have something to test with. MVEBU
DT is still at a very early stage. So for now, I guess removing the
device pointer is a bit early? I will also have to have a close look
into i2c core what makes those devices special here.
Sebastian
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 7/9] OF: remove device and resource pointer from struct device_node
2013-06-29 16:03 ` Sebastian Hesselbarth
@ 2013-06-29 16:09 ` Sascha Hauer
0 siblings, 0 replies; 41+ messages in thread
From: Sascha Hauer @ 2013-06-29 16:09 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Sat, Jun 29, 2013 at 06:03:44PM +0200, Sebastian Hesselbarth wrote:
> On 06/29/2013 04:31 PM, Sascha Hauer wrote:
> >On Sat, Jun 29, 2013 at 04:28:57PM +0200, Sascha Hauer wrote:
> >>On Tue, Jun 25, 2013 at 11:20:45AM +0200, Sebastian Hesselbarth wrote:
> >>>diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
> >>>index 41e91ec..7f6d99c 100644
> >>>--- a/drivers/of/gpio.c
> >>>+++ b/drivers/of/gpio.c
> >>>@@ -10,6 +10,10 @@ int of_get_named_gpio(struct device_node *np,
> >>> {
> >>> int ret;
> >>> struct of_phandle_args out_args;
> >>>+ struct device_d *dev = of_find_device_by_node(np);
> >>>+
> >>>+ if (!dev)
> >>>+ return -EINVAL;
> >>>
> >>> ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
> >>> index,&out_args);
> >>>@@ -18,7 +22,7 @@ int of_get_named_gpio(struct device_node *np,
> >>> return -EINVAL;
> >>> }
> >>>
> >>>- ret = gpio_get_num(out_args.np->device, out_args.args[0]);
> >>>+ ret = gpio_get_num(dev, out_args.args[0]);
> >>
> >>This doesn't work. What gpio_get_num needs is the device pointer from
> >>the gpio device, not from the device from the node we pass to this
> >>function. You would have to use of_find_device_by_node(out_args.np) here
> >>I guess.
> >
> >Apart from this of_find_device_by_node() only works on platform_devices,
> >so this will break calling of_get_named_gpio on i2c gpio expanders.
>
> Ok, to work on this I would have to have something to test with. MVEBU
> DT is still at a very early stage. So for now, I guess removing the
> device pointer is a bit early?
Probably, yes. I think the solution would be to adjust gpio_get_num() so
that it takes a device_node as argument instead of a device.
> I will also have to have a close look
> into i2c core what makes those devices special here.
I may be wrong here. In the kernel of_find_device_by_node() works only
for platform_devices, but since you do for_each_device(), it should work
for i2c devices in barebox aswell.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 00/10] OF: address and device related sync and cleanup
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (9 preceding siblings ...)
2013-06-27 6:51 ` [PATCH 0/9] OF: address and device related sync and cleanup Sascha Hauer
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-05 6:45 ` Sascha Hauer
2013-07-02 18:14 ` [PATCH v3 01/10] OF: import address related functions from Linux OF API Sebastian Hesselbarth
` (9 subsequent siblings)
20 siblings, 1 reply; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This patch set comprises a quite unsorted bunch of patches to further
improve and cleanup OF API. With address and device related functions,
two more API sets of Linux OF API are imported and modified to match
barebox driver core.
With above API improvements, device and resource pointer are removed
from struct device_node. Futher, of_translate_address, of_probe, and
of_add_memory are converted to recently introduced OF API.
At last, of_free is renamed to of_delete_node, which gives a better
impression of what the function is doing.
v3 of this patch set includes fixes introduced with v2 that have been
sent as separate patches. Also patch 5 is inserted to not break OF
gpio parsing with subsequent patches.
This time I have tested the OF gpio patches on Marvell Dove; side
effect: Orion GPIO driver that I will post as part of the MVEBU DT
improvement patches.
Sebastian Hesselbarth (10):
OF: import address related functions from Linux OF API
OF: convert of_translate_address to new API
OF: base: move OF_ROOT_NODE_ defines to local OF code
OF: import bus/device related functions from Linux OF API
OF: gpio: convert DT based gpio handling to new OF API
OF: base: use of_platform_populate for probing
OF: base: remove dead device related functions
OF: remove device and resource pointer from struct device_node
OF: base: convert of_add_memory to OF API
OF: base: rename of_free to of_delete_node
commands/of_node.c | 2 +-
commands/oftree.c | 4 +-
drivers/of/Makefile | 4 +-
drivers/of/address.c | 437 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/of/base.c | 339 +++++---------------------------------
drivers/of/fdt.c | 2 +-
drivers/of/gpio.c | 26 ---
drivers/of/of_gpio.c | 52 ++++++
drivers/of/platform.c | 321 ++++++++++++++++++++++++++++++++++++
drivers/spi/imx_spi.c | 1 +
include/of.h | 33 +++--
include/of_address.h | 72 ++++++++
include/of_gpio.h | 44 +++++
13 files changed, 999 insertions(+), 338 deletions(-)
create mode 100644 drivers/of/address.c
delete mode 100644 drivers/of/gpio.c
create mode 100644 drivers/of/of_gpio.c
create mode 100644 drivers/of/platform.c
create mode 100644 include/of_address.h
create mode 100644 include/of_gpio.h
---
Cc: barebox@lists.infradead.org
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 01/10] OF: import address related functions from Linux OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (10 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 00/10] " Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 02/10] OF: convert of_translate_address to new API Sebastian Hesselbarth
` (8 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This imports drivers/of/address.c from Linux with some minor modifications.
of_translate_address is not yet enabled and PCI and ISA related bus translations
have not been imported. Also, a corresponding include header is created with
prototypes and non-OF function stubs.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/Makefile | 2 +-
drivers/of/address.c | 431 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/of_address.h | 64 ++++++++
3 files changed, 496 insertions(+), 1 deletions(-)
create mode 100644 drivers/of/address.c
create mode 100644 include/of_address.h
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index c81bbec..b8add0b 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,4 @@
-obj-y += base.o fdt.o
+obj-y += address.o base.o fdt.o
obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-y += partition.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
new file mode 100644
index 0000000..3e5387a
--- /dev/null
+++ b/drivers/of/address.c
@@ -0,0 +1,431 @@
+/*
+ * address.c - address related devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <of.h>
+#include <of_address.h>
+
+/* 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)
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
+{
+ printk(KERN_DEBUG "%s", s);
+ while (na--)
+ printk(" %08x", be32_to_cpu(*(addr++)));
+ printk("\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)(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);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(dev);
+ if (sizec)
+ *sizec = of_n_size_cells(dev);
+}
+
+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);
+
+ pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
+ (unsigned long long)cp, (unsigned long long)s,
+ (unsigned long long)da);
+
+ /*
+ * If the number of address cells is larger than 2 we assume the
+ * mapping doesn't specify a physical address. Rather, the address
+ * specifies an identifier that must match exactly.
+ */
+ if (na > 2 && memcmp(range, addr, na * 4) != 0)
+ return OF_BAD_ADDR;
+
+ 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 & 0xffffffffu);
+
+ 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 &of_busses[i];
+ BUG();
+ return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+ struct of_bus *pbus, __be32 *addr,
+ int na, int ns, int pna, const char *rprop)
+{
+ const __be32 *ranges;
+ unsigned int rlen;
+ int rone;
+ u64 offset = OF_BAD_ADDR;
+
+ /* Normally, an absence of a "ranges" property means we are
+ * crossing a non-translatable boundary, and thus the addresses
+ * below the current not cannot be converted to CPU physical ones.
+ * Unfortunately, while this is very clear in the spec, it's not
+ * what Apple understood, and they do have things like /uni-n or
+ * /ht nodes with no "ranges" property and a lot of perfectly
+ * useable mapped devices below them. Thus we treat the absence of
+ * "ranges" as equivalent to an empty "ranges" property which means
+ * a 1:1 translation at that level. It's up to the caller not to try
+ * to translate addresses that aren't supposed to be translated in
+ * the first place. --BenH.
+ *
+ * As far as we know, this damage only exists on Apple machines, so
+ * This code is only enabled on powerpc. --gcl
+ */
+ ranges = of_get_property(parent, rprop, &rlen);
+#if !defined(CONFIG_PPC)
+ if (ranges == NULL) {
+ pr_err("OF: no ranges; cannot translate\n");
+ return 1;
+ }
+#endif /* !defined(CONFIG_PPC) */
+ if (ranges == NULL || rlen == 0) {
+ offset = of_read_number(addr, na);
+ memset(addr, 0, pna * 4);
+ pr_debug("OF: empty ranges; 1:1 translation\n");
+ goto finish;
+ }
+
+ pr_debug("OF: walking ranges...\n");
+
+ /* Now walk through the ranges */
+ rlen /= 4;
+ rone = na + pna + ns;
+ for (; rlen >= rone; rlen -= rone, ranges += rone) {
+ offset = bus->map(addr, ranges, na, ns, pna);
+ if (offset != OF_BAD_ADDR)
+ break;
+ }
+ if (offset == OF_BAD_ADDR) {
+ pr_debug("OF: not found !\n");
+ return 1;
+ }
+ memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+ of_dump_addr("OF: parent translation for:", addr, pna);
+ pr_debug("OF: with offset: %llx\n", (unsigned long long)offset);
+
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+static u64 __of_translate_address(struct device_node *dev,
+ const __be32 *in_addr, const char *rprop)
+{
+ struct device_node *parent = NULL;
+ struct of_bus *bus, *pbus;
+ __be32 addr[OF_MAX_ADDR_CELLS];
+ int na, ns, pna, pns;
+ u64 result = OF_BAD_ADDR;
+
+ pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return OF_BAD_ADDR;
+ bus = of_match_bus(parent);
+
+ /* Count address cells & copy address locally */
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_COUNTS(na, ns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ return OF_BAD_ADDR;
+ }
+ memcpy(addr, in_addr, na * 4);
+
+ pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+ bus->name, na, ns, parent->full_name);
+ of_dump_addr("OF: translating address:", addr, na);
+
+ /* Translate */
+ for (;;) {
+ /* Switch to parent bus */
+ dev = parent;
+ parent = of_get_parent(dev);
+
+ /* If root, we have finished */
+ if (parent == NULL) {
+ pr_debug("OF: reached root node\n");
+ result = of_read_number(addr, na);
+ break;
+ }
+
+ /* Get new parent bus and counts */
+ pbus = of_match_bus(parent);
+ pbus->count_cells(dev, &pna, &pns);
+ if (!OF_CHECK_COUNTS(pna, pns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ break;
+ }
+
+ pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+ pbus->name, pna, pns, parent->full_name);
+
+ /* Apply bus translation */
+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+ break;
+
+ /* Complete the move up one level */
+ na = pna;
+ ns = pns;
+ bus = pbus;
+
+ of_dump_addr("OF: one level translation:", addr, na);
+ }
+
+ return result;
+}
+
+u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
+{
+ return __of_translate_address(dev, in_addr, "dma-ranges");
+}
+EXPORT_SYMBOL(of_translate_dma_address);
+
+bool of_can_translate_address(struct device_node *dev)
+{
+ struct device_node *parent;
+ struct of_bus *bus;
+ int na, ns;
+
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return false;
+
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+
+ return OF_CHECK_COUNTS(na, ns);
+}
+EXPORT_SYMBOL(of_can_translate_address);
+
+const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
+ unsigned int *flags)
+{
+ const __be32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_ADDR_COUNT(na))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, bus->addresses, &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if (i == index) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev,
+ const __be32 *addrp, u64 size, unsigned int flags,
+ const char *name, struct resource *r)
+{
+ u64 taddr;
+
+ if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+ return -EINVAL;
+ taddr = of_translate_address(dev, addrp);
+ if (taddr == OF_BAD_ADDR)
+ return -EINVAL;
+ memset(r, 0, sizeof(struct resource));
+ if (flags & IORESOURCE_IO) {
+ unsigned long port;
+ port = pci_address_to_pio(taddr);
+ if (port == (unsigned long)-1)
+ return -EINVAL;
+ r->start = port;
+ r->end = port + size - 1;
+ } else {
+ r->start = taddr;
+ r->end = taddr + size - 1;
+ }
+ r->flags = flags;
+ r->name = name ? name : dev->full_name;
+
+ return 0;
+}
+
+/**
+ * of_address_to_resource - Translate device tree address and return as resource
+ *
+ * Note that if your address is a PIO address, the conversion will fail if
+ * the physical address can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early or it
+ * can't be matched to any host bridge IO space
+ */
+int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ const __be32 *addrp;
+ u64 size;
+ unsigned int flags;
+ const char *name = NULL;
+
+ addrp = of_get_address(dev, index, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+
+ /* Get optional "reg-names" property to add a name to a resource */
+ of_property_read_string_index(dev, "reg-names", index, &name);
+
+ return __of_address_to_resource(dev, addrp, size, flags, name, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+struct device_node *of_find_matching_node_by_address(struct device_node *from,
+ const struct of_device_id *matches,
+ u64 base_address)
+{
+ struct device_node *dn = of_find_matching_node(from, matches);
+ struct resource res;
+
+ while (dn) {
+ if (of_address_to_resource(dn, 0, &res))
+ continue;
+ if (res.start == base_address)
+ return dn;
+ dn = of_find_matching_node(dn, matches);
+ }
+
+ return NULL;
+}
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return IOMEM(res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/include/of_address.h b/include/of_address.h
new file mode 100644
index 0000000..a82e2e5
--- /dev/null
+++ b/include/of_address.h
@@ -0,0 +1,64 @@
+#ifndef __OF_ADDRESS_H
+#define __OF_ADDRESS_H
+
+#include <common.h>
+#include <of.h>
+
+#ifndef pci_address_to_pio
+static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
+#endif
+
+#ifdef CONFIG_OFTREE
+
+extern u64 of_translate_dma_address(struct device_node *dev,
+ const __be32 *in_addr);
+extern bool of_can_translate_address(struct device_node *dev);
+extern const __be32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags);
+extern int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+extern struct device_node *of_find_matching_node_by_address(
+ struct device_node *from, const struct of_device_id *matches,
+ u64 base_address);
+extern void __iomem *of_iomap(struct device_node *np, int index);
+
+#else /* CONFIG_OFTREE */
+
+static inline u64 of_translate_dma_address(struct device_node *dev,
+ const __be32 *in_addr)
+{
+ return OF_BAD_ADDR;
+}
+
+static inline bool of_can_translate_address(struct device_node *dev)
+{
+ return false;
+}
+
+static inline const __be32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags)
+{
+ return 0;
+}
+
+static inline int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ return -ENOSYS;
+}
+
+static inline struct device_node *of_find_matching_node_by_address(
+ struct device_node *from, const struct of_device_id *matches,
+ u64 base_address)
+{
+ return NULL;
+}
+
+static inline void __iomem *of_iomap(struct device_node *np, int index)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_OFTREE */
+
+#endif /* __OF_ADDRESS_H */
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 02/10] OF: convert of_translate_address to new API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (11 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 01/10] OF: import address related functions from Linux OF API Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 03/10] OF: base: move OF_ROOT_NODE_ defines to local OF code Sebastian Hesselbarth
` (7 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This converts existing of_translate_address to recently added API. In
contrast to existing behavior, the new function honors ranges properties
properly. It now allows reg properties to be set as offset with respect
to the correspoding parent node.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/address.c | 6 ++++++
drivers/of/base.c | 26 +-------------------------
include/of.h | 2 --
include/of_address.h | 8 ++++++++
4 files changed, 15 insertions(+), 27 deletions(-)
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 3e5387a..4cacdb1 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -278,6 +278,12 @@ static u64 __of_translate_address(struct device_node *dev,
return result;
}
+u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
+{
+ return __of_translate_address(dev, in_addr, "ranges");
+}
+EXPORT_SYMBOL(of_translate_address);
+
u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
{
return __of_translate_address(dev, in_addr, "dma-ranges");
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 63ff647..2778230 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -19,6 +19,7 @@
*/
#include <common.h>
#include <of.h>
+#include <of_address.h>
#include <errno.h>
#include <malloc.h>
#include <init.h>
@@ -242,31 +243,6 @@ const char *of_alias_get(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_alias_get);
-u64 of_translate_address(struct device_node *node, const __be32 *in_addr)
-{
- struct property *p;
- u64 addr = be32_to_cpu(*in_addr);
-
- while (1) {
- int na, nc;
-
- if (!node->parent)
- return addr;
-
- node = node->parent;
- p = of_find_property(node, "ranges", NULL);
- if (!p && node->parent)
- return OF_BAD_ADDR;
- of_bus_count_cells(node, &na, &nc);
- if (na != 1 || nc != 1) {
- printk("%s: #size-cells != 1 or #address-cells != 1 "
- "currently not supported\n", node->name);
- return OF_BAD_ADDR;
- }
- }
-}
-EXPORT_SYMBOL(of_translate_address);
-
/*
* of_find_node_by_phandle - Find a node given a phandle
* @handle: phandle of the node to find
diff --git a/include/of.h b/include/of.h
index b392ca9..e091326 100644
--- a/include/of.h
+++ b/include/of.h
@@ -101,8 +101,6 @@ int of_get_named_gpio(struct device_node *np,
void of_print_property(const void *data, int len);
void of_print_cmdline(struct device_node *root);
-u64 of_translate_address(struct device_node *node, const __be32 *in_addr);
-
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
diff --git a/include/of_address.h b/include/of_address.h
index a82e2e5..9022ab7 100644
--- a/include/of_address.h
+++ b/include/of_address.h
@@ -10,6 +10,8 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
#ifdef CONFIG_OFTREE
+extern u64 of_translate_address(struct device_node *dev,
+ const __be32 *in_addr);
extern u64 of_translate_dma_address(struct device_node *dev,
const __be32 *in_addr);
extern bool of_can_translate_address(struct device_node *dev);
@@ -24,6 +26,12 @@ extern void __iomem *of_iomap(struct device_node *np, int index);
#else /* CONFIG_OFTREE */
+static inline u64 of_translate_address(struct device_node *dev,
+ const __be32 *in_addr)
+{
+ return OF_BAD_ADDR;
+}
+
static inline u64 of_translate_dma_address(struct device_node *dev,
const __be32 *in_addr)
{
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 03/10] OF: base: move OF_ROOT_NODE_ defines to local OF code
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (12 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 02/10] OF: convert of_translate_address to new API Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 04/10] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
` (6 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
OF_ROOT_NODE_* defines should not be used outside of base.c. Move them
to drivers/of/base.c to ensure they will not be used elsewhere.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 3 +++
include/of.h | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 2778230..429f924 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -64,6 +64,9 @@ struct device_node *root_node;
struct device_node *of_aliases;
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+
int of_n_addr_cells(struct device_node *np)
{
const __be32 *ip;
diff --git a/include/of.h b/include/of.h
index e091326..8cab797 100644
--- a/include/of.h
+++ b/include/of.h
@@ -101,9 +101,6 @@ int of_get_named_gpio(struct device_node *np,
void of_print_property(const void *data, int len);
void of_print_cmdline(struct device_node *root);
-#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
-#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
-
void of_print_nodes(struct device_node *node, int indent);
int of_probe(void);
int of_parse_dtb(struct fdt_header *fdt);
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 04/10] OF: import bus/device related functions from Linux OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (13 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 03/10] OF: base: move OF_ROOT_NODE_ defines to local OF code Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 05/10] OF: gpio: convert DT based gpio handling to new " Sebastian Hesselbarth
` (5 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This imports some bus and device related functions from Linux OF API
with some modifcations for Barebox.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- check for existing devices on of_platform_device_create
- remove auxdata lookup from doxygen header
- fix whitespace damage (Reported by Sascha Hauer)
Cc: barebox@lists.infradead.org
---
drivers/of/Makefile | 2 +-
drivers/of/platform.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++
include/of.h | 18 +++
3 files changed, 340 insertions(+), 1 deletions(-)
create mode 100644 drivers/of/platform.c
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b8add0b..186074e 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,4 @@
-obj-y += address.o base.o fdt.o
+obj-y += address.o base.o fdt.o platform.o
obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-y += partition.o
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
new file mode 100644
index 0000000..e75a69b
--- /dev/null
+++ b/drivers/of/platform.c
@@ -0,0 +1,321 @@
+/*
+ * platform.c - bus/device related devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <malloc.h>
+#include <of.h>
+#include <of_address.h>
+#include <linux/amba/bus.h>
+
+/**
+ * of_find_device_by_node - Find the platform_device associated with a node
+ * @np: Pointer to device tree node
+ *
+ * Returns platform_device pointer, or NULL if not found
+ */
+struct device_d *of_find_device_by_node(struct device_node *np)
+{
+ struct device_d *dev;
+ for_each_device(dev)
+ if (dev->device_node == np)
+ return dev;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+/**
+ * of_device_make_bus_id - Use the device node data to assign a unique name
+ * @dev: pointer to device structure that is linked to a device tree node
+ *
+ * This routine will first try using either the dcr-reg or the reg property
+ * value to derive a unique name. As a last resort it will use the node
+ * name followed by a unique number.
+ */
+static void of_device_make_bus_id(struct device_d *dev)
+{
+ static int bus_no_reg_magic;
+ struct device_node *np = dev->device_node;
+ const __be32 *reg, *addrp;
+ u64 addr;
+ char *name, *at;
+
+ name = xstrdup(np->name);
+ at = strchr(name, '@');
+ if (at)
+ *at = '\0';
+
+#ifdef CONFIG_PPC_DCR
+ /*
+ * If it's a DCR based device, use 'd' for native DCRs
+ * and 'D' for MMIO DCRs.
+ */
+ reg = of_get_property(np, "dcr-reg", NULL);
+ if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+ snprintf(dev->name, MAX_DRIVER_NAME, "d%x.%s", *reg, name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+ u64 addr = of_translate_dcr_address(np, *reg, NULL);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(dev->name, MAX_DRIVER_NAME, "D%llx.%s",
+ (unsigned long long)addr, name);
+ free(name);
+ return;
+ }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+ }
+#endif /* CONFIG_PPC_DCR */
+
+ /*
+ * For MMIO, get the physical address
+ */
+ reg = of_get_property(np, "reg", NULL);
+ if (reg) {
+ if (of_can_translate_address(np)) {
+ addr = of_translate_address(np, reg);
+ } else {
+ addrp = of_get_address(np, 0, NULL, NULL);
+ if (addrp)
+ addr = of_read_number(addrp, 1);
+ else
+ addr = OF_BAD_ADDR;
+ }
+ if (addr != OF_BAD_ADDR) {
+ snprintf(dev->name, MAX_DRIVER_NAME, "%llx.%s",
+ (unsigned long long)addr, name);
+ free(name);
+ return;
+ }
+ }
+
+ /*
+ * No BusID, use the node name and add a globally incremented counter
+ */
+ snprintf(dev->name, MAX_DRIVER_NAME, "%s.%d", name, bus_no_reg_magic++);
+ free(name);
+}
+
+/**
+ * of_platform_device_create - Alloc, initialize and register an of_device
+ * @np: pointer to node to create device for
+ * @parent: device model parent device.
+ *
+ * Returns pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+static struct device_d *of_platform_device_create(struct device_node *np,
+ struct device_d *parent)
+{
+ struct device_d *dev;
+ struct resource *res = NULL, temp_res;
+ int i, j, ret, num_reg = 0, match;
+
+ if (!of_device_is_available(np))
+ return NULL;
+
+ /* count the io resources */
+ if (of_can_translate_address(np))
+ while (of_address_to_resource(np, num_reg, &temp_res) == 0)
+ num_reg++;
+
+ /* Populate the resource table */
+ if (num_reg) {
+ res = xzalloc(sizeof(*res) * num_reg);
+ for (i = 0; i < num_reg; i++) {
+ ret = of_address_to_resource(np, i, &res[i]);
+ if (ret) {
+ free(res);
+ return NULL;
+ }
+ }
+
+ /*
+ * A device may already be registered as platform_device.
+ * Instead of registering the same device again, just
+ * add this node to the existing device.
+ */
+ for_each_device(dev) {
+ if (!dev->resource)
+ continue;
+
+ for (i = 0, match = 0; i < num_reg; i++)
+ for (j = 0; j < dev->num_resources; j++)
+ if (dev->resource[j].start ==
+ res[i].start &&
+ dev->resource[j].end ==
+ res[i].end) {
+ match++;
+ break;
+ }
+
+ /* check if all address resources match */
+ if (match == num_reg) {
+ debug("connecting %s to %s\n",
+ np->name, dev_name(dev));
+ dev->device_node = np;
+ free(res);
+ return dev;
+ }
+ }
+ }
+
+ debug("register device 0x%08x\n",
+ (num_reg) ? dev->resource[0].start : (-1));
+
+ /* setup generic device info */
+ dev = xzalloc(sizeof(*dev));
+ dev->id = DEVICE_ID_SINGLE;
+ dev->device_node = np;
+ dev->parent = parent;
+ dev->resource = res;
+ dev->num_resources = num_reg;
+ of_device_make_bus_id(dev);
+
+ ret = platform_device_register(dev);
+ if (!ret)
+ return dev;
+
+ free(dev);
+ if (num_reg)
+ free(res);
+ return NULL;
+}
+
+#ifdef CONFIG_ARM_AMBA
+static struct device_d *of_amba_device_create(struct device_node *np)
+{
+ struct amba_device *dev;
+ int ret;
+
+ debug("Creating amba device %s\n", np->full_name);
+
+ if (!of_device_is_available(np))
+ return NULL;
+
+ dev = xzalloc(sizeof(*dev));
+
+ /* setup generic device info */
+ dev->dev.id = DEVICE_ID_SINGLE;
+ dev->dev.device_node = np;
+ of_device_make_bus_id(&dev->dev);
+
+ ret = of_address_to_resource(np, 0, &dev->res);
+ if (ret)
+ goto amba_err_free;
+
+ dev->dev.resource = &dev->res;
+ dev->dev.num_resources = 1;
+
+ /* Allow the HW Peripheral ID to be overridden */
+ of_property_read_u32(np, "arm,primecell-periphid", &dev->periphid);
+
+ debug("register device 0x%08x\n", dev->dev.resource[0].start);
+
+ ret = amba_device_add(dev);
+ if (ret)
+ goto amba_err_free;
+
+ return &dev->dev;
+
+amba_err_free:
+ free(dev);
+ return NULL;
+}
+#else /* CONFIG_ARM_AMBA */
+static inline struct amba_device *of_amba_device_create(struct device_node *np)
+{
+ return NULL;
+}
+#endif /* CONFIG_ARM_AMBA */
+
+/**
+ * of_platform_bus_create() - Create a device for a node and its children.
+ * @bus: device node of the bus to instantiate
+ * @matches: match table for bus nodes
+ * @parent: parent for new device, or NULL for top level.
+ *
+ * Creates a platform_device for the provided device_node, and optionally
+ * recursively create devices for all the child nodes.
+ */
+static int of_platform_bus_create(struct device_node *bus,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ struct device_node *child;
+ struct device_d *dev;
+ int rc = 0;
+
+ /* Make sure it has a compatible property */
+ if (!of_get_property(bus, "compatible", NULL)) {
+ pr_debug("%s() - skipping %s, no compatible prop\n",
+ __func__, bus->full_name);
+ return 0;
+ }
+
+ if (of_device_is_compatible(bus, "arm,primecell")) {
+ of_amba_device_create(bus);
+ return 0;
+ }
+
+ dev = of_platform_device_create(bus, parent);
+ if (!dev || !of_match_node(matches, bus))
+ return 0;
+
+ for_each_child_of_node(bus, child) {
+ pr_debug(" create child: %s\n", child->full_name);
+ rc = of_platform_bus_create(child, matches, dev);
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+/**
+ * of_platform_populate() - Populate platform_devices from device tree data
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * This function walks the device tree given by @root node and creates devices
+ * from nodes. It requires all device nodes to have a 'compatible' property,
+ * and it is suitable for creating devices which are children of the root
+ * node.
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ struct device_node *child;
+ int rc = 0;
+
+ if (!root)
+ root = of_find_node_by_path("/");
+ if (!root)
+ return -EINVAL;
+
+ for_each_child_of_node(root, child) {
+ rc = of_platform_bus_create(child, matches, parent);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(of_platform_populate);
diff --git a/include/of.h b/include/of.h
index 8cab797..f1f555f 100644
--- a/include/of.h
+++ b/include/of.h
@@ -61,6 +61,7 @@ struct of_reserve_map *of_get_reserve_map(void);
void of_clean_reserve_map(void);
void fdt_add_reserve_map(void *fdt);
+struct device_d;
struct driver_d;
int of_fix_tree(struct device_node *);
@@ -221,6 +222,11 @@ extern int of_modalias_node(struct device_node *node, char *modalias, int len);
extern struct device_node *of_get_root_node(void);
extern int of_set_root_node(struct device_node *node);
+extern int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent);
+extern struct device_d *of_find_device_by_node(struct device_node *np);
+
int of_parse_partitions(struct cdev *cdev, struct device_node *node);
int of_device_is_stdout_path(struct device_d *dev);
const char *of_get_model(void);
@@ -547,6 +553,18 @@ static inline int of_modalias_node(struct device_node *node, char *modalias,
{
return -ENOSYS;
}
+
+static inline int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device_d *parent)
+{
+ return -ENOSYS;
+}
+
+static inline struct device_d *of_find_device_by_node(struct device_node *np)
+{
+ return NULL;
+}
#endif
#define for_each_node_by_name(dn, name) \
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 05/10] OF: gpio: convert DT based gpio handling to new OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (14 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 04/10] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 06/10] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
` (4 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
This creates a Linux OF API compatible counterpart of of_get_named_gpio_flags.
Existing of_get_named_gpio is converted to a static inline function, which is
in the corresponding of_gpio.h include. While at it, drivers/of/gpio.c is
also renamed to drivers/of/of_gpio.c to follow the of_ prefix naming scheme.
The new include is also added to existing users of of_get_named_gpio.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v3:
- split off gpio related changes in this patch
Cc: barebox@lists.infradead.org
---
drivers/of/Makefile | 2 +-
drivers/of/gpio.c | 26 ------------------------
drivers/of/of_gpio.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/spi/imx_spi.c | 1 +
include/of.h | 3 --
include/of_gpio.h | 44 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 98 insertions(+), 30 deletions(-)
delete mode 100644 drivers/of/gpio.c
create mode 100644 drivers/of/of_gpio.c
create mode 100644 include/of_gpio.h
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 186074e..e7d0733 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,5 +1,5 @@
obj-y += address.o base.o fdt.o platform.o
obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
-obj-$(CONFIG_GPIOLIB) += gpio.o
+obj-$(CONFIG_GPIOLIB) += of_gpio.o
obj-y += partition.o
obj-y += of_net.o
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
deleted file mode 100644
index 41e91ec..0000000
--- a/drivers/of/gpio.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#define DEBUG
-
-#include <common.h>
-#include <errno.h>
-#include <of.h>
-#include <gpio.h>
-
-int of_get_named_gpio(struct device_node *np,
- const char *propname, int index)
-{
- int ret;
- struct of_phandle_args out_args;
-
- ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
- index, &out_args);
- if (ret) {
- pr_debug("%s: can't parse gpios property: %d\n", __func__, ret);
- return -EINVAL;
- }
-
- ret = gpio_get_num(out_args.np->device, out_args.args[0]);
- if (ret < 0)
- return ret;
-
- return ret;
-}
diff --git a/drivers/of/of_gpio.c b/drivers/of/of_gpio.c
new file mode 100644
index 0000000..3afdf0d
--- /dev/null
+++ b/drivers/of/of_gpio.c
@@ -0,0 +1,52 @@
+#include <common.h>
+#include <errno.h>
+#include <of.h>
+#include <of_gpio.h>
+#include <gpio.h>
+
+/**
+ * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API
+ * @np: device node to get GPIO from
+ * @propname: property name containing gpio specifier(s)
+ * @index: index of the GPIO
+ * @flags: a flags pointer to fill in
+ *
+ * Returns GPIO number to use with GPIO API, or one of the errno value on the
+ * error condition. If @flags is not NULL the function also fills in flags for
+ * the GPIO.
+ */
+int of_get_named_gpio_flags(struct device_node *np, const char *propname,
+ int index, enum of_gpio_flags *flags)
+{
+ struct of_phandle_args out_args;
+ struct device_d *dev;
+ int ret;
+
+ ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
+ index, &out_args);
+ if (ret) {
+ pr_err("%s: cannot parse %s property: %d\n",
+ __func__, propname, ret);
+ return ret;
+ }
+
+ dev = of_find_device_by_node(out_args.np);
+ if (!dev) {
+ pr_err("%s: unable to find device of node %s: %d\n",
+ __func__, out_args.np->full_name, ret);
+ return ret;
+ }
+
+ ret = gpio_get_num(dev, out_args.args[0]);
+ if (ret < 0) {
+ pr_err("%s: unable to get gpio num of device %s: %d\n",
+ __func__, dev_name(dev), ret);
+ return ret;
+ }
+
+ if (flags)
+ *flags = out_args.args[1];
+
+ return ret;
+}
+EXPORT_SYMBOL(of_get_named_gpio_flags);
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index b749337..6f942bf 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <malloc.h>
#include <gpio.h>
+#include <of_gpio.h>
#include <mach/spi.h>
#include <mach/generic.h>
#include <linux/clk.h>
diff --git a/include/of.h b/include/of.h
index f1f555f..f33ed20 100644
--- a/include/of.h
+++ b/include/of.h
@@ -96,9 +96,6 @@ static inline void of_write_number(void *__cell, u64 val, int size)
}
}
-int of_get_named_gpio(struct device_node *np,
- const char *propname, int index);
-
void of_print_property(const void *data, int len);
void of_print_cmdline(struct device_node *root);
diff --git a/include/of_gpio.h b/include/of_gpio.h
new file mode 100644
index 0000000..50536a8
--- /dev/null
+++ b/include/of_gpio.h
@@ -0,0 +1,44 @@
+/*
+ * OF helpers for the GPIO API
+ *
+ * based on Linux OF_GPIO API
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __OF_GPIO_H
+#define __OF_GPIO_H
+
+/*
+ * This is Linux-specific flags. By default controllers' and Linux' mapping
+ * match, but GPIO controllers are free to translate their own flags to
+ * Linux-specific in their .xlate callback. Though, 1:1 mapping is recommended.
+ */
+enum of_gpio_flags {
+ OF_GPIO_ACTIVE_LOW = 0x1,
+};
+
+#ifdef CONFIG_OFTREE
+extern int of_get_named_gpio_flags(struct device_node *np,
+ const char *list_name, int index, enum of_gpio_flags *flags);
+
+#else /* CONFIG_OFTREE */
+
+static inline int of_get_named_gpio_flags(struct device_node *np,
+ const char *list_name, int index, enum of_gpio_flags *flags)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_OFTREE */
+
+static inline int of_get_named_gpio(struct device_node *np,
+ const char *list_name, int index)
+{
+ return of_get_named_gpio_flags(np, list_name, index, NULL);
+}
+
+#endif
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 06/10] OF: base: use of_platform_populate for probing
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (15 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 05/10] OF: gpio: convert DT based gpio handling to new " Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 07/10] OF: base: remove dead device related functions Sebastian Hesselbarth
` (3 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
With recent bus/device related functions in OF API, we can now
convert to use of_platform_populate.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 429f924..eb9ac84 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1840,7 +1840,7 @@ const struct of_device_id of_default_bus_match_table[] = {
int of_probe(void)
{
- struct device_node *memory, *n;
+ struct device_node *memory;
if(!root_node)
return -ENODEV;
@@ -1854,8 +1854,7 @@ int of_probe(void)
if (memory)
of_add_memory(memory, false);
- list_for_each_entry(n, &root_node->children, parent_list)
- __of_probe(n, of_default_bus_match_table, NULL);
+ of_platform_populate(root_node, of_default_bus_match_table, NULL);
return 0;
}
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 07/10] OF: base: remove dead device related functions
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (16 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 06/10] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 08/10] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
` (2 subsequent siblings)
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
With recent conversion to of_platfrom_populate_some functions are now
dead code and can be removed.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 183 -----------------------------------------------------
1 files changed, 0 insertions(+), 183 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index eb9ac84..9d63127 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1543,94 +1543,6 @@ int of_set_property(struct device_node *np, const char *name, const void *val, i
return 0;
}
-static struct device_d *add_of_amba_device(struct device_node *node)
-{
- struct amba_device *dev;
- char *name, *at;
-
- dev = xzalloc(sizeof(*dev));
-
- name = xstrdup(node->name);
- at = strchr(name, '@');
- if (at) {
- *at = 0;
- snprintf(dev->dev.name, MAX_DRIVER_NAME, "%s.%s", at + 1, name);
- } else {
- strncpy(dev->dev.name, node->name, MAX_DRIVER_NAME);
- }
-
- dev->dev.id = DEVICE_ID_SINGLE;
- memcpy(&dev->res, &node->resource[0], sizeof(struct resource));
- dev->dev.resource = node->resource;
- dev->dev.num_resources = 1;
- dev->dev.device_node = node;
- node->device = &dev->dev;
-
- of_property_read_u32(node, "arm,primecell-periphid", &dev->periphid);
-
- debug("register device 0x%08x\n", node->resource[0].start);
-
- amba_device_add(dev);
-
- free(name);
-
- return &dev->dev;
-}
-
-static struct device_d *add_of_platform_device(struct device_node *node,
- struct device_d *parent)
-{
- struct device_d *dev;
- char *name, *at;
-
- dev = xzalloc(sizeof(*dev));
-
- dev->parent = parent;
-
- name = xstrdup(node->name);
- at = strchr(name, '@');
- if (at) {
- *at = 0;
- snprintf(dev->name, MAX_DRIVER_NAME, "%s.%s", at + 1, name);
- } else {
- strncpy(dev->name, node->name, MAX_DRIVER_NAME);
- }
-
- dev->id = DEVICE_ID_SINGLE;
- dev->resource = node->resource;
- dev->num_resources = node->num_resource;
- dev->device_node = node;
- node->device = dev;
-
- debug("register device 0x%08x\n", node->resource[0].start);
-
- platform_device_register(dev);
-
- free(name);
-
- return dev;
-}
-
-static struct device_d *add_of_device(struct device_node *node,
- struct device_d *parent)
-{
- const struct property *cp;
-
- if (!of_device_is_available(node))
- return NULL;
-
- cp = of_get_property(node, "compatible", NULL);
- if (!cp)
- return NULL;
-
- if (IS_ENABLED(CONFIG_ARM_AMBA) &&
- of_device_is_compatible(node, "arm,primecell") == 1)
- return add_of_amba_device(node);
- else
- return add_of_platform_device(node, parent);
-}
-EXPORT_SYMBOL(add_of_device);
-
static u64 dt_mem_next_cell(int s, const __be32 **cellp)
{
const __be32 *p = *cellp;
@@ -1678,82 +1590,6 @@ int of_add_memory(struct device_node *node, bool dump)
return 0;
}
-static struct device_d *add_of_device_resource(struct device_node *node,
- struct device_d *parent)
-{
- u64 address = 0, size;
- struct resource *res, *resp;
- struct device_d *dev;
- const __be32 *endp, *reg;
- const char *resname;
- int na, nc, n_resources;
- int ret, len, index;
-
- reg = of_get_property(node, "reg", &len);
- if (!reg)
- return add_of_device(node, parent);
-
- of_bus_count_cells(node, &na, &nc);
-
- n_resources = (len / sizeof(__be32)) / (na + nc);
-
- res = resp = xzalloc(sizeof(*res) * n_resources);
-
- endp = reg + (len / sizeof(__be32));
-
- index = 0;
-
- while ((endp - reg) >= (na + nc)) {
- address = of_translate_address(node, reg);
- if (address == OF_BAD_ADDR) {
- ret = -EINVAL;
- goto err_free;
- }
-
- reg += na;
- size = dt_mem_next_cell(nc, ®);
-
- resp->start = address;
- resp->end = address + size - 1;
- resname = NULL;
- of_property_read_string_index(node, "reg-names", index, &resname);
- if (resname)
- resp->name = xstrdup(resname);
- resp->flags = IORESOURCE_MEM;
- resp++;
- index++;
- }
-
- /*
- * A device may already be registered as platform_device.
- * Instead of registering the same device again, just
- * add this node to the existing device.
- */
- for_each_device(dev) {
- if (!dev->resource)
- continue;
- if (dev->resource->start == res->start &&
- dev->resource->end == res->end) {
- debug("connecting %s to %s\n", node->name, dev_name(dev));
- node->device = dev;
- dev->device_node = node;
- node->resource = dev->resource;
- ret = 0;
- goto err_free;
- }
- }
-
- node->resource = res;
- node->num_resource = n_resources;
-
- return add_of_device(node, parent);
-
-err_free:
- free(res);
-
- return NULL;
-}
-
void of_free(struct device_node *node)
{
struct device_node *n, *nt;
@@ -1787,25 +1623,6 @@ void of_free(struct device_node *node)
of_set_root_node(NULL);
}
-static void __of_probe(struct device_node *node,
- const struct of_device_id *matches,
- struct device_d *parent)
-{
- struct device_node *n;
- struct device_d *dev;
-
- if (node->device)
- return;
-
- dev = add_of_device_resource(node, parent);
-
- if (!of_match_node(matches, node))
- return;
-
- list_for_each_entry(n, &node->children, parent_list)
- __of_probe(n, matches, dev);
-}
-
static void __of_parse_phandles(struct device_node *node)
{
struct device_node *n;
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 08/10] OF: remove device and resource pointer from struct device_node
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (17 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 07/10] OF: base: remove dead device related functions Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 09/10] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 10/10] OF: base: rename of_free to of_delete_node Sebastian Hesselbarth
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
struct device_node has its own resources and a pointer to associated
device_d. With recent platform related OF code, we can convert the
only user of it and remove those pointers from struct device_node.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v3:
- remove gpio related changes as there is now a separate patch
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 8 ++++----
include/of.h | 3 ---
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 9d63127..0244281 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1594,6 +1594,7 @@ void of_free(struct device_node *node)
{
struct device_node *n, *nt;
struct property *p, *pt;
+ struct device_d *dev;
if (!node)
return;
@@ -1610,10 +1611,9 @@ void of_free(struct device_node *node)
list_del(&node->list);
}
- if (node->device)
- node->device->device_node = NULL;
- else
- free(node->resource);
+ dev = of_find_device_by_node(node);
+ if (dev)
+ dev->device_node = NULL;
free(node->name);
free(node->full_name);
diff --git a/include/of.h b/include/of.h
index f33ed20..f01d854 100644
--- a/include/of.h
+++ b/include/of.h
@@ -30,9 +30,6 @@ struct device_node {
struct list_head children;
struct list_head parent_list;
struct list_head list;
- struct resource *resource;
- int num_resource;
- struct device_d *device;
struct list_head phandles;
phandle phandle;
};
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 09/10] OF: base: convert of_add_memory to OF API
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (18 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 08/10] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 10/10] OF: base: rename of_free to of_delete_node Sebastian Hesselbarth
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
Convert of_add_memory parsing to make use of of_address_to_resource
instead of parsing memory ranges itself. This makes some functions
dead code which are also removed.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- fix check for return value of of_address_to_resource (Reported by
Sascha Hauer)
Cc: barebox@lists.infradead.org
---
drivers/of/base.c | 57 +++++++---------------------------------------------
1 files changed, 8 insertions(+), 49 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 0244281..1cf7a5f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -99,21 +99,6 @@ int of_n_size_cells(struct device_node *np)
}
EXPORT_SYMBOL(of_n_size_cells);
-static void of_bus_default_count_cells(struct device_node *dev,
- int *addrc, int *sizec)
-{
- if (addrc)
- *addrc = of_n_addr_cells(dev);
- if (sizec)
- *sizec = of_n_size_cells(dev);
-}
-
-static void of_bus_count_cells(struct device_node *dev,
- int *addrc, int *sizec)
-{
- of_bus_default_count_cells(dev, addrc, sizec);
-}
-
struct property *of_find_property(const struct device_node *np,
const char *name, int *lenp)
{
@@ -1543,48 +1528,22 @@ int of_set_property(struct device_node *np, const char *name, const void *val, i
return 0;
}
-static u64 dt_mem_next_cell(int s, const __be32 **cellp)
-{
- const __be32 *p = *cellp;
-
- *cellp = p + s;
- return of_read_number(p, s);
-}
-
int of_add_memory(struct device_node *node, bool dump)
{
- int na, nc;
- const __be32 *reg, *endp;
- int len, r = 0, ret;
const char *device_type;
+ struct resource res;
+ int n = 0, ret;
ret = of_property_read_string(node, "device_type", &device_type);
- if (ret)
+ if (ret || of_node_cmp(device_type, "memory"))
return -ENXIO;
- if (of_node_cmp(device_type, "memory"))
- return -ENXIO;
-
- of_bus_count_cells(node, &na, &nc);
-
- reg = of_get_property(node, "reg", &len);
- if (!reg)
- return -EINVAL;
-
- endp = reg + (len / sizeof(__be32));
-
- while ((endp - reg) >= (na + nc)) {
- u64 base, size;
-
- base = dt_mem_next_cell(na, ®);
- size = dt_mem_next_cell(nc, ®);
-
- if (size == 0)
+ while (!of_address_to_resource(node, n, &res)) {
+ if (!resource_size(&res))
continue;
-
- of_add_memory_bank(node, dump, r, base, size);
-
- r++;
+ of_add_memory_bank(node, dump, n,
+ res.start, resource_size(&res));
+ n++;
}
return 0;
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH v3 10/10] OF: base: rename of_free to of_delete_node
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
` (19 preceding siblings ...)
2013-07-02 18:14 ` [PATCH v3 09/10] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
@ 2013-07-02 18:14 ` Sebastian Hesselbarth
20 siblings, 0 replies; 41+ messages in thread
From: Sebastian Hesselbarth @ 2013-07-02 18:14 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
of_free is misleading about the actual purpose of the function. There is
already a of_create_node counterpart, so rename of_free to of_create_node
and update all users accordingly.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: barebox@lists.infradead.org
---
commands/of_node.c | 2 +-
commands/oftree.c | 4 +-
drivers/of/base.c | 65 +++++++++++++++++++++++++--------------------------
drivers/of/fdt.c | 2 +-
include/of.h | 4 +-
5 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/commands/of_node.c b/commands/of_node.c
index e60ef66..b1894b1 100644
--- a/commands/of_node.c
+++ b/commands/of_node.c
@@ -87,7 +87,7 @@ static int do_of_node(int argc, char *argv[])
return -ENOENT;
}
- of_free(node);
+ of_delete_node(node);
}
return 0;
diff --git a/commands/oftree.c b/commands/oftree.c
index 9149517..00e54dc 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -86,7 +86,7 @@ static int do_oftree(int argc, char *argv[])
struct device_node *root = of_get_root_node();
if (root)
- of_free(root);
+ of_delete_node(root);
return 0;
}
@@ -162,7 +162,7 @@ static int do_oftree(int argc, char *argv[])
goto out;
}
of_print_nodes(root, 0);
- of_free(root);
+ of_delete_node(root);
} else {
struct device_node *n = of_find_node_by_path(node);
if (!n) {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1cf7a5f..e9f1f79 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1549,39 +1549,6 @@ int of_add_memory(struct device_node *node, bool dump)
return 0;
}
-void of_free(struct device_node *node)
-{
- struct device_node *n, *nt;
- struct property *p, *pt;
- struct device_d *dev;
-
- if (!node)
- return;
-
- list_for_each_entry_safe(p, pt, &node->properties, list)
- of_delete_property(p);
-
- list_for_each_entry_safe(n, nt, &node->children, parent_list) {
- of_free(n);
- }
-
- if (node->parent) {
- list_del(&node->parent_list);
- list_del(&node->list);
- }
-
- dev = of_find_device_by_node(node);
- if (dev)
- dev->device_node = NULL;
-
- free(node->name);
- free(node->full_name);
- free(node);
-
- if (node == root_node)
- of_set_root_node(NULL);
-}
-
static void __of_parse_phandles(struct device_node *node)
{
struct device_node *n;
@@ -1679,6 +1646,38 @@ out:
return dn;
}
+void of_delete_node(struct device_node *node)
+{
+ struct device_node *n, *nt;
+ struct property *p, *pt;
+ struct device_d *dev;
+
+ if (!node)
+ return;
+
+ list_for_each_entry_safe(p, pt, &node->properties, list)
+ of_delete_property(p);
+
+ list_for_each_entry_safe(n, nt, &node->children, parent_list)
+ of_delete_node(n);
+
+ if (node->parent) {
+ list_del(&node->parent_list);
+ list_del(&node->list);
+ }
+
+ dev = of_find_device_by_node(node);
+ if (dev)
+ dev->device_node = NULL;
+
+ free(node->name);
+ free(node->full_name);
+ free(node);
+
+ if (node == root_node)
+ of_set_root_node(NULL);
+}
+
int of_device_is_stdout_path(struct device_d *dev)
{
struct device_node *dn;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index afaa4e0..76d6bb1 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -211,7 +211,7 @@ struct device_node *of_unflatten_dtb(struct device_node *root, void *infdt)
}
}
err:
- of_free(root);
+ of_delete_node(root);
return ERR_PTR(ret);
}
diff --git a/include/of.h b/include/of.h
index f01d854..ebe8e39 100644
--- a/include/of.h
+++ b/include/of.h
@@ -139,7 +139,7 @@ extern struct device_node *of_new_node(struct device_node *parent,
const char *name);
extern struct device_node *of_create_node(struct device_node *root,
const char *path);
-extern void of_free(struct device_node *node);
+extern void of_delete_node(struct device_node *node);
extern int of_machine_is_compatible(const char *compat);
extern int of_device_is_compatible(const struct device_node *device,
@@ -508,7 +508,7 @@ static inline struct device_node *of_create_node(struct device_node *root,
return NULL;
}
-static inline void of_free(struct device_node *node)
+static inline void of_delete_node(struct device_node *node)
{
}
--
1.7.2.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v3 00/10] OF: address and device related sync and cleanup
2013-07-02 18:14 ` [PATCH v3 00/10] " Sebastian Hesselbarth
@ 2013-07-05 6:45 ` Sascha Hauer
0 siblings, 0 replies; 41+ messages in thread
From: Sascha Hauer @ 2013-07-05 6:45 UTC (permalink / raw)
To: Sebastian Hesselbarth; +Cc: barebox
On Tue, Jul 02, 2013 at 08:14:29PM +0200, Sebastian Hesselbarth wrote:
> This patch set comprises a quite unsorted bunch of patches to further
> improve and cleanup OF API. With address and device related functions,
> two more API sets of Linux OF API are imported and modified to match
> barebox driver core.
>
> With above API improvements, device and resource pointer are removed
> from struct device_node. Futher, of_translate_address, of_probe, and
> of_add_memory are converted to recently introduced OF API.
>
> At last, of_free is renamed to of_delete_node, which gives a better
> impression of what the function is doing.
>
> v3 of this patch set includes fixes introduced with v2 that have been
> sent as separate patches. Also patch 5 is inserted to not break OF
> gpio parsing with subsequent patches.
>
> This time I have tested the OF gpio patches on Marvell Dove; side
> effect: Orion GPIO driver that I will post as part of the MVEBU DT
> improvement patches.
>
> Sebastian Hesselbarth (10):
> OF: import address related functions from Linux OF API
> OF: convert of_translate_address to new API
> OF: base: move OF_ROOT_NODE_ defines to local OF code
> OF: import bus/device related functions from Linux OF API
> OF: gpio: convert DT based gpio handling to new OF API
> OF: base: use of_platform_populate for probing
> OF: base: remove dead device related functions
> OF: remove device and resource pointer from struct device_node
> OF: base: convert of_add_memory to OF API
> OF: base: rename of_free to of_delete_node
Applied, thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2013-07-05 6:45 UTC | newest]
Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-25 9:20 [PATCH 0/9] OF: address and device related sync and cleanup Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 1/9] OF: import address related functions from Linux OF API Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 2/9] OF: convert of_translate_address to new API Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 3/9] OF: base: move OF_ROOT_NODE_ defines to local OF code Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 4/9] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
2013-06-25 12:55 ` Sebastian Hesselbarth
2013-06-26 6:11 ` Sascha Hauer
2013-06-26 8:23 ` Sebastian Hesselbarth
2013-06-26 8:43 ` [PATCH v2 " Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 5/9] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
2013-06-29 14:22 ` Sascha Hauer
2013-06-25 9:20 ` [PATCH 6/9] OF: base: remove dead device related functions Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 7/9] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
2013-06-29 14:28 ` Sascha Hauer
2013-06-29 14:31 ` Sascha Hauer
2013-06-29 16:03 ` Sebastian Hesselbarth
2013-06-29 16:09 ` Sascha Hauer
2013-06-25 9:20 ` [PATCH 8/9] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
2013-06-25 19:48 ` Sascha Hauer
2013-06-25 19:57 ` Sebastian Hesselbarth
2013-06-25 21:38 ` Sebastian Hesselbarth
2013-06-26 8:43 ` [PATCH v2 " Sebastian Hesselbarth
2013-06-25 9:20 ` [PATCH 9/9] OF: base: rename of_free to of_delete_node Sebastian Hesselbarth
2013-06-27 6:51 ` [PATCH 0/9] OF: address and device related sync and cleanup Sascha Hauer
2013-06-27 7:50 ` Sebastian Hesselbarth
2013-06-27 8:58 ` Sascha Hauer
2013-06-27 9:00 ` Sebastian Hesselbarth
2013-06-27 18:19 ` Sascha Hauer
2013-06-27 18:27 ` Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 00/10] " Sebastian Hesselbarth
2013-07-05 6:45 ` Sascha Hauer
2013-07-02 18:14 ` [PATCH v3 01/10] OF: import address related functions from Linux OF API Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 02/10] OF: convert of_translate_address to new API Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 03/10] OF: base: move OF_ROOT_NODE_ defines to local OF code Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 04/10] OF: import bus/device related functions from Linux OF API Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 05/10] OF: gpio: convert DT based gpio handling to new " Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 06/10] OF: base: use of_platform_populate for probing Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 07/10] OF: base: remove dead device related functions Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 08/10] OF: remove device and resource pointer from struct device_node Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 09/10] OF: base: convert of_add_memory to OF API Sebastian Hesselbarth
2013-07-02 18:14 ` [PATCH v3 10/10] OF: base: rename of_free to of_delete_node Sebastian Hesselbarth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox