regs->stride = ( regs->address_cells + regs->size_cells );
}
+/**
+ * Get parent region cell size specification
+ *
+ * @v fdt Device tree
+ * @v offset Starting node offset
+ * @v regs Region cell size specification to fill in
+ * @ret rc Return status code
+ */
+int fdt_parent_reg_cells ( struct fdt *fdt, unsigned int offset,
+ struct fdt_reg_cells *regs ) {
+ unsigned int parent;
+ int rc;
+
+ /* Get parent node */
+ if ( ( rc = fdt_parent ( fdt, offset, &parent ) ) != 0 )
+ return rc;
+
+ /* Read #address-cells and #size-cells, if present */
+ fdt_reg_cells ( fdt, parent, regs );
+
+ return 0;
+}
+
/**
* Get number of regions
*
return 0;
}
+/**
+ * Get unsized single-entry region address
+ *
+ * @v fdt Device tree
+ * @v offset Starting node offset
+ * @v address Region address to fill in
+ * @ret rc Return status code
+ *
+ * Many region types (e.g. I2C bus addresses) can only ever contain a
+ * single region with no size cells specified.
+ */
+int fdt_reg ( struct fdt *fdt, unsigned int offset, uint64_t *region ) {
+ struct fdt_reg_cells regs;
+ int rc;
+
+ /* Get parent region cell size specification */
+ if ( ( rc = fdt_parent_reg_cells ( fdt, offset, ®s ) ) != 0 )
+ return rc;
+
+ /* Get first region address */
+ if ( ( rc = fdt_reg_address ( fdt, offset, ®s, 0, region ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
/**
* Get MAC address from property
*
void * dt_ioremap ( struct dt_device *dt, unsigned int offset,
unsigned int index, size_t len ) {
struct fdt_reg_cells regs;
- unsigned int parent;
uint64_t address;
uint64_t size;
void *io_addr;
int rc;
- /* Get parent node */
- if ( ( rc = fdt_parent ( &sysfdt, offset, &parent ) ) != 0 ) {
- DBGC ( dt, "DT %s could not locate parent: %s\n",
+ /* Get parent region cell size specification */
+ if ( ( rc = fdt_parent_reg_cells ( &sysfdt, offset, ®s ) ) != 0 ) {
+ DBGC ( dt, "DT %s could not get region cell sizes: %s\n",
dt->name, strerror ( rc ) );
return NULL;
}
- /* Read #address-cells and #size-cells, if present */
- fdt_reg_cells ( &sysfdt, parent, ®s );
-
/* Read address */
if ( ( rc = fdt_reg_address ( &sysfdt, offset, ®s, index,
&address ) ) != 0 ) {
extern uint32_t fdt_phandle ( struct fdt *fdt, unsigned int offset );
extern void fdt_reg_cells ( struct fdt *fdt, unsigned int offset,
struct fdt_reg_cells *regs );
+extern int fdt_parent_reg_cells ( struct fdt *fdt, unsigned int offset,
+ struct fdt_reg_cells *regs );
extern int fdt_reg_count ( struct fdt *fdt, unsigned int offset,
struct fdt_reg_cells *regs );
extern int fdt_reg_address ( struct fdt *fdt, unsigned int offset,
extern int fdt_reg_size ( struct fdt *fdt, unsigned int offset,
struct fdt_reg_cells *regs, unsigned int index,
uint64_t *size );
+extern int fdt_reg ( struct fdt *fdt, unsigned int offset, uint64_t *region );
extern int fdt_mac ( struct fdt *fdt, unsigned int offset,
struct net_device *netdev );
extern int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr,