Browse Source

cmd: dm: Fixed/Added DM driver listing subcommands

Renamed dm "drivers" subcommand to "compat" (as it listed
compatibility strings) and prevent it from segfaulting when
drivers have no of_match populated.

Added a new "drivers" subcommand to dump a list of all known DM
drivers and for each, their uclass id, uclass driver and names of
attached devices.

Added a new "static" subcommand to dump a list of DM drivers with
statically defined platform data.

Signed-off-by: Niel Fourie <lusus@denx.de>
Cc: Simon Glass <sjg@chromium.org>
Cc: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Niel Fourie 4 years ago
parent
commit
2e48836895
4 changed files with 101 additions and 4 deletions
  1. 21 1
      cmd/dm.c
  2. 54 1
      drivers/core/dump.c
  3. 6 0
      include/dm/util.h
  4. 20 2
      test/py/tests/test_dm.py

+ 21 - 1
cmd/dm.c

@@ -48,11 +48,29 @@ static int do_dm_dump_drivers(struct cmd_tbl *cmdtp, int flag, int argc,
 	return 0;
 	return 0;
 }
 }
 
 
+static int do_dm_dump_driver_compat(struct cmd_tbl *cmdtp, int flag, int argc,
+				    char * const argv[])
+{
+	dm_dump_driver_compat();
+
+	return 0;
+}
+
+static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag, int argc,
+					 char * const argv[])
+{
+	dm_dump_static_driver_info();
+
+	return 0;
+}
+
 static struct cmd_tbl test_commands[] = {
 static struct cmd_tbl test_commands[] = {
 	U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""),
 	U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""),
 	U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""),
 	U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""),
 	U_BOOT_CMD_MKENT(devres, 1, 1, do_dm_dump_devres, "", ""),
 	U_BOOT_CMD_MKENT(devres, 1, 1, do_dm_dump_devres, "", ""),
 	U_BOOT_CMD_MKENT(drivers, 1, 1, do_dm_dump_drivers, "", ""),
 	U_BOOT_CMD_MKENT(drivers, 1, 1, do_dm_dump_drivers, "", ""),
+	U_BOOT_CMD_MKENT(compat, 1, 1, do_dm_dump_driver_compat, "", ""),
+	U_BOOT_CMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info, "", ""),
 };
 };
 
 
 static __maybe_unused void dm_reloc(void)
 static __maybe_unused void dm_reloc(void)
@@ -94,5 +112,7 @@ U_BOOT_CMD(
 	"tree          Dump driver model tree ('*' = activated)\n"
 	"tree          Dump driver model tree ('*' = activated)\n"
 	"dm uclass        Dump list of instances for each uclass\n"
 	"dm uclass        Dump list of instances for each uclass\n"
 	"dm devres        Dump list of device resources for each device\n"
 	"dm devres        Dump list of device resources for each device\n"
-	"dm drivers       Dump list of drivers and their compatible strings"
+	"dm drivers       Dump list of drivers with uclass and instances\n"
+	"dm compat        Dump list of drivers with compatibility strings\n"
+	"dm static        Dump list of drivers with static platform data"
 );
 );

+ 54 - 1
drivers/core/dump.c

@@ -97,7 +97,7 @@ void dm_dump_uclass(void)
 	}
 	}
 }
 }
 
 
-void dm_dump_drivers(void)
+void dm_dump_driver_compat(void)
 {
 {
 	struct driver *d = ll_entry_start(struct driver, driver);
 	struct driver *d = ll_entry_start(struct driver, driver);
 	const int n_ents = ll_entry_count(struct driver, driver);
 	const int n_ents = ll_entry_count(struct driver, driver);
@@ -120,3 +120,56 @@ void dm_dump_drivers(void)
 			printf("%-20.20s  %s\n", "", match->compatible);
 			printf("%-20.20s  %s\n", "", match->compatible);
 	}
 	}
 }
 }
+
+void dm_dump_drivers(void)
+{
+	struct driver *d = ll_entry_start(struct driver, driver);
+	const int n_ents = ll_entry_count(struct driver, driver);
+	struct driver *entry;
+	struct udevice *udev;
+	struct uclass *uc;
+	int i;
+
+	puts("Driver                    uid uclass               Devices\n");
+	puts("----------------------------------------------------------\n");
+
+	for (entry = d; entry < d + n_ents; entry++) {
+		uclass_get(entry->id, &uc);
+
+		printf("%-25.25s %-3.3d %-20.20s ", entry->name, entry->id,
+		       uc ? uc->uc_drv->name : "<no uclass>");
+
+		if (!uc) {
+			puts("\n");
+			continue;
+		}
+
+		i = 0;
+		uclass_foreach_dev(udev, uc) {
+			if (udev->driver != entry)
+				continue;
+			if (i)
+				printf("%-51.51s", "");
+
+			printf("%-25.25s\n", udev->name);
+			i++;
+		}
+		if (!i)
+			puts("<none>\n");
+	}
+}
+
+void dm_dump_static_driver_info(void)
+{
+	struct driver_info *drv = ll_entry_start(struct driver_info,
+						 driver_info);
+	const int n_ents = ll_entry_count(struct driver_info, driver_info);
+	struct driver_info *entry;
+
+	puts("Driver                    Address\n");
+	puts("---------------------------------\n");
+	for (entry = drv; entry != drv + n_ents; entry++) {
+		printf("%-25.25s @%08lx\n", entry->name,
+		       (ulong)map_to_sysmem(entry->platdata));
+	}
+}

+ 6 - 0
include/dm/util.h

@@ -42,4 +42,10 @@ static inline void dm_dump_devres(void)
 /* Dump out a list of drivers */
 /* Dump out a list of drivers */
 void dm_dump_drivers(void);
 void dm_dump_drivers(void);
 
 
+/* Dump out a list with each driver's compatibility strings */
+void dm_dump_driver_compat(void);
+
+/* Dump out a list of drivers with static platform data */
+void dm_dump_static_driver_info(void);
+
 #endif
 #endif

+ 20 - 2
test/py/tests/test_dm.py

@@ -4,14 +4,32 @@
 import pytest
 import pytest
 
 
 @pytest.mark.buildconfigspec('cmd_dm')
 @pytest.mark.buildconfigspec('cmd_dm')
-def test_dm_drivers(u_boot_console):
-    """Test that each driver in `dm tree` is also listed in `dm drivers`."""
+def test_dm_compat(u_boot_console):
+    """Test that each driver in `dm tree` is also listed in `dm compat`."""
     response = u_boot_console.run_command('dm tree')
     response = u_boot_console.run_command('dm tree')
     driver_index = response.find('Driver')
     driver_index = response.find('Driver')
     assert driver_index != -1
     assert driver_index != -1
     drivers = (line[driver_index:].split()[0]
     drivers = (line[driver_index:].split()[0]
                for line in response[:-1].split('\n')[2:])
                for line in response[:-1].split('\n')[2:])
 
 
+    response = u_boot_console.run_command('dm compat')
+    for driver in drivers:
+        assert driver in response
+
+@pytest.mark.buildconfigspec('cmd_dm')
+def test_dm_drivers(u_boot_console):
+    """Test that each driver in `dm compat` is also listed in `dm drivers`."""
+    response = u_boot_console.run_command('dm compat')
+    drivers = (line[:20].rstrip() for line in response[:-1].split('\n')[2:])
+    response = u_boot_console.run_command('dm drivers')
+    for driver in drivers:
+        assert driver in response
+
+@pytest.mark.buildconfigspec('cmd_dm')
+def test_dm_static(u_boot_console):
+    """Test that each driver in `dm static` is also listed in `dm drivers`."""
+    response = u_boot_console.run_command('dm static')
+    drivers = (line[:25].rstrip() for line in response[:-1].split('\n')[2:])
     response = u_boot_console.run_command('dm drivers')
     response = u_boot_console.run_command('dm drivers')
     for driver in drivers:
     for driver in drivers:
         assert driver in response
         assert driver in response