summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-01-09 08:52:21 -0500
committerTom Rini <trini@konsulko.com>2020-01-09 08:52:21 -0500
commitd6b92b9742f125542dd0985976c3a6c560ed40fd (patch)
treedf47458afa5280a80aa6ea789ac4d935aabe64ed /test
parenta74a2134b245d19a999c796d29285597a22954ed (diff)
parentaaa05deb1283b6beb7334adfa4094fb6bd4ab750 (diff)
Merge tag 'dm-pull-8jan20' of git://git.denx.de/u-boot-dm
dm: Increased separation of ofdata_to_platdata() and probe methods
Diffstat (limited to 'test')
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/devres.c186
-rw-r--r--test/dm/test-fdt.c58
-rw-r--r--test/ut.c14
4 files changed, 259 insertions, 0 deletions
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 201e2b093c..dd1ceff86c 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK) += blk.o
obj-$(CONFIG_BOARD) += board.o
obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
obj-$(CONFIG_CLK) += clk.o clk_ccf.o
+obj-$(CONFIG_DEVRES) += devres.o
obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_FIRMWARE) += firmware.o
diff --git a/test/dm/devres.c b/test/dm/devres.c
new file mode 100644
index 0000000000..e7331897de
--- /dev/null
+++ b/test/dm/devres.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for the devres (
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <malloc.h>
+#include <dm/device-internal.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <test/ut.h>
+
+/* Test that devm_kmalloc() allocates memory, free when device is removed */
+static int dm_test_devres_alloc(struct unit_test_state *uts)
+{
+ ulong mem_start, mem_dev, mem_kmalloc;
+ struct udevice *dev;
+ void *ptr;
+
+ mem_start = ut_check_delta(0);
+ ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev));
+ mem_dev = ut_check_delta(mem_start);
+ ut_assert(mem_dev > 0);
+
+ /* This should increase allocated memory */
+ ptr = devm_kmalloc(dev, TEST_DEVRES_SIZE, 0);
+ ut_assert(ptr != NULL);
+ mem_kmalloc = ut_check_delta(mem_dev);
+ ut_assert(mem_kmalloc > 0);
+
+ /* Check that ptr is freed */
+ device_remove(dev, DM_REMOVE_NORMAL);
+ ut_asserteq(0, ut_check_delta(mem_start));
+
+ return 0;
+}
+DM_TEST(dm_test_devres_alloc, DM_TESTF_SCAN_PDATA);
+
+/* Test devm_kfree() can be used to free memory too */
+static int dm_test_devres_free(struct unit_test_state *uts)
+{
+ ulong mem_start, mem_dev, mem_kmalloc;
+ struct udevice *dev;
+ void *ptr;
+
+ mem_start = ut_check_delta(0);
+ ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev));
+ mem_dev = ut_check_delta(mem_start);
+ ut_assert(mem_dev > 0);
+
+ ptr = devm_kmalloc(dev, TEST_DEVRES_SIZE, 0);
+ ut_assert(ptr != NULL);
+ mem_kmalloc = ut_check_delta(mem_dev);
+ ut_assert(mem_kmalloc > 0);
+
+ /* Free the ptr and check that memory usage goes down */
+ devm_kfree(dev, ptr);
+ ut_assert(ut_check_delta(mem_kmalloc) < 0);
+
+ device_remove(dev, DM_REMOVE_NORMAL);
+ ut_asserteq(0, ut_check_delta(mem_start));
+
+ return 0;
+}
+DM_TEST(dm_test_devres_free, DM_TESTF_SCAN_PDATA);
+
+
+/* Test that kzalloc() returns memory that is zeroed */
+static int dm_test_devres_kzalloc(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ u8 *ptr, val;
+ int i;
+
+ ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev));
+
+ ptr = devm_kzalloc(dev, TEST_DEVRES_SIZE, 0);
+ ut_assert(ptr != NULL);
+ for (val = 0, i = 0; i < TEST_DEVRES_SIZE; i++)
+ val |= *ptr;
+ ut_asserteq(0, val);
+
+ return 0;
+}
+DM_TEST(dm_test_devres_kzalloc, DM_TESTF_SCAN_PDATA);
+
+/* Test that devm_kmalloc_array() allocates an array that can be set */
+static int dm_test_devres_kmalloc_array(struct unit_test_state *uts)
+{
+ ulong mem_start, mem_dev;
+ struct udevice *dev;
+ u8 *ptr;
+
+ mem_start = ut_check_delta(0);
+ ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev));
+ mem_dev = ut_check_delta(mem_start);
+
+ ptr = devm_kmalloc_array(dev, TEST_DEVRES_COUNT, TEST_DEVRES_SIZE, 0);
+ ut_assert(ptr != NULL);
+ memset(ptr, '\xff', TEST_DEVRES_TOTAL);
+ ut_assert(ut_check_delta(mem_dev) > 0);
+
+ device_remove(dev, DM_REMOVE_NORMAL);
+ ut_asserteq(0, ut_check_delta(mem_start));
+
+ return 0;
+}
+DM_TEST(dm_test_devres_kmalloc_array, DM_TESTF_SCAN_PDATA);
+
+/* Test that devm_kcalloc() allocates a zeroed array */
+static int dm_test_devres_kcalloc(struct unit_test_state *uts)
+{
+ ulong mem_start, mem_dev;
+ struct udevice *dev;
+ u8 *ptr, val;
+ int i;
+
+ mem_start = ut_check_delta(0);
+ ut_assertok(uclass_first_device_err(UCLASS_TEST, &dev));
+ mem_dev = ut_check_delta(mem_start);
+ ut_assert(mem_dev > 0);
+
+ /* This should increase allocated memory */
+ ptr = devm_kcalloc(dev, TEST_DEVRES_SIZE, TEST_DEVRES_COUNT, 0);
+ ut_assert(ptr != NULL);
+ ut_assert(ut_check_delta(mem_dev) > 0);
+ for (val = 0, i = 0; i < TEST_DEVRES_TOTAL; i++)
+ val |= *ptr;
+ ut_asserteq(0, val);
+
+ /* Check that ptr is freed */
+ device_remove(dev, DM_REMOVE_NORMAL);
+ ut_asserteq(0, ut_check_delta(mem_start));
+
+ return 0;
+}
+DM_TEST(dm_test_devres_kcalloc, DM_TESTF_SCAN_PDATA);
+
+/* Test devres releases resources automatically as expected */
+static int dm_test_devres_phase(struct unit_test_state *uts)
+{
+ struct devres_stats stats;
+ struct udevice *dev;
+
+ /*
+ * The device is bound already, so find it and check that it has the
+ * allocation created in the bind() method.
+ */
+ ut_assertok(uclass_find_first_device(UCLASS_TEST_DEVRES, &dev));
+ devres_get_stats(dev, &stats);
+ ut_asserteq(1, stats.allocs);
+ ut_asserteq(TEST_DEVRES_SIZE, stats.total_size);
+
+ /* Getting platdata should add one allocation */
+ ut_assertok(device_ofdata_to_platdata(dev));
+ devres_get_stats(dev, &stats);
+ ut_asserteq(2, stats.allocs);
+ ut_asserteq(TEST_DEVRES_SIZE + TEST_DEVRES_SIZE3, stats.total_size);
+
+ /* Probing the device should add one allocation */
+ ut_assertok(uclass_first_device(UCLASS_TEST_DEVRES, &dev));
+ ut_assert(dev != NULL);
+ devres_get_stats(dev, &stats);
+ ut_asserteq(3, stats.allocs);
+ ut_asserteq(TEST_DEVRES_SIZE + TEST_DEVRES_SIZE2 + TEST_DEVRES_SIZE3,
+ stats.total_size);
+
+ /* Removing the device should drop both those allocations */
+ device_remove(dev, DM_REMOVE_NORMAL);
+ devres_get_stats(dev, &stats);
+ ut_asserteq(1, stats.allocs);
+ ut_asserteq(TEST_DEVRES_SIZE, stats.total_size);
+
+ /* Unbinding removes the other. Note this access a freed pointer */
+ device_unbind(dev);
+ devres_get_stats(dev, &stats);
+ ut_asserteq(0, stats.allocs);
+ ut_asserteq(0, stats.total_size);
+
+ return 0;
+}
+DM_TEST(dm_test_devres_phase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 1fb8b5c248..d59c449ce0 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -153,6 +153,64 @@ UCLASS_DRIVER(testprobe) = {
.flags = DM_UC_FLAG_SEQ_ALIAS,
};
+struct dm_testdevres_pdata {
+ void *ptr;
+};
+
+struct dm_testdevres_priv {
+ void *ptr;
+ void *ptr_ofdata;
+};
+
+static int testdevres_drv_bind(struct udevice *dev)
+{
+ struct dm_testdevres_pdata *pdata = dev_get_platdata(dev);
+
+ pdata->ptr = devm_kmalloc(dev, TEST_DEVRES_SIZE, 0);
+
+ return 0;
+}
+
+static int testdevres_drv_ofdata_to_platdata(struct udevice *dev)
+{
+ struct dm_testdevres_priv *priv = dev_get_priv(dev);
+
+ priv->ptr_ofdata = devm_kmalloc(dev, TEST_DEVRES_SIZE3, 0);
+
+ return 0;
+}
+
+static int testdevres_drv_probe(struct udevice *dev)
+{
+ struct dm_testdevres_priv *priv = dev_get_priv(dev);
+
+ priv->ptr = devm_kmalloc(dev, TEST_DEVRES_SIZE2, 0);
+
+ return 0;
+}
+
+static const struct udevice_id testdevres_ids[] = {
+ { .compatible = "denx,u-boot-devres-test" },
+ { }
+};
+
+U_BOOT_DRIVER(testdevres_drv) = {
+ .name = "testdevres_drv",
+ .of_match = testdevres_ids,
+ .id = UCLASS_TEST_DEVRES,
+ .bind = testdevres_drv_bind,
+ .ofdata_to_platdata = testdevres_drv_ofdata_to_platdata,
+ .probe = testdevres_drv_probe,
+ .platdata_auto_alloc_size = sizeof(struct dm_testdevres_pdata),
+ .priv_auto_alloc_size = sizeof(struct dm_testdevres_priv),
+};
+
+UCLASS_DRIVER(testdevres) = {
+ .name = "testdevres",
+ .id = UCLASS_TEST_DEVRES,
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+};
+
int dm_check_devices(struct unit_test_state *uts, int num_devices)
{
struct udevice *dev;
diff --git a/test/ut.c b/test/ut.c
index 55798041ba..265da4a0d8 100644
--- a/test/ut.c
+++ b/test/ut.c
@@ -6,6 +6,7 @@
*/
#include <common.h>
+#include <malloc.h>
#include <test/test.h>
#include <test/ut.h>
@@ -32,3 +33,16 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line,
putc('\n');
uts->fail_count++;
}
+
+ulong ut_check_free(void)
+{
+ struct mallinfo info = mallinfo();
+
+ return info.uordblks;
+}
+
+long ut_check_delta(ulong last)
+{
+ return ut_check_free() - last;
+}
+