At present the uclass list head is in global_data. This is convenient
but with the new of-platdata we need the list head to be declared by
the generated code.

Change this over to be a pointer. Provide a 'static' version in
global_data to retain the current behaviour.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 drivers/core/device.c             | 4 ++--
 drivers/core/root.c               | 7 ++++---
 drivers/core/uclass.c             | 4 ++--
 include/asm-generic/global_data.h | 8 +++++++-
 include/dm/device-internal.h      | 1 +
 test/dm/core.c                    | 6 +++---
 6 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 6a9bee093d0..aeab3836ed7 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -613,7 +613,7 @@ static int device_find_by_ofnode(ofnode node, struct 
udevice **devp)
        struct udevice *dev;
        int ret;
 
-       list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+       list_for_each_entry(uc, gd->uclass_root, sibling_node) {
                ret = uclass_find_device_by_ofnode(uc->uc_drv->id, node,
                                                   &dev);
                if (!ret || dev) {
@@ -1032,7 +1032,7 @@ int dev_disable_by_path(const char *path)
        if (!of_live_active())
                return -ENOSYS;
 
-       list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+       list_for_each_entry(uc, gd->uclass_root, sibling_node) {
                ret = uclass_find_device_by_ofnode(uc->uc_drv->id, node, &dev);
                if (!ret)
                        break;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 2a5ebec27d8..3adbc94eb94 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -45,8 +45,8 @@ void dm_fixup_for_gd_move(struct global_data *new_gd)
 {
        /* The sentinel node has moved, so update things that point to it */
        if (gd->dm_root) {
-               new_gd->uclass_root.next->prev = &new_gd->uclass_root;
-               new_gd->uclass_root.prev->next = &new_gd->uclass_root;
+               new_gd->uclass_root->next->prev = new_gd->uclass_root;
+               new_gd->uclass_root->prev->next = new_gd->uclass_root;
        }
 }
 
@@ -136,7 +136,8 @@ int dm_init(bool of_live)
                dm_warn("Virtual root driver already exists!\n");
                return -EINVAL;
        }
-       INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
+       gd->uclass_root = &DM_UCLASS_ROOT_S_NON_CONST;
+       INIT_LIST_HEAD(DM_UCLASS_ROOT_NON_CONST);
 
        if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
                fix_drivers();
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index e773e34833e..cdb975d5b31 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -33,7 +33,7 @@ struct uclass *uclass_find(enum uclass_id key)
         * node to the start of the list, or creating a linear array mapping
         * id to node.
         */
-       list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+       list_for_each_entry(uc, gd->uclass_root, sibling_node) {
                if (uc->uc_drv->id == key)
                        return uc;
        }
@@ -84,7 +84,7 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp)
        uc->uc_drv = uc_drv;
        INIT_LIST_HEAD(&uc->sibling_node);
        INIT_LIST_HEAD(&uc->dev_head);
-       list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);
+       list_add(&uc->sibling_node, DM_UCLASS_ROOT_NON_CONST);
 
        if (uc_drv->init) {
                ret = uc_drv->init(uc);
diff --git a/include/asm-generic/global_data.h 
b/include/asm-generic/global_data.h
index 87d827d0f43..b63575919f0 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -194,7 +194,13 @@ struct global_data {
        /**
         * @uclass_root: head of core tree
         */
-       struct list_head uclass_root;
+       struct list_head uclass_root_s;
+       /**
+        * @uclass_root: pointer to head of core tree, if uclasses are in
+        * read-only memory and cannot be adjusted to use @uclass_root as a
+        * list head.
+        */
+       struct list_head *uclass_root;
 # if CONFIG_IS_ENABLED(OF_PLATDATA)
         /** Dynamic info about the driver */
        struct driver_rt *dm_driver_rt;
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 03b092bdf7d..639bbd293d9 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -288,6 +288,7 @@ fdt_addr_t simple_bus_translate(struct udevice *dev, 
fdt_addr_t addr);
 /* Cast away any volatile pointer */
 #define DM_ROOT_NON_CONST              (((gd_t *)gd)->dm_root)
 #define DM_UCLASS_ROOT_NON_CONST       (((gd_t *)gd)->uclass_root)
+#define DM_UCLASS_ROOT_S_NON_CONST     (((gd_t *)gd)->uclass_root_s)
 
 /* device resource management */
 #ifdef CONFIG_DEVRES
diff --git a/test/dm/core.c b/test/dm/core.c
index 565896ed504..580d171e30e 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -116,14 +116,14 @@ static int dm_test_autobind(struct unit_test_state *uts)
         * device with no children.
         */
        ut_assert(dms->root);
-       ut_asserteq(1, list_count_items(&gd->uclass_root));
+       ut_asserteq(1, list_count_items(gd->uclass_root));
        ut_asserteq(0, list_count_items(&gd->dm_root->child_head));
        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
 
        ut_assertok(dm_scan_plat(false));
 
        /* We should have our test class now at least, plus more children */
-       ut_assert(1 < list_count_items(&gd->uclass_root));
+       ut_assert(1 < list_count_items(gd->uclass_root));
        ut_assert(0 < list_count_items(&gd->dm_root->child_head));
 
        /* Our 3 dm_test_infox children should be bound to the test uclass */
@@ -1073,7 +1073,7 @@ static int dm_test_all_have_seq(struct unit_test_state 
*uts)
        struct udevice *dev;
        struct uclass *uc;
 
-       list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+       list_for_each_entry(uc, gd->uclass_root, sibling_node) {
                list_for_each_entry(dev, &uc->dev_head, uclass_node) {
                        if (dev->seq_ == -1)
                                printf("Device '%s' has no seq (%d)\n",
-- 
2.29.2.684.gfbc64c5ab5-goog

Reply via email to