fdt: Add fdt_node_offset_by_compat_reg helper
authorKumar Gala <galak@kernel.crashing.org>
Sun, 4 Jul 2010 17:48:21 +0000 (12:48 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Tue, 20 Jul 2010 09:40:06 +0000 (04:40 -0500)
Given a compatible string and physical address try and find a node that
matches.  This is useful when we want to find a specific device node to
update (for example if we have multiple PCI nodes we can use the
physical address to distinguish them when trying to update the device
tree).

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Gerald Van Baren <vanbaren@cideas.com>
common/fdt_support.c
include/fdt_support.h

index 70ad81d298089044070949ade26f5bb38519b5d0..718b635d99bb92f4366ff15492f6ad04fec0d5d6 100644 (file)
@@ -1125,3 +1125,30 @@ u64 fdt_translate_address(void *blob, int node_offset, const u32 *in_addr)
 {
        return __of_translate_address(blob, node_offset, in_addr, "ranges");
 }
+
+/**
+ * fdt_node_offset_by_compat_reg: Find a node that matches compatiable and
+ * who's reg property matches a physical cpu address
+ *
+ * @blob: ptr to device tree
+ * @compat: compatiable string to match
+ * @compat_off: property name
+ *
+ */
+int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
+                                       phys_addr_t compat_off)
+{
+       int len, off = fdt_node_offset_by_compatible(blob, -1, compat);
+       while (off != -FDT_ERR_NOTFOUND) {
+               u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", &len);
+               if (reg) {
+                       if (compat_off == fdt_translate_address(blob, off, reg))
+                               return off;
+               }
+               off = fdt_node_offset_by_compatible(blob, off, compat);
+       }
+
+       return -FDT_ERR_NOTFOUND;
+}
+
+
index 78c38b2963d1eeecc906a8becc04917ecb10ac7b..54af9fe712be655434051f6ffb021ad61de78c14 100644 (file)
@@ -84,6 +84,8 @@ int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size);
 void fdt_fixup_mtdparts(void *fdt, void *node_info, int node_info_size);
 void fdt_del_node_and_alias(void *blob, const char *alias);
 u64 fdt_translate_address(void *blob, int node_offset, const u32 *in_addr);
+int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
+                                       phys_addr_t compat_off);
 
 #endif /* ifdef CONFIG_OF_LIBFDT */
 #endif /* ifndef __FDT_SUPPORT_H */