dm: core: Add pre-OS remove flag to device_remove()
Subsystems (8)
RFC PATCH 1/3 dm: core: Add pre-OS remove flag to device_remove()
This patch adds the pre_os_remove boolean flag to device_remove() and changes all calls to this function to provide the default value of "false". This is in preparation for the driver specific pre-OS remove support.
--- arch/x86/cpu/queensbay/tnc.c | 4 ++-- cmd/cros_ec.c | 2 +- cmd/sf.c | 2 +- drivers/block/blk-uclass.c | 2 +- drivers/block/sandbox.c | 2 +- drivers/core/device-remove.c | 9 +++++---- drivers/core/device.c | 2 +- drivers/core/root.c | 2 +- drivers/core/uclass.c | 2 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mtd/spi/sandbox.c | 2 +- drivers/mtd/spi/sf-uclass.c | 2 +- drivers/spi/spi-uclass.c | 4 ++-- drivers/usb/emul/sandbox_hub.c | 2 +- drivers/usb/host/usb-uclass.c | 4 ++-- include/dm/device-internal.h | 5 +++-- include/dm/device.h | 3 +++ test/dm/bus.c | 8 ++++---- test/dm/core.c | 16 ++++++++-------- test/dm/eth.c | 2 +- test/dm/spi.c | 2 +- 21 files changed, 42 insertions(+), 37 deletions(-)
arch/x86/cpu/queensbay/tnc.c +2 -2
@@ -76,13 +76,13 @@ static int __maybe_unused disable_igd(void)* * So the only option we have is to manually remove these two devices. */ - ret =device_remove (igd); + ret =device_remove (igd, false);if (ret)return ret; ret =device_unbind (igd);if (ret)return ret; - ret =device_remove (sdvo); + ret =device_remove (sdvo, false);if (ret)return ret; ret =device_unbind (sdvo);
cmd/cros_ec.c +1 -1
@@ -110,7 +110,7 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])/* Remove any existing device */ ret =uclass_find_device (UCLASS_CROS_EC ,0 , &udev);if (!ret) -device_remove (udev); +device_remove (udev, false); ret =uclass_get_device (UCLASS_CROS_EC ,0 , &udev);if (ret) {printf ("Could not init cros_ec device (err %d)\n" , ret);
cmd/sf.c +1 -1
@@ -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 */ ret =spi_find_bus_and_cs (bus, cs, &bus_dev, &new);if (!ret) { -device_remove (new); +device_remove (new, false); } flash =NULL ; ret =spi_flash_probe_bus_cs (bus, cs, speed, mode, &new);
drivers/block/blk-uclass.c +1 -1
@@ -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, false);if (ret)return ret; ret =device_unbind (dev);
drivers/block/sandbox.c +1 -1
@@ -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, false);if (ret)return ret; ret =device_unbind (dev);
drivers/core/device-remove.c +5 -4
@@ -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,bool pre_os_remove) {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, pre_os_remove);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,bool pre_os_remove) {const struct driver *drv;int ret;
@@ -169,7 +170,7 @@ int device_remove(struct udevice *dev)if (ret)return ret; - ret =device_chld_remove (dev); + ret =device_chld_remove (dev, pre_os_remove);if (ret) goto err;
drivers/core/device.c +1 -1
@@ -378,7 +378,7 @@ int device_probe(struct udevice *dev)return 0 ; fail_uclass: -if (device_remove (dev)) { +if (device_remove (dev, false)) {dm_warn ("%s: Device '%s' failed to remove on error path\n" , __func__, dev->name); }
drivers/core/root.c +1 -1
@@ -176,7 +176,7 @@ int dm_init(void)int dm_uninit (void ) { -device_remove (dm_root ()); +device_remove (dm_root (), false);device_unbind (dm_root ());return 0 ;
drivers/core/uclass.c +1 -1
@@ -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, false);if (ret)return ret; ret =device_unbind (dev);
drivers/mmc/mmc-uclass.c +1 -1
@@ -232,7 +232,7 @@ int mmc_unbind(struct udevice *dev)device_find_first_child (dev, &bdev);if (bdev) { -device_remove (bdev); +device_remove (bdev, false);device_unbind (bdev); }
drivers/mtd/spi/sandbox.c +1 -1
@@ -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, false);device_unbind (dev); state->spi[busnum][cs].emul =NULL ; }
drivers/mtd/spi/sf-uclass.c +1 -1
@@ -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, false); } int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
drivers/spi/spi-uclass.c +2 -2
@@ -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, false);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, false); slave->dev =NULL ; }
drivers/usb/emul/sandbox_hub.c +1 -1
@@ -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, false); clear |=USB_PORT_STAT_CONNECTION ; } }
drivers/usb/host/usb-uclass.c +2 -2
@@ -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, false);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, false);if (ret)return ret;
include/dm/device-internal.h +3 -2
@@ -96,12 +96,13 @@ int device_probe(struct udevice *dev);* children are deactivated first. * * @dev: Pointer to device to remove +* @pre_os_remove: Flag, if this functions is called in the pre-OS stage * @return 0 if OK, -ve on error (an error here is normally a very bad thing) */ #if CONFIG_IS_ENABLED (DM_DEVICE_REMOVE ) -int device_remove (struct udevice *dev); +int device_remove (struct udevice *dev,bool pre_os_remove);#else -static inline int device_remove (struct udevice *dev) {return 0 ; } +static inline int device_remove (struct udevice *dev,bool pre_os_remove) {return 0 ; }#endif /**
include/dm/device.h +3 -0
@@ -46,6 +46,9 @@ struct driver_info;#define DM_FLAG_OF_PLATDATA (1 << 8) +/* Call driver remove function before the OS is called (U-Boot exit) */ +#define DM_FLAG_PRE_OS_REMOVE (1 << 9) +/** * struct udevice - An instance of a driver *
test/dm/bus.c +4 -4
@@ -222,7 +222,7 @@ static int test_bus_parent_data(struct unit_test_state *uts)/* Check that it starts@0 and goes away when device is removed */ parent_data->sum +=5 ;ut_asserteq (5 , parent_data->sum); -device_remove (dev); +device_remove (dev, false);ut_asserteq_ptr (NULL ,dev_get_parent_priv (dev));/* Check that we can do this twice */
@@ -323,7 +323,7 @@ static int dm_test_bus_parent_ops(struct unit_test_state *uts)continue ; parent_data =dev_get_parent_priv (dev);ut_asserteq (FLAG_CHILD_PROBED , parent_data->flag); -ut_assertok (device_remove (dev)); +ut_assertok (device_remove (dev, false));ut_asserteq_ptr (NULL ,dev_get_parent_priv (dev));ut_asserteq_ptr (dms->removed, dev); }
@@ -360,7 +360,7 @@ static int test_bus_parent_platdata(struct unit_test_state *uts) plat->count++;ut_asserteq (1 , plat->count);device_probe (dev); -device_remove (dev); +device_remove (dev, false);ut_asserteq_ptr (plat,dev_get_parent_platdata (dev));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);/* Removing the bus should also have no effect (it is still bound) */ -device_remove (bus); +device_remove (bus, false);for (device_find_first_child (bus, &dev), child_count =0 ; dev;device_find_next_child (&dev)) {
test/dm/core.c +8 -8
@@ -319,7 +319,7 @@ static int dm_test_lifecycle(struct unit_test_state *uts)/* Now remove device 3 */ ut_asserteq (0 , dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE ]); -ut_assertok (device_remove (dev)); +ut_assertok (device_remove (dev, false));ut_asserteq (1 , dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE ]);ut_asserteq (0 , dm_testdrv_op_count[DM_TEST_OP_UNBIND ]);
@@ -352,7 +352,7 @@ static int dm_test_ordering(struct unit_test_state *uts)ut_assert (dev_last);/* Now remove device 3 */ -ut_assertok (device_remove (dev)); +ut_assertok (device_remove (dev, false));ut_assertok (device_unbind (dev));/* The device numbering should have shifted down one */
@@ -371,9 +371,9 @@ static int dm_test_ordering(struct unit_test_state *uts)ut_assert (pingret ==102 );/* Remove 3 and 4 */ -ut_assertok (device_remove (dev_penultimate)); +ut_assertok (device_remove (dev_penultimate, false));ut_assertok (device_unbind (dev_penultimate)); -ut_assertok (device_remove (dev_last)); +ut_assertok (device_remove (dev_last, false));ut_assertok (device_unbind (dev_last));/* Our device should now be in position 3 */
@@ -381,7 +381,7 @@ static int dm_test_ordering(struct unit_test_state *uts)ut_assert (dev == test_dev);/* Now remove device 3 */ -ut_assertok (device_remove (dev)); +ut_assertok (device_remove (dev, false));ut_assertok (device_unbind (dev));return 0 ;
@@ -457,7 +457,7 @@ static int dm_test_remove(struct unit_test_state *uts)ut_assert (dev);ut_assertf (dev->flags &DM_FLAG_ACTIVATED ,"Driver %d/%s not activated" , i, dev->name); -ut_assertok (device_remove (dev)); +ut_assertok (device_remove (dev, false));ut_assertf (!(dev->flags &DM_FLAG_ACTIVATED ),"Driver %d/%s should have deactivated" , i, dev->name);
@@ -611,14 +611,14 @@ static int dm_test_children(struct unit_test_state *uts)ut_asserteq (total, dm_testdrv_op_count[DM_TEST_OP_PROBE ]);/* Remove a top-level child and check that the children are removed */ -ut_assertok (device_remove (top[2 ])); +ut_assertok (device_remove (top[2 ], false));ut_asserteq (NODE_COUNT +1 , dm_testdrv_op_count[DM_TEST_OP_REMOVE ]); dm_testdrv_op_count[DM_TEST_OP_REMOVE ] =0 ;/* Try one with grandchildren */ ut_assertok (uclass_get_device (UCLASS_TEST ,5 , &dev));ut_asserteq_ptr (dev, top[5 ]); -ut_assertok (device_remove (dev)); +ut_assertok (device_remove (dev, false));ut_asserteq (1 +NODE_COUNT * (1 +NODE_COUNT ), dm_testdrv_op_count[DM_TEST_OP_REMOVE ]);
test/dm/eth.c +1 -1
@@ -116,7 +116,7 @@ static int dm_test_eth_act(struct unit_test_state *uts)for (i =0 ; i <DM_TEST_ETH_NUM ; i++) {ut_assertok (uclass_find_device_by_name (UCLASS_ETH , ethname[i], &dev[i])); -ut_assertok (device_remove (dev[i])); +ut_assertok (device_remove (dev[i], false));/* Invalidate MAC address */ strcpy (ethaddr[i],getenv (addrname[i]));
test/dm/spi.c +1 -1
@@ -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_assertok (spi_cs_info (bus, cs, &info)); of_offset =dev_of_offset (info.dev); -device_remove (info.dev); +device_remove (info.dev, false);device_unbind (info.dev);/*
Signature · 1 line
2.12.0
RFC PATCH 2/3 dm: core: Add dm_pre_os_remove() and hook it into device_remove()
The new function dm_pre_os_remove() is intented for driver specific last-stage cleanup operations before the OS is started. This patch adds this functionality and hooks it into the common device_remove() function.
To enable usage for custom driver (e.g. ethernet drivers), this patch also sets the pre-OS remove flag for the root driver and simple-bus drivers. Otherwise the recursive call starting from the root device would not reach the drivers in need for this specific remove call.
--- drivers/core/device-remove.c | 7 +++++++ drivers/core/root.c | 8 ++++++++ drivers/core/simple-bus.c | 1 + include/dm/root.h | 9 +++++++++ 4 files changed, 25 insertions(+)
drivers/core/device-remove.c +7 -0
@@ -166,6 +166,13 @@ int device_remove(struct udevice *dev, bool pre_os_remove) drv = dev->driver;assert (drv); +/* +* If pre-OS remove is requested, only continue for drivers with this +* flag set +*/ +if (pre_os_remove && !(drv->flags &DM_FLAG_PRE_OS_REMOVE )) +return 0 ; + ret =uclass_pre_remove_device (dev);if (ret)return ret;
drivers/core/root.c +8 -0
@@ -182,6 +182,13 @@ int dm_uninit(void)return 0 ; } +int dm_pre_os_remove (void ) +{ +device_remove (dm_root (), true); + +return 0 ; +} +int dm_scan_platdata (bool pre_reloc_only) {int ret;
@@ -280,6 +287,7 @@ U_BOOT_DRIVER(root_driver) = { .name = "root_driver", .id = UCLASS_ROOT, .priv_auto_alloc_size = sizeof(struct root_priv), + .flags = DM_FLAG_PRE_OS_REMOVE, };/* This is the root uclass */
drivers/core/simple-bus.c +1 -0
@@ -64,4 +64,5 @@ U_BOOT_DRIVER(simple_bus_drv) = { .name = "generic_simple_bus", .id = UCLASS_SIMPLE_BUS, .of_match = generic_simple_bus_ids, + .flags = DM_FLAG_PRE_OS_REMOVE, };
include/dm/root.h +9 -0
@@ -115,4 +115,13 @@ int dm_init(void);*/ int dm_uninit (void ); +/** +* dm_pre_os_remove - Call remove function of all drivers with the pre-OS +* remove flag set +* +* All devices with the pre-OS remove flag set, will be removed +* @return 0 if OK, -ve on error +*/ +int dm_pre_os_remove (void ); +#endif
Signature · 1 line
2.12.0
RFC PATCH 2/3 dm: core: Add dm_pre_os_remove() and hook it into device_remove()
Hi Stefan,
Quoted 24 lines · Stefan Roese
The new function
dm_pre_os_remove()is intented for driver specific last-stage cleanup operations before the OS is started. This patch adds this functionality and hooks it into the commondevice_remove()function.To enable usage for custom driver (e.g. ethernet drivers), this patch also sets the pre-OS remove flag for the root driver and simple-bus drivers. Otherwise the recursive call starting from the root device would not reach the drivers in need for this specific remove call.
Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- drivers/core/device-remove.c | 7 +++++++ drivers/core/root.c | 8 ++++++++ drivers/core/simple-bus.c | 1 + include/dm/root.h | 9 +++++++++ 4 files changed, 25 insertions(+)drivers/core/device-remove.c +0
-0
drivers/core/device-remove.c int device_remove(struct udevice *dev, bool pre_os_remove) · line 175
Quoted 10 lines
drivers/core/device-remove.c +7
-0@@ -166,6 +166,13 @@ int device_remove(struct udevice *dev, bool pre_os_remove) drv = dev->driver;assert (drv); +/* +* If pre-OS remove is requested, only continue for drivers with this +* flag set +*/ +if (pre_os_remove && !(drv->flags &DM_FLAG_PRE_OS_REMOVE )) +return 0 ; +
This doesn't seem good to me. I think it should scan the whole tree, and process devices with the flag set. That way you don't need the root node to have the flag.
If a device has DMA, it will be removed. But its parent may not, in which case the parent will not be removed. However any children of the device will need to be removed, even if they don't have DMA, because we cannot have active children of an inactive device. Does that make sense?
Quoted 58 lines
drivers/core/device-remove.c +0
-0ret =uclass_pre_remove_device (dev);if (ret)return ret;drivers/core/root.c +8
-0@@ -182,6 +182,13 @@ int dm_uninit(void)return 0 ; } +int dm_pre_os_remove (void ) +{ +device_remove (dm_root (), true); + +return 0 ; +} +int dm_scan_platdata (bool pre_reloc_only) {int ret;@@ -280,6 +287,7 @@ U_BOOT_DRIVER(root_driver) = { .name = "root_driver", .id = UCLASS_ROOT, .priv_auto_alloc_size = sizeof(struct root_priv), + .flags = DM_FLAG_PRE_OS_REMOVE, };/* This is the root uclass */ drivers/core/simple-bus.c +1
-0@@ -64,4 +64,5 @@ U_BOOT_DRIVER(simple_bus_drv) = { .name = "generic_simple_bus", .id = UCLASS_SIMPLE_BUS, .of_match = generic_simple_bus_ids, + .flags = DM_FLAG_PRE_OS_REMOVE, };include/dm/root.h +9
-1@@ -115,4 +115,13 @@ int dm_init(void);*/ int dm_uninit (void ); +/** +* dm_pre_os_remove - Call remove function of all drivers with the pre-OS +* remove flag set +* +* All devices with the pre-OS remove flag set, will be removed +* @return 0 if OK, -ve on error +*/ +int dm_pre_os_remove (void ); +#endif --
Quoted 2 lines
2.12.0
Regards,
Simon
RFC PATCH 2/3 dm: core: Add dm_pre_os_remove() and hook it into device_remove()
Hi Simon,
Quoted 28 lines · Simon Glass
Quoted 27 lines · Stefan Roese
The new function
dm_pre_os_remove()is intented for driver specific last-stage cleanup operations before the OS is started. This patch adds this functionality and hooks it into the commondevice_remove()function.To enable usage for custom driver (e.g. ethernet drivers), this patch also sets the pre-OS remove flag for the root driver and simple-bus drivers. Otherwise the recursive call starting from the root device would not reach the drivers in need for this specific remove call.
Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- drivers/core/device-remove.c | 7 +++++++ drivers/core/root.c | 8 ++++++++ drivers/core/simple-bus.c | 1 + include/dm/root.h | 9 +++++++++ 4 files changed, 25 insertions(+)drivers/core/device-remove.c +0
-0@@ -166,6 +166,13 @@ int device_remove(struct udevice *dev, bool pre_os_remove) drv = dev->driver;assert (drv);
Quoted 11 lines
drivers/core/device-remove.c int device_remove(struct udevice *dev, bool pre_os_remove) · line 175
Quoted 7 lines
drivers/core/device-remove.c +7
-0+/* +* If pre-OS remove is requested, only continue for drivers with this +* flag set +*/ +if (pre_os_remove && !(drv->flags &DM_FLAG_PRE_OS_REMOVE )) +return 0 ; +This doesn't seem good to me. I think it should scan the whole tree, and process devices with the flag set. That way you don't need the root node to have the flag.
Yes, thats better, I agree.
Quoted 5 lines
If a device has DMA, it will be removed. But its parent may not, in which case the parent will not be removed. However any children of the device will need to be removed, even if they don't have DMA, because we cannot have active children of an inactive device. Does that make sense?
Yes. I'll change this in the next patchset version accordingly.
Thanks,
Stefan
RFC PATCH 3/3 arm: bootm: Add dm_pre_os_remove() call to announce_and_cleanup()
In reply to Stefan RoeseThis patch adds a call to dm_pre_os_remove() to announce_and_cleanup() so that drivers that have the flag DM_FLAG_PRE_OS_REMOVE set may do some last-stage cleanup before the OS is started.
--- arch/arm/lib/bootm.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/lib/bootm.c +8 -0
@@ -91,6 +91,14 @@ static void announce_and_cleanup(int fake)board_quiesce_devices (); +/* +* Call remove function of all devices with the pre-OS remove flag +* set (DM_FLAG_PRE_OS_REMOVE). This may be useful for last-stage +* operations, like cancelling of DMA operation or releasing device +* internal buffers. +*/ +dm_pre_os_remove (); +cleanup_before_linux (); }
Signature · 1 line
2.12.0
RFC PATCH 3/3 arm: bootm: Add dm_pre_os_remove() call to announce_and_cleanup()
Hi Stefan,
Quoted 15 lines · Stefan Roese
This patch adds a call to
dm_pre_os_remove()toannounce_and_cleanup()so that drivers that have the flagDM_FLAG_PRE_OS_REMOVEset may do some last-stage cleanup before the OS is started.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/arm/lib/bootm.c | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/lib/bootm.c +0
-0
arch/arm/lib/bootm.c static void announce_and_cleanup(int fake) · line 100
Quoted 10 lines
arch/arm/lib/bootm.c +7
-0@@ -91,6 +91,14 @@ static void announce_and_cleanup(int fake)board_quiesce_devices (); +/* +* Call remove function of all devices with the pre-OS remove flag +* set (DM_FLAG_PRE_OS_REMOVE). This may be useful for last-stage +* operations, like cancelling of DMA operation or releasing device +* internal buffers. +*/ +dm_pre_os_remove ();
In a full DM world we could perhaps have devices which use the DMA uclass, so we can tell which ones need to be removed.
How about dm_remove_dma_devices()?
Quoted 7 lines
arch/arm/lib/bootm.c +1
-1+cleanup_before_linux (); } --2.12.0
Also (once we have things figured out) this needs some sort of test in test/.
Regards,
Simon
RFC PATCH 3/3 arm: bootm: Add dm_pre_os_remove() call to announce_and_cleanup()
Hi Simon,
Quoted 30 lines · Simon Glass
Quoted 15 lines · Stefan Roese
This patch adds a call to
dm_pre_os_remove()toannounce_and_cleanup()so that drivers that have the flagDM_FLAG_PRE_OS_REMOVEset may do some last-stage cleanup before the OS is started.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/arm/lib/bootm.c | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/lib/bootm.c +0
-0arch/arm/lib/bootm.c static void announce_and_cleanup(int fake) · line 100
Quoted 10 lines
arch/arm/lib/bootm.c +7
-0@@ -91,6 +91,14 @@ static void announce_and_cleanup(int fake)board_quiesce_devices (); +/* +* Call remove function of all devices with the pre-OS remove flag +* set (DM_FLAG_PRE_OS_REMOVE). This may be useful for last-stage +* operations, like cancelling of DMA operation or releasing device +* internal buffers. +*/ +dm_pre_os_remove ();In a full DM world we could perhaps have devices which use the DMA uclass, so we can tell which ones need to be removed.
Quoted 1 line
How about
dm_remove_dma_devices()?
I'm not so sure. As we would perhaps need to add other calls for further pre-OS removal reasons (e.g. the stop timer example). How about calling a function with the removal flags as parameter:
dm_remove_devices_conditional(ONLY_REMOVE_ACTIVE_DMA | ...);
or
dm_remove_devices_flags(ONLY_REMOVE_ACTIVE_DMA | ...);
What do you think?
Quoted 9 lines
Quoted 7 lines
arch/arm/lib/bootm.c +1
-1+cleanup_before_linux (); } --2.12.0
Also (once we have things figured out) this needs some sort of test in test/.
I already feared that. ;)
Sure, I'll try to add some test, once the path is clear.
Thanks,
Stefan
RFC PATCH 3/3 arm: bootm: Add dm_pre_os_remove() call to announce_and_cleanup()
Hi Stefan,
Quoted 46 lines · Stefan Roese
Hi Simon,
Quoted 35 lines · Simon Glass
Quoted 25 lines · Stefan Roese
This patch adds a call to
dm_pre_os_remove()toannounce_and_cleanup()so that drivers that have the flagDM_FLAG_PRE_OS_REMOVEset may do some last-stage cleanup before the OS is started.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/arm/lib/bootm.c | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/lib/bootm.c +2
-0@@ -91,6 +91,14 @@ static void announce_and_cleanup(int fake)board_quiesce_devices (); +/* +* Call remove function of all devices with the pre-OS remove flag
arch/arm/lib/bootm.c +2
-0+* set (DM_FLAG_PRE_OS_REMOVE). This may be useful for last-stage +* operations, like cancelling of DMA operation or releasing device
arch/arm/lib/bootm.c static void announce_and_cleanup(int fake) · line 100
Quoted 3 lines
arch/arm/lib/bootm.c +3
-0+* internal buffers. +*/ +dm_pre_os_remove ();In a full DM world we could perhaps have devices which use the DMA uclass, so we can tell which ones need to be removed.
Quoted 1 line
How about
dm_remove_dma_devices()?I'm not so sure. As we would perhaps need to add other calls for further pre-OS removal reasons (e.g. the stop timer example). How about calling a function with the removal flags as parameter:
Quoted 7 lines
dm_remove_devices_conditional(ONLY_REMOVE_ACTIVE_DMA | ...);or
dm_remove_devices_flags(ONLY_REMOVE_ACTIVE_DMA | ...);What do you think?
Seems reasonable - see my previous email for a flag naming idea (i.e. having an explicit ALL flag to avoid all the flags having to use negative logic).
Quoted 13 lines
Quoted 11 lines
Quoted 8 lines
+
cleanup_before_linux();}
--
2.12.0Also (once we have things figured out) this needs some sort of test in test/.
Quoted 6 lines
I already feared that. ;)
Sure, I'll try to add some test, once the path is clear.
Thanks,
Stefan
Regards,
Simon
RFC PATCH 1/3 dm: core: Add pre-OS remove flag to device_remove()
In reply to Stefan RoeseHi Stefan,
Quoted 22 lines · Stefan Roese
This patch adds the
pre_os_removeboolean flag todevice_remove()and changes all calls to this function to provide the default value of "false". This is in preparation for the driver specific pre-OS remove support.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/x86/cpu/queensbay/tnc.c | 4 ++-- cmd/cros_ec.c | 2 +- cmd/sf.c | 2 +- drivers/block/blk-uclass.c | 2 +- drivers/block/sandbox.c | 2 +- drivers/core/device-remove.c | 9 +++++---- drivers/core/device.c | 2 +- drivers/core/root.c | 2 +- drivers/core/uclass.c | 2 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mtd/spi/sandbox.c | 2 +- drivers/mtd/spi/sf-uclass.c | 2 +- drivers/spi/spi-uclass.c | 4 ++-- drivers/usb/emul/sandbox_hub.c | 2 +-
Quoted 8 lines
drivers/usb/host/usb-uclass.c | 4 ++-- include/dm/device-internal.h | 5 +++-- include/dm/device.h | 3 +++ test/dm/bus.c | 8 ++++---- test/dm/core.c | 16 ++++++++-------- test/dm/eth.c | 2 +- test/dm/spi.c | 2 +- 21 files changed, 42 insertions(+), 37 deletions(-)
I think adding a parameter to device_remove() makes sense, but how about using flags instead? The true/false meaning is not clear here and your comment in device.h doesn't really help.
Also I think it is better to name it after the required function rather than state related to the caller. IOW instead of 'pre-os' use something like 'active_dma_only' or as a flag ONLY_REMOVE_ACTIVE_DMA.
Do you think the presence of DMA should be a device flag?
Regards,
Simon
RFC PATCH 1/3 dm: core: Add pre-OS remove flag to device_remove()
Hi Simon,
Quoted 32 lines · Simon Glass
Quoted 22 lines · Stefan Roese
This patch adds the
pre_os_removeboolean flag todevice_remove()and changes all calls to this function to provide the default value of "false". This is in preparation for the driver specific pre-OS remove support.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/x86/cpu/queensbay/tnc.c | 4 ++-- cmd/cros_ec.c | 2 +- cmd/sf.c | 2 +- drivers/block/blk-uclass.c | 2 +- drivers/block/sandbox.c | 2 +- drivers/core/device-remove.c | 9 +++++---- drivers/core/device.c | 2 +- drivers/core/root.c | 2 +- drivers/core/uclass.c | 2 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mtd/spi/sandbox.c | 2 +- drivers/mtd/spi/sf-uclass.c | 2 +- drivers/spi/spi-uclass.c | 4 ++-- drivers/usb/emul/sandbox_hub.c | 2 +-Quoted 8 lines
drivers/usb/host/usb-uclass.c | 4 ++-- include/dm/device-internal.h | 5 +++-- include/dm/device.h | 3 +++ test/dm/bus.c | 8 ++++---- test/dm/core.c | 16 ++++++++-------- test/dm/eth.c | 2 +- test/dm/spi.c | 2 +- 21 files changed, 42 insertions(+), 37 deletions(-)
Quoted 3 lines
I think adding a parameter to
device_remove()makes sense, but how about using flags instead? The true/false meaning is not clear here and your comment indevice.hdoesn't really help.
So you are suggesting something like this:
int device_remove(struct udevice *dev, uin32_t remove_flags);
?
Quoted 5 lines
Also I think it is better to name it after the required function rather than state related to the caller. IOW instead of 'pre-os' use something like '
active_dma_only' or as a flagONLY_REMOVE_ACTIVE_DMA.Do you think the presence of DMA should be a device flag?
The usage of flags instead of this pre-os parameter could make sense to me, as its much more flexible. But I'm not so sure about the flag (re-)naming to something specific like DMA. As there could be multiple reasons other than DMA related for this last-stage driver cleanup / configuration before the OS is started. E.g. if a driver needs to stop an internal timer before the OS is started, it would need to "abuse" this DMA flag to get called at the last pre-OS stage. Or is your thinking that in such cases (e.g. stopping of timer) a new flag should get introduced and added to this "remove_flags" parameter in bootm?
Thanks,
Stefan
RFC PATCH 1/3 dm: core: Add pre-OS remove flag to device_remove()
Hi Stefan,
Quoted 35 lines · Stefan Roese
Hi Simon,
Quoted 32 lines · Simon Glass
Quoted 30 lines · Stefan Roese
This patch adds the
pre_os_removeboolean flag todevice_remove()and changes all calls to this function to provide the default value of "false". This is in preparation for the driver specific pre-OS remove support.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/x86/cpu/queensbay/tnc.c | 4 ++-- cmd/cros_ec.c | 2 +- cmd/sf.c | 2 +- drivers/block/blk-uclass.c | 2 +- drivers/block/sandbox.c | 2 +- drivers/core/device-remove.c | 9 +++++---- drivers/core/device.c | 2 +- drivers/core/root.c | 2 +- drivers/core/uclass.c | 2 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mtd/spi/sandbox.c | 2 +- drivers/mtd/spi/sf-uclass.c | 2 +- drivers/spi/spi-uclass.c | 4 ++-- drivers/usb/emul/sandbox_hub.c | 2 +- drivers/usb/host/usb-uclass.c | 4 ++-- include/dm/device-internal.h | 5 +++-- include/dm/device.h | 3 +++ test/dm/bus.c | 8 ++++---- test/dm/core.c | 16 ++++++++-------- test/dm/eth.c | 2 +- test/dm/spi.c | 2 +- 21 files changed, 42 insertions(+), 37 deletions(-)
Quoted 7 lines
Quoted 3 lines
I think adding a parameter to
device_remove()makes sense, but how about using flags instead? The true/false meaning is not clear here and your comment indevice.hdoesn't really help.So you are suggesting something like this:
int
device_remove(struct udevice *dev, uin32_t remove_flags);
Yes, or really 'uint remove_flags'
Quoted 9 lines
?
Quoted 5 lines
Also I think it is better to name it after the required function rather than state related to the caller. IOW instead of 'pre-os' use something like '
active_dma_only' or as a flagONLY_REMOVE_ACTIVE_DMA.Do you think the presence of DMA should be a device flag?
Quoted 10 lines
The usage of flags instead of this pre-os parameter could make sense to me, as its much more flexible. But I'm not so sure about the flag (re-)naming to something specific like DMA. As there could be multiple reasons other than DMA related for this last-stage driver cleanup / configuration before the OS is started. E.g. if a driver needs to stop an internal timer before the OS is started, it would need to "abuse" this DMA flag to get called at the last pre-OS stage. Or is your thinking that in such cases (e.g. stopping of timer) a new flag should get introduced and added to this "
remove_flags" parameter in bootm?
Yes, so that it is explicit. Another approach would be:
enum {
DM_REMOVE_ACTIVE_ALL = 1 << 0, /* Remove all devices */
DM_REMOVE_ACTIVE_DMA = 1 << 1, /* Remove only devices with active DMA */ /* Add more use cases here */
};
Then, DM_REMOVE_ACTIVE_ALL means everything will be removed, and if that flag is not set, the other flags can be used.
I am assuming that there actually will be other cases - your email suggests that could be true.
Regards,
Simon
RFC PATCH 1/3 dm: core: Add pre-OS remove flag to device_remove()
Hi Simon,
Quoted 68 lines · Simon Glass
Hi Stefan,
Quoted 35 lines · Stefan Roese
Hi Simon,
Quoted 32 lines · Simon Glass
Quoted 30 lines · Stefan Roese
This patch adds the
pre_os_removeboolean flag todevice_remove()and changes all calls to this function to provide the default value of "false". This is in preparation for the driver specific pre-OS remove support.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/x86/cpu/queensbay/tnc.c | 4 ++-- cmd/cros_ec.c | 2 +- cmd/sf.c | 2 +- drivers/block/blk-uclass.c | 2 +- drivers/block/sandbox.c | 2 +- drivers/core/device-remove.c | 9 +++++---- drivers/core/device.c | 2 +- drivers/core/root.c | 2 +- drivers/core/uclass.c | 2 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mtd/spi/sandbox.c | 2 +- drivers/mtd/spi/sf-uclass.c | 2 +- drivers/spi/spi-uclass.c | 4 ++-- drivers/usb/emul/sandbox_hub.c | 2 +- drivers/usb/host/usb-uclass.c | 4 ++-- include/dm/device-internal.h | 5 +++-- include/dm/device.h | 3 +++ test/dm/bus.c | 8 ++++---- test/dm/core.c | 16 ++++++++-------- test/dm/eth.c | 2 +- test/dm/spi.c | 2 +- 21 files changed, 42 insertions(+), 37 deletions(-)Quoted 7 lines
Quoted 3 lines
I think adding a parameter to
device_remove()makes sense, but how about using flags instead? The true/false meaning is not clear here and your comment indevice.hdoesn't really help.So you are suggesting something like this:
int
device_remove(struct udevice *dev, uin32_t remove_flags);Yes, or really 'uint
remove_flags'Quoted 9 lines
?
Quoted 5 lines
Also I think it is better to name it after the required function rather than state related to the caller. IOW instead of 'pre-os' use something like '
active_dma_only' or as a flagONLY_REMOVE_ACTIVE_DMA.Do you think the presence of DMA should be a device flag?
Quoted 10 lines
The usage of flags instead of this pre-os parameter could make sense to me, as its much more flexible. But I'm not so sure about the flag (re-)naming to something specific like DMA. As there could be multiple reasons other than DMA related for this last-stage driver cleanup / configuration before the OS is started. E.g. if a driver needs to stop an internal timer before the OS is started, it would need to "abuse" this DMA flag to get called at the last pre-OS stage. Or is your thinking that in such cases (e.g. stopping of timer) a new flag should get introduced and added to this "
remove_flags" parameter in bootm?
Quoted 7 lines
Yes, so that it is explicit. Another approach would be:
enum {
DM_REMOVE_ACTIVE_ALL= 1 << 0, /* Remove all devices */
DM_REMOVE_ACTIVE_DMA= 1 << 1, /* Remove only devices with active DMA */ /* Add more use cases here */
};
Okay, I'll go forward with this suggestion and will generate a new patchset version soon. Stay tuned...
Thanks,
Stefan
RFC PATCH 1/3 dm: core: Add pre-OS remove flag to device_remove()
Hi Simon,
Quoted 80 lines · Stefan Roese
Hi Simon,
Quoted 68 lines · Simon Glass
Hi Stefan,
Quoted 35 lines · Stefan Roese
Hi Simon,
Quoted 32 lines · Simon Glass
Quoted 30 lines · Stefan Roese
This patch adds the
pre_os_removeboolean flag todevice_remove()and changes all calls to this function to provide the default value of "false". This is in preparation for the driver specific pre-OS remove support.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>--- arch/x86/cpu/queensbay/tnc.c | 4 ++-- cmd/cros_ec.c | 2 +- cmd/sf.c | 2 +- drivers/block/blk-uclass.c | 2 +- drivers/block/sandbox.c | 2 +- drivers/core/device-remove.c | 9 +++++---- drivers/core/device.c | 2 +- drivers/core/root.c | 2 +- drivers/core/uclass.c | 2 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mtd/spi/sandbox.c | 2 +- drivers/mtd/spi/sf-uclass.c | 2 +- drivers/spi/spi-uclass.c | 4 ++-- drivers/usb/emul/sandbox_hub.c | 2 +- drivers/usb/host/usb-uclass.c | 4 ++-- include/dm/device-internal.h | 5 +++-- include/dm/device.h | 3 +++ test/dm/bus.c | 8 ++++---- test/dm/core.c | 16 ++++++++-------- test/dm/eth.c | 2 +- test/dm/spi.c | 2 +- 21 files changed, 42 insertions(+), 37 deletions(-)Quoted 7 lines
Quoted 3 lines
I think adding a parameter to
device_remove()makes sense, but how about using flags instead? The true/false meaning is not clear here and your comment indevice.hdoesn't really help.So you are suggesting something like this:
int
device_remove(struct udevice *dev, uin32_t remove_flags);Yes, or really 'uint
remove_flags'Quoted 9 lines
?
Quoted 5 lines
Also I think it is better to name it after the required function rather than state related to the caller. IOW instead of 'pre-os' use something like '
active_dma_only' or as a flagONLY_REMOVE_ACTIVE_DMA.Do you think the presence of DMA should be a device flag?
Quoted 10 lines
The usage of flags instead of this pre-os parameter could make sense to me, as its much more flexible. But I'm not so sure about the flag (re-)naming to something specific like DMA. As there could be multiple reasons other than DMA related for this last-stage driver cleanup / configuration before the OS is started. E.g. if a driver needs to stop an internal timer before the OS is started, it would need to "abuse" this DMA flag to get called at the last pre-OS stage. Or is your thinking that in such cases (e.g. stopping of timer) a new flag should get introduced and added to this "
remove_flags" parameter in bootm?Quoted 8 lines
Yes, so that it is explicit. Another approach would be:
enum {
DM_REMOVE_ACTIVE_ALL= 1 << 0, /* Remove all devices */
DM_REMOVE_ACTIVE_DMA= 1 << 1, /* Remove only devices with active
DMA */
/* Add more use cases here */
};
Quoted 2 lines
Okay, I'll go forward with this suggestion and will generate a new patchset version soon. Stay tuned...
Thinking about it, we need a bit for the "normal" remove case as well. How about this naming:
enum {
DM_REMOVE_NORMAL = 1 << 0, /* Remove all devices */ DM_REMOVE_ACTIVE_ALL = 1 << 1, /* Remove devices with any active flag set */ DM_REMOVE_ACTIVE_DMA = 1 << 2, /* Remove only devices with active DMA */ /* Add more use cases here */ };
Or do you have another suggestion in mind for this "normal" device remove case?
Thanks,
Stefan