[PATCH] regmap: Add debugfs file for forcing field writes

From: Waqar Hameed
Date: Mon Jun 12 2023 - 10:56:02 EST


`_regmap_update_bits` checks if the current register value differs from
the new value, and only writes to the register if they differ. When
testing hardware drivers, it might be desirable to always force a
register write, for example when writing to a `regmap_field`.

This enables and simplifies testing and verification of the hardware
interaction. For example, when using a hardware mock/simulation model,
one can then more easily verify that the driver makes the correct
expected register writes during certain events. Add a bool variable
`force_write_field` and a corresponding debugfs entry.

Signed-off-by: Waqar Hameed <waqarh@xxxxxxxx>
---
drivers/base/regmap/internal.h | 3 +++
drivers/base/regmap/regmap-debugfs.c | 3 +++
drivers/base/regmap/regmap.c | 2 +-
3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 9bd0dfd1e259..6472b3222b82 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -125,6 +125,9 @@ struct regmap {
int reg_stride;
int reg_stride_order;

+ /* If set, will always write field to HW. */
+ bool force_write_field;
+
/* regcache specific members */
const struct regcache_ops *cache_ops;
enum regcache_type cache_type;
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index c491fabe3617..ed677eb10063 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -636,6 +636,9 @@ void regmap_debugfs_init(struct regmap *map)
&regmap_cache_bypass_fops);
}

+ debugfs_create_bool("force_write_field", 0600, map->debugfs,
+ &map->force_write_field);
+
next = rb_first(&map->range_tree);
while (next) {
range_node = rb_entry(next, struct regmap_range_node, node);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index fa2d3fba6ac9..89b701ceb43f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -3273,7 +3273,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
tmp = orig & ~mask;
tmp |= val & mask;

- if (force_write || (tmp != orig)) {
+ if (force_write || (tmp != orig) || map->force_write_field) {
ret = _regmap_write(map, reg, tmp);
if (ret == 0 && change)
*change = true;

base-commit: 858fd168a95c5b9669aac8db6c14a9aeab446375
--
2.30.2