dm: core: Allow getting some basic stats
Add a function that returns some basic stats about driver model. For now we only have two. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
9855034397
commit
6476c4d981
@ -739,6 +739,17 @@ int device_get_child_count(const struct udevice *parent)
|
||||
return count;
|
||||
}
|
||||
|
||||
int device_get_decendent_count(const struct udevice *parent)
|
||||
{
|
||||
const struct udevice *dev;
|
||||
int count = 1;
|
||||
|
||||
list_for_each_entry(dev, &parent->child_head, sibling_node)
|
||||
count += device_get_decendent_count(dev);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int device_find_child_by_seq(const struct udevice *parent, int seq,
|
||||
struct udevice **devp)
|
||||
{
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <dm/read.h>
|
||||
#include <dm/root.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/util.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
@ -407,6 +408,12 @@ int dm_init_and_scan(bool pre_reloc_only)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dm_get_stats(int *device_countp, int *uclass_countp)
|
||||
{
|
||||
*device_countp = device_get_decendent_count(gd->dm_root);
|
||||
*uclass_countp = uclass_get_count();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPIGEN
|
||||
static int root_acpi_get_name(const struct udevice *dev, char *out_name)
|
||||
{
|
||||
|
@ -643,6 +643,19 @@ int uclass_next_device_check(struct udevice **devp)
|
||||
return device_probe(*devp);
|
||||
}
|
||||
|
||||
int uclass_get_count(void)
|
||||
{
|
||||
const struct uclass *uc;
|
||||
int count = 0;
|
||||
|
||||
if (gd->dm_root) {
|
||||
list_for_each_entry(uc, gd->uclass_root, sibling_node)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
|
||||
struct udevice **devp)
|
||||
{
|
||||
|
@ -593,7 +593,7 @@ int device_get_child(const struct udevice *parent, int index,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* device_get_child_count() - Get the available child count of a device
|
||||
* device_get_child_count() - Get the child count of a device
|
||||
*
|
||||
* Returns the number of children to a device.
|
||||
*
|
||||
@ -601,6 +601,15 @@ int device_get_child(const struct udevice *parent, int index,
|
||||
*/
|
||||
int device_get_child_count(const struct udevice *parent);
|
||||
|
||||
/**
|
||||
* device_get_decendent_count() - Get the total number of decendents of a device
|
||||
*
|
||||
* Returns the total number of decendents, including all children
|
||||
*
|
||||
* @parent: Parent device to check
|
||||
*/
|
||||
int device_get_decendent_count(const struct udevice *parent);
|
||||
|
||||
/**
|
||||
* device_find_child_by_seq() - Find a child device based on a sequence
|
||||
*
|
||||
|
@ -131,4 +131,12 @@ int dm_remove_devices_flags(uint flags);
|
||||
static inline int dm_remove_devices_flags(uint flags) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dm_get_stats() - Get some stats for driver mode
|
||||
*
|
||||
* @device_countp: Returns total number of devices that are bound
|
||||
* @uclass_countp: Returns total number of uclasses in use
|
||||
*/
|
||||
void dm_get_stats(int *device_countp, int *uclass_countp);
|
||||
|
||||
#endif
|
||||
|
@ -306,6 +306,13 @@ int uclass_pre_remove_device(struct udevice *dev);
|
||||
static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uclass_get_count() - Get the number of uclasses
|
||||
*
|
||||
* Returns the number of uclasses instantiated in driver model
|
||||
*/
|
||||
int uclass_get_count(void);
|
||||
|
||||
/**
|
||||
* uclass_find() - Find uclass by its id
|
||||
*
|
||||
|
@ -307,11 +307,15 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
|
||||
{
|
||||
int op_count[DM_TEST_OP_COUNT];
|
||||
struct udevice *dev, *test_dev;
|
||||
int start_dev_count, start_uc_count;
|
||||
int dev_count, uc_count;
|
||||
int pingret;
|
||||
int ret;
|
||||
|
||||
memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
|
||||
|
||||
dm_get_stats(&start_dev_count, &start_uc_count);
|
||||
|
||||
ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
|
||||
&dev));
|
||||
ut_assert(dev);
|
||||
@ -319,6 +323,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
|
||||
== op_count[DM_TEST_OP_BIND] + 1);
|
||||
ut_assert(!dev_get_priv(dev));
|
||||
|
||||
/* We should have one more device */
|
||||
dm_get_stats(&dev_count, &uc_count);
|
||||
ut_asserteq(start_dev_count + 1, dev_count);
|
||||
ut_asserteq(start_uc_count, uc_count);
|
||||
|
||||
/* Probe the device - it should fail allocating private data */
|
||||
uts->force_fail_alloc = 1;
|
||||
ret = device_probe(dev);
|
||||
@ -353,6 +362,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
|
||||
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
|
||||
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
|
||||
|
||||
/* We should have one less device */
|
||||
dm_get_stats(&dev_count, &uc_count);
|
||||
ut_asserteq(start_dev_count, dev_count);
|
||||
ut_asserteq(start_uc_count, uc_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_lifecycle, UT_TESTF_SCAN_PDATA | UT_TESTF_PROBE_TEST);
|
||||
@ -526,17 +540,31 @@ DM_TEST(dm_test_leak, 0);
|
||||
/* Test uclass init/destroy methods */
|
||||
static int dm_test_uclass(struct unit_test_state *uts)
|
||||
{
|
||||
int dev_count, uc_count;
|
||||
struct uclass *uc;
|
||||
|
||||
/* We should have just the root device and uclass */
|
||||
dm_get_stats(&dev_count, &uc_count);
|
||||
ut_asserteq(1, dev_count);
|
||||
ut_asserteq(1, uc_count);
|
||||
|
||||
ut_assertok(uclass_get(UCLASS_TEST, &uc));
|
||||
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
|
||||
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
|
||||
ut_assert(uclass_get_priv(uc));
|
||||
|
||||
dm_get_stats(&dev_count, &uc_count);
|
||||
ut_asserteq(1, dev_count);
|
||||
ut_asserteq(2, uc_count);
|
||||
|
||||
ut_assertok(uclass_destroy(uc));
|
||||
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
|
||||
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
|
||||
|
||||
dm_get_stats(&dev_count, &uc_count);
|
||||
ut_asserteq(1, dev_count);
|
||||
ut_asserteq(1, uc_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_uclass, 0);
|
||||
@ -1217,3 +1245,16 @@ static int dm_test_dma_offset(struct unit_test_state *uts)
|
||||
}
|
||||
DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
#endif
|
||||
|
||||
/* Test dm_get_stats() */
|
||||
static int dm_test_get_stats(struct unit_test_state *uts)
|
||||
{
|
||||
int dev_count, uc_count;
|
||||
|
||||
dm_get_stats(&dev_count, &uc_count);
|
||||
ut_assert(dev_count > 50);
|
||||
ut_assert(uc_count > 30);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_get_stats, UT_TESTF_SCAN_FDT);
|
||||
|
Loading…
Reference in New Issue
Block a user