]>
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 | ||
a56642c7 MY |
19 | static void show_devices(struct udevice *dev, int depth, int last_flag) |
20 | { | |
21 | int i, is_last; | |
22 | struct udevice *child; | |
23 | char class_name[12]; | |
24 | ||
25 | /* print the first 11 characters to not break the tree-format. */ | |
26 | strlcpy(class_name, dev->uclass->uc_drv->name, sizeof(class_name)); | |
27 | printf(" %-11s [ %c ] ", class_name, | |
28 | dev->flags & DM_FLAG_ACTIVATED ? '+' : ' '); | |
29 | ||
30 | for (i = depth; i >= 0; i--) { | |
31 | is_last = (last_flag >> i) & 1; | |
32 | if (i) { | |
33 | if (is_last) | |
34 | printf(" "); | |
35 | else | |
36 | printf("| "); | |
37 | } else { | |
38 | if (is_last) | |
39 | printf("`-- "); | |
40 | else | |
41 | printf("|-- "); | |
42 | } | |
43 | } | |
44 | ||
45 | printf("%s\n", dev->name); | |
46 | ||
47 | list_for_each_entry(child, &dev->child_head, sibling_node) { | |
48 | is_last = list_is_last(&child->sibling_node, &dev->child_head); | |
49 | show_devices(child, depth + 1, (last_flag << 1) | is_last); | |
50 | } | |
51 | } | |
52 | ||
53 | static int do_dm_dump_all(cmd_tbl_t *cmdtp, int flag, int argc, | |
54 | char * const argv[]) | |
55 | { | |
56 | struct udevice *root; | |
57 | ||
58 | root = dm_root(); | |
59 | if (root) { | |
60 | printf(" Class Probed Name\n"); | |
61 | printf("----------------------------------------\n"); | |
62 | show_devices(root, -1, 0); | |
63 | } | |
64 | ||
65 | return 0; | |
66 | } | |
67 | ||
fffa24d7 SG |
68 | /** |
69 | * dm_display_line() - Display information about a single device | |
70 | * | |
71 | * Displays a single line of information with an option prefix | |
72 | * | |
73 | * @dev: Device to display | |
fffa24d7 | 74 | */ |
a56642c7 | 75 | static void dm_display_line(struct udevice *dev) |
fffa24d7 | 76 | { |
a56642c7 | 77 | printf("- %c %s @ %08lx", |
fffa24d7 SG |
78 | dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ', |
79 | dev->name, (ulong)map_to_sysmem(dev)); | |
b7d66570 SG |
80 | if (dev->req_seq != -1) |
81 | printf(", %d", dev->req_seq); | |
fffa24d7 SG |
82 | puts("\n"); |
83 | } | |
84 | ||
06811959 SG |
85 | static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc, |
86 | char * const argv[]) | |
87 | { | |
88 | struct uclass *uc; | |
89 | int ret; | |
90 | int id; | |
91 | ||
92 | for (id = 0; id < UCLASS_COUNT; id++) { | |
54c5d08a | 93 | struct udevice *dev; |
06811959 SG |
94 | |
95 | ret = uclass_get(id, &uc); | |
96 | if (ret) | |
97 | continue; | |
98 | ||
99 | printf("uclass %d: %s\n", id, uc->uc_drv->name); | |
4e8bc211 SG |
100 | if (list_empty(&uc->dev_head)) |
101 | continue; | |
102 | list_for_each_entry(dev, &uc->dev_head, uclass_node) { | |
a56642c7 | 103 | dm_display_line(dev); |
06811959 SG |
104 | } |
105 | puts("\n"); | |
106 | } | |
107 | ||
108 | return 0; | |
109 | } | |
110 | ||
b6a49a7a | 111 | #ifdef CONFIG_DM_TEST |
06811959 SG |
112 | static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc, |
113 | char * const argv[]) | |
114 | { | |
115 | return dm_test_main(); | |
116 | } | |
b6a49a7a SG |
117 | #define TEST_HELP "\ndm test Run tests" |
118 | #else | |
119 | #define TEST_HELP | |
120 | #endif | |
06811959 SG |
121 | |
122 | static cmd_tbl_t test_commands[] = { | |
123 | U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""), | |
124 | U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), | |
b6a49a7a | 125 | #ifdef CONFIG_DM_TEST |
06811959 | 126 | U_BOOT_CMD_MKENT(test, 1, 1, do_dm_test, "", ""), |
b6a49a7a | 127 | #endif |
06811959 SG |
128 | }; |
129 | ||
130 | static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
131 | { | |
132 | cmd_tbl_t *test_cmd; | |
133 | int ret; | |
134 | ||
135 | if (argc != 2) | |
136 | return CMD_RET_USAGE; | |
137 | test_cmd = find_cmd_tbl(argv[1], test_commands, | |
138 | ARRAY_SIZE(test_commands)); | |
139 | argc -= 2; | |
140 | argv += 2; | |
141 | if (!test_cmd || argc > test_cmd->maxargs) | |
142 | return CMD_RET_USAGE; | |
143 | ||
144 | ret = test_cmd->cmd(test_cmd, flag, argc, argv); | |
145 | ||
146 | return cmd_process_error(test_cmd, ret); | |
147 | } | |
148 | ||
149 | U_BOOT_CMD( | |
150 | dm, 2, 1, do_dm, | |
151 | "Driver model low level access", | |
fffa24d7 | 152 | "tree Dump driver model tree ('*' = activated)\n" |
b6a49a7a SG |
153 | "dm uclass Dump list of instances for each uclass" |
154 | TEST_HELP | |
06811959 | 155 | ); |