return 0;
}
-/**
- * Find node by package handle (phandle)
- *
- * @v fdt Device tree
- * @v phandle Package handle
- * @v offset Offset to fill in
- * @ret rc Return status code
- */
-int fdt_phandle ( struct fdt *fdt, uint32_t phandle, unsigned int *offset ) {
- struct fdt_descriptor desc;
- uint32_t value;
- int depth;
- int rc;
-
- /* Initialise offset */
- *offset = 0;
-
- /* Find node with matching phandle */
- for ( depth = -1 ; ; depth += desc.depth, *offset = desc.next ) {
-
- /* Describe token */
- if ( ( rc = fdt_describe ( fdt, *offset, &desc ) ) != 0 ) {
- DBGC ( fdt, "FDT +%#04x has malformed node: %s\n",
- *offset, strerror ( rc ) );
- return rc;
- }
-
- /* Terminate when we exit the root node */
- if ( ( depth == 0 ) && ( desc.depth < 0 ) )
- break;
-
- /* Ignore non-nodes */
- if ( ( ! desc.name ) || desc.data )
- continue;
-
- /* Check for matching "phandle" or "linux-phandle" property */
- if ( ( ( ( rc = fdt_u32 ( fdt, *offset, "phandle",
- &value ) ) == 0 ) ||
- ( ( rc = fdt_u32 ( fdt, *offset, "linux,phandle",
- &value ) ) == 0 ) ) &&
- ( value == phandle ) ) {
- DBGC2 ( fdt, "FDT +%#04x has phandle %#02x\n",
- *offset, phandle );
- return 0;
- }
- }
-
- DBGC ( fdt, "FDT has no phandle %#02x\n", phandle );
- return -ENOENT;
-}
-
/**
* Find property
*
return 0;
}
+/**
+ * Get package handle (phandle) property
+ *
+ * @v fdt Device tree
+ * @v offset Starting node offset
+ * @ret phandle Package handle, or 0 on error
+ */
+uint32_t fdt_phandle ( struct fdt *fdt, unsigned int offset ) {
+ uint32_t phandle;
+ int rc;
+
+ /* Get "phandle" or "linux,phandle" property */
+ if ( ( ( rc = fdt_u32 ( fdt, offset, "phandle", &phandle ) ) == 0 ) ||
+ ( ( rc = fdt_u32 ( fdt, offset, "linux,phandle",
+ &phandle ) ) == 0 ) ) {
+ assert ( phandle != 0 );
+ return phandle;
+ }
+
+ return 0;
+}
+
/**
* Get region cell size specification
*
dt->name = dt->dev.name;
snprintf ( dt->dev.name, sizeof ( dt->dev.name ), "%s", name );
dt->dev.desc.bus_type = BUS_TYPE_DT;
+ dt->dev.desc.location = fdt_phandle ( &sysfdt, offset );
dt->dev.parent = parent;
INIT_LIST_HEAD ( &dt->dev.children );
list_add_tail ( &dt->dev.siblings, &parent->children );
unsigned int *offset );
extern int fdt_alias ( struct fdt *fdt, const char *name,
unsigned int *offset );
-extern int fdt_phandle ( struct fdt *fdt, uint32_t phandle,
- unsigned int *offset );
extern const char * fdt_strings ( struct fdt *fdt, unsigned int offset,
const char *name, unsigned int *count );
extern const char * fdt_string ( struct fdt *fdt, unsigned int offset,
uint64_t *value );
extern int fdt_u32 ( struct fdt *fdt, unsigned int offset, const char *name,
uint32_t *value );
+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_reg_count ( struct fdt *fdt, unsigned int offset,
ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 );
ok ( fdt_u32 ( &fdt, offset, "max-speed", &u32 ) != 0 );
+ /* Verify phandle properties */
+ ok ( fdt_path ( &fdt, "/cpus/cpu@0/interrupt-controller",
+ &offset ) == 0 );
+ ok ( fdt_phandle ( &fdt, offset ) == 0x03 );
+ ok ( fdt_path ( &fdt, "/soc/ethernet@10090000/ethernet-phy@0",
+ &offset ) == 0 );
+ ok ( fdt_phandle ( &fdt, offset ) == 0x08 );
+ ok ( fdt_path ( &fdt, "/soc/serial@10010000", &offset ) == 0 );
+ ok ( fdt_phandle ( &fdt, offset ) == 0 );
+
/* Verify cell properties */
ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 );
ok ( fdt_cells ( &fdt, offset, "reg", 4, 2, &u64 ) == 0 );
ok ( ( string = fdt_string ( &fdt, offset, "phy-mode" ) ) != NULL );
ok ( strcmp ( string, "gmii" ) == 0 );
- /* Verify phandle lookup */
- ok ( fdt_phandle ( &fdt, 0x03, &offset ) == 0 );
- ok ( fdt_describe ( &fdt, offset, &desc ) == 0 );
- ok ( strcmp ( desc.name, "interrupt-controller" ) == 0 );
- ok ( fdt_phandle ( &fdt, 0x08, &offset ) == 0 );
- ok ( fdt_describe ( &fdt, offset, &desc ) == 0 );
- ok ( strcmp ( desc.name, "ethernet-phy@0" ) == 0 );
- ok ( fdt_phandle ( &fdt, 0x2a, &offset ) != 0 );
-
/* Verify node description */
ok ( fdt_path ( &fdt, "/memory@80000000", &offset ) == 0 );
ok ( fdt_describe ( &fdt, offset, &desc ) == 0 );