]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[fdt] Use phandle as device location
authorMichael Brown <mcb30@ipxe.org>
Mon, 4 Aug 2025 13:52:00 +0000 (14:52 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 4 Aug 2025 13:52:00 +0000 (14:52 +0100)
Consumption of phandles will be in the form of locating a functional
device (e.g. a GPIO device, or an I2C device, or a reset controller)
by phandle, rather than locating the device tree node to which the
phandle refers.

Repurpose fdt_phandle() to obtain the phandle value (instead of
searching by phandle), and record this value as the bus location
within the generic device structure.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/fdt.c
src/drivers/bus/devtree.c
src/include/ipxe/fdt.h
src/tests/fdt_test.c

index 6989690bf3130112fa9cf1c9fd48dc88592236bd..ae723213bedf979c1b1094c8680ac16506548549 100644 (file)
@@ -482,57 +482,6 @@ int fdt_alias ( struct fdt *fdt, const char *name, unsigned int *offset ) {
        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
  *
@@ -730,6 +679,28 @@ int fdt_u32 ( struct fdt *fdt, unsigned int offset, const char *name,
        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
  *
index 59bbc9bf7faa6ddd75b00a4d169317cf438917ba..cd5bb09a055d870944e0dbef4b3b024013fbcae3 100644 (file)
@@ -219,6 +219,7 @@ int dt_probe_node ( struct device *parent, unsigned int offset ) {
        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 );
index c73389ad78807c469b7580375b2a88f17bf9c15f..eec02c5b36f4f82399128753e3b3238ab1d422ee 100644 (file)
@@ -176,8 +176,6 @@ extern int fdt_path ( struct fdt *fdt, const char *path,
                      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,
@@ -189,6 +187,7 @@ extern int fdt_u64 ( struct fdt *fdt, unsigned int offset, const char *name,
                     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,
index 099a093b426260242401f9fda03cbf1a8377ef2a..07f7e89114ed311be4a185c7a171d39e84944b7c 100644 (file)
@@ -237,6 +237,16 @@ static void fdt_test_exec ( void ) {
        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 );
@@ -261,15 +271,6 @@ static void fdt_test_exec ( void ) {
        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 );