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-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

Pull regmap updates from Mark Brown:
"The main change here is the implementation of a mechanism for
generating register defaults via a callback rather than with a table
in the driver.

This is useful for devices where there are large ranges of registers
with the same or generated values, it allows us to have a small amount
of code instead of a larger amount of default data"

* tag 'regmap-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regcache: Demote defaults readback from HW to debug print
regmap: add KUnit coverage for reg_default_cb callback
regmap: Add reg_default_cb callback for flat cache defaults
regmap: Enable REGMAP when REGMAP_SLIMBUS is enabled

+133 -3
+1 -1
drivers/base/regmap/Kconfig
··· 5 5 6 6 config REGMAP 7 7 bool 8 - default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO || REGMAP_FSI) 8 + default y if (REGMAP_I2C || REGMAP_SLIMBUS || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO || REGMAP_FSI) 9 9 help 10 10 Enable support for the Register Map (regmap) access API. 11 11
+3
drivers/base/regmap/internal.h
··· 117 117 void *val_buf, size_t val_size); 118 118 int (*write)(void *context, const void *data, size_t count); 119 119 120 + int (*reg_default_cb)(struct device *dev, unsigned int reg, 121 + unsigned int *val); 122 + 120 123 unsigned long read_flag_mask; 121 124 unsigned long write_flag_mask; 122 125
+19
drivers/base/regmap/regcache-flat.c
··· 79 79 __set_bit(index, cache->valid); 80 80 } 81 81 82 + if (map->reg_default_cb) { 83 + dev_dbg(map->dev, 84 + "Populating regcache_flat using reg_default_cb callback\n"); 85 + 86 + for (i = 0; i <= map->max_register; i += map->reg_stride) { 87 + unsigned int index = regcache_flat_get_index(map, i); 88 + unsigned int value; 89 + 90 + if (test_bit(index, cache->valid)) 91 + continue; 92 + 93 + if (map->reg_default_cb(map->dev, i, &value)) 94 + continue; 95 + 96 + cache->data[index] = value; 97 + __set_bit(index, cache->valid); 98 + } 99 + } 100 + 82 101 return 0; 83 102 } 84 103
+3 -2
drivers/base/regmap/regcache.c
··· 73 73 74 74 if (!map->reg_defaults_raw) { 75 75 bool cache_bypass = map->cache_bypass; 76 - dev_warn(map->dev, "No cache defaults, reading back from HW\n"); 76 + dev_dbg(map->dev, "No cache defaults, reading back from HW\n"); 77 77 78 78 /* Bypass the cache access till data read from HW */ 79 79 map->cache_bypass = true; ··· 223 223 goto err_free; 224 224 } 225 225 226 - if (map->num_reg_defaults && map->cache_ops->populate) { 226 + if (map->cache_ops->populate && 227 + (map->num_reg_defaults || map->reg_default_cb)) { 227 228 dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name); 228 229 map->lock(map->lock_arg); 229 230 ret = map->cache_ops->populate(map);
+91
drivers/base/regmap/regmap-kunit.c
··· 15 15 16 16 struct regmap_test_priv { 17 17 struct device *dev; 18 + bool *reg_default_called; 19 + unsigned int reg_default_max; 18 20 }; 19 21 20 22 struct regmap_test_param { ··· 119 117 }; 120 118 121 119 KUNIT_ARRAY_PARAM(real_cache_types_only, real_cache_types_only_list, param_to_desc); 120 + 121 + static const struct regmap_test_param flat_cache_types_list[] = { 122 + { .cache = REGCACHE_FLAT, .from_reg = 0 }, 123 + { .cache = REGCACHE_FLAT, .from_reg = 0, .fast_io = true }, 124 + { .cache = REGCACHE_FLAT, .from_reg = 0x2001 }, 125 + }; 126 + 127 + KUNIT_ARRAY_PARAM(flat_cache_types, flat_cache_types_list, param_to_desc); 122 128 123 129 static const struct regmap_test_param real_cache_types_list[] = { 124 130 { .cache = REGCACHE_FLAT, .from_reg = 0 }, ··· 256 246 const struct regmap_test_param *param = test->param_value; 257 247 258 248 return reg != (param->from_reg + 5); 249 + } 250 + 251 + static unsigned int reg_default_expected(unsigned int reg) 252 + { 253 + return 0x5a5a0000 | (reg & 0xffff); 254 + } 255 + 256 + static int reg_default_test_cb(struct device *dev, unsigned int reg, 257 + unsigned int *def) 258 + { 259 + struct kunit *test = dev_get_drvdata(dev); 260 + struct regmap_test_priv *priv = test->priv; 261 + 262 + if (priv && priv->reg_default_called && reg <= priv->reg_default_max) 263 + priv->reg_default_called[reg] = true; 264 + 265 + *def = reg_default_expected(reg); 266 + return 0; 267 + } 268 + 269 + static void expect_reg_default_value(struct kunit *test, struct regmap *map, 270 + struct regmap_ram_data *data, 271 + struct regmap_test_priv *priv, 272 + unsigned int reg) 273 + { 274 + unsigned int val; 275 + 276 + KUNIT_EXPECT_TRUE(test, priv->reg_default_called[reg]); 277 + KUNIT_EXPECT_EQ(test, 0, regmap_read(map, reg, &val)); 278 + KUNIT_EXPECT_EQ(test, reg_default_expected(reg), val); 279 + KUNIT_EXPECT_FALSE(test, data->read[reg]); 259 280 } 260 281 261 282 static void basic_read_write(struct kunit *test) ··· 667 626 /* The data should have been read from cache if there was one */ 668 627 for (i = 0; i < BLOCK_TEST_SIZE; i++) 669 628 KUNIT_EXPECT_EQ(test, config.cache_type == REGCACHE_NONE, data->read[i]); 629 + } 630 + 631 + static void reg_default_callback_populates_flat_cache(struct kunit *test) 632 + { 633 + const struct regmap_test_param *param = test->param_value; 634 + struct regmap_test_priv *priv = test->priv; 635 + struct regmap *map; 636 + struct regmap_config config; 637 + struct regmap_ram_data *data; 638 + unsigned int reg, val; 639 + unsigned int defaults_end; 640 + 641 + config = test_regmap_config; 642 + config.num_reg_defaults = 3; 643 + config.max_register = param->from_reg + BLOCK_TEST_SIZE - 1; 644 + config.reg_default_cb = reg_default_test_cb; 645 + 646 + priv->reg_default_max = config.max_register; 647 + priv->reg_default_called = kunit_kcalloc(test, config.max_register + 1, 648 + sizeof(*priv->reg_default_called), 649 + GFP_KERNEL); 650 + KUNIT_ASSERT_NOT_NULL(test, priv->reg_default_called); 651 + 652 + map = gen_regmap(test, &config, &data); 653 + KUNIT_ASSERT_FALSE(test, IS_ERR(map)); 654 + if (IS_ERR(map)) 655 + return; 656 + 657 + for (reg = 0; reg <= config.max_register; reg++) 658 + data->read[reg] = false; 659 + 660 + defaults_end = param->from_reg + config.num_reg_defaults - 1; 661 + 662 + for (reg = param->from_reg; reg <= defaults_end; reg++) { 663 + KUNIT_EXPECT_FALSE(test, priv->reg_default_called[reg]); 664 + KUNIT_EXPECT_EQ(test, 0, regmap_read(map, reg, &val)); 665 + KUNIT_EXPECT_EQ(test, data->vals[reg], val); 666 + KUNIT_EXPECT_FALSE(test, data->read[reg]); 667 + } 668 + 669 + if (param->from_reg > 0) 670 + expect_reg_default_value(test, map, data, priv, 0); 671 + 672 + if (defaults_end + 1 <= config.max_register) 673 + expect_reg_default_value(test, map, data, priv, defaults_end + 1); 674 + 675 + if (config.max_register > defaults_end + 1) 676 + expect_reg_default_value(test, map, data, priv, config.max_register); 670 677 } 671 678 672 679 static void reg_defaults_read_dev(struct kunit *test) ··· 2147 2058 KUNIT_CASE_PARAM(write_readonly, regcache_types_gen_params), 2148 2059 KUNIT_CASE_PARAM(read_writeonly, regcache_types_gen_params), 2149 2060 KUNIT_CASE_PARAM(reg_defaults, regcache_types_gen_params), 2061 + KUNIT_CASE_PARAM(reg_default_callback_populates_flat_cache, 2062 + flat_cache_types_gen_params), 2150 2063 KUNIT_CASE_PARAM(reg_defaults_read_dev, regcache_types_gen_params), 2151 2064 KUNIT_CASE_PARAM(register_patch, regcache_types_gen_params), 2152 2065 KUNIT_CASE_PARAM(stride, regcache_types_gen_params),
+2
drivers/base/regmap/regmap.c
··· 813 813 map->precious_reg = config->precious_reg; 814 814 map->writeable_noinc_reg = config->writeable_noinc_reg; 815 815 map->readable_noinc_reg = config->readable_noinc_reg; 816 + map->reg_default_cb = config->reg_default_cb; 816 817 map->cache_type = config->cache_type; 817 818 818 819 spin_lock_init(&map->async_lock); ··· 1436 1435 map->precious_reg = config->precious_reg; 1437 1436 map->writeable_noinc_reg = config->writeable_noinc_reg; 1438 1437 map->readable_noinc_reg = config->readable_noinc_reg; 1438 + map->reg_default_cb = config->reg_default_cb; 1439 1439 map->cache_type = config->cache_type; 1440 1440 1441 1441 ret = regmap_set_name(map, config);
+14
include/linux/regmap.h
··· 359 359 * @reg_defaults: Power on reset values for registers (for use with 360 360 * register cache support). 361 361 * @num_reg_defaults: Number of elements in reg_defaults. 362 + * @reg_default_cb: Optional callback to return default values for registers 363 + * not listed in reg_defaults. This is only used for 364 + * REGCACHE_FLAT population; drivers must ensure the readable_reg/ 365 + * writeable_reg callbacks are defined to handle holes. 362 366 * 363 367 * @read_flag_mask: Mask to be set in the top bytes of the register when doing 364 368 * a read. ··· 453 449 const struct regmap_access_table *rd_noinc_table; 454 450 const struct reg_default *reg_defaults; 455 451 unsigned int num_reg_defaults; 452 + int (*reg_default_cb)(struct device *dev, unsigned int reg, 453 + unsigned int *def); 456 454 enum regcache_type cache_type; 457 455 const void *reg_defaults_raw; 458 456 unsigned int num_reg_defaults_raw; ··· 1353 1347 unsigned int mask, unsigned int val) 1354 1348 { 1355 1349 return regmap_update_bits_base(map, reg, mask, val, NULL, false, true); 1350 + } 1351 + 1352 + static inline int regmap_default_zero_cb(struct device *dev, 1353 + unsigned int reg, 1354 + unsigned int *def) 1355 + { 1356 + *def = 0; 1357 + return 0; 1356 1358 } 1357 1359 1358 1360 int regmap_get_val_bytes(struct regmap *map);