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(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(-EINVAL); 66 } 67 68 data->read = kcalloc(sizeof(bool), config->max_register + 1, 69 GFP_KERNEL); 70 if (!data->read) 71 return ERR_PTR(-ENOMEM); 72 73 data->written = kcalloc(sizeof(bool), config->max_register + 1, 74 GFP_KERNEL); 75 if (!data->written) 76 return ERR_PTR(-ENOMEM); 77 78 map = __regmap_init(NULL, ®map_ram, 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