aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass2023-08-14 16:40:34 -0600
committerTom Rini2023-08-25 13:54:33 -0400
commit472317cb12e534f56b631365987934960dfb0a3f (patch)
tree3ac102f38603af6ee02075c0743bb08f824119dd
parent2dee81fe5f4a6427ba48fe17ff017930ddf3b4e4 (diff)
expo: cedit: Support reading settings from a file
Add a command to read cedit settings from a devicetree file. Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r--boot/cedit.c52
-rw-r--r--cmd/cedit.c39
-rw-r--r--doc/usage/cmd/cedit.rst8
-rw-r--r--include/cedit.h13
-rw-r--r--test/boot/cedit.c22
5 files changed, 131 insertions, 3 deletions
diff --git a/boot/cedit.c b/boot/cedit.c
index 4dd79a2263d..6a74a380989 100644
--- a/boot/cedit.c
+++ b/boot/cedit.c
@@ -23,9 +23,11 @@
* struct cedit_iter_priv - private data for cedit operations
*
* @buf: Buffer to use when writing settings to the devicetree
+ * @node: Node to read from when reading settings from devicetree
*/
struct cedit_iter_priv {
struct abuf *buf;
+ ofnode node;
};
int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
@@ -318,3 +320,53 @@ int cedit_write_settings(struct expo *exp, struct abuf *buf)
return 0;
}
+
+static int h_read_settings(struct scene_obj *obj, void *vpriv)
+{
+ struct cedit_iter_priv *priv = vpriv;
+ ofnode node = priv->node;
+
+ switch (obj->type) {
+ case SCENEOBJT_NONE:
+ case SCENEOBJT_IMAGE:
+ case SCENEOBJT_TEXT:
+ break;
+ case SCENEOBJT_MENU: {
+ struct scene_obj_menu *menu;
+ uint val;
+
+ if (ofnode_read_u32(node, obj->name, &val))
+ return log_msg_ret("rd", -ENOENT);
+ menu = (struct scene_obj_menu *)obj;
+ menu->cur_item_id = val;
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int cedit_read_settings(struct expo *exp, oftree tree)
+{
+ struct cedit_iter_priv priv;
+ ofnode root, node;
+ int ret;
+
+ root = oftree_root(tree);
+ if (!ofnode_valid(root))
+ return log_msg_ret("roo", -ENOENT);
+ node = ofnode_find_subnode(root, CEDIT_NODE_NAME);
+ if (!ofnode_valid(node))
+ return log_msg_ret("pat", -ENOENT);
+
+ /* read in the items */
+ priv.node = node;
+ ret = expo_iter_scene_objs(exp, h_read_settings, &priv);
+ if (ret) {
+ log_debug("Failed to read settings (err=%d)\n", ret);
+ return log_msg_ret("set", ret);
+ }
+
+ return 0;
+}
diff --git a/cmd/cedit.c b/cmd/cedit.c
index 18cc8ba191b..a155e080b1f 100644
--- a/cmd/cedit.c
+++ b/cmd/cedit.c
@@ -99,6 +99,43 @@ static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc,
return 0;
}
+static int do_cedit_read_fdt(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ const char *fname;
+ void *buf;
+ oftree tree;
+ ulong size;
+ int ret;
+
+ if (argc < 4)
+ return CMD_RET_USAGE;
+ fname = argv[3];
+
+ ret = fs_load_alloc(argv[1], argv[2], argv[3], SZ_1M, 0, &buf, &size);
+ if (ret) {
+ printf("File not found\n");
+ return CMD_RET_FAILURE;
+ }
+
+ tree = oftree_from_fdt(buf);
+ if (!oftree_valid(tree)) {
+ free(buf);
+ printf("Cannot create oftree\n");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = cedit_read_settings(cur_exp, tree);
+ oftree_dispose(tree);
+ free(buf);
+ if (ret) {
+ printf("Failed to read settings: %dE\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
@@ -128,12 +165,14 @@ static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc,
#ifdef CONFIG_SYS_LONGHELP
static char cedit_help_text[] =
"load <interface> <dev[:part]> <filename> - load config editor\n"
+ "cedit read_fdt <i/f> <dev[:part]> <filename> - read settings\n"
"cedit write_fdt <i/f> <dev[:part]> <filename> - write settings\n"
"cedit run - run config editor";
#endif /* CONFIG_SYS_LONGHELP */
U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text,
U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load),
+ U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt),
U_BOOT_SUBCMD_MKENT(write_fdt, 5, 1, do_cedit_write_fdt),
U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run),
);
diff --git a/doc/usage/cmd/cedit.rst b/doc/usage/cmd/cedit.rst
index 0581594831f..0a9f620b59b 100644
--- a/doc/usage/cmd/cedit.rst
+++ b/doc/usage/cmd/cedit.rst
@@ -11,6 +11,7 @@ Synopis
cedit load <interface> <dev[:part]> <filename>
cedit run
cedit write_fdt <dev[:part]> <filename>
+ cedit read_fdt <dev[:part]> <filename>
Description
-----------
@@ -45,6 +46,11 @@ cedit write_fdt
Writes the current user settings to a devicetree file. For each menu item the
selected ID and its text string are written.
+cedit read_fdt
+~~~~~~~~~~~~~~
+
+Reads the user settings from a devicetree file and updates the cedit with those
+settings.
Example
-------
@@ -65,3 +71,5 @@ That results in::
power-loss-str = "Always Off";
};
}
+
+ => cedit read_fdt hostfs - settings.dtb
diff --git a/include/cedit.h b/include/cedit.h
index 6086e302006..bb6e87d4af7 100644
--- a/include/cedit.h
+++ b/include/cedit.h
@@ -7,6 +7,8 @@
#ifndef __CEDIT_H
#define __CEDIT_H
+#include <dm/ofnode_decl.h>
+
struct abuf;
struct expo;
struct scene;
@@ -67,4 +69,15 @@ int cedit_prepare(struct expo *exp, struct video_priv **vid_privp,
*/
int cedit_write_settings(struct expo *exp, struct abuf *buf);
+/**
+ * cedit_read_settings() - Read settings in FDT format
+ *
+ * Read an FDT with the settings
+ *
+ * @exp: Expo to read settings into
+ * @tree: Tree to read from
+ * Return: 0 if OK, -ve on error
+ */
+int cedit_read_settings(struct expo *exp, oftree tree);
+
#endif /* __CEDIT_H */
diff --git a/test/boot/cedit.c b/test/boot/cedit.c
index 1dd78c64158..659c47ed35f 100644
--- a/test/boot/cedit.c
+++ b/test/boot/cedit.c
@@ -54,11 +54,12 @@ static int cedit_base(struct unit_test_state *uts)
}
BOOTSTD_TEST(cedit_base, 0);
-/* Check the cedit write_fdt commands */
+/* Check the cedit write_fdt and read_fdt commands */
static int cedit_fdt(struct unit_test_state *uts)
{
struct video_priv *vid_priv;
extern struct expo *cur_exp;
+ struct scene_obj_menu *menu;
ulong addr = 0x1000;
struct ofprop prop;
struct scene *scn;
@@ -72,6 +73,11 @@ static int cedit_fdt(struct unit_test_state *uts)
ut_asserteq(ID_SCENE1, cedit_prepare(cur_exp, &vid_priv, &scn));
+ /* get a menu to fiddle with */
+ menu = scene_obj_find(scn, ID_CPU_SPEED, SCENEOBJT_MENU);
+ ut_assertnonnull(menu);
+ menu->cur_item_id = ID_CPU_SPEED_2;
+
ut_assertok(run_command("cedit write_fdt hostfs - settings.dtb", 0));
ut_assertok(run_commandf("load hostfs - %lx settings.dtb", addr));
ut_assert_nextlinen("1024 bytes read");
@@ -80,9 +86,9 @@ static int cedit_fdt(struct unit_test_state *uts)
tree = oftree_from_fdt(fdt);
node = ofnode_find_subnode(oftree_root(tree), CEDIT_NODE_NAME);
- ut_asserteq(ID_CPU_SPEED_1,
+ ut_asserteq(ID_CPU_SPEED_2,
ofnode_read_u32_default(node, "cpu-speed", 0));
- ut_asserteq_str("2 GHz", ofnode_read_string(node, "cpu-speed-str"));
+ ut_asserteq_str("2.5 GHz", ofnode_read_string(node, "cpu-speed-str"));
ut_assert(ofnode_valid(node));
/* There should only be 4 properties */
@@ -93,6 +99,16 @@ static int cedit_fdt(struct unit_test_state *uts)
ut_assert_console_end();
+ /* reset the expo */
+ menu->cur_item_id = ID_CPU_SPEED_1;
+
+ /* load in the settings and make sure they update */
+ ut_assertok(run_command("cedit read_fdt hostfs - settings.dtb", 0));
+ ut_asserteq(ID_CPU_SPEED_2, menu->cur_item_id);
+
+ ut_assertnonnull(menu);
+ ut_assert_console_end();
+
return 0;
}
BOOTSTD_TEST(cedit_fdt, 0);