Calling device_chld_remove() before flags_remove() means all devices
get removed no matter whether they should be removed late or not. This
breaks teardown of eMMC when booting and other critical boot paths.

Fixes: c51d2e704a1 ("dm: core: Avoid partially removing devices")
Signed-off-by: Marek Vasut <ma...@denx.de>
Cc: Simon Glass <s...@chromium.org>
---
 drivers/core/device-remove.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index e6ec6ff4212..0454f55c330 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -207,14 +207,6 @@ int device_remove(struct udevice *dev, uint flags)
        if (!(dev_get_flags(dev) & DM_FLAG_ACTIVATED))
                return 0;
 
-       /*
-        * If the child returns EKEYREJECTED, continue. It just means that it
-        * didn't match the flags.
-        */
-       ret = device_chld_remove(dev, NULL, flags);
-       if (ret && ret != -EKEYREJECTED)
-               return ret;
-
        /*
         * Remove the device if called with the "normal" remove flag set,
         * or if the remove flag matches any of the drivers remove flags
@@ -228,6 +220,14 @@ int device_remove(struct udevice *dev, uint flags)
                return ret;
        }
 
+       /*
+        * If the child returns EKEYREJECTED, continue. It just means that it
+        * didn't match the flags.
+        */
+       ret = device_chld_remove(dev, NULL, flags);
+       if (ret && ret != -EKEYREJECTED)
+               return ret;
+
        ret = uclass_pre_remove_device(dev);
        if (ret)
                return ret;
-- 
2.34.1

Reply via email to