// SPDX-License-Identifier: GPL-2.0
//
// regmap KUnit tests
//
// Copyright 2023 Arm Ltd
#include <kunit/test.h>
#include "internal.h"
#define BLOCK_TEST_SIZE 12
static const struct regmap_config test_regmap_config = {
.max_register = BLOCK_TEST_SIZE,
.reg_stride = 1,
.val_bits = sizeof(unsigned int) * 8,
};
struct regcache_types {
enum regcache_type type;
const char *name;
};
static void case_to_desc(const struct regcache_types *t, char *desc)
{
strcpy(desc, t->name);
}
static const struct regcache_types regcache_types_list[] = {
{ REGCACHE_NONE, "none" },
{ REGCACHE_FLAT, "flat" },
{ REGCACHE_RBTREE, "rbtree" },
{ REGCACHE_MAPLE, "maple" },
};
KUNIT_ARRAY_PARAM(regcache_types, regcache_types_list, case_to_desc);
static const struct regcache_types real_cache_types_list[] = {
{ REGCACHE_FLAT, "flat" },
{ REGCACHE_RBTREE, "rbtree" },
{ REGCACHE_MAPLE, "maple" },
};
KUNIT_ARRAY_PARAM(real_cache_types, real_cache_types_list, case_to_desc);
static const struct regcache_types sparse_cache_types_list[] = {
{ REGCACHE_RBTREE, "rbtree" },
{ REGCACHE_MAPLE, "maple" },
};
KUNIT_ARRAY_PARAM(sparse_cache_types, sparse_cache_types_list, case_to_desc);
static struct regmap *gen_regmap(struct regmap_config *config,
struct regmap_ram_data **data)
{
unsigned int *buf;
struct regmap *ret;
size_t size = (config->max_register + 1) * sizeof(unsigned int);
int i;
struct reg_default *defaults;
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
get_random_bytes(buf, size);
*data = kzalloc(sizeof(**data), GFP_KERNEL);
if (!(*data))
return ERR_PTR(-ENOMEM);
(*data)->vals = buf;
if (config->num_reg_defaults) {
defaults = kcalloc(config->num_reg_defaults,
sizeof(struct reg_default),
GFP_KERNEL);
if (!defaults)
return ERR_PTR(-ENOMEM);
config->reg_defaults = defaults;
for (i = 0; i < config->num_reg_defaults; i++) {
defaults[i].reg = i * config->reg_stride;
defaults[i].def = buf[i * config->reg_stride];
}
}
ret = regmap_init_ram(config, *data);
if (IS_ERR(ret)) {
kfree(buf);
kfree(*data);
}
return ret;
}
static bool reg_5_false(struct device *context, unsigned int reg)
{
return reg != 5;
}
static void basic_read_write(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
struct regmap *map;
struct regmap_config config;
struct regmap_ram_data *data;
unsigned int val, rval;
config = test_regmap_config;
config.cache_type = t->type;
map = gen_regmap(&config, &data);
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
if (IS_ERR(map))
return;
get_random_bytes(&val, sizeof(val));
/* If we write a value to a register we can read it back */
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, 0, val));
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, 0, &