diff options
author | Simon Glass <sjg@chromium.org> | 2023-01-17 20:47:12 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-01-24 02:11:39 +0300 |
commit | 3d01254140fc9e5e900d739cb97bd9fba6aa2b68 (patch) | |
tree | f0ab5ee057999c7b07d19beefd3761ddeb6696a8 /drivers | |
parent | c0f19fedaa742adbe0f4e29e9a956ea05fe22057 (diff) | |
download | u-boot-3d01254140fc9e5e900d739cb97bd9fba6aa2b68.tar.xz |
dm: core: Support sorting devices with dm tree
Add a -s flag to sort the top-level devices in order of uclass ID.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/core/dump.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 1c1f7e4d30..0c7d2ec4d0 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -5,12 +5,34 @@ #include <common.h> #include <dm.h> +#include <malloc.h> #include <mapmem.h> +#include <sort.h> #include <dm/root.h> #include <dm/util.h> #include <dm/uclass-internal.h> -static void show_devices(struct udevice *dev, int depth, int last_flag) +/** + * struct sort_info - information used for sorting + * + * @dev: List of devices + * @alloced: Maximum number of devices in @dev + */ +struct sort_info { + struct udevice **dev; + int size; +}; + +static int h_cmp_uclass_id(const void *d1, const void *d2) +{ + const struct udevice *const *dev1 = d1; + const struct udevice *const *dev2 = d2; + + return device_get_uclass_id(*dev1) - device_get_uclass_id(*dev2); +} + +static void show_devices(struct udevice *dev, int depth, int last_flag, + struct udevice **devs) { int i, is_last; struct udevice *child; @@ -39,21 +61,52 @@ static void show_devices(struct udevice *dev, int depth, int last_flag) printf("%s\n", dev->name); - device_foreach_child(child, dev) { - is_last = list_is_last(&child->sibling_node, &dev->child_head); - show_devices(child, depth + 1, (last_flag << 1) | is_last); + if (devs) { + int count; + int i; + + count = 0; + device_foreach_child(child, dev) + devs[count++] = child; + qsort(devs, count, sizeof(struct udevice *), h_cmp_uclass_id); + + for (i = 0; i < count; i++) { + show_devices(devs[i], depth + 1, + (last_flag << 1) | (i == count - 1), + devs + count); + } + } else { + device_foreach_child(child, dev) { + is_last = list_is_last(&child->sibling_node, + &dev->child_head); + show_devices(child, depth + 1, + (last_flag << 1) | is_last, NULL); + } } } -void dm_dump_tree(void) +void dm_dump_tree(bool sort) { struct udevice *root; root = dm_root(); if (root) { + int dev_count, uclasses; + struct udevice **devs = NULL; + + dm_get_stats(&dev_count, &uclasses); + printf(" Class Index Probed Driver Name\n"); printf("-----------------------------------------------------------\n"); - show_devices(root, -1, 0); + if (sort) { + devs = calloc(dev_count, sizeof(struct udevice *)); + if (!devs) { + printf("(out of memory)\n"); + return; + } + } + show_devices(root, -1, 0, devs); + free(devs); } } |