diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 32168d3576..05e18bac4c 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -236,7 +236,7 @@ int board_late_init(void)
 	return 0;
 }
 
-int board_fix_fdt(void *rw_fdt_blob)
+int board_fix_fdt_get_info(void)
 {
 	struct udevice *bus = NULL;
 	uint k;
@@ -254,7 +254,23 @@ int board_fix_fdt(void *rw_fdt_blob)
 		snprintf(name, 64,
 			 "/soc/internal-regs/i2c@11000/pca9698@%02x", k);
 
-		if (!dm_i2c_simple_probe(bus, k))
+		gd->board_fixup_data.chip_exists[k - 0x21] = dm_i2c_simple_probe(bus, k);
+	}
+
+	return 0;
+}
+
+int board_fix_fdt_change(void *rw_fdt_blob)
+{
+	struct of_board_fixup_data data = gd->board_fixup_data;
+	uint k;
+	char name[64];
+
+	for (k = 0x21; k <= 0x26; k++) {
+		snprintf(name, 64,
+			 "/soc/internal-regs/i2c@11000/pca9698@%02x", k);
+
+		if (!data.chip_exists[k - 0x21])
 			fdt_disable_by_ofname(rw_fdt_blob, name);
 	}
 
diff --git a/common/board_f.c b/common/board_f.c
index b258a1a73c..b835bd22bc 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -660,9 +660,9 @@ static int setup_reloc(void)
 }
 
 #ifdef CONFIG_OF_BOARD_FIXUP
-static int fix_fdt(void)
+static int fix_fdt_get_info(void)
 {
-	return board_fix_fdt((void *)gd->fdt_blob);
+	return board_fix_fdt_get_info();
 }
 #endif
 
@@ -887,7 +887,7 @@ static const init_fnc_t init_sequence_f[] = {
 #endif
 	display_new_sp,
 #ifdef CONFIG_OF_BOARD_FIXUP
-	fix_fdt,
+	fix_fdt_get_info,
 #endif
 	INIT_FUNC_WATCHDOG_RESET
 	reloc_fdt,
diff --git a/common/board_r.c b/common/board_r.c
index 199cadbed1..25f27f0843 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -694,6 +694,13 @@ static int run_main_loop(void)
 	return 0;
 }
 
+#ifdef CONFIG_OF_BOARD_FIXUP
+static int fix_fdt_change(void)
+{
+	return board_fix_fdt_change((void *)gd->fdt_blob);
+}
+#endif
+
 /*
  * Over time we hope to remove these functions with code fragments and
  * stub funtcions, and instead call the relevant function directly.
@@ -731,6 +738,9 @@ static init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_OF_LIVE
 	initr_of_live,
 #endif
+#ifdef CONFIG_OF_BOARD_FIXUP
+	fix_fdt_change,
+#endif
 #ifdef CONFIG_DM
 	initr_dm,
 #endif
diff --git a/doc/driver-model/fdt-fixup.txt b/doc/driver-model/fdt-fixup.txt
index 70344bd2c3..9a9467edd8 100644
--- a/doc/driver-model/fdt-fixup.txt
+++ b/doc/driver-model/fdt-fixup.txt
@@ -52,81 +52,122 @@ tree (at least after the relocation) would greatly simplify the solution of
 this problem, it is a non-negligible task to implement it, an a interim
 solution is needed to address the problem at least in the medium-term.
 
-Hence, we propose a solution to this problem by offering a board-specific
-call-back function, which is passed a writeable pointer to the device tree.
-This function is called before the device tree is relocated, and specifically
-before the main U-Boot's driver model is instantiated, hence the main U-Boot
-"sees" all modifications to the device tree made in this function. Furthermore,
-we have the pre-relocation driver model at our disposal at this stage, which
-means that we can query the hardware for the existence and variety of the
-components easily.
+Hence, we propose a solution to this problem by offering a set of two board-specific
+call-back functions:
+
+ * One function which is called prior to relocation that gathers information
+   about the device using the pre-relocation DM instance and stores the
+   collected information in a special data structure within the global data
+   section; using the pre-relocation driver model means that we can query the
+   hardware for the existence and variety of the components easily.
+ * A second function which is called just after relocation, but before the
+   post-relocation DM is instantiated; it is passed a writeable pointer to the
+   device tree, so that it can exectute the actual modifications of the device
+   tree based upon the information gathered by the first function.
+
+Notice that since the "modification function" is called prior to the DM
+instantiation, the main U-Boot "sees" all modifications to the device tree made
+by the function.
 
 2. Implementation
 -----------------
 
 To take advantage of the pre-relocation device tree manipulation mechanism,
-boards have to implement the function board_fix_fdt, which has the following
-signature:
+boards have to implement the functions board_fix_fdt_get_info and
+board_fix_fdt_change, which have the following signatures:
 
-int board_fix_fdt (void *rw_fdt_blob)
+int board_fix_fdt_get_info (void)
+int board_fix_fdt_change (void *rw_fdt_blob)
 
-The passed-in void pointer is a writeable pointer to the device tree, which can
-be used to manipulate the device tree using e.g. functions from
-include/fdt_support.h. The return value should either be 0 in case of
-successful execution of the device tree manipulation or something else for a
+The void pointer passed to board_fix_fdt_change is a writeable pointer to the
+device tree, which can be used to manipulate the device tree using e.g.
+functions from include/fdt_support.h. The return value for both functions
+should either be 0 in case of successful execution of the device information
+gathering and device tree manipulation respectively or something else for a
 failure. Note that returning a non-null value from the function will
 unrecoverably halt the boot process, as with any function from init_sequence_f
-(in common/board_f.c).
+(in common/board_f.c) or init_sequence_r (in common/board_r.c).  .
 
-Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
+Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the functions
 to be called:
 
 Device Tree Control
 -> [*] Board-specific manipulation of Device Tree
 
-+----------------------------------------------------------+
-| WARNING: The actual manipulation of the device tree has  |
-| to be the _last_ set of operations in board_fix_fdt!     |
-| Since the pre-relocation driver model does not adapt to  |
-| changes made to the device tree either, its references   |
-| into the device tree will be invalid after manipulating  |
-| it, and unpredictable behavior might occur when          |
-| functions that rely on them are executed!                |
-+----------------------------------------------------------+
+The transfer of the collected device information is accomplished via the
+board_fixup_data sub-structure in the global data structure. The layout of this
+structure is board-defined, and every user of the mechanism should define a
+suitable set of fields in include/fdt_fixup.h surrounded by preprocessor #ifdef
+instructions. For example, a board with the target Kconfig variable
+CONFIG_TARGET_SAMPLEBOARD that needs to check the existence of two I2C devices
+and has to determine a board variant identified by an int, might add the
+following member declarations for itself:
 
-Hence, the recommended layout of the board_fixup_fdt call-back function is the
-following:
+#ifdef CONFIG_TARGET_SAMPLEBOARD
+    bool chip1_present;
+    bool chip2_present;
+    int variant;
+#endif
 
-int board_fix_fdt(void *rw_fdt_blob)
+A schemetic implementation of the two functions might then look like the following:
+
+int board_fix_fdt_get_info(void)
 {
 	/* Collect information about device's hardware and store them in e.g.
-	   local variables */
+       local variables, e.g. chip1_present, chip2_present, variant. Return a
+       non-zero value if the information gathering failed. */
+
+    /* Store the collected information in the sub-structure, so they will be
+       available to board_fix_fdt_change: */
 
-	/* Do device tree manipulation using the values previously collected */
+    gd->board_fixup_data.chip1_present = chip1_present;
+    gd->board_fixup_data.chip2_present = chip2_present;
+    gd->board_fixup_data.variant = variant;
 
-	/* Return 0 on successful manipulation and non-zero otherwise */
+    return 0;
 }
 
-If this convention is kept, both an "additive" approach, meaning that nodes for
-detected components are added to the device tree, as well as a "subtractive"
-approach, meaning that nodes for absent components are removed from the tree,
-as well as a combination of both approaches should work.
+int board_fix_fdt_change(void *rw_fdt_blob)
+{
+    /* Read back the information from the sub-structure: */
+
+    bool chip1_present = gd->board_fixup_data.chip1_present;
+    bool chip2_present = gd->board_fixup_data.chip2_present;
+    int variant = gd->board_fixup_data.variant;
+
+    /* Employ device tree manipulation based on the information: */
+
+    if (chip1_present) {
+        ...
+    }
+
+    if (chip2_present) {
+        ...
+    }
+
+    switch(variant)
+        ...
+    }
+}
+
+This convention of split functions also enables that both an "additive"
+approach for DT manipulation, meaning that nodes for detected components are
+added to the device tree, as well as a "subtractive" approach, meaning that
+nodes for absent components are removed from the tree, as well as a combination
+of both approaches should work.
 
 3. Example
 ----------
 
-The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
-board_fix_fdt function, in which six GPIO expanders (which might be present or
+The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features
+board_fix_fdt functions, in which six GPIO expanders (which might be present or
 not, since they are on daughter boards) on a I2C bus are queried for, and
 subsequently deactivated in the device tree if they are not present.
 
-Note that the dm_i2c_simple_probe function does not use the device tree, hence
-it is safe to call it after the tree has already been manipulated.
-
 4. Work to be done
 ------------------
 
-* The application of device tree overlay should be possible in board_fixup_fdt,
-  but has not been tested at this stage.
+* The application of device tree overlay should be possible in
+  board_fixup_fdt_change, but has not been tested at this stage.
 
-2017-01-06, Mario Six <mario.six@gdsys.cc>
+2017-07-04, Mario Six <mario.six@gdsys.cc>
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index fb90be9d3e..731a4163a9 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -24,6 +24,10 @@
 #include <membuff.h>
 #include <linux/list.h>
 
+#ifdef CONFIG_OF_BOARD_FIXUP
+#include <fdt_fixup.h>
+#endif
+
 typedef struct global_data {
 	bd_t *bd;
 	unsigned long flags;
@@ -75,6 +79,9 @@ typedef struct global_data {
 #ifdef CONFIG_OF_LIVE
 	struct device_node *of_root;
 #endif
+#ifdef CONFIG_OF_BOARD_FIXUP
+	struct of_board_fixup_data board_fixup_data;
+#endif
 	struct jt_funcs *jt;		/* jump table */
 	char env_buf[32];		/* buffer for getenv() before reloc. */
 #ifdef CONFIG_TRACE
diff --git a/include/common.h b/include/common.h
index 751665f8a4..80a004d4b4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -416,7 +416,8 @@ extern ssize_t spi_write (uchar *, int, uchar *, int);
 
 /* $(BOARD)/$(BOARD).c */
 int board_early_init_f (void);
-int board_fix_fdt (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */
+int board_fix_fdt_get_info (void); /* manipulate the U-Boot fdt before its relocation */
+int board_fix_fdt_change (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */
 int board_late_init (void);
 int board_postclk_init (void); /* after clocks/timebase, before env/serial */
 int board_early_init_r (void);
diff --git a/include/fdt_fixup.h b/include/fdt_fixup.h
new file mode 100644
index 0000000000..9390f0a633
--- /dev/null
+++ b/include/fdt_fixup.h
@@ -0,0 +1,5 @@
+struct of_board_fixup_data {
+#ifdef CONFIG_TARGET_CONTROLCENTERDC
+	bool chip_exists[6];
+#endif
+};
