u-boot-brain/test/dm/devres.c
Simon Glass caa4daa2ae dm: treewide: Rename 'platdata' variables to just 'plat'
We use 'priv' for private data but often use 'platdata' for platform data.
We can't really use 'pdata' since that is ambiguous (it could mean private
or platform data).

Rename some of the latter variables to end with 'plat' for consistency.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-12-13 16:51:08 -07:00

190 lines
5.1 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Tests for the devres (
*
* Copyright 2019 Google LLC
*/
#include <common.h>
#include <errno.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <dm/device-internal.h>
#include <dm/devres.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, UT_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, UT_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, UT_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, UT_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, UT_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));
ut_assertnonnull(dev);
devres_get_stats(dev, &stats);
ut_asserteq(1, stats.allocs);
ut_asserteq(TEST_DEVRES_SIZE, stats.total_size);
/* Getting plat 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, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);