summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/blk-uclass.c2
-rw-r--r--drivers/block/sandbox.c2
-rw-r--r--drivers/core/device-remove.c26
-rw-r--r--drivers/core/device.c2
-rw-r--r--drivers/core/root.c11
-rw-r--r--drivers/core/uclass.c2
-rw-r--r--drivers/mmc/mmc-uclass.c2
-rw-r--r--drivers/mtd/spi/sandbox.c2
-rw-r--r--drivers/mtd/spi/sf-uclass.c2
-rw-r--r--drivers/spi/spi-uclass.c4
-rw-r--r--drivers/usb/emul/sandbox_hub.c2
-rw-r--r--drivers/usb/host/usb-uclass.c4
12 files changed, 40 insertions, 21 deletions
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 38cb9388da..af3c35f6d0 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -530,7 +530,7 @@ int blk_unbind_all(int if_type)
struct blk_desc *desc = dev_get_uclass_platdata(dev);
if (desc->if_type == if_type) {
- ret = device_remove(dev);
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;
ret = device_unbind(dev);
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 36c2ff3007..34d1c638bc 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -98,7 +98,7 @@ int host_dev_bind(int devnum, char *filename)
/* Remove and unbind the old device, if any */
ret = blk_get_device(IF_TYPE_HOST, devnum, &dev);
if (ret == 0) {
- ret = device_remove(dev);
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;
ret = device_unbind(dev);
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index a7f77b4a21..cc0043b990 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;
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 70fcfc23e0..e1b0ebffc5 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -378,7 +378,7 @@ int device_probe(struct udevice *dev)
return 0;
fail_uclass:
- if (device_remove(dev)) {
+ if (device_remove(dev, DM_REMOVE_NORMAL)) {
dm_warn("%s: Device '%s' failed to remove on error path\n",
__func__, dev->name);
}
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 33cfde6a5c..42679d047c 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -178,12 +178,21 @@ int dm_init(void)
int dm_uninit(void)
{
- device_remove(dm_root());
+ device_remove(dm_root(), DM_REMOVE_NORMAL);
device_unbind(dm_root());
return 0;
}
+#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
+int dm_remove_devices_flags(uint flags)
+{
+ device_remove(dm_root(), flags);
+
+ return 0;
+}
+#endif
+
int dm_scan_platdata(bool pre_reloc_only)
{
int ret;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 7de370644d..d94d43a98d 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -116,7 +116,7 @@ int uclass_destroy(struct uclass *uc)
while (!list_empty(&uc->dev_head)) {
dev = list_first_entry(&uc->dev_head, struct udevice,
uclass_node);
- ret = device_remove(dev);
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;
ret = device_unbind(dev);
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 5bb446bcc2..9c07871d3a 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -232,7 +232,7 @@ int mmc_unbind(struct udevice *dev)
device_find_first_child(dev, &bdev);
if (bdev) {
- device_remove(bdev);
+ device_remove(bdev, DM_REMOVE_NORMAL);
device_unbind(bdev);
}
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 36a50fe3a1..a53f4ebc68 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -595,7 +595,7 @@ void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
struct udevice *dev;
dev = state->spi[busnum][cs].emul;
- device_remove(dev);
+ device_remove(dev, DM_REMOVE_NORMAL);
device_unbind(dev);
state->spi[busnum][cs].emul = NULL;
}
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 19de964e61..83876485fe 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -46,7 +46,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
void spi_flash_free(struct spi_flash *flash)
{
- device_remove(flash->spi->dev);
+ device_remove(flash->spi->dev, DM_REMOVE_NORMAL);
}
int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index ac17da0777..c061c05443 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -343,7 +343,7 @@ err:
debug("%s: Error path, created=%d, device '%s'\n", __func__,
created, dev->name);
if (created) {
- device_remove(dev);
+ device_remove(dev, DM_REMOVE_NORMAL);
device_unbind(dev);
}
@@ -384,7 +384,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
void spi_free_slave(struct spi_slave *slave)
{
- device_remove(slave->dev);
+ device_remove(slave->dev, DM_REMOVE_NORMAL);
slave->dev = NULL;
}
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index c3a8e73389..f0939b19f4 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -156,7 +156,7 @@ static int clrset_post_state(struct udevice *hub, int port, int clear, int set)
} else if (clear & USB_PORT_STAT_POWER) {
debug("%s: %s: power off, removed, ret=%d\n",
__func__, dev->name, ret);
- ret = device_remove(dev);
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
clear |= USB_PORT_STAT_CONNECTION;
}
}
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 5cf1e9a36c..6eded4abad 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -154,7 +154,7 @@ int usb_stop(void)
uc_priv = uc->priv;
uclass_foreach_dev(bus, uc) {
- ret = device_remove(bus);
+ ret = device_remove(bus, DM_REMOVE_NORMAL);
if (ret && !err)
err = ret;
}
@@ -358,7 +358,7 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
if (ret)
return ret;
- ret = device_remove(dev);
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;