* [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults
@ 2026-01-23 9:53 Sheetal .
2026-01-23 9:53 ` [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes Sheetal .
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Sheetal . @ 2026-01-23 9:53 UTC (permalink / raw)
To: Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra, sheetal
From: sheetal <sheetal@nvidia.com>
This series adds a reg_default_cb callback for REGCACHE_FLAT to provide
defaults for registers not listed in reg_defaults. Defaults are loaded
eagerly during regcache init and the callback can use writeable_reg to
filter valid addresses and avoid holes.
Tegra ASoC drivers set reg_default_cb and add writeable_reg filtering for
AHUB RX holes to prevent invalid addresses from being marked valid.
Changes in v3:
- Add AHUB writeable_reg filtering for RX holes.
- Replace flat_cache_default_is_zero flag with reg_default_cb callback
- Load defaults at regcache init using reg_default_cb
- Set reg_default_cb in Tegra ASoC drivers
- Add KUnit coverage for reg_default_cb callback
Note:
"ASoC: tegra: set reg_default_cb callback" patch depends on
"ASoC: tegra: Add AHUB writeable_reg for RX holes" patch,
hence included in this series.
Sheetal (4):
ASoC: tegra: Add AHUB writeable_reg for RX holes
regmap: Add reg_default_cb callback for flat cache defaults
ASoC: tegra: set reg_default_cb callback
regmap: add KUnit coverage for reg_default_cb callback
drivers/base/regmap/internal.h | 3 +
drivers/base/regmap/regcache-flat.c | 19 ++++++
drivers/base/regmap/regcache.c | 3 +-
drivers/base/regmap/regmap-kunit.c | 91 +++++++++++++++++++++++++++++
drivers/base/regmap/regmap.c | 2 +
include/linux/regmap.h | 14 +++++
sound/soc/tegra/tegra186_asrc.c | 1 +
sound/soc/tegra/tegra186_dspk.c | 1 +
sound/soc/tegra/tegra210_admaif.c | 3 +
sound/soc/tegra/tegra210_adx.c | 2 +
sound/soc/tegra/tegra210_ahub.c | 60 +++++++++++++++++++
sound/soc/tegra/tegra210_ahub.h | 30 ++++++++++
sound/soc/tegra/tegra210_amx.c | 3 +
sound/soc/tegra/tegra210_dmic.c | 1 +
sound/soc/tegra/tegra210_i2s.c | 2 +
sound/soc/tegra/tegra210_mbdrc.c | 1 +
sound/soc/tegra/tegra210_mixer.c | 1 +
sound/soc/tegra/tegra210_mvc.c | 1 +
sound/soc/tegra/tegra210_ope.c | 1 +
sound/soc/tegra/tegra210_peq.c | 1 +
sound/soc/tegra/tegra210_sfc.c | 1 +
21 files changed, 240 insertions(+), 1 deletion(-)
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
@ 2026-01-23 9:53 ` Sheetal .
2026-01-27 19:27 ` Jon Hunter
2026-01-23 9:53 ` [RFC PATCH v3 2/4] regmap: Add reg_default_cb callback for flat cache defaults Sheetal .
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Sheetal . @ 2026-01-23 9:53 UTC (permalink / raw)
To: Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra, Sheetal
From: Sheetal <sheetal@nvidia.com>
Add writeable_reg callbacks for Tegra210/186 AHUB RX registers so the
flat cache only treats valid RX locations as writable, avoiding holes
in the register map.
Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver")
Signed-off-by: Sheetal <sheetal@nvidia.com>
---
sound/soc/tegra/tegra210_ahub.c | 57 +++++++++++++++++++++++++++++++++
sound/soc/tegra/tegra210_ahub.h | 30 +++++++++++++++++
2 files changed, 87 insertions(+)
diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
index e795907a3963..fc5892056f83 100644
--- a/sound/soc/tegra/tegra210_ahub.c
+++ b/sound/soc/tegra/tegra210_ahub.c
@@ -2049,6 +2049,61 @@ static const struct snd_soc_component_driver tegra264_ahub_component = {
.num_dapm_routes = ARRAY_SIZE(tegra264_ahub_routes),
};
+static bool tegra210_ahub_wr_reg(struct device *dev, unsigned int reg)
+{
+ int part;
+
+ if (reg % TEGRA210_XBAR_RX_STRIDE)
+ return false;
+
+ for (part = 0; part < TEGRA210_XBAR_UPDATE_MAX_REG; part++) {
+ switch (reg & ~(part * TEGRA210_XBAR_PART1_RX)) {
+ case TEGRA210_AXBAR_PART_0_ADMAIF_RX1_0 ... TEGRA210_AXBAR_PART_0_ADMAIF_RX10_0:
+ case TEGRA210_AXBAR_PART_0_I2S1_RX1_0 ... TEGRA210_AXBAR_PART_0_I2S5_RX1_0:
+ case TEGRA210_AXBAR_PART_0_SFC1_RX1_0 ... TEGRA210_AXBAR_PART_0_SFC4_RX1_0:
+ case TEGRA210_AXBAR_PART_0_MIXER1_RX1_0 ... TEGRA210_AXBAR_PART_0_MIXER1_RX10_0:
+ case TEGRA210_AXBAR_PART_0_SPDIF1_RX1_0 ... TEGRA210_AXBAR_PART_0_SPDIF1_RX2_0:
+ case TEGRA210_AXBAR_PART_0_AFC1_RX1_0 ... TEGRA210_AXBAR_PART_0_AFC6_RX1_0:
+ case TEGRA210_AXBAR_PART_0_OPE1_RX1_0 ... TEGRA210_AXBAR_PART_0_OPE2_RX1_0:
+ case TEGRA210_AXBAR_PART_0_SPKPROT1_RX1_0:
+ case TEGRA210_AXBAR_PART_0_MVC1_RX1_0 ... TEGRA210_AXBAR_PART_0_MVC2_RX1_0:
+ case TEGRA210_AXBAR_PART_0_AMX1_RX1_0 ... TEGRA210_AXBAR_PART_0_ADX2_RX1_0:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+static bool tegra186_ahub_wr_reg(struct device *dev, unsigned int reg)
+{
+ int part;
+
+ if (reg % TEGRA210_XBAR_RX_STRIDE)
+ return false;
+
+ for (part = 0; part < TEGRA186_XBAR_UPDATE_MAX_REG; part++) {
+ switch (reg & ~(part * TEGRA210_XBAR_PART1_RX)) {
+ case TEGRA210_AXBAR_PART_0_ADMAIF_RX1_0 ... TEGRA186_AXBAR_PART_0_I2S6_RX1_0:
+ case TEGRA210_AXBAR_PART_0_SFC1_RX1_0 ... TEGRA210_AXBAR_PART_0_SFC4_RX1_0:
+ case TEGRA210_AXBAR_PART_0_MIXER1_RX1_0 ... TEGRA210_AXBAR_PART_0_MIXER1_RX10_0:
+ case TEGRA186_AXBAR_PART_0_DSPK1_RX1_0 ... TEGRA186_AXBAR_PART_0_DSPK2_RX1_0:
+ case TEGRA210_AXBAR_PART_0_AFC1_RX1_0 ... TEGRA210_AXBAR_PART_0_AFC6_RX1_0:
+ case TEGRA210_AXBAR_PART_0_OPE1_RX1_0:
+ case TEGRA186_AXBAR_PART_0_MVC1_RX1_0 ... TEGRA186_AXBAR_PART_0_MVC2_RX1_0:
+ case TEGRA186_AXBAR_PART_0_AMX1_RX1_0 ... TEGRA186_AXBAR_PART_0_AMX3_RX4_0:
+ case TEGRA210_AXBAR_PART_0_ADX1_RX1_0 ... TEGRA186_AXBAR_PART_0_ASRC1_RX7_0:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
static bool tegra264_ahub_wr_reg(struct device *dev, unsigned int reg)
{
int part;
@@ -2076,6 +2131,7 @@ static const struct regmap_config tegra210_ahub_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
+ .writeable_reg = tegra210_ahub_wr_reg,
.max_register = TEGRA210_MAX_REGISTER_ADDR,
.cache_type = REGCACHE_FLAT,
};
@@ -2084,6 +2140,7 @@ static const struct regmap_config tegra186_ahub_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
+ .writeable_reg = tegra186_ahub_wr_reg,
.max_register = TEGRA186_MAX_REGISTER_ADDR,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_ahub.h b/sound/soc/tegra/tegra210_ahub.h
index f355b2cfd19b..acbe640dd3b5 100644
--- a/sound/soc/tegra/tegra210_ahub.h
+++ b/sound/soc/tegra/tegra210_ahub.h
@@ -68,6 +68,36 @@
#define TEGRA210_MAX_REGISTER_ADDR (TEGRA210_XBAR_PART2_RX + \
(TEGRA210_XBAR_RX_STRIDE * (TEGRA210_XBAR_AUDIO_RX_COUNT - 1)))
+/* AXBAR register offsets */
+#define TEGRA186_AXBAR_PART_0_AMX1_RX1_0 0x120
+#define TEGRA186_AXBAR_PART_0_AMX3_RX4_0 0x14c
+#define TEGRA186_AXBAR_PART_0_ASRC1_RX7_0 0x1a8
+#define TEGRA186_AXBAR_PART_0_DSPK1_RX1_0 0xc0
+#define TEGRA186_AXBAR_PART_0_DSPK2_RX1_0 0xc4
+#define TEGRA186_AXBAR_PART_0_I2S6_RX1_0 0x54
+#define TEGRA186_AXBAR_PART_0_MVC1_RX1_0 0x110
+#define TEGRA186_AXBAR_PART_0_MVC2_RX1_0 0x114
+#define TEGRA210_AXBAR_PART_0_ADMAIF_RX10_0 0x24
+#define TEGRA210_AXBAR_PART_0_ADMAIF_RX1_0 0x0
+#define TEGRA210_AXBAR_PART_0_ADX1_RX1_0 0x160
+#define TEGRA210_AXBAR_PART_0_ADX2_RX1_0 0x164
+#define TEGRA210_AXBAR_PART_0_AFC1_RX1_0 0xd0
+#define TEGRA210_AXBAR_PART_0_AFC6_RX1_0 0xe4
+#define TEGRA210_AXBAR_PART_0_AMX1_RX1_0 0x140
+#define TEGRA210_AXBAR_PART_0_I2S1_RX1_0 0x40
+#define TEGRA210_AXBAR_PART_0_I2S5_RX1_0 0x50
+#define TEGRA210_AXBAR_PART_0_MIXER1_RX10_0 0xa4
+#define TEGRA210_AXBAR_PART_0_MIXER1_RX1_0 0x80
+#define TEGRA210_AXBAR_PART_0_MVC1_RX1_0 0x120
+#define TEGRA210_AXBAR_PART_0_MVC2_RX1_0 0x124
+#define TEGRA210_AXBAR_PART_0_OPE1_RX1_0 0x100
+#define TEGRA210_AXBAR_PART_0_OPE2_RX1_0 0x104
+#define TEGRA210_AXBAR_PART_0_SFC1_RX1_0 0x60
+#define TEGRA210_AXBAR_PART_0_SFC4_RX1_0 0x6c
+#define TEGRA210_AXBAR_PART_0_SPDIF1_RX1_0 0xc0
+#define TEGRA210_AXBAR_PART_0_SPDIF1_RX2_0 0xc4
+#define TEGRA210_AXBAR_PART_0_SPKPROT1_RX1_0 0x110
+
#define MUX_REG(id) (TEGRA210_XBAR_RX_STRIDE * (id))
#define MUX_VALUE(npart, nbit) (1 + (nbit) + (npart) * 32)
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH v3 2/4] regmap: Add reg_default_cb callback for flat cache defaults
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
2026-01-23 9:53 ` [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes Sheetal .
@ 2026-01-23 9:53 ` Sheetal .
2026-01-27 19:29 ` Jon Hunter
2026-01-23 9:53 ` [RFC PATCH v3 3/4] ASoC: tegra: set reg_default_cb callback Sheetal .
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Sheetal . @ 2026-01-23 9:53 UTC (permalink / raw)
To: Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra, Sheetal
From: Sheetal <sheetal@nvidia.com>
Commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache")
warns when REGCACHE_FLAT is used without full defaults. This causes
false positives on hardware where many registers reset to zero but are
not listed in reg_defaults, forcing drivers to maintain large tables
just to silence the warning.
Add a reg_default_cb() hook so drivers can supply defaults for registers
not present in reg_defaults when populating REGCACHE_FLAT. This keeps
the warning quiet for known zero-reset registers without bloating
tables. Provide a generic regmap_default_zero_cb() helper for drivers
that need zero defaults.
The hook is only used for REGCACHE_FLAT; the core does not
check readable/writeable access, so drivers must provide readable_reg/
writeable_reg callbacks and handle holes in the register map.
Signed-off-by: Sheetal <sheetal@nvidia.com>
---
drivers/base/regmap/internal.h | 3 +++
drivers/base/regmap/regcache-flat.c | 19 +++++++++++++++++++
drivers/base/regmap/regcache.c | 3 ++-
drivers/base/regmap/regmap.c | 2 ++
include/linux/regmap.h | 14 ++++++++++++++
5 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 1477329410ec..5bf993165438 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -117,6 +117,9 @@ struct regmap {
void *val_buf, size_t val_size);
int (*write)(void *context, const void *data, size_t count);
+ int (*reg_default_cb)(struct device *dev, unsigned int reg,
+ unsigned int *val);
+
unsigned long read_flag_mask;
unsigned long write_flag_mask;
diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c
index 53cc59c84e2f..c924817e19b1 100644
--- a/drivers/base/regmap/regcache-flat.c
+++ b/drivers/base/regmap/regcache-flat.c
@@ -79,6 +79,25 @@ static int regcache_flat_populate(struct regmap *map)
__set_bit(index, cache->valid);
}
+ if (map->reg_default_cb) {
+ dev_dbg(map->dev,
+ "Populating regcache_flat using reg_default_cb callback\n");
+
+ for (i = 0; i <= map->max_register; i += map->reg_stride) {
+ unsigned int index = regcache_flat_get_index(map, i);
+ unsigned int value;
+
+ if (test_bit(index, cache->valid))
+ continue;
+
+ if (map->reg_default_cb(map->dev, i, &value))
+ continue;
+
+ cache->data[index] = value;
+ __set_bit(index, cache->valid);
+ }
+ }
+
return 0;
}
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 319c342bf5a0..31bdbf37dbed 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -223,7 +223,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
goto err_free;
}
- if (map->num_reg_defaults && map->cache_ops->populate) {
+ if (map->cache_ops->populate &&
+ (map->num_reg_defaults || map->reg_default_cb)) {
dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name);
map->lock(map->lock_arg);
ret = map->cache_ops->populate(map);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ce9be3989a21..57c5551044ed 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -811,6 +811,7 @@ struct regmap *__regmap_init(struct device *dev,
map->precious_reg = config->precious_reg;
map->writeable_noinc_reg = config->writeable_noinc_reg;
map->readable_noinc_reg = config->readable_noinc_reg;
+ map->reg_default_cb = config->reg_default_cb;
map->cache_type = config->cache_type;
spin_lock_init(&map->async_lock);
@@ -1433,6 +1434,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
map->precious_reg = config->precious_reg;
map->writeable_noinc_reg = config->writeable_noinc_reg;
map->readable_noinc_reg = config->readable_noinc_reg;
+ map->reg_default_cb = config->reg_default_cb;
map->cache_type = config->cache_type;
ret = regmap_set_name(map, config);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index b0b9be750d93..51940eeff872 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -359,6 +359,10 @@ typedef void (*regmap_unlock)(void *);
* @reg_defaults: Power on reset values for registers (for use with
* register cache support).
* @num_reg_defaults: Number of elements in reg_defaults.
+ * @reg_default_cb: Optional callback to return default values for registers
+ * not listed in reg_defaults. This is only used for
+ * REGCACHE_FLAT population; drivers must ensure the readable_reg/
+ * writeable_reg callbacks are defined to handle holes.
*
* @read_flag_mask: Mask to be set in the top bytes of the register when doing
* a read.
@@ -449,6 +453,8 @@ struct regmap_config {
const struct regmap_access_table *rd_noinc_table;
const struct reg_default *reg_defaults;
unsigned int num_reg_defaults;
+ int (*reg_default_cb)(struct device *dev, unsigned int reg,
+ unsigned int *def);
enum regcache_type cache_type;
const void *reg_defaults_raw;
unsigned int num_reg_defaults_raw;
@@ -1349,6 +1355,14 @@ static inline int regmap_write_bits(struct regmap *map, unsigned int reg,
return regmap_update_bits_base(map, reg, mask, val, NULL, false, true);
}
+static inline int regmap_default_zero_cb(struct device *dev,
+ unsigned int reg,
+ unsigned int *def)
+{
+ *def = 0;
+ return 0;
+}
+
int regmap_get_val_bytes(struct regmap *map);
int regmap_get_max_register(struct regmap *map);
int regmap_get_reg_stride(struct regmap *map);
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH v3 3/4] ASoC: tegra: set reg_default_cb callback
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
2026-01-23 9:53 ` [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes Sheetal .
2026-01-23 9:53 ` [RFC PATCH v3 2/4] regmap: Add reg_default_cb callback for flat cache defaults Sheetal .
@ 2026-01-23 9:53 ` Sheetal .
2026-01-27 19:29 ` Jon Hunter
2026-01-23 9:53 ` [RFC PATCH v3 4/4] regmap: add KUnit coverage for " Sheetal .
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Sheetal . @ 2026-01-23 9:53 UTC (permalink / raw)
To: Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra, Sheetal
From: Sheetal <sheetal@nvidia.com>
Set reg_default_cb so REGCACHE_FLAT can supply zero defaults without
large reg_defaults tables, simplifying cache initialization for
zero-reset registers.
Signed-off-by: Sheetal <sheetal@nvidia.com>
---
sound/soc/tegra/tegra186_asrc.c | 1 +
sound/soc/tegra/tegra186_dspk.c | 1 +
sound/soc/tegra/tegra210_admaif.c | 3 +++
sound/soc/tegra/tegra210_adx.c | 2 ++
sound/soc/tegra/tegra210_ahub.c | 3 +++
sound/soc/tegra/tegra210_amx.c | 3 +++
sound/soc/tegra/tegra210_dmic.c | 1 +
sound/soc/tegra/tegra210_i2s.c | 2 ++
sound/soc/tegra/tegra210_mbdrc.c | 1 +
sound/soc/tegra/tegra210_mixer.c | 1 +
sound/soc/tegra/tegra210_mvc.c | 1 +
sound/soc/tegra/tegra210_ope.c | 1 +
sound/soc/tegra/tegra210_peq.c | 1 +
sound/soc/tegra/tegra210_sfc.c | 1 +
14 files changed, 22 insertions(+)
diff --git a/sound/soc/tegra/tegra186_asrc.c b/sound/soc/tegra/tegra186_asrc.c
index 2c0220e14a57..d2a5ec7c54cc 100644
--- a/sound/soc/tegra/tegra186_asrc.c
+++ b/sound/soc/tegra/tegra186_asrc.c
@@ -950,6 +950,7 @@ static const struct regmap_config tegra186_asrc_regmap_config = {
.volatile_reg = tegra186_asrc_volatile_reg,
.reg_defaults = tegra186_asrc_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra186_asrc_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra186_dspk.c b/sound/soc/tegra/tegra186_dspk.c
index a762150db802..8816e4967331 100644
--- a/sound/soc/tegra/tegra186_dspk.c
+++ b/sound/soc/tegra/tegra186_dspk.c
@@ -467,6 +467,7 @@ static const struct regmap_config tegra186_dspk_regmap = {
.volatile_reg = tegra186_dspk_volatile_reg,
.reg_defaults = tegra186_dspk_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra186_dspk_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
index f9f6040c4e34..0976779d29f2 100644
--- a/sound/soc/tegra/tegra210_admaif.c
+++ b/sound/soc/tegra/tegra210_admaif.c
@@ -241,6 +241,7 @@ static const struct regmap_config tegra210_admaif_regmap_config = {
.volatile_reg = tegra_admaif_volatile_reg,
.reg_defaults = tegra210_admaif_reg_defaults,
.num_reg_defaults = TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1,
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -254,6 +255,7 @@ static const struct regmap_config tegra186_admaif_regmap_config = {
.volatile_reg = tegra_admaif_volatile_reg,
.reg_defaults = tegra186_admaif_reg_defaults,
.num_reg_defaults = TEGRA186_ADMAIF_CHANNEL_COUNT * 6 + 1,
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -267,6 +269,7 @@ static const struct regmap_config tegra264_admaif_regmap_config = {
.volatile_reg = tegra_admaif_volatile_reg,
.reg_defaults = tegra264_admaif_reg_defaults,
.num_reg_defaults = TEGRA264_ADMAIF_CHANNEL_COUNT * 6 + 1,
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c
index 6c9a410085bc..95875c75ddf8 100644
--- a/sound/soc/tegra/tegra210_adx.c
+++ b/sound/soc/tegra/tegra210_adx.c
@@ -625,6 +625,7 @@ static const struct regmap_config tegra210_adx_regmap_config = {
.volatile_reg = tegra210_adx_volatile_reg,
.reg_defaults = tegra210_adx_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_adx_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -638,6 +639,7 @@ static const struct regmap_config tegra264_adx_regmap_config = {
.volatile_reg = tegra264_adx_volatile_reg,
.reg_defaults = tegra264_adx_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra264_adx_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
index fc5892056f83..43a45f785d5b 100644
--- a/sound/soc/tegra/tegra210_ahub.c
+++ b/sound/soc/tegra/tegra210_ahub.c
@@ -2133,6 +2133,7 @@ static const struct regmap_config tegra210_ahub_regmap_config = {
.reg_stride = 4,
.writeable_reg = tegra210_ahub_wr_reg,
.max_register = TEGRA210_MAX_REGISTER_ADDR,
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -2142,6 +2143,7 @@ static const struct regmap_config tegra186_ahub_regmap_config = {
.reg_stride = 4,
.writeable_reg = tegra186_ahub_wr_reg,
.max_register = TEGRA186_MAX_REGISTER_ADDR,
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -2151,6 +2153,7 @@ static const struct regmap_config tegra264_ahub_regmap_config = {
.reg_stride = 4,
.writeable_reg = tegra264_ahub_wr_reg,
.max_register = TEGRA264_MAX_REGISTER_ADDR,
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c
index c94f8c84e04f..bfda82505298 100644
--- a/sound/soc/tegra/tegra210_amx.c
+++ b/sound/soc/tegra/tegra210_amx.c
@@ -654,6 +654,7 @@ static const struct regmap_config tegra210_amx_regmap_config = {
.volatile_reg = tegra210_amx_volatile_reg,
.reg_defaults = tegra210_amx_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_amx_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -667,6 +668,7 @@ static const struct regmap_config tegra194_amx_regmap_config = {
.volatile_reg = tegra210_amx_volatile_reg,
.reg_defaults = tegra210_amx_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_amx_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -680,6 +682,7 @@ static const struct regmap_config tegra264_amx_regmap_config = {
.volatile_reg = tegra264_amx_volatile_reg,
.reg_defaults = tegra264_amx_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra264_amx_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_dmic.c b/sound/soc/tegra/tegra210_dmic.c
index 66fff53aeaa6..93def7ac4fde 100644
--- a/sound/soc/tegra/tegra210_dmic.c
+++ b/sound/soc/tegra/tegra210_dmic.c
@@ -483,6 +483,7 @@ static const struct regmap_config tegra210_dmic_regmap_config = {
.volatile_reg = tegra210_dmic_volatile_reg,
.reg_defaults = tegra210_dmic_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_dmic_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c
index b91e0e6cd7fe..d8e02f0a3025 100644
--- a/sound/soc/tegra/tegra210_i2s.c
+++ b/sound/soc/tegra/tegra210_i2s.c
@@ -997,6 +997,7 @@ static const struct regmap_config tegra210_regmap_conf = {
.volatile_reg = tegra210_i2s_volatile_reg,
.reg_defaults = tegra210_i2s_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_i2s_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
@@ -1044,6 +1045,7 @@ static const struct regmap_config tegra264_regmap_conf = {
.volatile_reg = tegra264_i2s_volatile_reg,
.reg_defaults = tegra264_i2s_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra264_i2s_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_mbdrc.c b/sound/soc/tegra/tegra210_mbdrc.c
index 09fe3c5cf540..6a268dbb7197 100644
--- a/sound/soc/tegra/tegra210_mbdrc.c
+++ b/sound/soc/tegra/tegra210_mbdrc.c
@@ -763,6 +763,7 @@ static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
.precious_reg = tegra210_mbdrc_precious_reg,
.reg_defaults = tegra210_mbdrc_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_mbdrc_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_mixer.c b/sound/soc/tegra/tegra210_mixer.c
index ff8e9f2d7abf..6d3a2b76fd61 100644
--- a/sound/soc/tegra/tegra210_mixer.c
+++ b/sound/soc/tegra/tegra210_mixer.c
@@ -608,6 +608,7 @@ static const struct regmap_config tegra210_mixer_regmap_config = {
.precious_reg = tegra210_mixer_precious_reg,
.reg_defaults = tegra210_mixer_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_mixer_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_mvc.c b/sound/soc/tegra/tegra210_mvc.c
index 779d4c199da9..6cdc5e1f5507 100644
--- a/sound/soc/tegra/tegra210_mvc.c
+++ b/sound/soc/tegra/tegra210_mvc.c
@@ -699,6 +699,7 @@ static const struct regmap_config tegra210_mvc_regmap_config = {
.volatile_reg = tegra210_mvc_volatile_reg,
.reg_defaults = tegra210_mvc_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_mvc_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_ope.c b/sound/soc/tegra/tegra210_ope.c
index 27db70af2746..a440888dcdbd 100644
--- a/sound/soc/tegra/tegra210_ope.c
+++ b/sound/soc/tegra/tegra210_ope.c
@@ -297,6 +297,7 @@ static const struct regmap_config tegra210_ope_regmap_config = {
.volatile_reg = tegra210_ope_volatile_reg,
.reg_defaults = tegra210_ope_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_ope_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_peq.c b/sound/soc/tegra/tegra210_peq.c
index 9a05e6913276..2f72e9d541dc 100644
--- a/sound/soc/tegra/tegra210_peq.c
+++ b/sound/soc/tegra/tegra210_peq.c
@@ -306,6 +306,7 @@ static const struct regmap_config tegra210_peq_regmap_config = {
.precious_reg = tegra210_peq_precious_reg,
.reg_defaults = tegra210_peq_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_peq_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
diff --git a/sound/soc/tegra/tegra210_sfc.c b/sound/soc/tegra/tegra210_sfc.c
index d6341968bebe..b298bf0421b1 100644
--- a/sound/soc/tegra/tegra210_sfc.c
+++ b/sound/soc/tegra/tegra210_sfc.c
@@ -3569,6 +3569,7 @@ static const struct regmap_config tegra210_sfc_regmap_config = {
.precious_reg = tegra210_sfc_precious_reg,
.reg_defaults = tegra210_sfc_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(tegra210_sfc_reg_defaults),
+ .reg_default_cb = regmap_default_zero_cb,
.cache_type = REGCACHE_FLAT,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH v3 4/4] regmap: add KUnit coverage for reg_default_cb callback
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
` (2 preceding siblings ...)
2026-01-23 9:53 ` [RFC PATCH v3 3/4] ASoC: tegra: set reg_default_cb callback Sheetal .
@ 2026-01-23 9:53 ` Sheetal .
2026-01-28 4:31 ` (subset) [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Mark Brown
2026-01-29 11:13 ` Mark Brown
5 siblings, 0 replies; 10+ messages in thread
From: Sheetal . @ 2026-01-23 9:53 UTC (permalink / raw)
To: Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra, Sheetal
From: Sheetal <sheetal@nvidia.com>
Add a flat-cache KUnit test that verifies reg_defaults are honored while
missing entries are populated via the reg_default_cb callback without
hardware reads. This exercises the new callback path added for
REGCACHE_FLAT defaults.
Test: ./tools/testing/kunit/kunit.py run regmap
Result:
======== reg_default_callback_populates_flat_cache ========
[PASSED] flat-default @0x0
[PASSED] flat-default fast I/O @0x0
[PASSED] flat-default @0x2001
==== [PASSED] reg_default_callback_populates_flat_cache ====
Signed-off-by: Sheetal <sheetal@nvidia.com>
---
drivers/base/regmap/regmap-kunit.c | 91 ++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/drivers/base/regmap/regmap-kunit.c b/drivers/base/regmap/regmap-kunit.c
index f6fc5ed016da..38c20a09670c 100644
--- a/drivers/base/regmap/regmap-kunit.c
+++ b/drivers/base/regmap/regmap-kunit.c
@@ -15,6 +15,8 @@ KUNIT_DEFINE_ACTION_WRAPPER(regmap_exit_action, regmap_exit, struct regmap *);
struct regmap_test_priv {
struct device *dev;
+ bool *reg_default_called;
+ unsigned int reg_default_max;
};
struct regmap_test_param {
@@ -118,6 +120,14 @@ static const struct regmap_test_param real_cache_types_only_list[] = {
KUNIT_ARRAY_PARAM(real_cache_types_only, real_cache_types_only_list, param_to_desc);
+static const struct regmap_test_param flat_cache_types_list[] = {
+ { .cache = REGCACHE_FLAT, .from_reg = 0 },
+ { .cache = REGCACHE_FLAT, .from_reg = 0, .fast_io = true },
+ { .cache = REGCACHE_FLAT, .from_reg = 0x2001 },
+};
+
+KUNIT_ARRAY_PARAM(flat_cache_types, flat_cache_types_list, param_to_desc);
+
static const struct regmap_test_param real_cache_types_list[] = {
{ .cache = REGCACHE_FLAT, .from_reg = 0 },
{ .cache = REGCACHE_FLAT, .from_reg = 0, .fast_io = true },
@@ -248,6 +258,37 @@ static bool reg_5_false(struct device *dev, unsigned int reg)
return reg != (param->from_reg + 5);
}
+static unsigned int reg_default_expected(unsigned int reg)
+{
+ return 0x5a5a0000 | (reg & 0xffff);
+}
+
+static int reg_default_test_cb(struct device *dev, unsigned int reg,
+ unsigned int *def)
+{
+ struct kunit *test = dev_get_drvdata(dev);
+ struct regmap_test_priv *priv = test->priv;
+
+ if (priv && priv->reg_default_called && reg <= priv->reg_default_max)
+ priv->reg_default_called[reg] = true;
+
+ *def = reg_default_expected(reg);
+ return 0;
+}
+
+static void expect_reg_default_value(struct kunit *test, struct regmap *map,
+ struct regmap_ram_data *data,
+ struct regmap_test_priv *priv,
+ unsigned int reg)
+{
+ unsigned int val;
+
+ KUNIT_EXPECT_TRUE(test, priv->reg_default_called[reg]);
+ KUNIT_EXPECT_EQ(test, 0, regmap_read(map, reg, &val));
+ KUNIT_EXPECT_EQ(test, reg_default_expected(reg), val);
+ KUNIT_EXPECT_FALSE(test, data->read[reg]);
+}
+
static void basic_read_write(struct kunit *test)
{
struct regmap *map;
@@ -628,6 +669,54 @@ static void reg_defaults(struct kunit *test)
KUNIT_EXPECT_EQ(test, config.cache_type == REGCACHE_NONE, data->read[i]);
}
+static void reg_default_callback_populates_flat_cache(struct kunit *test)
+{
+ const struct regmap_test_param *param = test->param_value;
+ struct regmap_test_priv *priv = test->priv;
+ struct regmap *map;
+ struct regmap_config config;
+ struct regmap_ram_data *data;
+ unsigned int reg, val;
+ unsigned int defaults_end;
+
+ config = test_regmap_config;
+ config.num_reg_defaults = 3;
+ config.max_register = param->from_reg + BLOCK_TEST_SIZE - 1;
+ config.reg_default_cb = reg_default_test_cb;
+
+ priv->reg_default_max = config.max_register;
+ priv->reg_default_called = kunit_kcalloc(test, config.max_register + 1,
+ sizeof(*priv->reg_default_called),
+ GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->reg_default_called);
+
+ map = gen_regmap(test, &config, &data);
+ KUNIT_ASSERT_FALSE(test, IS_ERR(map));
+ if (IS_ERR(map))
+ return;
+
+ for (reg = 0; reg <= config.max_register; reg++)
+ data->read[reg] = false;
+
+ defaults_end = param->from_reg + config.num_reg_defaults - 1;
+
+ for (reg = param->from_reg; reg <= defaults_end; reg++) {
+ KUNIT_EXPECT_FALSE(test, priv->reg_default_called[reg]);
+ KUNIT_EXPECT_EQ(test, 0, regmap_read(map, reg, &val));
+ KUNIT_EXPECT_EQ(test, data->vals[reg], val);
+ KUNIT_EXPECT_FALSE(test, data->read[reg]);
+ }
+
+ if (param->from_reg > 0)
+ expect_reg_default_value(test, map, data, priv, 0);
+
+ if (defaults_end + 1 <= config.max_register)
+ expect_reg_default_value(test, map, data, priv, defaults_end + 1);
+
+ if (config.max_register > defaults_end + 1)
+ expect_reg_default_value(test, map, data, priv, config.max_register);
+}
+
static void reg_defaults_read_dev(struct kunit *test)
{
struct regmap *map;
@@ -2058,6 +2147,8 @@ static struct kunit_case regmap_test_cases[] = {
KUNIT_CASE_PARAM(write_readonly, regcache_types_gen_params),
KUNIT_CASE_PARAM(read_writeonly, regcache_types_gen_params),
KUNIT_CASE_PARAM(reg_defaults, regcache_types_gen_params),
+ KUNIT_CASE_PARAM(reg_default_callback_populates_flat_cache,
+ flat_cache_types_gen_params),
KUNIT_CASE_PARAM(reg_defaults_read_dev, regcache_types_gen_params),
KUNIT_CASE_PARAM(register_patch, regcache_types_gen_params),
KUNIT_CASE_PARAM(stride, regcache_types_gen_params),
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes
2026-01-23 9:53 ` [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes Sheetal .
@ 2026-01-27 19:27 ` Jon Hunter
0 siblings, 0 replies; 10+ messages in thread
From: Jon Hunter @ 2026-01-27 19:27 UTC (permalink / raw)
To: Sheetal ., Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Mohan kumar, linux-kernel, linux-sound,
linux-tegra
On 23/01/2026 09:53, Sheetal . wrote:
> From: Sheetal <sheetal@nvidia.com>
>
> Add writeable_reg callbacks for Tegra210/186 AHUB RX registers so the
> flat cache only treats valid RX locations as writable, avoiding holes
> in the register map.
>
> Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver")
> Signed-off-by: Sheetal <sheetal@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Thanks
Jon
--
nvpublic
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH v3 2/4] regmap: Add reg_default_cb callback for flat cache defaults
2026-01-23 9:53 ` [RFC PATCH v3 2/4] regmap: Add reg_default_cb callback for flat cache defaults Sheetal .
@ 2026-01-27 19:29 ` Jon Hunter
0 siblings, 0 replies; 10+ messages in thread
From: Jon Hunter @ 2026-01-27 19:29 UTC (permalink / raw)
To: Sheetal ., Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Mohan kumar, linux-kernel, linux-sound,
linux-tegra
On 23/01/2026 09:53, Sheetal . wrote:
> From: Sheetal <sheetal@nvidia.com>
>
> Commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache")
> warns when REGCACHE_FLAT is used without full defaults. This causes
> false positives on hardware where many registers reset to zero but are
> not listed in reg_defaults, forcing drivers to maintain large tables
> just to silence the warning.
>
> Add a reg_default_cb() hook so drivers can supply defaults for registers
> not present in reg_defaults when populating REGCACHE_FLAT. This keeps
> the warning quiet for known zero-reset registers without bloating
> tables. Provide a generic regmap_default_zero_cb() helper for drivers
> that need zero defaults.
>
> The hook is only used for REGCACHE_FLAT; the core does not
> check readable/writeable access, so drivers must provide readable_reg/
> writeable_reg callbacks and handle holes in the register map.
>
> Signed-off-by: Sheetal <sheetal@nvidia.com>
> ---
> drivers/base/regmap/internal.h | 3 +++
> drivers/base/regmap/regcache-flat.c | 19 +++++++++++++++++++
> drivers/base/regmap/regcache.c | 3 ++-
> drivers/base/regmap/regmap.c | 2 ++
> include/linux/regmap.h | 14 ++++++++++++++
> 5 files changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
> index 1477329410ec..5bf993165438 100644
> --- a/drivers/base/regmap/internal.h
> +++ b/drivers/base/regmap/internal.h
> @@ -117,6 +117,9 @@ struct regmap {
> void *val_buf, size_t val_size);
> int (*write)(void *context, const void *data, size_t count);
>
> + int (*reg_default_cb)(struct device *dev, unsigned int reg,
> + unsigned int *val);
> +
> unsigned long read_flag_mask;
> unsigned long write_flag_mask;
>
> diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c
> index 53cc59c84e2f..c924817e19b1 100644
> --- a/drivers/base/regmap/regcache-flat.c
> +++ b/drivers/base/regmap/regcache-flat.c
> @@ -79,6 +79,25 @@ static int regcache_flat_populate(struct regmap *map)
> __set_bit(index, cache->valid);
> }
>
> + if (map->reg_default_cb) {
> + dev_dbg(map->dev,
> + "Populating regcache_flat using reg_default_cb callback\n");
> +
> + for (i = 0; i <= map->max_register; i += map->reg_stride) {
> + unsigned int index = regcache_flat_get_index(map, i);
> + unsigned int value;
> +
> + if (test_bit(index, cache->valid))
> + continue;
> +
> + if (map->reg_default_cb(map->dev, i, &value))
> + continue;
> +
> + cache->data[index] = value;
> + __set_bit(index, cache->valid);
> + }
> + }
> +
> return 0;
> }
>
> diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
> index 319c342bf5a0..31bdbf37dbed 100644
> --- a/drivers/base/regmap/regcache.c
> +++ b/drivers/base/regmap/regcache.c
> @@ -223,7 +223,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
> goto err_free;
> }
>
> - if (map->num_reg_defaults && map->cache_ops->populate) {
> + if (map->cache_ops->populate &&
> + (map->num_reg_defaults || map->reg_default_cb)) {
> dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name);
> map->lock(map->lock_arg);
> ret = map->cache_ops->populate(map);
> diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
> index ce9be3989a21..57c5551044ed 100644
> --- a/drivers/base/regmap/regmap.c
> +++ b/drivers/base/regmap/regmap.c
> @@ -811,6 +811,7 @@ struct regmap *__regmap_init(struct device *dev,
> map->precious_reg = config->precious_reg;
> map->writeable_noinc_reg = config->writeable_noinc_reg;
> map->readable_noinc_reg = config->readable_noinc_reg;
> + map->reg_default_cb = config->reg_default_cb;
> map->cache_type = config->cache_type;
>
> spin_lock_init(&map->async_lock);
> @@ -1433,6 +1434,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
> map->precious_reg = config->precious_reg;
> map->writeable_noinc_reg = config->writeable_noinc_reg;
> map->readable_noinc_reg = config->readable_noinc_reg;
> + map->reg_default_cb = config->reg_default_cb;
> map->cache_type = config->cache_type;
>
> ret = regmap_set_name(map, config);
> diff --git a/include/linux/regmap.h b/include/linux/regmap.h
> index b0b9be750d93..51940eeff872 100644
> --- a/include/linux/regmap.h
> +++ b/include/linux/regmap.h
> @@ -359,6 +359,10 @@ typedef void (*regmap_unlock)(void *);
> * @reg_defaults: Power on reset values for registers (for use with
> * register cache support).
> * @num_reg_defaults: Number of elements in reg_defaults.
> + * @reg_default_cb: Optional callback to return default values for registers
> + * not listed in reg_defaults. This is only used for
> + * REGCACHE_FLAT population; drivers must ensure the readable_reg/
> + * writeable_reg callbacks are defined to handle holes.
> *
> * @read_flag_mask: Mask to be set in the top bytes of the register when doing
> * a read.
> @@ -449,6 +453,8 @@ struct regmap_config {
> const struct regmap_access_table *rd_noinc_table;
> const struct reg_default *reg_defaults;
> unsigned int num_reg_defaults;
> + int (*reg_default_cb)(struct device *dev, unsigned int reg,
> + unsigned int *def);
> enum regcache_type cache_type;
> const void *reg_defaults_raw;
> unsigned int num_reg_defaults_raw;
> @@ -1349,6 +1355,14 @@ static inline int regmap_write_bits(struct regmap *map, unsigned int reg,
> return regmap_update_bits_base(map, reg, mask, val, NULL, false, true);
> }
>
> +static inline int regmap_default_zero_cb(struct device *dev,
> + unsigned int reg,
> + unsigned int *def)
> +{
> + *def = 0;
> + return 0;
It might be worth ...
if (!def)
return -EINVAL;
*def = 0;
Otherwise ...
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Thanks
Jon
--
nvpublic
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH v3 3/4] ASoC: tegra: set reg_default_cb callback
2026-01-23 9:53 ` [RFC PATCH v3 3/4] ASoC: tegra: set reg_default_cb callback Sheetal .
@ 2026-01-27 19:29 ` Jon Hunter
0 siblings, 0 replies; 10+ messages in thread
From: Jon Hunter @ 2026-01-27 19:29 UTC (permalink / raw)
To: Sheetal ., Mark Brown
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Mohan kumar, linux-kernel, linux-sound,
linux-tegra
On 23/01/2026 09:53, Sheetal . wrote:
> From: Sheetal <sheetal@nvidia.com>
>
> Set reg_default_cb so REGCACHE_FLAT can supply zero defaults without
> large reg_defaults tables, simplifying cache initialization for
> zero-reset registers.
>
> Signed-off-by: Sheetal <sheetal@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Thanks
Jon
--
nvpublic
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (subset) [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
` (3 preceding siblings ...)
2026-01-23 9:53 ` [RFC PATCH v3 4/4] regmap: add KUnit coverage for " Sheetal .
@ 2026-01-28 4:31 ` Mark Brown
2026-01-29 11:13 ` Mark Brown
5 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2026-01-28 4:31 UTC (permalink / raw)
To: Sheetal .
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra
On Fri, 23 Jan 2026 15:23:42 +0530, Sheetal . wrote:
> This series adds a reg_default_cb callback for REGCACHE_FLAT to provide
> defaults for registers not listed in reg_defaults. Defaults are loaded
> eagerly during regcache init and the callback can use writeable_reg to
> filter valid addresses and avoid holes.
>
> Tegra ASoC drivers set reg_default_cb and add writeable_reg filtering for
> AHUB RX holes to prevent invalid addresses from being marked valid.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next
Thanks!
[2/4] regmap: Add reg_default_cb callback for flat cache defaults
commit: dc65b1ed4bb34ab6235ff2cc6a917b9295c04c2c
[4/4] regmap: add KUnit coverage for reg_default_cb callback
commit: 70a65c53d228562cf0c8ae0f38c847d2a5dd59e6
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (subset) [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
` (4 preceding siblings ...)
2026-01-28 4:31 ` (subset) [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Mark Brown
@ 2026-01-29 11:13 ` Mark Brown
5 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2026-01-29 11:13 UTC (permalink / raw)
To: Sheetal .
Cc: Sander Vanheule, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Thierry Reding, Jonathan Hunter, Mohan kumar, linux-kernel,
linux-sound, linux-tegra
On Fri, 23 Jan 2026 15:23:42 +0530, Sheetal . wrote:
> This series adds a reg_default_cb callback for REGCACHE_FLAT to provide
> defaults for registers not listed in reg_defaults. Defaults are loaded
> eagerly during regcache init and the callback can use writeable_reg to
> filter valid addresses and avoid holes.
>
> Tegra ASoC drivers set reg_default_cb and add writeable_reg filtering for
> AHUB RX holes to prevent invalid addresses from being marked valid.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes
commit: 0ba6286a71581aaf8413a55b9bd90ea3463fd23b
[3/4] ASoC: tegra: set reg_default_cb callback
commit: 9409d18bf7d58ab716337749e28e2caba0d64cb0
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-01-29 11:13 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-23 9:53 [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Sheetal .
2026-01-23 9:53 ` [RFC PATCH v3 1/4] ASoC: tegra: Add AHUB writeable_reg for RX holes Sheetal .
2026-01-27 19:27 ` Jon Hunter
2026-01-23 9:53 ` [RFC PATCH v3 2/4] regmap: Add reg_default_cb callback for flat cache defaults Sheetal .
2026-01-27 19:29 ` Jon Hunter
2026-01-23 9:53 ` [RFC PATCH v3 3/4] ASoC: tegra: set reg_default_cb callback Sheetal .
2026-01-27 19:29 ` Jon Hunter
2026-01-23 9:53 ` [RFC PATCH v3 4/4] regmap: add KUnit coverage for " Sheetal .
2026-01-28 4:31 ` (subset) [RFC PATCH v3 0/4] regmap: reg_default_cb for flat cache defaults Mark Brown
2026-01-29 11:13 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox