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(data->vals); 44 kfree(data->read); 45 kfree(data->written); 46 kfree(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(struct device *dev, 57 const struct regmap_config *config, 58 struct regmap_ram_data *data, 59 struct lock_class_key *lock_key, 60 const char *lock_name) 61 { 62 struct regmap *map; 63 64 if (!config->max_register) { 65 pr_crit("No max_register specified for RAM regmap\n"); 66 return ERR_PTR(-EINVAL); 67 } 68 69 data->read = kcalloc(config->max_register + 1, sizeof(bool), 70 GFP_KERNEL); 71 if (!data->read) 72 return ERR_PTR(-ENOMEM); 73 74 data->written = kcalloc(config->max_register + 1, sizeof(bool), 75 GFP_KERNEL); 76 if (!data->written) 77 return ERR_PTR(-ENOMEM); 78 79 map = __regmap_init(dev, ®map_ram, data, config, 80 lock_key, lock_name); 81 82 return map; 83 } 84 EXPORT_SYMBOL_GPL(__regmap_init_ram); 85 86 MODULE_LICENSE("GPL v2"); 87