summaryrefslogtreecommitdiff
path: root/drivers/core/device-remove.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/core/device-remove.c')
-rw-r--r--drivers/core/device-remove.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index a7f77b4..cc0043b 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -46,9 +46,10 @@ static int device_chld_unbind(struct udevice *dev)
/**
* device_chld_remove() - Stop all device's children
* @dev: The device whose children are to be removed
+ * @pre_os_remove: Flag, if this functions is called in the pre-OS stage
* @return 0 on success, -ve on error
*/
-static int device_chld_remove(struct udevice *dev)
+static int device_chld_remove(struct udevice *dev, uint flags)
{
struct udevice *pos, *n;
int ret;
@@ -56,7 +57,7 @@ static int device_chld_remove(struct udevice *dev)
assert(dev);
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
- ret = device_remove(pos);
+ ret = device_remove(pos, flags);
if (ret)
return ret;
}
@@ -151,7 +152,7 @@ void device_free(struct udevice *dev)
devres_release_probe(dev);
}
-int device_remove(struct udevice *dev)
+int device_remove(struct udevice *dev, uint flags)
{
const struct driver *drv;
int ret;
@@ -169,11 +170,17 @@ int device_remove(struct udevice *dev)
if (ret)
return ret;
- ret = device_chld_remove(dev);
+ ret = device_chld_remove(dev, flags);
if (ret)
goto err;
- if (drv->remove) {
+ /*
+ * Remove the device if called with the "normal" remove flag set,
+ * or if the remove flag matches any of the drivers remove flags
+ */
+ if (drv->remove &&
+ ((flags & DM_REMOVE_NORMAL) ||
+ (flags & (drv->flags & DM_FLAG_ACTIVE_DMA)))) {
ret = drv->remove(dev);
if (ret)
goto err_remove;
@@ -187,10 +194,13 @@ int device_remove(struct udevice *dev)
}
}
- device_free(dev);
+ if ((flags & DM_REMOVE_NORMAL) ||
+ (flags & (drv->flags & DM_FLAG_ACTIVE_DMA))) {
+ device_free(dev);
- dev->seq = -1;
- dev->flags &= ~DM_FLAG_ACTIVATED;
+ dev->seq = -1;
+ dev->flags &= ~DM_FLAG_ACTIVATED;
+ }
return ret;