[U-Boot] [RFC PATCH 2/3] dm: core: Add dm_pre_os_remove() and hook it into device_remove()

Simon Glass sjg at chromium.org
Fri Mar 3 04:53:08 UTC 2017


Hi Stefan,

On 1 March 2017 at 03:23, Stefan Roese <sr at denx.de> wrote:
> 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.
>
> Signed-off-by: Stefan Roese <sr at denx.de>
> Cc: Simon Glass <sjg at chromium.org>
> ---
>  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(+)
>
> diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
> index 4725d4751c..0dfb20cdce 100644
> --- a/drivers/core/device-remove.c
> +++ b/drivers/core/device-remove.c
> @@ -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?

>         ret = uclass_pre_remove_device(dev);
>         if (ret)
>                 return ret;
> diff --git a/drivers/core/root.c b/drivers/core/root.c
> index 583daa88b0..1468a15db4 100644
> --- a/drivers/core/root.c
> +++ b/drivers/core/root.c
> @@ -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 */
> diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
> index a300217d39..4142626ff6 100644
> --- a/drivers/core/simple-bus.c
> +++ b/drivers/core/simple-bus.c
> @@ -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,
>  };
> diff --git a/include/dm/root.h b/include/dm/root.h
> index 3cf730dcee..8ac7bc3512 100644
> --- a/include/dm/root.h
> +++ b/include/dm/root.h
> @@ -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
> --
> 2.12.0
>

Regards,
Simon


More information about the U-Boot mailing list