Index: sys/dev/fdt/fdt_common.h =================================================================== --- sys/dev/fdt/fdt_common.h +++ sys/dev/fdt/fdt_common.h @@ -88,6 +88,7 @@ int fdt_get_range(phandle_t, int, u_long *, u_long *); int fdt_immr_addr(vm_offset_t); int fdt_regsize(phandle_t, u_long *, u_long *); +int fdt_reg_by_name(phandle_t node, const char *name, u_long *start, u_long *count); int fdt_is_compatible_strict(phandle_t, const char *); int fdt_is_enabled(phandle_t); int fdt_pm_is_enabled(phandle_t); Index: sys/dev/fdt/fdt_common.c =================================================================== --- sys/dev/fdt/fdt_common.c +++ sys/dev/fdt/fdt_common.c @@ -477,6 +477,54 @@ } int +fdt_reg_by_name(phandle_t node, const char *name, u_long *start, u_long *count) +{ + pcell_t *reg, *regptr; + pcell_t addr_cells, size_cells; + int tuple_size, tuples, idx; + long busaddr, bussize; + int rv; + + rv = 0; + regptr = NULL; + if (ofw_bus_find_string_index(node, "reg-names", name, &idx) != 0) + return (EINVAL); + + if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0) + return (ENXIO); + if (fdt_get_range(OF_parent(node), 0, &busaddr, &bussize)) { + busaddr = 0; + bussize = 0; + } + + tuple_size = sizeof(pcell_t) * (addr_cells + size_cells); + tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)®); + debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells); + debugf(dev, "tuples = %d, tuple size = %d\n", tuples, tuple_size); + if (tuples <= 0) { + rv = EINVAL; + goto out; + } + if (idx > tuples - 1) { + rv = EINVAL; + goto out; + } + + regptr = reg; + reg = regptr + ((addr_cells + size_cells) * idx); + fdt_data_to_res(reg, addr_cells, size_cells, start, count); + + *start = *start + busaddr; + *count = *count + bussize; + +out: + if (regptr) + OF_prop_free(regptr); + + return (rv); +} + +int fdt_reg_to_rl(phandle_t node, struct resource_list *rl) { u_long end, count, start;