From 47903aacc520c96bafae1225484e5df740a233e6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 15 Nov 2024 16:19:08 -0700 Subject: bootstd: Move bootflow-adding to bootstd This relates to more than just the bootdev, since there is a global list of bootflows. Move the function to the bootstd file and rename it. Signed-off-by: Simon Glass --- boot/bootstd-uclass.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'boot/bootstd-uclass.c') diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index fdb8d69e320..bf6e49ad97a 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -61,6 +61,31 @@ void bootstd_clear_glob(void) bootstd_clear_glob_(std); } +int bootstd_add_bootflow(struct bootflow *bflow) +{ + struct bootstd_priv *std; + struct bootflow *new; + int ret; + + ret = bootstd_get_priv(&std); + if (ret) + return ret; + + new = malloc(sizeof(*bflow)); + if (!new) + return log_msg_ret("bflow", -ENOMEM); + memcpy(new, bflow, sizeof(*bflow)); + + list_add_tail(&new->glob_node, &std->glob_head); + if (bflow->dev) { + struct bootdev_uc_plat *ucp = dev_get_uclass_plat(bflow->dev); + + list_add_tail(&new->bm_node, &ucp->bootflow_head); + } + + return 0; +} + static int bootstd_remove(struct udevice *dev) { struct bootstd_priv *priv = dev_get_priv(dev); -- cgit v1.2.3 From 92182257733b446f3074a8a9b0a7eafea6ea8c1c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 15 Nov 2024 16:19:09 -0700 Subject: bootstd: Move bootflow-clearing to bootstd This relates to more than just the bootdev, since there is a global list of bootflows. Move the function to the bootstd file and rename it. Signed-off-by: Simon Glass Acked-by: Heinrich Schuchardt --- boot/bootstd-uclass.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'boot/bootstd-uclass.c') diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index bf6e49ad97a..596d3e5e41d 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -86,6 +86,21 @@ int bootstd_add_bootflow(struct bootflow *bflow) return 0; } +int bootstd_clear_bootflows_for_bootdev(struct udevice *dev) +{ + struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev); + + while (!list_empty(&ucp->bootflow_head)) { + struct bootflow *bflow; + + bflow = list_first_entry(&ucp->bootflow_head, struct bootflow, + bm_node); + bootflow_remove(bflow); + } + + return 0; +} + static int bootstd_remove(struct udevice *dev) { struct bootstd_priv *priv = dev_get_priv(dev); -- cgit v1.2.3 From 529f92677defa4788ef0d43229caa5771be041a0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 15 Nov 2024 16:19:10 -0700 Subject: bootstd: Add a function to get bootstd only if available Provide a function which is safe to call in the 'unbind' path, which returns the bootstd priv data if available. Signed-off-by: Simon Glass --- boot/bootstd-uclass.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'boot/bootstd-uclass.c') diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index 596d3e5e41d..b2f80808c85 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -140,6 +140,17 @@ const char *const *const bootstd_get_prefixes(struct udevice *dev) return std->prefixes ? std->prefixes : default_prefixes; } +struct bootstd_priv *bootstd_try_priv(void) +{ + struct udevice *dev; + + dev = uclass_try_first_device(UCLASS_BOOTSTD); + if (!dev || !device_active(dev)) + return NULL; + + return dev_get_priv(dev); +} + int bootstd_get_priv(struct bootstd_priv **stdp) { struct udevice *dev; -- cgit v1.2.3 From 6a3eb84b18333eb4beb7e660fa9ae8ccff07b0c4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 15 Nov 2024 16:19:11 -0700 Subject: bootstd: Drop the bootdev-specific list of bootflows This list is only used by two functions, which can be updated to iterate through the global list. Take this approach, which allows the bootdev list to be dropped. Overall this makes the code slightly more complicated, but will allow moving the bootflow list into an alist Signed-off-by: Simon Glass --- boot/bootstd-uclass.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'boot/bootstd-uclass.c') diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index b2f80808c85..91e90bdf43c 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -77,25 +77,22 @@ int bootstd_add_bootflow(struct bootflow *bflow) memcpy(new, bflow, sizeof(*bflow)); list_add_tail(&new->glob_node, &std->glob_head); - if (bflow->dev) { - struct bootdev_uc_plat *ucp = dev_get_uclass_plat(bflow->dev); - - list_add_tail(&new->bm_node, &ucp->bootflow_head); - } return 0; } int bootstd_clear_bootflows_for_bootdev(struct udevice *dev) { - struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev); + struct bootstd_priv *std = bootstd_try_priv(); - while (!list_empty(&ucp->bootflow_head)) { + if (std) { struct bootflow *bflow; + struct list_head *pos; - bflow = list_first_entry(&ucp->bootflow_head, struct bootflow, - bm_node); - bootflow_remove(bflow); + list_for_each(pos, &std->glob_head) { + bflow = list_entry(pos, struct bootflow, glob_node); + bootflow_remove(bflow); + } } return 0; -- cgit v1.2.3 From 49867e804543f64ca216653c3905d8022c31fc84 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 15 Nov 2024 16:19:12 -0700 Subject: bootstd: Move the bootflow list into an alist Use an alist for this data structure as it is somewhat simpler to manage. This means that bootstd holds a simple list of bootflow structs and can drop it at will, without chasing down lists. Signed-off-by: Simon Glass --- boot/bootstd-uclass.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'boot/bootstd-uclass.c') diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index 91e90bdf43c..8c0fd4e63c3 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -6,6 +6,7 @@ * Written by Simon Glass */ +#include #include #include #include @@ -42,13 +43,11 @@ static int bootstd_of_to_plat(struct udevice *dev) static void bootstd_clear_glob_(struct bootstd_priv *priv) { - while (!list_empty(&priv->glob_head)) { - struct bootflow *bflow; + struct bootflow *bflow; - bflow = list_first_entry(&priv->glob_head, struct bootflow, - glob_node); + alist_for_each(bflow, &priv->bootflows) bootflow_remove(bflow); - } + alist_empty(&priv->bootflows); } void bootstd_clear_glob(void) @@ -64,36 +63,37 @@ void bootstd_clear_glob(void) int bootstd_add_bootflow(struct bootflow *bflow) { struct bootstd_priv *std; - struct bootflow *new; int ret; ret = bootstd_get_priv(&std); if (ret) return ret; - new = malloc(sizeof(*bflow)); - if (!new) - return log_msg_ret("bflow", -ENOMEM); - memcpy(new, bflow, sizeof(*bflow)); - - list_add_tail(&new->glob_node, &std->glob_head); + ret = std->bootflows.count; + bflow = alist_add(&std->bootflows, *bflow); + if (!bflow) + return log_msg_ret("bf2", -ENOMEM); - return 0; + return ret; } int bootstd_clear_bootflows_for_bootdev(struct udevice *dev) { struct bootstd_priv *std = bootstd_try_priv(); + struct bootflow *from, *to; - if (std) { - struct bootflow *bflow; - struct list_head *pos; + /* if bootstd does not exist we cannot have any bootflows */ + if (!std) + return 0; - list_for_each(pos, &std->glob_head) { - bflow = list_entry(pos, struct bootflow, glob_node); - bootflow_remove(bflow); - } + /* Drop any bootflows that mention this dev */ + alist_for_each_filter(from, to, &std->bootflows) { + if (from->dev == dev) + bootflow_remove(from); + else + *to++ = *from; } + alist_update_end(&std->bootflows, to); return 0; } @@ -165,7 +165,7 @@ static int bootstd_probe(struct udevice *dev) { struct bootstd_priv *std = dev_get_priv(dev); - INIT_LIST_HEAD(&std->glob_head); + alist_init_struct(&std->bootflows, struct bootflow); return 0; } -- cgit v1.2.3