Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 365015
b: refs/heads/master
c: 065b4c5
h: refs/heads/master
i:
  365013: 0c36a3c
  365011: 3eaa4c8
  365007: d836eb5
v: v3
  • Loading branch information
Dimitris Papastamos authored and Mark Brown committed Mar 4, 2013
1 parent 210ff10 commit 1b77779
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 480738de0e076d759a973be623fac195cb901b82
refs/heads/master: 065b4c587557dcd3dc8d3ff1ba2b9ecc6e0c6668
1 change: 1 addition & 0 deletions trunk/drivers/base/regmap/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ struct regmap {
unsigned int debugfs_tot_len;

struct list_head debugfs_off_cache;
struct mutex cache_lock;
#endif

unsigned int max_register;
Expand Down
83 changes: 83 additions & 0 deletions trunk/drivers/base/regmap/regmap-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
* If we don't have a cache build one so we don't have to do a
* linear scan each time.
*/
mutex_lock(&map->cache_lock);
i = base;
if (list_empty(&map->debugfs_off_cache)) {
for (; i <= map->max_register; i += map->reg_stride) {
Expand All @@ -110,6 +111,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
regmap_debugfs_free_dump_cache(map);
mutex_unlock(&map->cache_lock);
return base;
}
c->min = p;
Expand Down Expand Up @@ -142,12 +144,14 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
fpos_offset = from - c->min;
reg_offset = fpos_offset / map->debugfs_tot_len;
*pos = c->min + (reg_offset * map->debugfs_tot_len);
mutex_unlock(&map->cache_lock);
return c->base_reg + reg_offset;
}

*pos = c->max;
ret = c->max_reg;
}
mutex_unlock(&map->cache_lock);

return ret;
}
Expand Down Expand Up @@ -308,6 +312,79 @@ static const struct file_operations regmap_range_fops = {
.llseek = default_llseek,
};

static ssize_t regmap_reg_ranges_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
{
struct regmap *map = file->private_data;
struct regmap_debugfs_off_cache *c;
loff_t p = 0;
size_t buf_pos = 0;
char *buf;
char *entry;
int ret;

if (*ppos < 0 || !count)
return -EINVAL;

buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;

entry = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!entry) {
kfree(buf);
return -ENOMEM;
}

/* While we are at it, build the register dump cache
* now so the read() operation on the `registers' file
* can benefit from using the cache. We do not care
* about the file position information that is contained
* in the cache, just about the actual register blocks */
regmap_calc_tot_len(map, buf, count);
regmap_debugfs_get_dump_start(map, 0, *ppos, &p);

/* Reset file pointer as the fixed-format of the `registers'
* file is not compatible with the `range' file */
p = 0;
mutex_lock(&map->cache_lock);
list_for_each_entry(c, &map->debugfs_off_cache, list) {
snprintf(entry, PAGE_SIZE, "%x-%x",
c->base_reg, c->max_reg);
if (p >= *ppos) {
if (buf_pos + 1 + strlen(entry) > count)
break;
snprintf(buf + buf_pos, count - buf_pos,
"%s", entry);
buf_pos += strlen(entry);
buf[buf_pos] = '\n';
buf_pos++;
}
p += strlen(entry) + 1;
}
mutex_unlock(&map->cache_lock);

kfree(entry);
ret = buf_pos;

if (copy_to_user(user_buf, buf, buf_pos)) {
ret = -EFAULT;
goto out_buf;
}

*ppos += buf_pos;
out_buf:
kfree(buf);
return ret;
}

static const struct file_operations regmap_reg_ranges_fops = {
.open = simple_open,
.read = regmap_reg_ranges_read_file,
.llseek = default_llseek,
};

static ssize_t regmap_access_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
Expand Down Expand Up @@ -382,6 +459,7 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
struct regmap_range_node *range_node;

INIT_LIST_HEAD(&map->debugfs_off_cache);
mutex_init(&map->cache_lock);

if (name) {
map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
Expand All @@ -400,6 +478,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
debugfs_create_file("name", 0400, map->debugfs,
map, &regmap_name_fops);

debugfs_create_file("range", 0400, map->debugfs,
map, &regmap_reg_ranges_fops);

if (map->max_register) {
debugfs_create_file("registers", 0400, map->debugfs,
map, &regmap_map_fops);
Expand Down Expand Up @@ -432,7 +513,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
void regmap_debugfs_exit(struct regmap *map)
{
debugfs_remove_recursive(map->debugfs);
mutex_lock(&map->cache_lock);
regmap_debugfs_free_dump_cache(map);
mutex_unlock(&map->cache_lock);
kfree(map->debugfs_name);
}

Expand Down

0 comments on commit 1b77779

Please sign in to comment.