On my x86 platform I've noticed, that calling dm_uninit() or the new function dm_remove_devices_flags() does not remove the desired device at all. Debugging showed, that the serial uclass returns -EPERM in serial_pre_remove() and this leads to a complete stop of the device removal pretty early, as the serial device is one of the first ones in the DM. Here the dm tree output:
=> dm tree Class Probed Name ---------------------------------------- root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw serial [ + ] |-- serial rtc [ ] |-- rtc timer [ + ] |-- tsc-timer syscon [ + ] |-- pch_pinctrl ... In this example, device_remove(root) will stop directly after trying to remove the "serial" device. To solve this problem, this patch removes the return upon error check in the device_remove() call in device_chld_remove(). This leads to device_chld_remove() continuing with the device_remove() call to the following child devices. Signed-off-by: Stefan Roese <s...@denx.de> Cc: Simon Glass <s...@chromium.org> Cc: Bin Meng <bmeng...@gmail.com> --- v2: - Add debug() output in error case drivers/core/device-remove.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index cc0043b990..a1c0103af0 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -58,8 +58,14 @@ static int device_chld_remove(struct udevice *dev, uint flags) list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) { ret = device_remove(pos, flags); - if (ret) - return ret; + /* + * Don't stop on error here, the remaining child devices still + * need to get removed. + */ + if (ret) { + debug("%s: device_remove(%s) returned %d\n", + __func__, pos->name, ret); + } } return 0; -- 2.12.2 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot