]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
bootstd: Drop the bootdev-specific list of bootflows
authorSimon Glass <sjg@chromium.org>
Fri, 15 Nov 2024 23:19:11 +0000 (16:19 -0700)
committerTom Rini <trini@konsulko.com>
Wed, 15 Jan 2025 14:48:42 +0000 (08:48 -0600)
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 <sjg@chromium.org>
boot/bootdev-uclass.c
boot/bootflow.c
boot/bootstd-uclass.c
include/bootdev.h
include/bootflow.h
include/bootstd.h

index 26b003427ecdc75f382f43d88883d935cb3c2516..81adfb4cfb78198c339e71f5472a165c4e82e201 100644 (file)
@@ -32,30 +32,57 @@ enum {
        BOOT_TARGETS_MAX_LEN    = 100,
 };
 
+struct bootflow *bootdev_next_bootflow_(struct bootstd_priv *std,
+                                       struct udevice *dev,
+                                       struct bootflow *prev)
+{
+       struct bootflow *bflow = prev;
+
+       if (bflow) {
+               if (list_is_last(&bflow->glob_node, &std->glob_head))
+                       return NULL;
+               bflow = list_entry(bflow->glob_node.next, struct bootflow,
+                                  glob_node);
+       } else {
+               if (list_empty(&std->glob_head))
+                       return NULL;
+
+               bflow = list_first_entry(&std->glob_head, struct bootflow,
+                                        glob_node);
+       }
+
+       while (bflow->dev != dev) {
+               if (list_is_last(&bflow->glob_node, &std->glob_head))
+                       return NULL;
+               bflow = list_entry(bflow->glob_node.next, struct bootflow,
+                                  glob_node);
+       }
+
+       return bflow;
+}
+
 int bootdev_first_bootflow(struct udevice *dev, struct bootflow **bflowp)
 {
-       struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+       struct bootstd_priv *std = bootstd_try_priv();
+       struct bootflow *bflow;
 
-       if (list_empty(&ucp->bootflow_head))
+       bflow = bootdev_next_bootflow_(std, dev, NULL);
+       if (!bflow)
                return -ENOENT;
-
-       *bflowp = list_first_entry(&ucp->bootflow_head, struct bootflow,
-                                  bm_node);
+       *bflowp = bflow;
 
        return 0;
 }
 
 int bootdev_next_bootflow(struct bootflow **bflowp)
 {
-       struct bootflow *bflow = *bflowp;
-       struct bootdev_uc_plat *ucp = dev_get_uclass_plat(bflow->dev);
-
-       *bflowp = NULL;
+       struct bootstd_priv *std = bootstd_try_priv();
+       struct bootflow *bflow;
 
-       if (list_is_last(&bflow->bm_node, &ucp->bootflow_head))
+       bflow = bootdev_next_bootflow_(std, (*bflowp)->dev, *bflowp);
+       if (!bflow)
                return -ENOENT;
-
-       *bflowp = list_entry(bflow->bm_node.next, struct bootflow, bm_node);
+       *bflowp = bflow;
 
        return 0;
 }
@@ -911,15 +938,6 @@ void bootdev_list_hunters(struct bootstd_priv *std)
        printf("(total hunters: %d)\n", n_ent);
 }
 
-static int bootdev_post_bind(struct udevice *dev)
-{
-       struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
-
-       INIT_LIST_HEAD(&ucp->bootflow_head);
-
-       return 0;
-}
-
 static int bootdev_pre_unbind(struct udevice *dev)
 {
        int ret;
@@ -936,6 +954,5 @@ UCLASS_DRIVER(bootdev) = {
        .name           = "bootdev",
        .flags          = DM_UC_FLAG_SEQ_ALIAS,
        .per_device_plat_auto   = sizeof(struct bootdev_uc_plat),
-       .post_bind      = bootdev_post_bind,
        .pre_unbind     = bootdev_pre_unbind,
 };
index d8807eb109dff724f24c43e58adc4ab57762cfa9..804809dc100ccfd1a75ea7608448214c96b30013 100644 (file)
@@ -476,8 +476,6 @@ void bootflow_free(struct bootflow *bflow)
 
 void bootflow_remove(struct bootflow *bflow)
 {
-       if (bflow->dev)
-               list_del(&bflow->bm_node);
        list_del(&bflow->glob_node);
 
        bootflow_free(bflow);
index b2f80808c8597b8d6da5a7c0318a08237e69b9a9..91e90bdf43c45b4467e0db50cf3b34a812c83f30 100644 (file)
@@ -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;
index f9cae2fd1fd0cd4ad359aa7c74ab46e9a59d10bd..991b6229c1cefba273395ae64af9f8913e506667 100644 (file)
@@ -109,11 +109,9 @@ struct bootdev_hunter {
  * This is attached to each device in the bootdev uclass and accessible via
  * dev_get_uclass_plat(dev)
  *
- * @bootflows: List of available bootflows for this bootdev
  * @piro: Priority of this bootdev
  */
 struct bootdev_uc_plat {
-       struct list_head bootflow_head;
        enum bootdev_prio_t prio;
 };
 
index 4d2fc7b69b57c8c22485322b3a0911a2cb4ab85d..64d1d6c37860d7c1e939d4724a327a74f6074c85 100644 (file)
@@ -56,12 +56,10 @@ enum bootflow_flags_t {
 /**
  * struct bootflow - information about a bootflow
  *
- * This is connected into two separate linked lists:
+ * This is connected into a linked list:
  *
- *   bm_sibling - links all bootflows in the same bootdev
  *   glob_sibling - links all bootflows in all bootdevs
  *
- * @bm_node: Points to siblings in the same bootdev
  * @glob_node: Points to siblings in the global list (all bootdev)
  * @dev: Bootdev device which produced this bootflow, NULL for flows created by
  *      BOOTMETHF_GLOBAL bootmeths
@@ -92,7 +90,6 @@ enum bootflow_flags_t {
  * @bootmeth_priv: Private data for the bootmeth
  */
 struct bootflow {
-       struct list_head bm_node;
        struct list_head glob_node;
        struct udevice *dev;
        struct udevice *blk;
index 4535d91e2ad73441a71f36a4759669398c2f0ec7..8aff536e3cb7347a773113e523161776899a5e0c 100644 (file)
@@ -123,7 +123,7 @@ void bootstd_clear_glob(void);
 int bootstd_prog_boot(void);
 
 /**
- * bootstd_add_bootflow() - Add a bootflow to the bootdev's and global list
+ * bootstd_add_bootflow() - Add a bootflow to the global list
  *
  * All fields in @bflow must be set up. Note that @bflow->dev is used to add the
  * bootflow to that device.