Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 294170
b: refs/heads/master
c: 7d9aca3
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Mar 14, 2012
1 parent 1f6b40e commit 950b948
Show file tree
Hide file tree
Showing 9 changed files with 358 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a0cc0209abb9fe2b9ab71aa41be70eddd0cbdd61
refs/heads/master: 7d9aca39dcacd2b3f42e2e287162329f410f93e1
9 changes: 5 additions & 4 deletions trunk/drivers/base/regmap/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct regcache_ops;
struct regmap_format {
size_t buf_size;
size_t reg_bytes;
size_t pad_bytes;
size_t val_bytes;
void (*format_write)(struct regmap *map,
unsigned int reg, unsigned int val);
Expand Down Expand Up @@ -65,16 +66,16 @@ struct regmap {
unsigned int num_reg_defaults_raw;

/* if set, only the cache is modified not the HW */
unsigned int cache_only:1;
u32 cache_only;
/* if set, only the HW is modified not the cache */
unsigned int cache_bypass:1;
u32 cache_bypass;
/* if set, remember to free reg_defaults_raw */
unsigned int cache_free:1;
bool cache_free;

struct reg_default *reg_defaults;
const void *reg_defaults_raw;
void *cache;
bool cache_dirty;
u32 cache_dirty;

struct reg_default *patch;
int patch_regs;
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/base/regmap/regcache-lzo.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@ static int regcache_lzo_sync(struct regmap *map)
ret = regcache_read(map, i, &val);
if (ret)
return ret;

/* Is this the hardware default? If so skip. */
ret = regcache_lookup_reg(map, i);
if (ret > 0 && val == map->reg_defaults[ret].def)
continue;

map->cache_bypass = 1;
ret = _regmap_write(map, i, val);
map->cache_bypass = 0;
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/base/regmap/regcache-rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ static int regcache_rbtree_sync(struct regmap *map)

/* Is this the hardware default? If so skip. */
ret = regcache_lookup_reg(map, i);
if (ret > 0 && val == map->reg_defaults[ret].def)
if (ret >= 0 && val == map->reg_defaults[ret].def)
continue;

map->cache_bypass = 1;
Expand Down
16 changes: 13 additions & 3 deletions trunk/drivers/base/regmap/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ int regcache_read(struct regmap *map,

return -EINVAL;
}
EXPORT_SYMBOL_GPL(regcache_read);

/**
* regcache_write: Set the value of a given register in the cache.
Expand All @@ -238,7 +237,6 @@ int regcache_write(struct regmap *map,

return 0;
}
EXPORT_SYMBOL_GPL(regcache_write);

/**
* regcache_sync: Sync the register cache with the hardware.
Expand Down Expand Up @@ -329,6 +327,7 @@ void regcache_cache_only(struct regmap *map, bool enable)
mutex_lock(&map->lock);
WARN_ON(map->cache_bypass && enable);
map->cache_only = enable;
trace_regmap_cache_only(map->dev, enable);
mutex_unlock(&map->lock);
}
EXPORT_SYMBOL_GPL(regcache_cache_only);
Expand Down Expand Up @@ -366,6 +365,7 @@ void regcache_cache_bypass(struct regmap *map, bool enable)
mutex_lock(&map->lock);
WARN_ON(map->cache_only && enable);
map->cache_bypass = enable;
trace_regmap_cache_bypass(map->dev, enable);
mutex_unlock(&map->lock);
}
EXPORT_SYMBOL_GPL(regcache_cache_bypass);
Expand All @@ -388,10 +388,16 @@ bool regcache_set_val(void *base, unsigned int idx,
cache[idx] = val;
break;
}
case 4: {
u32 *cache = base;
if (cache[idx] == val)
return true;
cache[idx] = val;
break;
}
default:
BUG();
}
/* unreachable */
return false;
}

Expand All @@ -410,6 +416,10 @@ unsigned int regcache_get_val(const void *base, unsigned int idx,
const u16 *cache = base;
return cache[idx];
}
case 4: {
const u32 *cache = base;
return cache[idx];
}
default:
BUG();
}
Expand Down
84 changes: 83 additions & 1 deletion trunk/drivers/base/regmap/regmap-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*/

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
Expand All @@ -33,6 +32,35 @@ static int regmap_open_file(struct inode *inode, struct file *file)
return 0;
}

static ssize_t regmap_name_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
{
struct regmap *map = file->private_data;
int ret;
char *buf;

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

ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name);
if (ret < 0) {
kfree(buf);
return ret;
}

ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf);
return ret;
}

static const struct file_operations regmap_name_fops = {
.open = regmap_open_file,
.read = regmap_name_read_file,
.llseek = default_llseek,
};

static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
Expand Down Expand Up @@ -103,9 +131,51 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
return ret;
}

#undef REGMAP_ALLOW_WRITE_DEBUGFS
#ifdef REGMAP_ALLOW_WRITE_DEBUGFS
/*
* This can be dangerous especially when we have clients such as
* PMICs, therefore don't provide any real compile time configuration option
* for this feature, people who want to use this will need to modify
* the source code directly.
*/
static ssize_t regmap_map_write_file(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[32];
size_t buf_size;
char *start = buf;
unsigned long reg, value;
struct regmap *map = file->private_data;

buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
buf[buf_size] = 0;

while (*start == ' ')
start++;
reg = simple_strtoul(start, &start, 16);
while (*start == ' ')
start++;
if (strict_strtoul(start, 16, &value))
return -EINVAL;

/* Userspace has been fiddling around behind the kernel's back */
add_taint(TAINT_USER);

regmap_write(map, reg, value);
return buf_size;
}
#else
#define regmap_map_write_file NULL
#endif

static const struct file_operations regmap_map_fops = {
.open = regmap_open_file,
.read = regmap_map_read_file,
.write = regmap_map_write_file,
.llseek = default_llseek,
};

Expand Down Expand Up @@ -186,12 +256,24 @@ void regmap_debugfs_init(struct regmap *map)
return;
}

debugfs_create_file("name", 0400, map->debugfs,
map, &regmap_name_fops);

if (map->max_register) {
debugfs_create_file("registers", 0400, map->debugfs,
map, &regmap_map_fops);
debugfs_create_file("access", 0400, map->debugfs,
map, &regmap_access_fops);
}

if (map->cache_type) {
debugfs_create_bool("cache_only", 0400, map->debugfs,
&map->cache_only);
debugfs_create_bool("cache_dirty", 0400, map->debugfs,
&map->cache_dirty);
debugfs_create_bool("cache_bypass", 0400, map->debugfs,
&map->cache_bypass);
}
}

void regmap_debugfs_exit(struct regmap *map)
Expand Down
Loading

0 comments on commit 950b948

Please sign in to comment.