regmap: Add debugfs file for forcing field writes
authorWaqar Hameed <waqar.hameed@axis.com>
Tue, 13 Jun 2023 11:42:27 +0000 (13:42 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 13 Jun 2023 12:15:04 +0000 (13:15 +0100)
`_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 to enable this. Since this feature could interfere with driver
operation, guard it with a macro.

Signed-off-by: Waqar Hameed <waqar.hameed@axis.com>
Link: https://lore.kernel.org/r/pnd1qifa7sj.fsf@axis.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/base/regmap/internal.h
drivers/base/regmap/regmap-debugfs.c
drivers/base/regmap/regmap.c

index 7211babbe4ee7ab0c37cebc7a831b3c28e3b4e22..9a9ea514c2d8176ded59056c7565ff195e6a64d1 100644 (file)
@@ -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;
index c491fabe3617a94e5be45aecd090d1720028556e..f36027591e1a8db986c54a2f04f1a645d5f77b76 100644 (file)
@@ -636,6 +636,17 @@ void regmap_debugfs_init(struct regmap *map)
                                    &regmap_cache_bypass_fops);
        }
 
+       /*
+        * This could interfere with driver operation. Therefore, don't provide
+        * any real compile time configuration option for this feature. One will
+        * have to modify the source code directly in order to use it.
+        */
+#undef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS
+#ifdef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS
+       debugfs_create_bool("force_write_field", 0600, map->debugfs,
+                           &map->force_write_field);
+#endif
+
        next = rb_first(&map->range_tree);
        while (next) {
                range_node = rb_entry(next, struct regmap_range_node, node);
index 627a767fa04704872f6ec00967885e6f714c2ffa..89a7f1c459c1ad0319c0cb757266c3330d4f1b50 100644 (file)
@@ -3279,7 +3279,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;