summaryrefslogtreecommitdiff
path: root/drivers/core
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-03-18 18:36:50 -0600
committerTom Rini <[email protected]>2026-03-18 18:36:50 -0600
commiteb00c710508d09b2a3b9aca75dd18280f1304703 (patch)
treef91864725bde06d16a7243e0a539b28b03c0f125 /drivers/core
parent28608c808774a39ec47d31353b141db547136e58 (diff)
parentdc88ac7681084b2aff8c3c4e1bb3e861451489a3 (diff)
Merge patch series "bootm: Clean up arch-specific, pre-OS clean-up"
Simon Glass <[email protected]> says: Each arch does something slightly different before booting the OS. Some archs even do different things depending on the CPU type. It is quite hard to know what actually happens in the final milliseconds before the OS boot. This series attempts to start cleaning up U-Boot in this area. The basic intent is to create a new bootm_final() function which can be called by all archs. It provides some flags for a couple of necessary variations but otherwise it is generic. All architectures are converted over to use this new function. board_quiesce_devices() is moved into bootm_final() so that all archs benefit from it. This series fixes a bug in device_remove() is fixed where removing a parent with specialised flags (e.g. DM_REMOVE_ACTIVE_ALL) could leave children activated, since they do not match the flags. This fixes is needed to avoid bootm_final() causing test failures on sandbox. Future work could take this a little further: - Convert EFI loader to use the same function - Improve comments for cleanup_before_linux() across architectures - Support fake-run tracing on all archs Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'drivers/core')
-rw-r--r--drivers/core/device-remove.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 437080ed778..557afb8d817 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -198,7 +198,7 @@ static int flags_remove(uint flags, uint drv_flags)
int device_remove(struct udevice *dev, uint flags)
{
const struct driver *drv;
- int ret;
+ int ret, cret;
if (!dev)
return -EINVAL;
@@ -211,24 +211,34 @@ int device_remove(struct udevice *dev, uint flags)
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
+ */
+ drv = dev->driver;
+ assert(drv);
+ cret = flags_remove(flags, drv->flags);
+
+ /*
+ * Remove all children. If this device is being removed due to
+ * active-DMA or OS-prepare flags, drop the active-flag requirement
+ * for children so they are removed even without matching active
+ * flags, since a deactivated device must not have activated
+ * children. Preserve other flags (e.g. DM_REMOVE_NON_VITAL) so
+ * that vital children are still protected.
+ *
* If the child returns EKEYREJECTED, continue. It just means that it
* didn't match the flags.
*/
- ret = device_chld_remove(dev, NULL, flags);
+ ret = device_chld_remove(dev, NULL,
+ cret ? flags :
+ (flags & ~DM_REMOVE_ACTIVE_ALL));
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
- */
- drv = dev->driver;
- assert(drv);
- ret = flags_remove(flags, drv->flags);
- if (ret) {
+ if (cret) {
log_debug("%s: When removing: flags=%x, drv->flags=%x, err=%d\n",
- dev->name, flags, drv->flags, ret);
- return ret;
+ dev->name, flags, drv->flags, cret);
+ return cret;
}
ret = uclass_pre_remove_device(dev);