Skip to content

Commit

Permalink
Merge tag 'regmap-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/broonie/regmap

Pull regmap updates from Mark Brown:
 "There's no real overall theme to the regmap changes for this release,
  it's a collection of individual features.  The main bits are:

   - Support for 64 bit registers, mainly for MMIO use, from Xiubo Li.

   - Support for trigger type configuration for regmap-irq from Laxman
     Dewangan.

   - Use native physical I/O for MMIO register maps to avoid confusion
     with the conversions that readl() and writel() do to little endian
     on big endian systems (with some DT updates to fix some workarounds
     people were doing), code from Simon Arlott.

   - Use a binary search rather than iteraton to improve the runtime
     performance of the rbtree code from Nikesh Oswal"

* tag 'regmap-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: debugfs: Use seq_file for the access map
  regmap: irq: add support for configuration of trigger type
  regmap: use IS_ALIGNED instead of % to improve the performance
  regmap: cache: Move the num_reg_defaults check as early as possible
  regmap: cache: Add warning info for the cache check
  regmap: missing case statement
  regmap: shift wrapping bugs in 64 bit code
  regmap: cache: Add 64-bit mode support
  regmap: cache: To suppress the noise of checkpatch
  regmap: fix the warning about unused variable
  regmap: add 64-bit mode support
  regmap: mmio: Add regmap_mmio_get_min_stride
  regmap: mmio: remove the useless code
  regmap: Fix leftover from struct reg_default to struct reg_sequence change
  regmap: replace kmalloc with kmalloc_array
  regmap: replace kzalloc with kcalloc
  regmap: rbtree: When adding a reg do a bsearch for target node
  regmap-mmio: Use native endianness for read/write
  • Loading branch information
torvalds committed Jan 12, 2016
2 parents 581dbc8 + 6cb07ab commit e795e5f
Show file tree
Hide file tree
Showing 18 changed files with 341 additions and 119 deletions.
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm6328.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
timer: timer@10000040 {
compatible = "syscon";
reg = <0x10000040 0x2c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7125.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7346.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7358.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7360.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7362.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7420.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7425.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
};

reboot {
Expand Down
1 change: 0 additions & 1 deletion arch/mips/boot/dts/brcm/bcm7435.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
};

reboot {
Expand Down
2 changes: 1 addition & 1 deletion drivers/base/regmap/regcache-flat.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static int regcache_flat_init(struct regmap *map)
int i;
unsigned int *cache;

map->cache = kzalloc(sizeof(unsigned int) * (map->max_register + 1),
map->cache = kcalloc(map->max_register + 1, sizeof(unsigned int),
GFP_KERNEL);
if (!map->cache)
return -ENOMEM;
Expand Down
6 changes: 3 additions & 3 deletions drivers/base/regmap/regcache-lzo.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static int regcache_lzo_init(struct regmap *map)
ret = 0;

blkcount = regcache_lzo_block_count(map);
map->cache = kzalloc(blkcount * sizeof *lzo_blocks,
map->cache = kcalloc(blkcount, sizeof(*lzo_blocks),
GFP_KERNEL);
if (!map->cache)
return -ENOMEM;
Expand All @@ -152,8 +152,8 @@ static int regcache_lzo_init(struct regmap *map)
* that register.
*/
bmp_size = map->num_reg_defaults_raw;
sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
GFP_KERNEL);
sync_bmp = kmalloc_array(BITS_TO_LONGS(bmp_size), sizeof(long),
GFP_KERNEL);
if (!sync_bmp) {
ret = -ENOMEM;
goto err;
Expand Down
18 changes: 12 additions & 6 deletions drivers/base/regmap/regcache-rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,13 +361,14 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
rbnode->base_reg = reg;
}

rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
GFP_KERNEL);
rbnode->block = kmalloc_array(rbnode->blklen, map->cache_word_size,
GFP_KERNEL);
if (!rbnode->block)
goto err_free;

rbnode->cache_present = kzalloc(BITS_TO_LONGS(rbnode->blklen) *
sizeof(*rbnode->cache_present), GFP_KERNEL);
rbnode->cache_present = kcalloc(BITS_TO_LONGS(rbnode->blklen),
sizeof(*rbnode->cache_present),
GFP_KERNEL);
if (!rbnode->cache_present)
goto err_free_block;

Expand Down Expand Up @@ -413,8 +414,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
max = reg + max_dist;

/* look for an adjacent register to the one we are about to add */
for (node = rb_first(&rbtree_ctx->root); node;
node = rb_next(node)) {
node = rbtree_ctx->root.rb_node;
while (node) {
rbnode_tmp = rb_entry(node, struct regcache_rbtree_node,
node);

Expand All @@ -425,6 +426,11 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
new_base_reg = min(reg, base_reg);
new_top_reg = max(reg, top_reg);
} else {
if (max < base_reg)
node = node->rb_left;
else
node = node->rb_right;

continue;
}

Expand Down
41 changes: 35 additions & 6 deletions drivers/base/regmap/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,25 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
int i;
void *tmp_buf;

for (i = 0; i < config->num_reg_defaults; i++)
if (config->reg_defaults[i].reg % map->reg_stride)
return -EINVAL;

if (map->cache_type == REGCACHE_NONE) {
if (config->reg_defaults || config->num_reg_defaults_raw)
dev_warn(map->dev,
"No cache used with register defaults set!\n");

map->cache_bypass = true;
return 0;
}

if (config->reg_defaults && !config->num_reg_defaults) {
dev_err(map->dev,
"Register defaults are set without the number!\n");
return -EINVAL;
}

for (i = 0; i < config->num_reg_defaults; i++)
if (config->reg_defaults[i].reg % map->reg_stride)
return -EINVAL;

for (i = 0; i < ARRAY_SIZE(cache_types); i++)
if (cache_types[i]->type == map->cache_type)
break;
Expand Down Expand Up @@ -138,8 +148,6 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
* a copy of it.
*/
if (config->reg_defaults) {
if (!map->num_reg_defaults)
return -EINVAL;
tmp_buf = kmemdup(config->reg_defaults, map->num_reg_defaults *
sizeof(struct reg_default), GFP_KERNEL);
if (!tmp_buf)
Expand Down Expand Up @@ -535,19 +543,30 @@ bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
switch (map->cache_word_size) {
case 1: {
u8 *cache = base;

cache[idx] = val;
break;
}
case 2: {
u16 *cache = base;

cache[idx] = val;
break;
}
case 4: {
u32 *cache = base;

cache[idx] = val;
break;
}
#ifdef CONFIG_64BIT
case 8: {
u64 *cache = base;

cache[idx] = val;
break;
}
#endif
default:
BUG();
}
Expand All @@ -568,16 +587,26 @@ unsigned int regcache_get_val(struct regmap *map, const void *base,
switch (map->cache_word_size) {
case 1: {
const u8 *cache = base;

return cache[idx];
}
case 2: {
const u16 *cache = base;

return cache[idx];
}
case 4: {
const u32 *cache = base;

return cache[idx];
}
#ifdef CONFIG_64BIT
case 8: {
const u64 *cache = base;

return cache[idx];
}
#endif
default:
BUG();
}
Expand Down
69 changes: 18 additions & 51 deletions drivers/base/regmap/regmap-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,72 +397,39 @@ static const struct file_operations regmap_reg_ranges_fops = {
.llseek = default_llseek,
};

static ssize_t regmap_access_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
static int regmap_access_show(struct seq_file *s, void *ignored)
{
int reg_len, tot_len;
size_t buf_pos = 0;
loff_t p = 0;
ssize_t ret;
int i;
struct regmap *map = file->private_data;
char *buf;

if (*ppos < 0 || !count)
return -EINVAL;
struct regmap *map = s->private;
int i, reg_len;

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);
tot_len = reg_len + 10; /* ': R W V P\n' */

for (i = 0; i <= map->max_register; i += map->reg_stride) {
/* Ignore registers which are neither readable nor writable */
if (!regmap_readable(map, i) && !regmap_writeable(map, i))
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 */
snprintf(buf + buf_pos, count - buf_pos,
"%.*x: %c %c %c %c\n",
reg_len, i,
regmap_readable(map, i) ? 'y' : 'n',
regmap_writeable(map, i) ? 'y' : 'n',
regmap_volatile(map, i) ? 'y' : 'n',
regmap_precious(map, i) ? 'y' : 'n');

buf_pos += tot_len;
}
p += tot_len;
}

ret = buf_pos;

if (copy_to_user(user_buf, buf, buf_pos)) {
ret = -EFAULT;
goto out;
/* Format the register */
seq_printf(s, "%.*x: %c %c %c %c\n", reg_len, i,
regmap_readable(map, i) ? 'y' : 'n',
regmap_writeable(map, i) ? 'y' : 'n',
regmap_volatile(map, i) ? 'y' : 'n',
regmap_precious(map, i) ? 'y' : 'n');
}

*ppos += buf_pos;
return 0;
}

out:
kfree(buf);
return ret;
static int access_open(struct inode *inode, struct file *file)
{
return single_open(file, regmap_access_show, inode->i_private);
}

static const struct file_operations regmap_access_fops = {
.open = simple_open,
.read = regmap_access_read_file,
.llseek = default_llseek,
.open = access_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static ssize_t regmap_cache_only_write_file(struct file *file,
Expand Down
Loading

0 comments on commit e795e5f

Please sign in to comment.