devres: add debug command to dump device resources

This new command can dump all device resources associated to
each device.  The fields in every line shows:
  - The address of the resource
  - The size of the resource
  - The name of the release function
  - The stage in which the resource has been acquired (BIND/PROBE)

Currently, there is no driver using devres, but if such drivers are
implemented, the output of this command should look like this:

=> dm devres
- root_driver
- soc
- extbus
- serial@54006800
    bfb541e8 (8 byte) devm_kmalloc_release  BIND
    bfb54440 (4 byte) devm_kmalloc_release  PROBE
    bfb54460 (4 byte) devm_kmalloc_release  PROBE
- serial@54006900
    bfb54270 (8 byte) devm_kmalloc_release  BIND
- gpio@55000000
- i2c@58780000
    bfb5bce8 (12 byte) devm_kmalloc_release  PROBE
    bfb5bd10 (4 byte) devm_kmalloc_release  PROBE
- eeprom
    bfb54418 (12 byte) devm_kmalloc_release  BIND

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Masahiro Yamada 2015-07-25 21:52:38 +09:00 committed by Simon Glass
parent e2282d7076
commit 40b6f2d020
4 changed files with 51 additions and 2 deletions

View file

@ -93,10 +93,11 @@ config DEVRES
devm_kmalloc() to kmalloc(), etc.
config DEBUG_DEVRES
bool "Managed device resources verbose debug messages"
bool "Managed device resources debugging functions"
depends on DEVRES
help
If this option is enabled, devres debug messages are printed.
Also, a function is available to dump a list of device resources.
Select this if you are having a problem with devres or want to
debug resource management for a managed device.

View file

@ -13,6 +13,8 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <dm/device.h>
#include <dm/root.h>
#include <dm/util.h>
/**
* struct devres - Bookkeeping info for managed device resource
@ -195,6 +197,33 @@ void devres_release_all(struct udevice *dev)
release_nodes(dev, &dev->devres_head, false);
}
#ifdef CONFIG_DEBUG_DEVRES
static void dump_resources(struct udevice *dev, int depth)
{
struct devres *dr;
struct udevice *child;
printf("- %s\n", dev->name);
list_for_each_entry(dr, &dev->devres_head, entry)
printf(" %p (%lu byte) %s %s\n", dr,
(unsigned long)dr->size, dr->name,
dr->probe ? "PROBE" : "BIND");
list_for_each_entry(child, &dev->child_head, sibling_node)
dump_resources(child, depth + 1);
}
void dm_dump_devres(void)
{
struct udevice *root;
root = dm_root();
if (root)
dump_resources(root, 0);
}
#endif
/*
* Managed kmalloc/kfree
*/

View file

@ -39,4 +39,13 @@ void dm_dump_all(void);
/* Dump out a list of uclasses and their devices */
void dm_dump_uclass(void);
#ifdef CONFIG_DEBUG_DEVRES
/* Dump out a list of device resources */
void dm_dump_devres(void);
#else
static inline void dm_dump_devres(void)
{
}
#endif
#endif

View file

@ -32,9 +32,18 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
return 0;
}
static int do_dm_dump_devres(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
dm_dump_devres();
return 0;
}
static cmd_tbl_t test_commands[] = {
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(devres, 1, 1, do_dm_dump_devres, "", ""),
};
static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@ -60,5 +69,6 @@ U_BOOT_CMD(
dm, 3, 1, do_dm,
"Driver model low level access",
"tree Dump driver model tree ('*' = activated)\n"
"dm uclass Dump list of instances for each uclass"
"dm uclass Dump list of instances for each uclass\n"
"dm devres Dump list of device resources for each device"
);