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 if (reg < data->base_reg) 24 return -EINVAL; 25 26 data->vals[reg - data->base_reg] = val; 27 data->written[reg - data->base_reg] = true; 28 29 return 0; 30 } 31 32 static int regmap_ram_read(void *context, unsigned int reg, unsigned int *val) 33 { 34 struct regmap_ram_data *data = context; 35 36 if (reg < data->base_reg) 37 return -EINVAL; 38 39 *val = data->vals[reg - data->base_reg]; 40 data->read[reg - data->base_reg] = true; 41 42 return 0; 43 } 44 45 static void regmap_ram_free_context(void *context) 46 { 47 struct regmap_ram_data *data = context; 48 49 kfree(data->vals); 50 kfree(data->read); 51 kfree(data->written); 52 kfree(data); 53 } 54 55 static const struct regmap_bus regmap_ram = { 56 .fast_io = true, 57 .reg_write = regmap_ram_write, 58 .reg_read = regmap_ram_read, 59 .free_context = regmap_ram_free_context, 60 }; 61 62 struct regmap *__regmap_init_ram(struct device *dev, 63 const struct regmap_config *config, 64 struct regmap_ram_data *data, 65 struct lock_class_key *lock_key, 66 const char *lock_name) 67 { 68 struct regmap *map; 69 unsigned int num_regs; 70 71 if (!config->max_register) { 72 pr_crit("No max_register specified for RAM regmap\n"); 73 return ERR_PTR(-EINVAL); 74 } 75 76 if (data->base_reg > config->max_register) { 77 pr_crit("base_reg above max_register for RAM regmap\n"); 78 return ERR_PTR(-EINVAL); 79 } 80 81 num_regs = config->max_register - data->base_reg + 1; 82 83 data->read = kzalloc_objs(bool, num_regs); 84 if (!data->read) 85 return ERR_PTR(-ENOMEM); 86 87 data->written = kzalloc_objs(bool, num_regs); 88 if (!data->written) { 89 kfree(data->read); 90 return ERR_PTR(-ENOMEM); 91 } 92 93 map = __regmap_init(dev, ®map_ram, data, config, 94 lock_key, lock_name); 95 if (IS_ERR(map)) { 96 kfree(data->read); 97 kfree(data->written); 98 } 99 100 return map; 101 } 102 EXPORT_SYMBOL_GPL(__regmap_init_ram); 103 104 MODULE_DESCRIPTION("Register map access API - Memory region"); 105 MODULE_LICENSE("GPL v2"); 106