Merge tag 'dm-pull-5jan21' of git://git.denx.de/u-boot-dm into next
[platform/kernel/u-boot.git] / drivers / core / dump.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <mapmem.h>
9 #include <dm/root.h>
10 #include <dm/util.h>
11 #include <dm/uclass-internal.h>
12
13 static void show_devices(struct udevice *dev, int depth, int last_flag)
14 {
15         int i, is_last;
16         struct udevice *child;
17         u32 flags = dev_get_flags(dev);
18
19         /* print the first 20 characters to not break the tree-format. */
20         printf(IS_ENABLED(CONFIG_SPL_BUILD) ? " %s  %d  [ %c ]   %s  " :
21                " %-10.10s  %3d  [ %c ]   %-20.20s  ", dev->uclass->uc_drv->name,
22                dev_get_uclass_index(dev, NULL),
23                flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
24
25         for (i = depth; i >= 0; i--) {
26                 is_last = (last_flag >> i) & 1;
27                 if (i) {
28                         if (is_last)
29                                 printf("    ");
30                         else
31                                 printf("|   ");
32                 } else {
33                         if (is_last)
34                                 printf("`-- ");
35                         else
36                                 printf("|-- ");
37                 }
38         }
39
40         printf("%s\n", dev->name);
41
42         list_for_each_entry(child, &dev->child_head, sibling_node) {
43                 is_last = list_is_last(&child->sibling_node, &dev->child_head);
44                 show_devices(child, depth + 1, (last_flag << 1) | is_last);
45         }
46 }
47
48 void dm_dump_all(void)
49 {
50         struct udevice *root;
51
52         root = dm_root();
53         if (root) {
54                 printf(" Class     Index  Probed  Driver                Name\n");
55                 printf("-----------------------------------------------------------\n");
56                 show_devices(root, -1, 0);
57         }
58 }
59
60 /**
61  * dm_display_line() - Display information about a single device
62  *
63  * Displays a single line of information with an option prefix
64  *
65  * @dev:        Device to display
66  */
67 static void dm_display_line(struct udevice *dev, int index)
68 {
69         printf("%-3i %c %s @ %08lx", index,
70                dev_get_flags(dev) & DM_FLAG_ACTIVATED ? '*' : ' ',
71                dev->name, (ulong)map_to_sysmem(dev));
72         if (dev->seq_ != -1)
73                 printf(", seq %d", dev_seq(dev));
74         puts("\n");
75 }
76
77 void dm_dump_uclass(void)
78 {
79         struct uclass *uc;
80         int ret;
81         int id;
82
83         for (id = 0; id < UCLASS_COUNT; id++) {
84                 struct udevice *dev;
85                 int i = 0;
86
87                 ret = uclass_get(id, &uc);
88                 if (ret)
89                         continue;
90
91                 printf("uclass %d: %s\n", id, uc->uc_drv->name);
92                 if (list_empty(&uc->dev_head))
93                         continue;
94                 uclass_foreach_dev(dev, uc) {
95                         dm_display_line(dev, i);
96                         i++;
97                 }
98                 puts("\n");
99         }
100 }
101
102 void dm_dump_driver_compat(void)
103 {
104         struct driver *d = ll_entry_start(struct driver, driver);
105         const int n_ents = ll_entry_count(struct driver, driver);
106         struct driver *entry;
107         const struct udevice_id *match;
108
109         puts("Driver                Compatible\n");
110         puts("--------------------------------\n");
111         for (entry = d; entry < d + n_ents; entry++) {
112                 match = entry->of_match;
113
114                 printf("%-20.20s", entry->name);
115                 if (match) {
116                         printf("  %s", match->compatible);
117                         match++;
118                 }
119                 printf("\n");
120
121                 for (; match && match->compatible; match++)
122                         printf("%-20.20s  %s\n", "", match->compatible);
123         }
124 }
125
126 void dm_dump_drivers(void)
127 {
128         struct driver *d = ll_entry_start(struct driver, driver);
129         const int n_ents = ll_entry_count(struct driver, driver);
130         struct driver *entry;
131         struct udevice *udev;
132         struct uclass *uc;
133         int i;
134
135         puts("Driver                    uid uclass               Devices\n");
136         puts("----------------------------------------------------------\n");
137
138         for (entry = d; entry < d + n_ents; entry++) {
139                 uclass_get(entry->id, &uc);
140
141                 printf("%-25.25s %-3.3d %-20.20s ", entry->name, entry->id,
142                        uc ? uc->uc_drv->name : "<no uclass>");
143
144                 if (!uc) {
145                         puts("\n");
146                         continue;
147                 }
148
149                 i = 0;
150                 uclass_foreach_dev(udev, uc) {
151                         if (udev->driver != entry)
152                                 continue;
153                         if (i)
154                                 printf("%-51.51s", "");
155
156                         printf("%-25.25s\n", udev->name);
157                         i++;
158                 }
159                 if (!i)
160                         puts("<none>\n");
161         }
162 }
163
164 void dm_dump_static_driver_info(void)
165 {
166         struct driver_info *drv = ll_entry_start(struct driver_info,
167                                                  driver_info);
168         const int n_ents = ll_entry_count(struct driver_info, driver_info);
169         struct driver_info *entry;
170
171         puts("Driver                    Address\n");
172         puts("---------------------------------\n");
173         for (entry = drv; entry != drv + n_ents; entry++) {
174                 printf("%-25.25s @%08lx\n", entry->name,
175                        (ulong)map_to_sysmem(entry->plat));
176         }
177 }