staticint of_bus_pci_match(struct device_node *np)
{ if (of_node_is_type(np, "pci") || of_node_is_type(np, "pciex")) { /* Do not do PCI specific frobbing if the * PCI bridge lacks a ranges property. We * want to pass it through up to the next * parent as-is, not with the PCI translate * method which chops off the top address cell.
*/ if (!of_property_present(np, "ranges")) return 0;
return 1;
}
return 0;
}
staticvoid of_bus_pci_count_cells(struct device_node *np, int *addrc, int *sizec)
{ if (addrc)
*addrc = 3; if (sizec)
*sizec = 2;
}
staticint of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
{
u32 result[OF_MAX_ADDR_CELLS]; int i;
/* Check address type match */ if ((addr[0] ^ range[0]) & 0x03000000) return -EINVAL;
if (of_out_of_range(addr + 1, range + 1, range + na + pna,
na - 1, ns)) return -EINVAL;
/* Start with the parent range base. */
memcpy(result, range + na, pna * 4);
/* Add in the child address offset, skipping high cell. */ for (i = 0; i < na - 1; i++)
result[pna - 1 - i] +=
(addr[na - 1 - i] -
range[na - 1 - i]);
staticstruct 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;
}
staticint __init build_one_resource(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus,
u32 *addr, int na, int ns, int pna)
{ const u32 *ranges; unsignedint rlen; int rone;
ranges = of_get_property(parent, "ranges", &rlen); if (ranges == NULL || rlen == 0) {
u32 result[OF_MAX_ADDR_CELLS]; int i;
memset(result, 0, pna * 4); for (i = 0; i < na; i++)
result[pna - 1 - i] =
addr[na - 1 - i];
memcpy(addr, result, pna * 4); return 0;
}
/* Now walk through the ranges */
rlen /= 4;
rone = na + pna + ns; for (; rlen >= rone; rlen -= rone, ranges += rone) { if (!bus->map(addr, ranges, na, ns, pna)) return 0;
}
return 1;
}
staticint __init use_1to1_mapping(struct device_node *pp)
{ /* If we have a ranges property in the parent, use it. */ if (of_property_present(pp, "ranges")) return 0;
/* Some SBUS devices use intermediate nodes to express * hierarchy within the device itself. These aren't * real bus nodes, and don't have a 'ranges' property. * But, we should still pass the translation work up * to the SBUS itself.
*/ if (of_node_name_eq(pp, "dma") ||
of_node_name_eq(pp, "espdma") ||
of_node_name_eq(pp, "ledma") ||
of_node_name_eq(pp, "lebuffer")) return 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.