Merge tag 'regmap-debugfs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap debugfs optimisation fixes from Mark Brown: "The debugfs optimisations merged in v3.8 weren't my finest hour, there were a number of cases that the more complex algorithm made worse especially around the error handling. This patch series should address those issues." * tag 'regmap-debugfs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: debugfs: Make sure we store the last entry in the offset cache regmap: debugfs: Ensure a correct return value for empty caches regmap: debugfs: Discard the cache if we fail to allocate an entry regmap: debugfs: Fix check for block start in cached seeks regmap: debugfs: Fix attempts to read nonexistant register blocks
This commit is contained in:
@@ -56,6 +56,19 @@ static const struct file_operations regmap_name_fops = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static void regmap_debugfs_free_dump_cache(struct regmap *map)
|
||||
{
|
||||
struct regmap_debugfs_off_cache *c;
|
||||
|
||||
while (!list_empty(&map->debugfs_off_cache)) {
|
||||
c = list_first_entry(&map->debugfs_off_cache,
|
||||
struct regmap_debugfs_off_cache,
|
||||
list);
|
||||
list_del(&c->list);
|
||||
kfree(c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Work out where the start offset maps into register numbers, bearing
|
||||
* in mind that we suppress hidden registers.
|
||||
@@ -91,8 +104,10 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
|
||||
/* No cache entry? Start a new one */
|
||||
if (!c) {
|
||||
c = kzalloc(sizeof(*c), GFP_KERNEL);
|
||||
if (!c)
|
||||
break;
|
||||
if (!c) {
|
||||
regmap_debugfs_free_dump_cache(map);
|
||||
return base;
|
||||
}
|
||||
c->min = p;
|
||||
c->base_reg = i;
|
||||
}
|
||||
@@ -101,14 +116,34 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the last entry off if we didn't scan beyond it */
|
||||
if (c) {
|
||||
c->max = p - 1;
|
||||
list_add_tail(&c->list,
|
||||
&map->debugfs_off_cache);
|
||||
} else {
|
||||
return base;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should never happen; we return above if we fail to
|
||||
* allocate and we should never be in this code if there are
|
||||
* no registers at all.
|
||||
*/
|
||||
if (list_empty(&map->debugfs_off_cache)) {
|
||||
WARN_ON(list_empty(&map->debugfs_off_cache));
|
||||
return base;
|
||||
}
|
||||
|
||||
/* Find the relevant block */
|
||||
list_for_each_entry(c, &map->debugfs_off_cache, list) {
|
||||
if (*pos >= c->min && *pos <= c->max) {
|
||||
if (from >= c->min && from <= c->max) {
|
||||
*pos = c->min;
|
||||
return c->base_reg;
|
||||
}
|
||||
|
||||
ret = c->max;
|
||||
*pos = c->min;
|
||||
ret = c->base_reg;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -387,16 +422,8 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
|
||||
|
||||
void regmap_debugfs_exit(struct regmap *map)
|
||||
{
|
||||
struct regmap_debugfs_off_cache *c;
|
||||
|
||||
debugfs_remove_recursive(map->debugfs);
|
||||
while (!list_empty(&map->debugfs_off_cache)) {
|
||||
c = list_first_entry(&map->debugfs_off_cache,
|
||||
struct regmap_debugfs_off_cache,
|
||||
list);
|
||||
list_del(&c->list);
|
||||
kfree(c);
|
||||
}
|
||||
regmap_debugfs_free_dump_cache(map);
|
||||
kfree(map->debugfs_name);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user