[PATCH 1/3] drivers: of: import PCI bus specific translator
Sebastian Hesselbarth
sebastian.hesselbarth at gmail.com
Tue Jun 24 04:45:34 PDT 2014
DT PCI address translation needs a special handling. This imports
the corresponding translator into of/address.c but makes it selectable
through Kconfig. Compared to the Linux version, we don't check for
struct device_node's type which does not exist on Barebox but directly
for device_type property set to "pci".
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
Cc: barebox at lists.infradead.org
---
drivers/of/Kconfig | 3 ++
drivers/of/address.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c4525cbffcc4..45f77a759fd4 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -15,6 +15,9 @@ config OFDEVICE
select DTC
bool "Enable probing of devices from the devicetree"
+config OF_ADDRESS_PCI
+ bool
+
config OF_NET
depends on NET
def_bool y
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 4cacdb1cf78e..b3cbb154539a 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -108,11 +108,94 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
return IORESOURCE_MEM;
}
+#ifdef CONFIG_OF_ADDRESS_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+ return !of_property_match_string(np, "device_type", "pci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 3;
+ if (sizec)
+ *sizec = 2;
+}
+
+static unsigned int of_bus_pci_get_flags(const __be32 *addr)
+{
+ unsigned int flags = 0;
+ u32 w = be32_to_cpup(addr);
+
+ switch ((w >> 24) & 0x03) {
+ case 0x01:
+ flags |= IORESOURCE_IO;
+ break;
+ case 0x02: /* 32 bits */
+ case 0x03: /* 64 bits */
+ flags |= IORESOURCE_MEM;
+ break;
+ }
+ if (w & 0x40000000)
+ flags |= IORESOURCE_PREFETCH;
+ return flags;
+}
+
+static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns,
+ int pna)
+{
+ u64 cp, s, da;
+ unsigned int af, rf;
+
+ af = of_bus_pci_get_flags(addr);
+ rf = of_bus_pci_get_flags(range);
+
+ /* Check address type match */
+ if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_number(range + 1, na - 1);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr + 1, na - 1);
+
+ pr_debug("OF: PCI map, cp=%llx, s=%llx, da=%llx\n",
+ (unsigned long long)cp, (unsigned long long)s,
+ (unsigned long long)da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
+{
+ return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+#endif /* CONFIG_OF_ADDRESS_PCI */
+
/*
* Array of bus specific translators
*/
static struct of_bus of_busses[] = {
+#ifdef CONFIG_OF_ADDRESS_PCI
+ /* PCI */
+ {
+ .name = "pci",
+ .addresses = "assigned-addresses",
+ .match = of_bus_pci_match,
+ .count_cells = of_bus_pci_count_cells,
+ .map = of_bus_pci_map,
+ .translate = of_bus_pci_translate,
+ .get_flags = of_bus_pci_get_flags,
+ },
+#endif
/* Default */
{
.name = "default",
--
2.0.0
More information about the barebox
mailing list