]>
Commit | Line | Data |
---|---|---|
06811959 SG |
1 | /* |
2 | * Copyright (c) 2013 Google, Inc | |
3 | * | |
4 | * (C) Copyright 2012 | |
5 | * Marek Vasut <marex@denx.de> | |
6 | * | |
7 | * SPDX-License-Identifier: GPL-2.0+ | |
8 | */ | |
9 | ||
10 | #include <common.h> | |
11 | #include <dm.h> | |
12 | #include <malloc.h> | |
13 | #include <errno.h> | |
14 | #include <asm/io.h> | |
15 | #include <dm/root.h> | |
16 | #include <dm/test.h> | |
17 | #include <dm/uclass-internal.h> | |
18 | ||
fffa24d7 SG |
19 | /** |
20 | * dm_display_line() - Display information about a single device | |
21 | * | |
22 | * Displays a single line of information with an option prefix | |
23 | * | |
24 | * @dev: Device to display | |
25 | * @buf: Prefix to display at the start of the line | |
26 | */ | |
27 | static void dm_display_line(struct udevice *dev, char *buf) | |
28 | { | |
29 | printf("%s- %c %s @ %08lx", buf, | |
30 | dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ', | |
31 | dev->name, (ulong)map_to_sysmem(dev)); | |
b7d66570 SG |
32 | if (dev->req_seq != -1) |
33 | printf(", %d", dev->req_seq); | |
fffa24d7 SG |
34 | puts("\n"); |
35 | } | |
36 | ||
54c5d08a | 37 | static int display_succ(struct udevice *in, char *buf) |
06811959 SG |
38 | { |
39 | int len; | |
40 | int ip = 0; | |
41 | char local[16]; | |
54c5d08a | 42 | struct udevice *pos, *n, *prev = NULL; |
06811959 | 43 | |
fffa24d7 | 44 | dm_display_line(in, buf); |
06811959 SG |
45 | |
46 | if (list_empty(&in->child_head)) | |
47 | return 0; | |
48 | ||
49 | len = strlen(buf); | |
50 | strncpy(local, buf, sizeof(local)); | |
51 | snprintf(local + len, 2, "|"); | |
52 | if (len && local[len - 1] == '`') | |
53 | local[len - 1] = ' '; | |
54 | ||
55 | list_for_each_entry_safe(pos, n, &in->child_head, sibling_node) { | |
56 | if (ip++) | |
57 | display_succ(prev, local); | |
58 | prev = pos; | |
59 | } | |
60 | ||
61 | snprintf(local + len, 2, "`"); | |
62 | display_succ(prev, local); | |
63 | ||
64 | return 0; | |
65 | } | |
66 | ||
54c5d08a | 67 | static int dm_dump(struct udevice *dev) |
06811959 SG |
68 | { |
69 | if (!dev) | |
70 | return -EINVAL; | |
71 | return display_succ(dev, ""); | |
72 | } | |
73 | ||
74 | static int do_dm_dump_all(cmd_tbl_t *cmdtp, int flag, int argc, | |
75 | char * const argv[]) | |
76 | { | |
54c5d08a | 77 | struct udevice *root; |
06811959 SG |
78 | |
79 | root = dm_root(); | |
184b1b71 | 80 | printf("ROOT %08lx\n", (ulong)map_to_sysmem(root)); |
06811959 SG |
81 | return dm_dump(root); |
82 | } | |
83 | ||
84 | static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc, | |
85 | char * const argv[]) | |
86 | { | |
87 | struct uclass *uc; | |
88 | int ret; | |
89 | int id; | |
90 | ||
91 | for (id = 0; id < UCLASS_COUNT; id++) { | |
54c5d08a | 92 | struct udevice *dev; |
06811959 SG |
93 | |
94 | ret = uclass_get(id, &uc); | |
95 | if (ret) | |
96 | continue; | |
97 | ||
98 | printf("uclass %d: %s\n", id, uc->uc_drv->name); | |
4e8bc211 SG |
99 | if (list_empty(&uc->dev_head)) |
100 | continue; | |
101 | list_for_each_entry(dev, &uc->dev_head, uclass_node) { | |
fffa24d7 | 102 | dm_display_line(dev, ""); |
06811959 SG |
103 | } |
104 | puts("\n"); | |
105 | } | |
106 | ||
107 | return 0; | |
108 | } | |
109 | ||
b6a49a7a | 110 | #ifdef CONFIG_DM_TEST |
06811959 SG |
111 | static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc, |
112 | char * const argv[]) | |
113 | { | |
114 | return dm_test_main(); | |
115 | } | |
b6a49a7a SG |
116 | #define TEST_HELP "\ndm test Run tests" |
117 | #else | |
118 | #define TEST_HELP | |
119 | #endif | |
06811959 SG |
120 | |
121 | static cmd_tbl_t test_commands[] = { | |
122 | U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""), | |
123 | U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), | |
b6a49a7a | 124 | #ifdef CONFIG_DM_TEST |
06811959 | 125 | U_BOOT_CMD_MKENT(test, 1, 1, do_dm_test, "", ""), |
b6a49a7a | 126 | #endif |
06811959 SG |
127 | }; |
128 | ||
129 | static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
130 | { | |
131 | cmd_tbl_t *test_cmd; | |
132 | int ret; | |
133 | ||
134 | if (argc != 2) | |
135 | return CMD_RET_USAGE; | |
136 | test_cmd = find_cmd_tbl(argv[1], test_commands, | |
137 | ARRAY_SIZE(test_commands)); | |
138 | argc -= 2; | |
139 | argv += 2; | |
140 | if (!test_cmd || argc > test_cmd->maxargs) | |
141 | return CMD_RET_USAGE; | |
142 | ||
143 | ret = test_cmd->cmd(test_cmd, flag, argc, argv); | |
144 | ||
145 | return cmd_process_error(test_cmd, ret); | |
146 | } | |
147 | ||
148 | U_BOOT_CMD( | |
149 | dm, 2, 1, do_dm, | |
150 | "Driver model low level access", | |
fffa24d7 | 151 | "tree Dump driver model tree ('*' = activated)\n" |
b6a49a7a SG |
152 | "dm uclass Dump list of instances for each uclass" |
153 | TEST_HELP | |
06811959 | 154 | ); |