[OpenWrt-Devel] [PATCH] regmap: Fix debugfs for write-only devices

Cody Harris cody at deadcode.xyz
Fri Aug 5 15:51:36 EDT 2016

In its current implementation, regmap's debugfs interface fails to
correctly print out register values for write-only devices.

The implementation of regmap's debugfs interface doesn't facilitate dumping
out register values for write-only devices because it requires readability
in the sense that the register exists in a map and can be read over the
bus.  Write-only devices fail this criteria despite regmap holding cached
values of the register contents.

Executing 'cat /sys/kernel/debug/regmap/<device>/registers' against a
write-only device results in a WARN_ON in dmesg and nothing printed to

My patch makes the following changes: in addition to checking if the
register is unreadable, it must also be uncached by regmap in order to be
skipped. In other words, write-only devices should have their cached
register values (if they exist) printed out the same as read-write devices.
Checks for cached values are added in several places where regmap-debugfs.c
checks for the existence of a register.

I originally wrote this patch for 15.05/kernel 3.18 which supports the
LinkIt7688 and its breakout board. Though there isn't LinkIt support for
4.4 in trunk yet, I managed to cobble enough together to test this change.

Signed-off-by: Cody Harris <cody at deadcode.xyz>

--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -105,8 +105,9 @@ static unsigned int regmap_debugfs_get_d
 	if (list_empty(&map->debugfs_off_cache)) {
 		for (; i <= map->max_register; i += map->reg_stride) {
 			/* Skip unprinted registers, closing off cache entry */
-			if (!regmap_readable(map, i) ||
-			    regmap_precious(map, i)) {
+			if ((regcache_lookup_reg(map, i) < 0
+			    && !regmap_readable(map, i)) ||
+				regmap_precious(map, i)) {
 				if (c) {
 					c->max = p - 1;
 					c->max_reg = i - map->reg_stride;
@@ -204,7 +205,7 @@ static ssize_t regmap_read_debugfs(struc
 	start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);

 	for (i = start_reg; i <= to; i += map->reg_stride) {
-		if (!regmap_readable(map, i))
+		if (!regmap_readable(map, i) && regcache_lookup_reg(map, i) < 0)

 		if (regmap_precious(map, i))
@@ -592,7 +593,8 @@ void regmap_debugfs_init(struct regmap *
 	debugfs_create_file("range", 0400, map->debugfs,
 			    map, &regmap_reg_ranges_fops);

-	if (map->max_register || regmap_readable(map, 0)) {
+	if (map->max_register || regmap_readable(map, 0)
+		|| regcache_lookup_reg(map, 0) > 0) {
 		umode_t registers_mode;

openwrt-devel mailing list
openwrt-devel at lists.openwrt.org

More information about the openwrt-devel mailing list