[PATCH] regmap: debugfs: Fix a boot time crash with early regmap init

From: Tero Kristo
Date: Thu Oct 24 2013 - 05:08:05 EST


If called early enough, regmap_debugfs_init causes a crash, if the
fs subsystem does not have its mount cache created yet. Even if this
would work, the root node for the regmap debugfs is still missing,
thus postpone the regmap_debugfs_init in this case until the root
node is created. A special regmap_debugfs_early list is created for
this purpose which is parsed later in the boot.

Signed-off-by: Tero Kristo <t-kristo@xxxxxx>
---
drivers/base/regmap/regmap-debugfs.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index de11eca..e2d8f03 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -15,10 +15,18 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
+#include <linux/list.h>

#include "internal.h"

+struct regmap_debugfs_node {
+ struct regmap *map;
+ const char *name;
+ struct list_head link;
+};
+
static struct dentry *regmap_debugfs_root;
+static LIST_HEAD(regmap_debugfs_early);

/* Calculate the length of a fixed format */
static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size)
@@ -465,6 +473,18 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
struct rb_node *next;
struct regmap_range_node *range_node;

+ /* If we don't have the debugfs root yet, postpone init */
+ if (!regmap_debugfs_root) {
+ struct regmap_debugfs_node *node;
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ if (!node)
+ return;
+ node->map = map;
+ node->name = name;
+ list_add(&node->link, &regmap_debugfs_early);
+ return;
+ }
+
INIT_LIST_HEAD(&map->debugfs_off_cache);
mutex_init(&map->cache_lock);

@@ -528,9 +548,17 @@ void regmap_debugfs_exit(struct regmap *map)

void regmap_debugfs_initcall(void)
{
+ struct regmap_debugfs_node *node, *tmp;
+
regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
if (!regmap_debugfs_root) {
pr_warn("regmap: Failed to create debugfs root\n");
return;
}
+
+ list_for_each_entry_safe(node, tmp, &regmap_debugfs_early, link) {
+ regmap_debugfs_init(node->map, node->name);
+ list_del(&node->link);
+ kfree(node);
+ }
}
--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/