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