dm: core: Create a struct for device runtime info
authorSimon Glass <sjg@chromium.org>
Mon, 15 Mar 2021 04:25:36 +0000 (17:25 +1300)
committerSimon Glass <sjg@chromium.org>
Fri, 26 Mar 2021 04:03:09 +0000 (17:03 +1300)
At present when driver model needs to change a device it simply updates
the struct udevice structure. But with of-platdata-inst most of the fields
are not modified at runtime. In fact, typically only the flags need to
change.

For systems running SPL from read-only memory it is convenient to separate
out the runtime information, so that the devices don't need to be copied
before being used.

Create a new udevice_rt table, similar to the existing driver_rt. For now
it just holds the flags, although they are not used in this patch.

Add a new Kconfig for the driver_rt data, since this is not needed when
of-platdata-inst is used.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/core/root.c
dts/Kconfig
include/asm-generic/global_data.h
include/dm/device.h
test/dm/of_platdata.c

index 3e52452..446ac2f 100644 (file)
@@ -133,6 +133,18 @@ static int dm_setup_inst(void)
 {
        DM_ROOT_NON_CONST = DM_DEVICE_GET(root);
 
+       if (CONFIG_IS_ENABLED(OF_PLATDATA_RT)) {
+               struct udevice_rt *urt;
+               int n_ents;
+
+               /* Allocate the udevice_rt table */
+               n_ents = ll_entry_count(struct udevice, udevice);
+               urt = calloc(n_ents, sizeof(struct udevice_rt));
+               if (!urt)
+                       return log_msg_ret("urt", -ENOMEM);
+               gd_set_dm_udevice_rt(urt);
+       }
+
        return 0;
 }
 
@@ -205,7 +217,7 @@ int dm_scan_plat(bool pre_reloc_only)
 {
        int ret;
 
-       if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+       if (CONFIG_IS_ENABLED(OF_PLATDATA_DRIVER_RT)) {
                struct driver_rt *dyn;
                int n_ents;
 
index e6bbdc5..99ce75e 100644 (file)
@@ -338,6 +338,7 @@ config SPL_OF_PLATDATA
        bool "Generate platform data for use in SPL"
        depends on SPL_OF_CONTROL
        select DTOC
+       select SPL_OF_PLATDATA_DRIVER_RT if !SPL_OF_PLATDATA_INST
        help
          For very constrained SPL environments the overhead of decoding
          device tree nodes and converting their contents into platform data
@@ -391,12 +392,22 @@ config SPL_OF_PLATDATA_RT
          struct udevice (at present just the flags) into a separate struct,
          which is allocated at runtime.
 
+config SPL_OF_PLATDATA_DRIVER_RT
+       bool
+       help
+         Use a separate struct for driver runtime data.
+
+         This enables the driver_rt information, used with of-platdata when
+         of-platdata-inst is not used. It allows finding devices by their
+         driver data.
+
 endif
 
 config TPL_OF_PLATDATA
        bool "Generate platform data for use in TPL"
        depends on TPL_OF_CONTROL
        select DTOC
+       select TPL_OF_PLATDATA_DRIVER_RT if !TPL_OF_PLATDATA_INST
        help
          For very constrained SPL environments the overhead of decoding
          device tree nodes and converting their contents into platform data
@@ -451,6 +462,15 @@ config TPL_OF_PLATDATA_RT
          struct udevice (at present just the flags) into a separate struct,
          which is allocated at runtime.
 
+config TPL_OF_PLATDATA_DRIVER_RT
+       bool
+       help
+         Use a separate struct for driver runtime data.
+
+         This enables the driver_rt information, used with of-platdata when
+         of-platdata-inst is not used. It allows finding devices by their
+         driver data.
+
 endif
 
 endmenu
index c24f5e0..f6189ef 100644 (file)
@@ -215,10 +215,14 @@ struct global_data {
         * @uclass_root_s.
         */
        struct list_head *uclass_root;
-# if CONFIG_IS_ENABLED(OF_PLATDATA)
+# if CONFIG_IS_ENABLED(OF_PLATDATA_DRIVER_RT)
        /** @dm_driver_rt: Dynamic info about the driver */
        struct driver_rt *dm_driver_rt;
 # endif
+#if CONFIG_IS_ENABLED(OF_PLATDATA_RT)
+       /** @dm_udevice_rt: Dynamic info about the udevice */
+       struct udevice_rt *dm_udevice_rt;
+# endif
 #endif
 #ifdef CONFIG_TIMER
        /**
@@ -483,7 +487,7 @@ struct global_data {
 #define gd_set_of_root(_root)
 #endif
 
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
+#if CONFIG_IS_ENABLED(OF_PLATDATA_DRIVER_RT)
 #define gd_set_dm_driver_rt(dyn)       gd->dm_driver_rt = dyn
 #define gd_dm_driver_rt()              gd->dm_driver_rt
 #else
@@ -491,6 +495,14 @@ struct global_data {
 #define gd_dm_driver_rt()              NULL
 #endif
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA_RT)
+#define gd_set_dm_udevice_rt(dyn)      gd->dm_udevice_rt = dyn
+#define gd_dm_udevice_rt()             gd->dm_udevice_rt
+#else
+#define gd_set_dm_udevice_rt(dyn)
+#define gd_dm_udevice_rt()             NULL
+#endif
+
 #ifdef CONFIG_GENERATE_ACPI_TABLE
 #define gd_acpi_ctx()          gd->acpi_ctx
 #else
index 9183356..8e16f2e 100644 (file)
@@ -190,6 +190,21 @@ struct udevice {
 #endif
 };
 
+/**
+ * udevice_rt - runtime information set up by U-Boot
+ *
+ * This is only used with OF_PLATDATA_RT
+ *
+ * There is one of these for every udevice in the linker list, indexed by
+ * the udevice_info idx value.
+ *
+ * @flags_: Flags for this device DM_FLAG_... (do not access outside driver
+ *     model)
+ */
+struct udevice_rt {
+       u32 flags_;
+};
+
 /* Maximum sequence number supported */
 #define DM_MAX_SEQ     999
 
index f2b45b9..0f89c7a 100644 (file)
@@ -147,7 +147,7 @@ static int dm_test_of_plat_dev(struct unit_test_state *uts)
        uint i;
 
        /* Skip this test if there is no platform data */
-       if (CONFIG_IS_ENABLED(OF_PLATDATA_INST))
+       if (!CONFIG_IS_ENABLED(OF_PLATDATA_DRIVER_RT))
                return 0;
 
        /* Record the indexes that are found */