Merge remote-tracking branches 'regmap/topic/mmio', 'regmap/topic/rbtree' and 'regmap/topic/seq' into regmap-next
This commit is contained in:
commit
6cb07abcc3
|
@ -73,7 +73,6 @@
|
||||||
timer: timer@10000040 {
|
timer: timer@10000040 {
|
||||||
compatible = "syscon";
|
compatible = "syscon";
|
||||||
reg = <0x10000040 0x2c>;
|
reg = <0x10000040 0x2c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -98,7 +98,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x60c>;
|
reg = <0x404000 0x60c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -118,7 +118,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x51c>;
|
reg = <0x404000 0x51c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -112,7 +112,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x51c>;
|
reg = <0x404000 0x51c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -112,7 +112,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x51c>;
|
reg = <0x404000 0x51c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -118,7 +118,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x51c>;
|
reg = <0x404000 0x51c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -99,7 +99,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x60c>;
|
reg = <0x404000 0x60c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -100,7 +100,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x51c>;
|
reg = <0x404000 0x51c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -114,7 +114,6 @@
|
||||||
sun_top_ctrl: syscon@404000 {
|
sun_top_ctrl: syscon@404000 {
|
||||||
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
|
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
|
||||||
reg = <0x404000 0x51c>;
|
reg = <0x404000 0x51c>;
|
||||||
little-endian;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reboot {
|
reboot {
|
||||||
|
|
|
@ -414,8 +414,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
|
||||||
max = reg + max_dist;
|
max = reg + max_dist;
|
||||||
|
|
||||||
/* look for an adjacent register to the one we are about to add */
|
/* look for an adjacent register to the one we are about to add */
|
||||||
for (node = rb_first(&rbtree_ctx->root); node;
|
node = rbtree_ctx->root.rb_node;
|
||||||
node = rb_next(node)) {
|
while (node) {
|
||||||
rbnode_tmp = rb_entry(node, struct regcache_rbtree_node,
|
rbnode_tmp = rb_entry(node, struct regcache_rbtree_node,
|
||||||
node);
|
node);
|
||||||
|
|
||||||
|
@ -426,6 +426,11 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
|
||||||
new_base_reg = min(reg, base_reg);
|
new_base_reg = min(reg, base_reg);
|
||||||
new_top_reg = max(reg, top_reg);
|
new_top_reg = max(reg, top_reg);
|
||||||
} else {
|
} else {
|
||||||
|
if (max < base_reg)
|
||||||
|
node = node->rb_left;
|
||||||
|
else
|
||||||
|
node = node->rb_right;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -397,72 +397,39 @@ static const struct file_operations regmap_reg_ranges_fops = {
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t regmap_access_read_file(struct file *file,
|
static int regmap_access_show(struct seq_file *s, void *ignored)
|
||||||
char __user *user_buf, size_t count,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
{
|
||||||
int reg_len, tot_len;
|
struct regmap *map = s->private;
|
||||||
size_t buf_pos = 0;
|
int i, reg_len;
|
||||||
loff_t p = 0;
|
|
||||||
ssize_t ret;
|
|
||||||
int i;
|
|
||||||
struct regmap *map = file->private_data;
|
|
||||||
char *buf;
|
|
||||||
|
|
||||||
if (*ppos < 0 || !count)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
buf = kmalloc(count, GFP_KERNEL);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* Calculate the length of a fixed format */
|
|
||||||
reg_len = regmap_calc_reg_len(map->max_register);
|
reg_len = regmap_calc_reg_len(map->max_register);
|
||||||
tot_len = reg_len + 10; /* ': R W V P\n' */
|
|
||||||
|
|
||||||
for (i = 0; i <= map->max_register; i += map->reg_stride) {
|
for (i = 0; i <= map->max_register; i += map->reg_stride) {
|
||||||
/* Ignore registers which are neither readable nor writable */
|
/* Ignore registers which are neither readable nor writable */
|
||||||
if (!regmap_readable(map, i) && !regmap_writeable(map, i))
|
if (!regmap_readable(map, i) && !regmap_writeable(map, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If we're in the region the user is trying to read */
|
|
||||||
if (p >= *ppos) {
|
|
||||||
/* ...but not beyond it */
|
|
||||||
if (buf_pos + tot_len + 1 >= count)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Format the register */
|
/* Format the register */
|
||||||
snprintf(buf + buf_pos, count - buf_pos,
|
seq_printf(s, "%.*x: %c %c %c %c\n", reg_len, i,
|
||||||
"%.*x: %c %c %c %c\n",
|
|
||||||
reg_len, i,
|
|
||||||
regmap_readable(map, i) ? 'y' : 'n',
|
regmap_readable(map, i) ? 'y' : 'n',
|
||||||
regmap_writeable(map, i) ? 'y' : 'n',
|
regmap_writeable(map, i) ? 'y' : 'n',
|
||||||
regmap_volatile(map, i) ? 'y' : 'n',
|
regmap_volatile(map, i) ? 'y' : 'n',
|
||||||
regmap_precious(map, i) ? 'y' : 'n');
|
regmap_precious(map, i) ? 'y' : 'n');
|
||||||
|
|
||||||
buf_pos += tot_len;
|
|
||||||
}
|
|
||||||
p += tot_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = buf_pos;
|
return 0;
|
||||||
|
|
||||||
if (copy_to_user(user_buf, buf, buf_pos)) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppos += buf_pos;
|
static int access_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
out:
|
return single_open(file, regmap_access_show, inode->i_private);
|
||||||
kfree(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations regmap_access_fops = {
|
static const struct file_operations regmap_access_fops = {
|
||||||
.open = simple_open,
|
.open = access_open,
|
||||||
.read = regmap_access_read_file,
|
.read = seq_read,
|
||||||
.llseek = default_llseek,
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t regmap_cache_only_write_file(struct file *file,
|
static ssize_t regmap_cache_only_write_file(struct file *file,
|
||||||
|
|
|
@ -61,6 +61,33 @@ static int regmap_mmio_regbits_check(size_t reg_bits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int regmap_mmio_get_min_stride(size_t val_bits)
|
||||||
|
{
|
||||||
|
int min_stride;
|
||||||
|
|
||||||
|
switch (val_bits) {
|
||||||
|
case 8:
|
||||||
|
/* The core treats 0 as 1 */
|
||||||
|
min_stride = 0;
|
||||||
|
return 0;
|
||||||
|
case 16:
|
||||||
|
min_stride = 2;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
min_stride = 4;
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_64BIT
|
||||||
|
case 64:
|
||||||
|
min_stride = 8;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min_stride;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void regmap_mmio_count_check(size_t count, u32 offset)
|
static inline void regmap_mmio_count_check(size_t count, u32 offset)
|
||||||
{
|
{
|
||||||
BUG_ON(count <= offset);
|
BUG_ON(count <= offset);
|
||||||
|
@ -106,17 +133,17 @@ static int regmap_mmio_gather_write(void *context,
|
||||||
while (val_size) {
|
while (val_size) {
|
||||||
switch (ctx->val_bytes) {
|
switch (ctx->val_bytes) {
|
||||||
case 1:
|
case 1:
|
||||||
writeb(*(u8 *)val, ctx->regs + offset);
|
__raw_writeb(*(u8 *)val, ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
writew(*(u16 *)val, ctx->regs + offset);
|
__raw_writew(*(u16 *)val, ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
writel(*(u32 *)val, ctx->regs + offset);
|
__raw_writel(*(u32 *)val, ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
case 8:
|
case 8:
|
||||||
writeq(*(u64 *)val, ctx->regs + offset);
|
__raw_writeq(*(u64 *)val, ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -166,17 +193,17 @@ static int regmap_mmio_read(void *context,
|
||||||
while (val_size) {
|
while (val_size) {
|
||||||
switch (ctx->val_bytes) {
|
switch (ctx->val_bytes) {
|
||||||
case 1:
|
case 1:
|
||||||
*(u8 *)val = readb(ctx->regs + offset);
|
*(u8 *)val = __raw_readb(ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
*(u16 *)val = readw(ctx->regs + offset);
|
*(u16 *)val = __raw_readw(ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
*(u32 *)val = readl(ctx->regs + offset);
|
*(u32 *)val = __raw_readl(ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
case 8:
|
case 8:
|
||||||
*(u64 *)val = readq(ctx->regs + offset);
|
*(u64 *)val = __raw_readq(ctx->regs + offset);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -231,26 +258,9 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
|
||||||
if (config->pad_bits)
|
if (config->pad_bits)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
switch (config->val_bits) {
|
min_stride = regmap_mmio_get_min_stride(config->val_bits);
|
||||||
case 8:
|
if (min_stride < 0)
|
||||||
/* The core treats 0 as 1 */
|
return ERR_PTR(min_stride);
|
||||||
min_stride = 0;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
min_stride = 2;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
min_stride = 4;
|
|
||||||
break;
|
|
||||||
#ifdef CONFIG_64BIT
|
|
||||||
case 64:
|
|
||||||
min_stride = 8;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->reg_stride < min_stride)
|
if (config->reg_stride < min_stride)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
Loading…
Reference in New Issue