From: Lucas Stach <dev@lynxeye.de>
To: barebox@lists.infradead.org
Subject: [PATCH 13/15] of: import pci range parser from linux
Date: Thu, 25 Sep 2014 19:05:07 +0200 [thread overview]
Message-ID: <1411664709-13699-14-git-send-email-dev@lynxeye.de> (raw)
In-Reply-To: <1411664709-13699-1-git-send-email-dev@lynxeye.de>
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
drivers/of/address.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/of_address.h | 51 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/drivers/of/address.c b/drivers/of/address.c
index b3cbb15..15f3ade 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -179,6 +179,74 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
}
#endif /* CONFIG_OF_ADDRESS_PCI */
+#ifdef CONFIG_PCI
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node)
+{
+ const int na = 3, ns = 2;
+ int rlen;
+
+ parser->node = node;
+ parser->pna = of_n_addr_cells(node);
+ parser->np = parser->pna + na + ns;
+
+ parser->range = of_get_property(node, "ranges", &rlen);
+ if (parser->range == NULL)
+ return -ENOENT;
+
+ parser->end = parser->range + rlen / sizeof(__be32);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+ struct of_pci_range *range)
+{
+ const int na = 3, ns = 2;
+
+ if (!range)
+ return NULL;
+
+ if (!parser->range || parser->range + parser->np > parser->end)
+ return NULL;
+
+ range->pci_space = parser->range[0];
+ range->flags = of_bus_pci_get_flags(parser->range);
+ range->pci_addr = of_read_number(parser->range + 1, ns);
+ range->cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+ parser->range += parser->np;
+
+ /* Now consume following elements while they are contiguous */
+ while (parser->range + parser->np <= parser->end) {
+ u32 flags, pci_space;
+ u64 pci_addr, cpu_addr, size;
+
+ pci_space = be32_to_cpup(parser->range);
+ flags = of_bus_pci_get_flags(parser->range);
+ pci_addr = of_read_number(parser->range + 1, ns);
+ cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ size = of_read_number(parser->range + parser->pna + na, ns);
+
+ if (flags != range->flags)
+ break;
+ if (pci_addr != range->pci_addr + range->size ||
+ cpu_addr != range->cpu_addr + range->size)
+ break;
+
+ range->size += size;
+ parser->range += parser->np;
+ }
+
+ return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+#endif /* CONFIG_PCI */
+
/*
* Array of bus specific translators
*/
diff --git a/include/of_address.h b/include/of_address.h
index 9022ab7..f9c3c0f 100644
--- a/include/of_address.h
+++ b/include/of_address.h
@@ -4,6 +4,38 @@
#include <common.h>
#include <of.h>
+struct of_pci_range_parser {
+ struct device_node *node;
+ const __be32 *range;
+ const __be32 *end;
+ int np;
+ int pna;
+};
+
+struct of_pci_range {
+ u32 pci_space;
+ u64 pci_addr;
+ u64 cpu_addr;
+ u64 size;
+ u32 flags;
+};
+
+#define for_each_of_pci_range(parser, range) \
+ for (; of_pci_range_parser_one(parser, range);)
+
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+ struct device_node *np,
+ struct resource *res)
+{
+ res->flags = range->flags;
+ res->start = range->cpu_addr;
+ res->end = range->cpu_addr + range->size - 1;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->children);
+ INIT_LIST_HEAD(&res->sibling);
+ res->name = np->full_name;
+}
+
#ifndef pci_address_to_pio
static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
#endif
@@ -23,7 +55,11 @@ 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);
-
+extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node);
+extern struct of_pci_range *of_pci_range_parser_one(
+ struct of_pci_range_parser *parser,
+ struct of_pci_range *range);
#else /* CONFIG_OFTREE */
static inline u64 of_translate_address(struct device_node *dev,
@@ -67,6 +103,19 @@ static inline void __iomem *of_iomap(struct device_node *np, int index)
return NULL;
}
+static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node)
+{
+ return -1;
+}
+
+static inline struct of_pci_range *of_pci_range_parser_one(
+ struct of_pci_range_parser *parser,
+ struct of_pci_range *range)
+{
+ return NULL;
+}
+
#endif /* CONFIG_OFTREE */
#endif /* __OF_ADDRESS_H */
--
1.9.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2014-09-25 17:00 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-25 17:04 [PATCH 00/15] PCI bridges and Tegra PCI stuff Lucas Stach
2014-09-25 17:04 ` [PATCH 01/15] pci: split out device init Lucas Stach
2014-09-25 17:04 ` [PATCH 02/15] pci: add resource enum Lucas Stach
2014-09-25 17:04 ` [PATCH 03/15] pci: properly populate prefetchable BARs Lucas Stach
2014-09-25 17:04 ` [PATCH 04/15] pci: setup bridges and traverse buses behind them Lucas Stach
2014-09-25 17:04 ` [PATCH 05/15] pci: prettyprint device names Lucas Stach
2014-09-25 17:05 ` [PATCH 06/15] pci: track parent<->child relationship Lucas Stach
2014-09-25 17:05 ` [PATCH 07/15] commands: lspci: go down into subordinate busses Lucas Stach
2014-09-25 17:05 ` [PATCH 08/15] clk: tegra: add PLLE setup functions Lucas Stach
2014-09-25 17:05 ` [PATCH 09/15] clk: tegra30: add PCIe clocks Lucas Stach
2014-09-25 17:05 ` [PATCH 10/15] i2c: tegra: move to fs initcall Lucas Stach
2014-09-25 17:05 ` [PATCH 11/15] ARM: tegra: beaver: enable PEX voltage rail Lucas Stach
2014-09-25 17:05 ` [PATCH 12/15] tegra: pmc: add powerdomain handling Lucas Stach
2014-09-25 17:05 ` Lucas Stach [this message]
2014-09-25 17:05 ` [PATCH 14/15] pci: add Tegra host controller driver Lucas Stach
2014-09-25 17:05 ` [PATCH 15/15] ARM: tegra: advertise PCI support Lucas Stach
2014-09-25 19:02 ` [PATCH 00/15] PCI bridges and Tegra PCI stuff Antony Pavlov
2014-09-25 20:46 ` Lucas Stach
2014-10-01 6:17 ` Sascha Hauer
2014-10-01 7:19 ` Antony Pavlov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1411664709-13699-14-git-send-email-dev@lynxeye.de \
--to=dev@lynxeye.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox