9
0
Fork 0

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:
Sascha Hauer 2013-01-09 13:14:45 +01:00
parent 9e824f30c2
commit e118761c5f
3 changed files with 79 additions and 44 deletions

View File

@ -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"

View File

@ -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

View File

@ -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;