xref: /linux/drivers/base/regmap/regmap-ram.c (revision 7b7982f1)
1f6352424SMark Brown // SPDX-License-Identifier: GPL-2.0
2f6352424SMark Brown //
3f6352424SMark Brown // Register map access API - Memory region
4f6352424SMark Brown //
5f6352424SMark Brown // This is intended for testing only
6f6352424SMark Brown //
7f6352424SMark Brown // Copyright (c) 2023, Arm Ltd
8f6352424SMark Brown 
9f6352424SMark Brown #include <linux/clk.h>
10f6352424SMark Brown #include <linux/err.h>
11f6352424SMark Brown #include <linux/io.h>
12f6352424SMark Brown #include <linux/module.h>
13f6352424SMark Brown #include <linux/regmap.h>
14f6352424SMark Brown #include <linux/slab.h>
15f6352424SMark Brown #include <linux/swab.h>
16f6352424SMark Brown 
17f6352424SMark Brown #include "internal.h"
18f6352424SMark Brown 
regmap_ram_write(void * context,unsigned int reg,unsigned int val)19f6352424SMark Brown static int regmap_ram_write(void *context, unsigned int reg, unsigned int val)
20f6352424SMark Brown {
21f6352424SMark Brown 	struct regmap_ram_data *data = context;
22f6352424SMark Brown 
23f6352424SMark Brown 	data->vals[reg] = val;
24f6352424SMark Brown 	data->written[reg] = true;
25f6352424SMark Brown 
26f6352424SMark Brown 	return 0;
27f6352424SMark Brown }
28f6352424SMark Brown 
regmap_ram_read(void * context,unsigned int reg,unsigned int * val)29f6352424SMark Brown static int regmap_ram_read(void *context, unsigned int reg, unsigned int *val)
30f6352424SMark Brown {
31f6352424SMark Brown 	struct regmap_ram_data *data = context;
32f6352424SMark Brown 
33f6352424SMark Brown 	*val = data->vals[reg];
34f6352424SMark Brown 	data->read[reg] = true;
35f6352424SMark Brown 
36f6352424SMark Brown 	return 0;
37f6352424SMark Brown }
38f6352424SMark Brown 
regmap_ram_free_context(void * context)39f6352424SMark Brown static void regmap_ram_free_context(void *context)
40f6352424SMark Brown {
41f6352424SMark Brown 	struct regmap_ram_data *data = context;
42f6352424SMark Brown 
43f6352424SMark Brown 	kfree(data->vals);
44f6352424SMark Brown 	kfree(data->read);
45f6352424SMark Brown 	kfree(data->written);
46f6352424SMark Brown 	kfree(data);
47f6352424SMark Brown }
48f6352424SMark Brown 
49f6352424SMark Brown static const struct regmap_bus regmap_ram = {
50f6352424SMark Brown 	.fast_io = true,
51f6352424SMark Brown 	.reg_write = regmap_ram_write,
52f6352424SMark Brown 	.reg_read = regmap_ram_read,
53f6352424SMark Brown 	.free_context = regmap_ram_free_context,
54f6352424SMark Brown };
55f6352424SMark Brown 
__regmap_init_ram(struct device * dev,const struct regmap_config * config,struct regmap_ram_data * data,struct lock_class_key * lock_key,const char * lock_name)56*7b7982f1SRichard Fitzgerald struct regmap *__regmap_init_ram(struct device *dev,
57*7b7982f1SRichard Fitzgerald 				 const struct regmap_config *config,
58f6352424SMark Brown 				 struct regmap_ram_data *data,
59f6352424SMark Brown 				 struct lock_class_key *lock_key,
60f6352424SMark Brown 				 const char *lock_name)
61f6352424SMark Brown {
62f6352424SMark Brown 	struct regmap *map;
63f6352424SMark Brown 
64f6352424SMark Brown 	if (!config->max_register) {
65f6352424SMark Brown 		pr_crit("No max_register specified for RAM regmap\n");
66f6352424SMark Brown 		return ERR_PTR(-EINVAL);
67f6352424SMark Brown 	}
68f6352424SMark Brown 
693b201c9aSDmitry Antipov 	data->read = kcalloc(config->max_register + 1, sizeof(bool),
70f6352424SMark Brown 			     GFP_KERNEL);
71f6352424SMark Brown 	if (!data->read)
72f6352424SMark Brown 		return ERR_PTR(-ENOMEM);
73f6352424SMark Brown 
743b201c9aSDmitry Antipov 	data->written = kcalloc(config->max_register + 1, sizeof(bool),
75f6352424SMark Brown 				GFP_KERNEL);
76f6352424SMark Brown 	if (!data->written)
77f6352424SMark Brown 		return ERR_PTR(-ENOMEM);
78f6352424SMark Brown 
79*7b7982f1SRichard Fitzgerald 	map = __regmap_init(dev, &regmap_ram, data, config,
80f6352424SMark Brown 			    lock_key, lock_name);
81f6352424SMark Brown 
82f6352424SMark Brown 	return map;
83f6352424SMark Brown }
84f6352424SMark Brown EXPORT_SYMBOL_GPL(__regmap_init_ram);
85f6352424SMark Brown 
86f6352424SMark Brown MODULE_LICENSE("GPL v2");
87