oftree command: refactor
This has several improvements for the oftree command: - loading a devicetree (-l) and actually probing (-p) it now is separated - the command now can dump the internal devicetree or a dtb given on the command line. - The -f option now actually frees the internal devicetree With this the usage pattern for this command is: oftree -l /env/oftree oftree -d -n /sound oftree -d /env/oftree oftree -f oftree -p oftree -l -p /env/oftree Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
9e824f30c2
commit
e118761c5f
|
@ -471,19 +471,12 @@ config CMD_GO
|
||||||
config CMD_OFTREE
|
config CMD_OFTREE
|
||||||
tristate
|
tristate
|
||||||
select OFTREE
|
select OFTREE
|
||||||
|
select OFDEVICE
|
||||||
prompt "oftree"
|
prompt "oftree"
|
||||||
help
|
help
|
||||||
The oftree command has support for dumping devicetrees and, if
|
The oftree command has support for dumping devicetrees and, if
|
||||||
enabled, to probe devices from the devicetree
|
enabled, to probe devices from the devicetree
|
||||||
|
|
||||||
config CMD_OFTREE_PROBE
|
|
||||||
bool
|
|
||||||
depends on CMD_OFTREE
|
|
||||||
select OFDEVICE
|
|
||||||
prompt "oftree probe support"
|
|
||||||
help
|
|
||||||
This enables the -p option to probe devices from the devicetree
|
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "testing"
|
menu "testing"
|
||||||
|
|
|
@ -39,17 +39,23 @@
|
||||||
|
|
||||||
static int do_oftree(int argc, char *argv[])
|
static int do_oftree(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct fdt_header *fdt;
|
struct fdt_header *fdt = NULL;
|
||||||
|
void *fdt_free = NULL;
|
||||||
int size;
|
int size;
|
||||||
int opt;
|
int opt;
|
||||||
char *file = NULL;
|
char *file = NULL;
|
||||||
const char *node = "/";
|
const char *node = "/";
|
||||||
int dump = 0;
|
int dump = 0;
|
||||||
int probe = 0;
|
int probe = 0;
|
||||||
|
int load = 0;
|
||||||
|
int free_of = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "dpfn:")) > 0) {
|
while ((opt = getopt(argc, argv, "dpfn:l")) > 0) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'l':
|
||||||
|
load = 1;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
dump = 1;
|
dump = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -62,66 +68,97 @@ static int do_oftree(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
return 0;
|
free_of = 1;
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
node = optarg;
|
node = optarg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind < argc)
|
if (free_of) {
|
||||||
file = argv[optind];
|
struct device_node *root = of_get_root_node();
|
||||||
|
|
||||||
if (!dump && !probe)
|
if (root)
|
||||||
return COMMAND_ERROR_USAGE;
|
of_free(root);
|
||||||
|
|
||||||
if (dump) {
|
|
||||||
if (file) {
|
|
||||||
fdt = read_file(file, &size);
|
|
||||||
if (!fdt) {
|
|
||||||
printf("unable to read %s\n", file);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fdt_print(fdt, node);
|
|
||||||
free(fdt);
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (probe) {
|
if (optind < argc)
|
||||||
if (!file)
|
file = argv[optind];
|
||||||
return COMMAND_ERROR_USAGE;
|
|
||||||
|
|
||||||
|
if (!dump && !probe && !load)
|
||||||
|
return COMMAND_ERROR_USAGE;
|
||||||
|
|
||||||
|
if (file) {
|
||||||
fdt = read_file(file, &size);
|
fdt = read_file(file, &size);
|
||||||
if (!fdt) {
|
if (!fdt) {
|
||||||
perror("open");
|
printf("unable to read %s\n", file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fdt_free = fdt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (load) {
|
||||||
|
if (!fdt) {
|
||||||
|
printf("no fdt given\n");
|
||||||
|
ret = -ENOENT;
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = of_unflatten_dtb(fdt);
|
ret = of_unflatten_dtb(fdt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("parse oftree: %s\n", strerror(-ret));
|
printf("parse oftree: %s\n", strerror(-ret));
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_probe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (dump) {
|
||||||
|
if (fdt) {
|
||||||
|
ret = fdt_print(fdt, node);
|
||||||
|
} else {
|
||||||
|
struct device_node *n = of_find_node_by_path(node);
|
||||||
|
|
||||||
|
if (!n) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
of_print_nodes(n, 0);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (probe) {
|
||||||
|
ret = of_probe();
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
free(fdt_free);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAREBOX_CMD_HELP_START(oftree)
|
BAREBOX_CMD_HELP_START(oftree)
|
||||||
BAREBOX_CMD_HELP_USAGE("oftree [OPTIONS]\n")
|
BAREBOX_CMD_HELP_USAGE("oftree [OPTIONS] [DTB]\n")
|
||||||
BAREBOX_CMD_HELP_OPT ("-p <FILE>", "probe devices in oftree from <file>\n")
|
BAREBOX_CMD_HELP_OPT ("-l", "Load [DTB] to internal devicetree\n")
|
||||||
BAREBOX_CMD_HELP_OPT ("-d [FILE]", "dump oftree from [FILE] or the parsed tree if no file is given\n")
|
BAREBOX_CMD_HELP_OPT ("-p", "probe devices from stored devicetree\n")
|
||||||
BAREBOX_CMD_HELP_OPT ("-f", "free stored oftree\n")
|
BAREBOX_CMD_HELP_OPT ("-d", "dump oftree from [DTB] or the parsed tree if no dtb is given\n")
|
||||||
|
BAREBOX_CMD_HELP_OPT ("-f", "free stored devicetree\n")
|
||||||
|
BAREBOX_CMD_HELP_OPT ("-n <node>", "specify root devicenode to dump for -d\n")
|
||||||
BAREBOX_CMD_HELP_END
|
BAREBOX_CMD_HELP_END
|
||||||
|
|
||||||
BAREBOX_CMD_START(oftree)
|
BAREBOX_CMD_START(oftree)
|
||||||
.cmd = do_oftree,
|
.cmd = do_oftree,
|
||||||
.usage = "handle oftrees",
|
.usage = "handle devicetrees",
|
||||||
BAREBOX_CMD_HELP(cmd_oftree_help)
|
BAREBOX_CMD_HELP(cmd_oftree_help)
|
||||||
BAREBOX_CMD_END
|
BAREBOX_CMD_END
|
||||||
|
|
|
@ -325,11 +325,14 @@ int of_fix_tree(struct fdt_header *fdt)
|
||||||
struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt)
|
struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *fixfdt;
|
void *fixfdt, *internalfdt = NULL;
|
||||||
int size, align;
|
int size, align;
|
||||||
|
|
||||||
if (!fdt)
|
if (!fdt) {
|
||||||
return NULL;
|
fdt = internalfdt = of_flatten_dtb();
|
||||||
|
if (!fdt)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
size = fdt_totalsize(fdt);
|
size = fdt_totalsize(fdt);
|
||||||
|
|
||||||
|
@ -343,6 +346,8 @@ struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt)
|
||||||
fixfdt = xmemalign(align, size + OFTREE_SIZE_INCREASE);
|
fixfdt = xmemalign(align, size + OFTREE_SIZE_INCREASE);
|
||||||
ret = fdt_open_into(fdt, fixfdt, size + OFTREE_SIZE_INCREASE);
|
ret = fdt_open_into(fdt, fixfdt, size + OFTREE_SIZE_INCREASE);
|
||||||
|
|
||||||
|
free(internalfdt);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue