Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'regmap-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

Pull regmap updates from Mark Brown:
"This has been quite a busy release for regmap, the user visible
changes are quite minor but there's some quite good work on internal
code improvements:

- Cleanup helper for __free()ing regmap_fields

- Support non-devm I3C regmaps

- A bunch of cleanup work, mostly from Andy Shevchenko

- Fix for bootstrapping issues with hardware initialised regmaps,
which was the main inspiration for some of the cleanups"

* tag 'regmap-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: i3c: Add non-devm regmap_init_i3c() helper
regmap: debugfs: fix race condition in dummy name allocation
regmap: Synchronize cache for the page selector
regmap: Simplify devres handling
regcache: Move HW readback after cache initialisation
regcache: Allocate and free reg_defaults on the same level
regcache: Move count check and cache_bypass assignment to the caller
regcache: Factor out regcache_hw_exit() helper
regcache: Amend printf() specifiers when printing registers
regcache: Define iterator inside for-loop and align their types
regmap: define cleanup helper for regmap_field
regmap: sort header includes
regcache: Split regcache_count_cacheable_registers() helper
regcache: Remove duplicate check in regcache_hw_init()

+118 -73
+2 -1
drivers/base/regmap/internal.h
··· 84 84 bool debugfs_disable; 85 85 struct dentry *debugfs; 86 86 const char *debugfs_name; 87 + int debugfs_dummy_id; 87 88 88 89 unsigned int debugfs_reg_len; 89 90 unsigned int debugfs_val_len; ··· 163 162 bool no_sync_defaults; 164 163 165 164 struct reg_sequence *patch; 166 - int patch_regs; 165 + unsigned int patch_regs; 167 166 168 167 /* if set, the regmap core can sleep */ 169 168 bool can_sleep;
+54 -48
drivers/base/regmap/regcache.c
··· 42 42 } 43 43 EXPORT_SYMBOL_GPL(regcache_sort_defaults); 44 44 45 - static int regcache_hw_init(struct regmap *map) 45 + static int regcache_count_cacheable_registers(struct regmap *map) 46 46 { 47 - int i, j; 48 - int ret; 49 - int count; 50 - unsigned int reg, val; 51 - void *tmp_buf; 52 - 53 - if (!map->num_reg_defaults_raw) 54 - return -EINVAL; 47 + unsigned int count; 55 48 56 49 /* calculate the size of reg_defaults */ 57 - for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) 50 + count = 0; 51 + for (unsigned int i = 0; i < map->num_reg_defaults_raw; i++) 58 52 if (regmap_readable(map, i * map->reg_stride) && 59 53 !regmap_volatile(map, i * map->reg_stride)) 60 54 count++; 61 55 62 - /* all registers are unreadable or volatile, so just bypass */ 63 - if (!count) { 64 - map->cache_bypass = true; 65 - return 0; 66 - } 56 + return count; 57 + } 67 58 68 - map->num_reg_defaults = count; 69 - map->reg_defaults = kmalloc_objs(struct reg_default, count); 70 - if (!map->reg_defaults) 71 - return -ENOMEM; 59 + static int regcache_hw_init(struct regmap *map) 60 + { 61 + int ret; 62 + unsigned int reg, val; 63 + void *tmp_buf; 72 64 73 65 if (!map->reg_defaults_raw) { 74 66 bool cache_bypass = map->cache_bypass; ··· 69 77 /* Bypass the cache access till data read from HW */ 70 78 map->cache_bypass = true; 71 79 tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); 72 - if (!tmp_buf) { 73 - ret = -ENOMEM; 74 - goto err_free; 75 - } 80 + if (!tmp_buf) 81 + return -ENOMEM; 76 82 ret = regmap_raw_read(map, 0, tmp_buf, 77 83 map->cache_size_raw); 78 84 map->cache_bypass = cache_bypass; ··· 83 93 } 84 94 85 95 /* fill the reg_defaults */ 86 - for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { 96 + for (unsigned int i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { 87 97 reg = i * map->reg_stride; 88 98 89 99 if (!regmap_readable(map, reg)) ··· 101 111 ret = regmap_read(map, reg, &val); 102 112 map->cache_bypass = cache_bypass; 103 113 if (ret != 0) { 104 - dev_err(map->dev, "Failed to read %d: %d\n", 114 + dev_err(map->dev, "Failed to read %x: %d\n", 105 115 reg, ret); 106 - goto err_free; 116 + return ret; 107 117 } 108 118 } 109 119 ··· 113 123 } 114 124 115 125 return 0; 126 + } 116 127 117 - err_free: 118 - kfree(map->reg_defaults); 119 - 120 - return ret; 128 + static void regcache_hw_exit(struct regmap *map) 129 + { 130 + if (map->cache_free) 131 + kfree(map->reg_defaults_raw); 121 132 } 122 133 123 134 int regcache_init(struct regmap *map, const struct regmap_config *config) 124 135 { 136 + int count = 0; 125 137 int ret; 126 138 int i; 127 139 void *tmp_buf; ··· 188 196 return -ENOMEM; 189 197 map->reg_defaults = tmp_buf; 190 198 } else if (map->num_reg_defaults_raw) { 191 - /* Some devices such as PMICs don't have cache defaults, 192 - * we cope with this by reading back the HW registers and 193 - * crafting the cache defaults by hand. 194 - */ 195 - ret = regcache_hw_init(map); 196 - if (ret < 0) 197 - return ret; 199 + count = regcache_count_cacheable_registers(map); 200 + if (!count) 201 + map->cache_bypass = true; 202 + 203 + /* All registers are unreadable or volatile, so just bypass */ 198 204 if (map->cache_bypass) 199 205 return 0; 206 + 207 + map->num_reg_defaults = count; 208 + map->reg_defaults = kmalloc_objs(struct reg_default, count); 209 + if (!map->reg_defaults) 210 + return -ENOMEM; 200 211 } 201 212 202 213 if (!map->max_register_is_set && map->num_reg_defaults_raw) { ··· 214 219 ret = map->cache_ops->init(map); 215 220 map->unlock(map->lock_arg); 216 221 if (ret) 217 - goto err_free; 222 + goto err_free_reg_defaults; 223 + } 224 + 225 + /* 226 + * Some devices such as PMICs don't have cache defaults, 227 + * we cope with this by reading back the HW registers and 228 + * crafting the cache defaults by hand. 229 + */ 230 + if (count) { 231 + ret = regcache_hw_init(map); 232 + if (ret) 233 + goto err_exit; 218 234 } 219 235 220 236 if (map->cache_ops->populate && ··· 235 229 ret = map->cache_ops->populate(map); 236 230 map->unlock(map->lock_arg); 237 231 if (ret) 238 - goto err_exit; 232 + goto err_free; 239 233 } 240 234 return 0; 241 235 236 + err_free: 237 + regcache_hw_exit(map); 242 238 err_exit: 243 239 if (map->cache_ops->exit) { 244 240 dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name); ··· 248 240 ret = map->cache_ops->exit(map); 249 241 map->unlock(map->lock_arg); 250 242 } 251 - err_free: 243 + err_free_reg_defaults: 252 244 kfree(map->reg_defaults); 253 - if (map->cache_free) 254 - kfree(map->reg_defaults_raw); 255 245 256 246 return ret; 257 247 } ··· 261 255 262 256 BUG_ON(!map->cache_ops); 263 257 264 - kfree(map->reg_defaults); 265 - if (map->cache_free) 266 - kfree(map->reg_defaults_raw); 258 + regcache_hw_exit(map); 267 259 268 260 if (map->cache_ops->exit) { 269 261 dev_dbg(map->dev, "Destroying %s cache\n", ··· 270 266 map->cache_ops->exit(map); 271 267 map->unlock(map->lock_arg); 272 268 } 269 + 270 + kfree(map->reg_defaults); 273 271 } 274 272 275 273 /** ··· 510 504 bypass = map->cache_bypass; 511 505 512 506 name = map->cache_ops->name; 513 - dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max); 507 + dev_dbg(map->dev, "Syncing %s cache from %#x-%#x\n", name, min, max); 514 508 515 509 trace_regcache_sync(map, name, "start region"); 516 510 ··· 841 835 unsigned int block_base, unsigned int start, 842 836 unsigned int end) 843 837 { 844 - unsigned int i, val; 845 838 unsigned int regtmp = 0; 846 839 unsigned int base = 0; 847 840 const void *data = NULL; 841 + unsigned int val; 848 842 int ret; 849 843 850 - for (i = start; i < end; i++) { 844 + for (unsigned int i = start; i < end; i++) { 851 845 regtmp = block_base + (i * map->reg_stride); 852 846 853 847 if (!regcache_reg_present(cache_present, i) ||
+16 -5
drivers/base/regmap/regmap-debugfs.c
··· 12 12 #include <linux/uaccess.h> 13 13 #include <linux/device.h> 14 14 #include <linux/list.h> 15 + #include <linux/idr.h> 15 16 16 17 #include "internal.h" 17 18 ··· 21 20 struct list_head link; 22 21 }; 23 22 24 - static unsigned int dummy_index; 23 + static DEFINE_IDA(dummy_ida); 25 24 static struct dentry *regmap_debugfs_root; 26 25 static LIST_HEAD(regmap_debugfs_early_list); 27 26 static DEFINE_MUTEX(regmap_debugfs_early_lock); ··· 540 539 struct regmap_range_node *range_node; 541 540 const char *devname = "dummy"; 542 541 const char *name = map->name; 542 + int id; 543 543 544 544 /* 545 545 * Userspace can initiate reads from the hardware over debugfs. ··· 569 567 570 568 INIT_LIST_HEAD(&map->debugfs_off_cache); 571 569 mutex_init(&map->cache_lock); 570 + map->debugfs_dummy_id = -1; 572 571 573 572 if (map->dev) 574 573 devname = dev_name(map->dev); ··· 588 585 589 586 if (!strcmp(name, "dummy")) { 590 587 kfree(map->debugfs_name); 591 - map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", 592 - dummy_index); 593 - if (!map->debugfs_name) 588 + id = ida_alloc(&dummy_ida, GFP_KERNEL); 589 + if (id < 0) 594 590 return; 591 + map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", id); 592 + if (!map->debugfs_name) { 593 + ida_free(&dummy_ida, id); 594 + return; 595 + } 596 + map->debugfs_dummy_id = id; 595 597 name = map->debugfs_name; 596 - dummy_index++; 597 598 } 598 599 599 600 map->debugfs = debugfs_create_dir(name, regmap_debugfs_root); ··· 667 660 mutex_lock(&map->cache_lock); 668 661 regmap_debugfs_free_dump_cache(map); 669 662 mutex_unlock(&map->cache_lock); 663 + if (map->debugfs_dummy_id >= 0) { 664 + ida_free(&dummy_ida, map->debugfs_dummy_id); 665 + map->debugfs_dummy_id = -1; 666 + } 670 667 kfree(map->debugfs_name); 671 668 map->debugfs_name = NULL; 672 669 } else {
+10
drivers/base/regmap/regmap-i3c.c
··· 46 46 .read = regmap_i3c_read, 47 47 }; 48 48 49 + struct regmap *__regmap_init_i3c(struct i3c_device *i3c, 50 + const struct regmap_config *config, 51 + struct lock_class_key *lock_key, 52 + const char *lock_name) 53 + { 54 + return __regmap_init(&i3c->dev, &regmap_i3c, &i3c->dev, config, 55 + lock_key, lock_name); 56 + } 57 + EXPORT_SYMBOL_GPL(__regmap_init_i3c); 58 + 49 59 struct regmap *__devm_regmap_init_i3c(struct i3c_device *i3c, 50 60 const struct regmap_config *config, 51 61 struct lock_class_key *lock_key,
+10 -13
drivers/base/regmap/regmap.c
··· 1182 1182 } 1183 1183 EXPORT_SYMBOL_GPL(__regmap_init); 1184 1184 1185 - static void devm_regmap_release(struct device *dev, void *res) 1185 + static void devm_regmap_release(void *regmap) 1186 1186 { 1187 - regmap_exit(*(struct regmap **)res); 1187 + regmap_exit(regmap); 1188 1188 } 1189 1189 1190 1190 struct regmap *__devm_regmap_init(struct device *dev, ··· 1194 1194 struct lock_class_key *lock_key, 1195 1195 const char *lock_name) 1196 1196 { 1197 - struct regmap **ptr, *regmap; 1198 - 1199 - ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL); 1200 - if (!ptr) 1201 - return ERR_PTR(-ENOMEM); 1197 + struct regmap *regmap; 1198 + int ret; 1202 1199 1203 1200 regmap = __regmap_init(dev, bus, bus_context, config, 1204 1201 lock_key, lock_name); 1205 - if (!IS_ERR(regmap)) { 1206 - *ptr = regmap; 1207 - devres_add(dev, ptr); 1208 - } else { 1209 - devres_free(ptr); 1210 - } 1202 + if (IS_ERR(regmap)) 1203 + return regmap; 1204 + 1205 + ret = devm_add_action_or_reset(dev, devm_regmap_release, regmap); 1206 + if (ret) 1207 + return ERR_PTR(ret); 1211 1208 1212 1209 return regmap; 1213 1210 }
+26 -6
include/linux/regmap.h
··· 10 10 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 11 11 */ 12 12 13 - #include <linux/list.h> 14 - #include <linux/rbtree.h> 15 - #include <linux/ktime.h> 13 + #include <linux/bug.h> 14 + #include <linux/cleanup.h> 16 15 #include <linux/delay.h> 17 16 #include <linux/err.h> 18 - #include <linux/bug.h> 19 - #include <linux/lockdep.h> 20 - #include <linux/iopoll.h> 21 17 #include <linux/fwnode.h> 18 + #include <linux/iopoll.h> 19 + #include <linux/ktime.h> 20 + #include <linux/list.h> 21 + #include <linux/lockdep.h> 22 + #include <linux/rbtree.h> 22 23 23 24 struct module; 24 25 struct clk; ··· 693 692 const struct regmap_sdw_mbq_cfg *mbq_config, 694 693 struct lock_class_key *lock_key, 695 694 const char *lock_name); 695 + struct regmap *__regmap_init_i3c(struct i3c_device *i3c, 696 + const struct regmap_config *config, 697 + struct lock_class_key *lock_key, 698 + const char *lock_name); 696 699 struct regmap *__regmap_init_spi_avmm(struct spi_device *spi, 697 700 const struct regmap_config *config, 698 701 struct lock_class_key *lock_key, ··· 1002 997 #define regmap_init_sdw_mbq_cfg(dev, sdw, config, mbq_config) \ 1003 998 __regmap_lockdep_wrapper(__regmap_init_sdw_mbq, #config, \ 1004 999 dev, sdw, config, mbq_config) 1000 + 1001 + /** 1002 + * regmap_init_i3c() - Initialise register map 1003 + * 1004 + * @i3c: Device that will be interacted with 1005 + * @config: Configuration for register map 1006 + * 1007 + * The return value will be an ERR_PTR() on error or a valid pointer to 1008 + * a struct regmap. 1009 + */ 1010 + #define regmap_init_i3c(i3c, config) \ 1011 + __regmap_lockdep_wrapper(__regmap_init_i3c, #config, \ 1012 + i3c, config) 1005 1013 1006 1014 /** 1007 1015 * regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave ··· 1477 1459 struct regmap_field *regmap_field_alloc(struct regmap *regmap, 1478 1460 struct reg_field reg_field); 1479 1461 void regmap_field_free(struct regmap_field *field); 1462 + 1463 + DEFINE_FREE(regmap_field, struct regmap_field *, if (_T) regmap_field_free(_T)) 1480 1464 1481 1465 struct regmap_field *devm_regmap_field_alloc(struct device *dev, 1482 1466 struct regmap *regmap, struct reg_field reg_field);