Merge git://git.denx.de/u-boot-dm
This commit is contained in:
commit
433647a7ef
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
|
#include <dm/device.h>
|
||||||
|
#include <dm/root.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <u-boot/zlib.h>
|
#include <u-boot/zlib.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
@ -91,6 +93,13 @@ static void announce_and_cleanup(int fake)
|
|||||||
|
|
||||||
board_quiesce_devices();
|
board_quiesce_devices();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call remove function of all devices with a removal flag set.
|
||||||
|
* This may be useful for last-stage operations, like cancelling
|
||||||
|
* of DMA operation or releasing device internal buffers.
|
||||||
|
*/
|
||||||
|
dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
|
||||||
|
|
||||||
cleanup_before_linux();
|
cleanup_before_linux();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,13 +76,13 @@ static int __maybe_unused disable_igd(void)
|
|||||||
*
|
*
|
||||||
* So the only option we have is to manually remove these two devices.
|
* So the only option we have is to manually remove these two devices.
|
||||||
*/
|
*/
|
||||||
ret = device_remove(igd);
|
ret = device_remove(igd, DM_REMOVE_NORMAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_unbind(igd);
|
ret = device_unbind(igd);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_remove(sdvo);
|
ret = device_remove(sdvo, DM_REMOVE_NORMAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_unbind(sdvo);
|
ret = device_unbind(sdvo);
|
||||||
|
@ -110,7 +110,7 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
/* Remove any existing device */
|
/* Remove any existing device */
|
||||||
ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
|
ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
device_remove(udev);
|
device_remove(udev, DM_REMOVE_NORMAL);
|
||||||
ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
|
ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Could not init cros_ec device (err %d)\n", ret);
|
printf("Could not init cros_ec device (err %d)\n", ret);
|
||||||
|
2
cmd/sf.c
2
cmd/sf.c
@ -124,7 +124,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])
|
|||||||
/* Remove the old device, otherwise probe will just be a nop */
|
/* Remove the old device, otherwise probe will just be a nop */
|
||||||
ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new);
|
ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
device_remove(new);
|
device_remove(new, DM_REMOVE_NORMAL);
|
||||||
}
|
}
|
||||||
flash = NULL;
|
flash = NULL;
|
||||||
ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new);
|
ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new);
|
||||||
|
@ -530,7 +530,7 @@ int blk_unbind_all(int if_type)
|
|||||||
struct blk_desc *desc = dev_get_uclass_platdata(dev);
|
struct blk_desc *desc = dev_get_uclass_platdata(dev);
|
||||||
|
|
||||||
if (desc->if_type == if_type) {
|
if (desc->if_type == if_type) {
|
||||||
ret = device_remove(dev);
|
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_unbind(dev);
|
ret = device_unbind(dev);
|
||||||
|
@ -98,7 +98,7 @@ int host_dev_bind(int devnum, char *filename)
|
|||||||
/* Remove and unbind the old device, if any */
|
/* Remove and unbind the old device, if any */
|
||||||
ret = blk_get_device(IF_TYPE_HOST, devnum, &dev);
|
ret = blk_get_device(IF_TYPE_HOST, devnum, &dev);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = device_remove(dev);
|
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_unbind(dev);
|
ret = device_unbind(dev);
|
||||||
|
@ -46,9 +46,10 @@ static int device_chld_unbind(struct udevice *dev)
|
|||||||
/**
|
/**
|
||||||
* device_chld_remove() - Stop all device's children
|
* device_chld_remove() - Stop all device's children
|
||||||
* @dev: The device whose children are to be removed
|
* @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
|
* @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;
|
struct udevice *pos, *n;
|
||||||
int ret;
|
int ret;
|
||||||
@ -56,7 +57,7 @@ static int device_chld_remove(struct udevice *dev)
|
|||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
|
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
|
||||||
ret = device_remove(pos);
|
ret = device_remove(pos, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -151,7 +152,7 @@ void device_free(struct udevice *dev)
|
|||||||
devres_release_probe(dev);
|
devres_release_probe(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_remove(struct udevice *dev)
|
int device_remove(struct udevice *dev, uint flags)
|
||||||
{
|
{
|
||||||
const struct driver *drv;
|
const struct driver *drv;
|
||||||
int ret;
|
int ret;
|
||||||
@ -169,11 +170,17 @@ int device_remove(struct udevice *dev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = device_chld_remove(dev);
|
ret = device_chld_remove(dev, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
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);
|
ret = drv->remove(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_remove;
|
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->seq = -1;
|
||||||
dev->flags &= ~DM_FLAG_ACTIVATED;
|
dev->flags &= ~DM_FLAG_ACTIVATED;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ int device_probe(struct udevice *dev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail_uclass:
|
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",
|
dm_warn("%s: Device '%s' failed to remove on error path\n",
|
||||||
__func__, dev->name);
|
__func__, dev->name);
|
||||||
}
|
}
|
||||||
|
@ -178,12 +178,21 @@ int dm_init(void)
|
|||||||
|
|
||||||
int dm_uninit(void)
|
int dm_uninit(void)
|
||||||
{
|
{
|
||||||
device_remove(dm_root());
|
device_remove(dm_root(), DM_REMOVE_NORMAL);
|
||||||
device_unbind(dm_root());
|
device_unbind(dm_root());
|
||||||
|
|
||||||
return 0;
|
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 dm_scan_platdata(bool pre_reloc_only)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -116,7 +116,7 @@ int uclass_destroy(struct uclass *uc)
|
|||||||
while (!list_empty(&uc->dev_head)) {
|
while (!list_empty(&uc->dev_head)) {
|
||||||
dev = list_first_entry(&uc->dev_head, struct udevice,
|
dev = list_first_entry(&uc->dev_head, struct udevice,
|
||||||
uclass_node);
|
uclass_node);
|
||||||
ret = device_remove(dev);
|
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_unbind(dev);
|
ret = device_unbind(dev);
|
||||||
|
@ -232,7 +232,7 @@ int mmc_unbind(struct udevice *dev)
|
|||||||
|
|
||||||
device_find_first_child(dev, &bdev);
|
device_find_first_child(dev, &bdev);
|
||||||
if (bdev) {
|
if (bdev) {
|
||||||
device_remove(bdev);
|
device_remove(bdev, DM_REMOVE_NORMAL);
|
||||||
device_unbind(bdev);
|
device_unbind(bdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +595,7 @@ void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
|
|||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
||||||
dev = state->spi[busnum][cs].emul;
|
dev = state->spi[busnum][cs].emul;
|
||||||
device_remove(dev);
|
device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
device_unbind(dev);
|
device_unbind(dev);
|
||||||
state->spi[busnum][cs].emul = NULL;
|
state->spi[busnum][cs].emul = NULL;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
|
|||||||
|
|
||||||
void spi_flash_free(struct spi_flash *flash)
|
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,
|
int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
|
||||||
|
@ -343,7 +343,7 @@ err:
|
|||||||
debug("%s: Error path, created=%d, device '%s'\n", __func__,
|
debug("%s: Error path, created=%d, device '%s'\n", __func__,
|
||||||
created, dev->name);
|
created, dev->name);
|
||||||
if (created) {
|
if (created) {
|
||||||
device_remove(dev);
|
device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
device_unbind(dev);
|
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)
|
void spi_free_slave(struct spi_slave *slave)
|
||||||
{
|
{
|
||||||
device_remove(slave->dev);
|
device_remove(slave->dev, DM_REMOVE_NORMAL);
|
||||||
slave->dev = NULL;
|
slave->dev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
} else if (clear & USB_PORT_STAT_POWER) {
|
||||||
debug("%s: %s: power off, removed, ret=%d\n",
|
debug("%s: %s: power off, removed, ret=%d\n",
|
||||||
__func__, dev->name, ret);
|
__func__, dev->name, ret);
|
||||||
ret = device_remove(dev);
|
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
clear |= USB_PORT_STAT_CONNECTION;
|
clear |= USB_PORT_STAT_CONNECTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ int usb_stop(void)
|
|||||||
uc_priv = uc->priv;
|
uc_priv = uc->priv;
|
||||||
|
|
||||||
uclass_foreach_dev(bus, uc) {
|
uclass_foreach_dev(bus, uc) {
|
||||||
ret = device_remove(bus);
|
ret = device_remove(bus, DM_REMOVE_NORMAL);
|
||||||
if (ret && !err)
|
if (ret && !err)
|
||||||
err = ret;
|
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);
|
ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = device_remove(dev);
|
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -83,8 +83,8 @@ config OF_LIST
|
|||||||
config OF_SPL_REMOVE_PROPS
|
config OF_SPL_REMOVE_PROPS
|
||||||
string "List of device tree properties to drop for SPL"
|
string "List of device tree properties to drop for SPL"
|
||||||
depends on SPL_OF_CONTROL
|
depends on SPL_OF_CONTROL
|
||||||
default "interrupt-parent" if SPL_PINCTRL_FULL && SPL_CLK
|
default "interrupt-parent" if SPL_PINCTRL && SPL_CLK
|
||||||
default "clocks clock-names interrupt-parent" if SPL_PINCTRL_FULL
|
default "clocks clock-names interrupt-parent" if SPL_PINCTRL
|
||||||
default "pinctrl-0 pinctrl-names interrupt-parent" if SPL_CLK
|
default "pinctrl-0 pinctrl-names interrupt-parent" if SPL_CLK
|
||||||
default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent"
|
default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent"
|
||||||
help
|
help
|
||||||
|
@ -96,12 +96,13 @@ int device_probe(struct udevice *dev);
|
|||||||
* children are deactivated first.
|
* children are deactivated first.
|
||||||
*
|
*
|
||||||
* @dev: Pointer to device to remove
|
* @dev: Pointer to device to remove
|
||||||
|
* @flags: Flags for selective device removal
|
||||||
* @return 0 if OK, -ve on error (an error here is normally a very bad thing)
|
* @return 0 if OK, -ve on error (an error here is normally a very bad thing)
|
||||||
*/
|
*/
|
||||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||||
int device_remove(struct udevice *dev);
|
int device_remove(struct udevice *dev, uint flags);
|
||||||
#else
|
#else
|
||||||
static inline int device_remove(struct udevice *dev) { return 0; }
|
static inline int device_remove(struct udevice *dev, uint flags) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,6 +46,32 @@ struct driver_info;
|
|||||||
|
|
||||||
#define DM_FLAG_OF_PLATDATA (1 << 8)
|
#define DM_FLAG_OF_PLATDATA (1 << 8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call driver remove function to stop currently active DMA transfers or
|
||||||
|
* give DMA buffers back to the HW / controller. This may be needed for
|
||||||
|
* some drivers to do some final stage cleanup before the OS is called
|
||||||
|
* (U-Boot exit)
|
||||||
|
*/
|
||||||
|
#define DM_FLAG_ACTIVE_DMA (1 << 9)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One or multiple of these flags are passed to device_remove() so that
|
||||||
|
* a selective device removal as specified by the remove-stage and the
|
||||||
|
* driver flags can be done.
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
/* Normal remove, remove all devices */
|
||||||
|
DM_REMOVE_NORMAL = 1 << 0,
|
||||||
|
|
||||||
|
/* Remove devices with active DMA */
|
||||||
|
DM_REMOVE_ACTIVE_DMA = DM_FLAG_ACTIVE_DMA,
|
||||||
|
|
||||||
|
/* Add more use cases here */
|
||||||
|
|
||||||
|
/* Remove devices with any active flag */
|
||||||
|
DM_REMOVE_ACTIVE_ALL = DM_REMOVE_ACTIVE_DMA,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct udevice - An instance of a driver
|
* struct udevice - An instance of a driver
|
||||||
*
|
*
|
||||||
|
@ -115,4 +115,20 @@ int dm_init(void);
|
|||||||
*/
|
*/
|
||||||
int dm_uninit(void);
|
int dm_uninit(void);
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||||
|
/**
|
||||||
|
* dm_remove_devices_flags - Call remove function of all drivers with
|
||||||
|
* specific removal flags set to selectively
|
||||||
|
* remove drivers
|
||||||
|
*
|
||||||
|
* All devices with the matching flags set will be removed
|
||||||
|
*
|
||||||
|
* @flags: Flags for selective device removal
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int dm_remove_devices_flags(uint flags);
|
||||||
|
#else
|
||||||
|
static inline int dm_remove_devices_flags(uint flags) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -222,7 +222,7 @@ static int test_bus_parent_data(struct unit_test_state *uts)
|
|||||||
/* Check that it starts at 0 and goes away when device is removed */
|
/* Check that it starts at 0 and goes away when device is removed */
|
||||||
parent_data->sum += 5;
|
parent_data->sum += 5;
|
||||||
ut_asserteq(5, parent_data->sum);
|
ut_asserteq(5, parent_data->sum);
|
||||||
device_remove(dev);
|
device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
|
ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
|
||||||
|
|
||||||
/* Check that we can do this twice */
|
/* Check that we can do this twice */
|
||||||
@ -323,7 +323,7 @@ static int dm_test_bus_parent_ops(struct unit_test_state *uts)
|
|||||||
continue;
|
continue;
|
||||||
parent_data = dev_get_parent_priv(dev);
|
parent_data = dev_get_parent_priv(dev);
|
||||||
ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
|
ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
|
||||||
ut_assertok(device_remove(dev));
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
|
ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
|
||||||
ut_asserteq_ptr(dms->removed, dev);
|
ut_asserteq_ptr(dms->removed, dev);
|
||||||
}
|
}
|
||||||
@ -360,7 +360,7 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
|
|||||||
plat->count++;
|
plat->count++;
|
||||||
ut_asserteq(1, plat->count);
|
ut_asserteq(1, plat->count);
|
||||||
device_probe(dev);
|
device_probe(dev);
|
||||||
device_remove(dev);
|
device_remove(dev, DM_REMOVE_NORMAL);
|
||||||
|
|
||||||
ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
|
ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
|
||||||
ut_asserteq(1, plat->count);
|
ut_asserteq(1, plat->count);
|
||||||
@ -370,7 +370,7 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
|
|||||||
ut_asserteq(3, child_count);
|
ut_asserteq(3, child_count);
|
||||||
|
|
||||||
/* Removing the bus should also have no effect (it is still bound) */
|
/* Removing the bus should also have no effect (it is still bound) */
|
||||||
device_remove(bus);
|
device_remove(bus, DM_REMOVE_NORMAL);
|
||||||
for (device_find_first_child(bus, &dev), child_count = 0;
|
for (device_find_first_child(bus, &dev), child_count = 0;
|
||||||
dev;
|
dev;
|
||||||
device_find_next_child(&dev)) {
|
device_find_next_child(&dev)) {
|
||||||
|
@ -67,6 +67,10 @@ static struct driver_info driver_info_pre_reloc = {
|
|||||||
.platdata = &test_pdata_pre_reloc,
|
.platdata = &test_pdata_pre_reloc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct driver_info driver_info_act_dma = {
|
||||||
|
.name = "test_act_dma_drv",
|
||||||
|
};
|
||||||
|
|
||||||
void dm_leak_check_start(struct unit_test_state *uts)
|
void dm_leak_check_start(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
uts->start = mallinfo();
|
uts->start = mallinfo();
|
||||||
@ -319,7 +323,7 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
|
|||||||
|
|
||||||
/* Now remove device 3 */
|
/* Now remove device 3 */
|
||||||
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
|
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
|
||||||
ut_assertok(device_remove(dev));
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
|
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
|
||||||
|
|
||||||
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
|
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
|
||||||
@ -352,7 +356,7 @@ static int dm_test_ordering(struct unit_test_state *uts)
|
|||||||
ut_assert(dev_last);
|
ut_assert(dev_last);
|
||||||
|
|
||||||
/* Now remove device 3 */
|
/* Now remove device 3 */
|
||||||
ut_assertok(device_remove(dev));
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
ut_assertok(device_unbind(dev));
|
ut_assertok(device_unbind(dev));
|
||||||
|
|
||||||
/* The device numbering should have shifted down one */
|
/* The device numbering should have shifted down one */
|
||||||
@ -371,9 +375,9 @@ static int dm_test_ordering(struct unit_test_state *uts)
|
|||||||
ut_assert(pingret == 102);
|
ut_assert(pingret == 102);
|
||||||
|
|
||||||
/* Remove 3 and 4 */
|
/* Remove 3 and 4 */
|
||||||
ut_assertok(device_remove(dev_penultimate));
|
ut_assertok(device_remove(dev_penultimate, DM_REMOVE_NORMAL));
|
||||||
ut_assertok(device_unbind(dev_penultimate));
|
ut_assertok(device_unbind(dev_penultimate));
|
||||||
ut_assertok(device_remove(dev_last));
|
ut_assertok(device_remove(dev_last, DM_REMOVE_NORMAL));
|
||||||
ut_assertok(device_unbind(dev_last));
|
ut_assertok(device_unbind(dev_last));
|
||||||
|
|
||||||
/* Our device should now be in position 3 */
|
/* Our device should now be in position 3 */
|
||||||
@ -381,7 +385,7 @@ static int dm_test_ordering(struct unit_test_state *uts)
|
|||||||
ut_assert(dev == test_dev);
|
ut_assert(dev == test_dev);
|
||||||
|
|
||||||
/* Now remove device 3 */
|
/* Now remove device 3 */
|
||||||
ut_assertok(device_remove(dev));
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
ut_assertok(device_unbind(dev));
|
ut_assertok(device_unbind(dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -457,7 +461,7 @@ static int dm_test_remove(struct unit_test_state *uts)
|
|||||||
ut_assert(dev);
|
ut_assert(dev);
|
||||||
ut_assertf(dev->flags & DM_FLAG_ACTIVATED,
|
ut_assertf(dev->flags & DM_FLAG_ACTIVATED,
|
||||||
"Driver %d/%s not activated", i, dev->name);
|
"Driver %d/%s not activated", i, dev->name);
|
||||||
ut_assertok(device_remove(dev));
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED),
|
ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED),
|
||||||
"Driver %d/%s should have deactivated", i,
|
"Driver %d/%s should have deactivated", i,
|
||||||
dev->name);
|
dev->name);
|
||||||
@ -611,14 +615,14 @@ static int dm_test_children(struct unit_test_state *uts)
|
|||||||
ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
|
ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
|
||||||
|
|
||||||
/* Remove a top-level child and check that the children are removed */
|
/* Remove a top-level child and check that the children are removed */
|
||||||
ut_assertok(device_remove(top[2]));
|
ut_assertok(device_remove(top[2], DM_REMOVE_NORMAL));
|
||||||
ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
|
ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
|
||||||
dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0;
|
dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0;
|
||||||
|
|
||||||
/* Try one with grandchildren */
|
/* Try one with grandchildren */
|
||||||
ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
|
ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
|
||||||
ut_asserteq_ptr(dev, top[5]);
|
ut_asserteq_ptr(dev, top[5]);
|
||||||
ut_assertok(device_remove(dev));
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
|
ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
|
||||||
dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
|
dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
|
||||||
|
|
||||||
@ -656,6 +660,68 @@ static int dm_test_pre_reloc(struct unit_test_state *uts)
|
|||||||
}
|
}
|
||||||
DM_TEST(dm_test_pre_reloc, 0);
|
DM_TEST(dm_test_pre_reloc, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that removal of devices, either via the "normal" device_remove()
|
||||||
|
* API or via the device driver selective flag works as expected
|
||||||
|
*/
|
||||||
|
static int dm_test_remove_active_dma(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct dm_test_state *dms = uts->priv;
|
||||||
|
struct udevice *dev;
|
||||||
|
|
||||||
|
ut_assertok(device_bind_by_name(dms->root, false, &driver_info_act_dma,
|
||||||
|
&dev));
|
||||||
|
ut_assert(dev);
|
||||||
|
|
||||||
|
/* Probe the device */
|
||||||
|
ut_assertok(device_probe(dev));
|
||||||
|
|
||||||
|
/* Test if device is active right now */
|
||||||
|
ut_asserteq(true, device_active(dev));
|
||||||
|
|
||||||
|
/* Remove the device via selective remove flag */
|
||||||
|
dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
|
||||||
|
|
||||||
|
/* Test if device is inactive right now */
|
||||||
|
ut_asserteq(false, device_active(dev));
|
||||||
|
|
||||||
|
/* Probe the device again */
|
||||||
|
ut_assertok(device_probe(dev));
|
||||||
|
|
||||||
|
/* Test if device is active right now */
|
||||||
|
ut_asserteq(true, device_active(dev));
|
||||||
|
|
||||||
|
/* Remove the device via "normal" remove API */
|
||||||
|
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
|
||||||
|
|
||||||
|
/* Test if device is inactive right now */
|
||||||
|
ut_asserteq(false, device_active(dev));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test if a device without the active DMA flags is not removed upon
|
||||||
|
* the active DMA remove call
|
||||||
|
*/
|
||||||
|
ut_assertok(device_unbind(dev));
|
||||||
|
ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
|
||||||
|
&dev));
|
||||||
|
ut_assert(dev);
|
||||||
|
|
||||||
|
/* Probe the device */
|
||||||
|
ut_assertok(device_probe(dev));
|
||||||
|
|
||||||
|
/* Test if device is active right now */
|
||||||
|
ut_asserteq(true, device_active(dev));
|
||||||
|
|
||||||
|
/* Remove the device via selective remove flag */
|
||||||
|
dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
|
||||||
|
|
||||||
|
/* Test if device is still active right now */
|
||||||
|
ut_asserteq(true, device_active(dev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_remove_active_dma, 0);
|
||||||
|
|
||||||
static int dm_test_uclass_before_ready(struct unit_test_state *uts)
|
static int dm_test_uclass_before_ready(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
struct uclass *uc;
|
struct uclass *uc;
|
||||||
|
@ -116,7 +116,7 @@ static int dm_test_eth_act(struct unit_test_state *uts)
|
|||||||
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
|
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
|
||||||
ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
|
ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
|
||||||
ethname[i], &dev[i]));
|
ethname[i], &dev[i]));
|
||||||
ut_assertok(device_remove(dev[i]));
|
ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
|
||||||
|
|
||||||
/* Invalidate MAC address */
|
/* Invalidate MAC address */
|
||||||
strcpy(ethaddr[i], getenv(addrname[i]));
|
strcpy(ethaddr[i], getenv(addrname[i]));
|
||||||
|
@ -36,7 +36,7 @@ static int dm_test_spi_find(struct unit_test_state *uts)
|
|||||||
ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus));
|
ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus));
|
||||||
ut_assertok(spi_cs_info(bus, cs, &info));
|
ut_assertok(spi_cs_info(bus, cs, &info));
|
||||||
of_offset = dev_of_offset(info.dev);
|
of_offset = dev_of_offset(info.dev);
|
||||||
device_remove(info.dev);
|
device_remove(info.dev, DM_REMOVE_NORMAL);
|
||||||
device_unbind(info.dev);
|
device_unbind(info.dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,3 +157,14 @@ U_BOOT_DRIVER(test_pre_reloc_drv) = {
|
|||||||
.unbind = test_manual_unbind,
|
.unbind = test_manual_unbind,
|
||||||
.flags = DM_FLAG_PRE_RELOC,
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(test_act_dma_drv) = {
|
||||||
|
.name = "test_act_dma_drv",
|
||||||
|
.id = UCLASS_TEST,
|
||||||
|
.ops = &test_manual_ops,
|
||||||
|
.bind = test_manual_bind,
|
||||||
|
.probe = test_manual_probe,
|
||||||
|
.remove = test_manual_remove,
|
||||||
|
.unbind = test_manual_unbind,
|
||||||
|
.flags = DM_FLAG_ACTIVE_DMA,
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user