fdt_support: Add fdt_for_each_node_by_compatible() helper macro

Add macro fdt_for_each_node_by_compatible() to allow iterating over
fdt nodes by compatible string.

Convert various usages of
    off = fdt_node_offset_by_compatible(fdt, start, compat);
    while (off > 0) {
        code();
        off = fdt_node_offset_by_compatible(fdt, off, compat);
    }
and similar, to
    fdt_for_each_node_by_compatible(off, fdt, start, compat)
        code();

Signed-off-by: Marek BehĂșn <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/misc/fsl_portals.c b/drivers/misc/fsl_portals.c
index 02bc3f8..59df57a 100644
--- a/drivers/misc/fsl_portals.c
+++ b/drivers/misc/fsl_portals.c
@@ -208,8 +208,7 @@
 			     maj, min, ip_cfg) + 1;
 	compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1;
 
-	off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal");
-	while (off != -FDT_ERR_NOTFOUND) {
+	fdt_for_each_node_by_compatible(off, blob, -1, "fsl,qman-portal") {
 #if defined(CONFIG_PPC) || defined(CONFIG_ARCH_LS1043A) || \
 defined(CONFIG_ARCH_LS1046A)
 #ifdef CONFIG_FSL_CORENET
@@ -295,9 +294,6 @@
 			       fdt_strerror(err));
 			return;
 		}
-
-		off = fdt_node_offset_by_compatible(blob, off,
-						    "fsl,qman-portal");
 	}
 }
 
diff --git a/drivers/net/fm/fdt.c b/drivers/net/fm/fdt.c
index 3855d7d..9828753 100644
--- a/drivers/net/fm/fdt.c
+++ b/drivers/net/fm/fdt.c
@@ -115,8 +115,7 @@
 	}
 
 	/* Find all other Fman nodes and point them to the firmware node. */
-	while ((fmnode = fdt_node_offset_by_compatible(blob, fmnode,
-		"fsl,fman")) > 0) {
+	fdt_for_each_node_by_compatible(fmnode, blob, fmnode, "fsl,fman") {
 		rc = fdt_setprop_cell(blob, fmnode, "fsl,firmware-phandle",
 				      phandle);
 		if (rc < 0) {
diff --git a/drivers/pci/pcie_layerscape_fixup_common.c b/drivers/pci/pcie_layerscape_fixup_common.c
index faccf6c..095874a 100644
--- a/drivers/pci/pcie_layerscape_fixup_common.c
+++ b/drivers/pci/pcie_layerscape_fixup_common.c
@@ -48,8 +48,7 @@
 	const fdt32_t *prop;
 	u32 ob_wins, ib_wins;
 
-	off = fdt_node_offset_by_compatible(fdt, -1, "fsl,lx2160a-pcie");
-	while (off != -FDT_ERR_NOTFOUND) {
+	fdt_for_each_node_by_compatible(off, fdt, -1, "fsl,lx2160a-pcie") {
 		fdt_setprop(fdt, off, "compatible", "fsl,ls2088a-pcie",
 			    strlen("fsl,ls2088a-pcie") + 1);
 
@@ -89,14 +88,10 @@
 		fdt_setprop(fdt, off, "reg-names", reg_names, names_len);
 		fdt_delprop(fdt, off, "apio-wins");
 		fdt_delprop(fdt, off, "ppio-wins");
-		off = fdt_node_offset_by_compatible(fdt, off,
-						    "fsl,lx2160a-pcie");
 	}
 
 	/* Fixup PCIe EP nodes */
-	off = -1;
-	off = fdt_node_offset_by_compatible(fdt, off, "fsl,lx2160a-pcie-ep");
-	while (off != -FDT_ERR_NOTFOUND) {
+	fdt_for_each_node_by_compatible(off, fdt, -1, "fsl,lx2160a-pcie-ep") {
 		fdt_setprop_string(fdt, off, "compatible",
 				   "fsl,lx2160ar2-pcie-ep");
 		prop = fdt_getprop(fdt, off, "apio-wins", NULL);
@@ -113,9 +108,6 @@
 		fdt_setprop_u32(fdt, off, "num-ib-windows", ib_wins);
 		fdt_setprop_u32(fdt, off, "num-ob-windows", ob_wins);
 		fdt_delprop(fdt, off, "apio-wins");
-
-		off = fdt_node_offset_by_compatible(fdt, off,
-						    "fsl,lx2160a-pcie-ep");
 	}
 
 	return 0;
diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 4104353..7cde59b 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -4,7 +4,7 @@
  */
 
 #include <common.h>
-#include <fdtdec.h>
+#include <fdt_support.h>
 #include <log.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
@@ -985,12 +985,12 @@
 
 static int find_available_node_by_compatible(int offset, const char *compatible)
 {
-	do {
-		offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
-						       compatible);
-	} while (offset > 0 && !fdtdec_get_is_enabled(gd->fdt_blob, offset));
+	fdt_for_each_node_by_compatible(offset, gd->fdt_blob, offset,
+					compatible)
+		if (fdtdec_get_is_enabled(gd->fdt_blob, offset))
+			return offset;
 
-	return offset;
+	return -1;
 }
 
 static bool comphy_a3700_find_lane(const int nodes[3], int node,
diff --git a/drivers/video/meson/simplefb_common.c b/drivers/video/meson/simplefb_common.c
index 8178232..c8b5af5 100644
--- a/drivers/video/meson/simplefb_common.c
+++ b/drivers/video/meson/simplefb_common.c
@@ -7,22 +7,19 @@
  * (C) Copyright 2017 Icenowy Zheng <icenowy@aosc.io>
  */
 
-#include <fdtdec.h>
+#include <fdt_support.h>
 
 int meson_simplefb_fdt_match(void *blob, const char *pipeline)
 {
 	int offset, ret;
 
 	/* Find a prefilled simpefb node, matching out pipeline config */
-	offset = fdt_node_offset_by_compatible(blob, -1,
-					       "amlogic,simple-framebuffer");
-	while (offset >= 0) {
+	fdt_for_each_node_by_compatible(offset, blob, -1,
+					"amlogic,simple-framebuffer") {
 		ret = fdt_stringlist_search(blob, offset, "amlogic,pipeline",
 					    pipeline);
 		if (ret == 0)
 			break;
-		offset = fdt_node_offset_by_compatible(blob, offset,
-						"amlogic,simple-framebuffer");
 	}
 
 	return offset;
diff --git a/drivers/video/sunxi/simplefb_common.c b/drivers/video/sunxi/simplefb_common.c
index df6501e..ce0dc8f 100644
--- a/drivers/video/sunxi/simplefb_common.c
+++ b/drivers/video/sunxi/simplefb_common.c
@@ -7,7 +7,7 @@
  * (C) Copyright 2017 Icenowy Zheng <icenowy@aosc.io>
  */
 
-#include <fdtdec.h>
+#include <fdt_support.h>
 
 int sunxi_simplefb_fdt_match(void *blob, const char *pipeline)
 {
@@ -16,13 +16,12 @@
 	/* Find a prefilled simpefb node, matching out pipeline config */
 	offset = fdt_node_offset_by_compatible(blob, -1,
 					       "allwinner,simple-framebuffer");
-	while (offset >= 0) {
+	fdt_for_each_node_by_compatible(offset, blob, -1,
+					"allwinner,simple-framebuffer") {
 		ret = fdt_stringlist_search(blob, offset, "allwinner,pipeline",
 					    pipeline);
 		if (ret == 0)
 			break;
-		offset = fdt_node_offset_by_compatible(blob, offset,
-						"allwinner,simple-framebuffer");
 	}
 
 	return offset;