// 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);
