Skip to content

Commit

Permalink
Merge tag 'regmap-v3.15' 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:
 "Quite a busy release for regmap this time around, the standout changes
  are:

   - A real implementation of regmap_multi_write() and a bypassed
     version of it for use by drivers doing patch-like things with more
     open coding for surrounding startup sequences.
   - Support fast_io on bulk operations.
   - Support split device binding and map initialisation for use by
     devices required in early init (mainly system controllers).
   - Fixes for some operations on maps with strides set.
   - Export the value parsing operations to help generic code built on
     top of the API.
   - Support for MMIO regmaps with non-32 bit register sizes.

  plus a few smaller fixes"

* tag 'regmap-v3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: (22 commits)
  regmap: mmio: Add regmap_mmio_regbits_check.
  regmap: mmio: Add support for 1/2/8 bytes wide register address.
  regmap: mmio: add regmap_mmio_{regsize, count}_check.
  regmap: cache: Don't attempt to sync non-writeable registers
  regmap: cache: Step by stride in default sync
  regmap: Fix possible sleep-in-atomic in regmap_bulk_write()
  regmap: Ensure regmap_register_patch() is compatible with fast_io
  regmap: irq: Set data pointer only on regmap_add_irq_chip success
  regmap: Implementation for regmap_multi_reg_write
  regmap: add regmap_parse_val api
  mfd: arizona: Use new regmap features for manual register patch
  regmap: Base regmap_register_patch on _regmap_multi_reg_write
  regmap: Add bypassed version of regmap_multi_reg_write
  regmap: Mark reg_defaults in regmap_multi_reg_write as const
  regmap: fix coccinelle warnings
  regmap: Check stride of register patch as we register it
  regmap: Clean up _regmap_update_bits()
  regmap: Separate regmap dev initialization
  regmap: Check readable regs in _regmap_read
  regmap: irq: Remove domain on exit
  ...
  • Loading branch information
torvalds committed Apr 1, 2014
2 parents d64b393 + 6012b1f commit c6b38ec
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 100 deletions.
2 changes: 2 additions & 0 deletions drivers/base/regmap/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ struct regmap {

/* if set, converts bulk rw to single rw */
bool use_single_rw;
/* if set, the device supports multi write mode */
bool can_multi_write;

struct rb_root range_tree;
void *selector_work_buf; /* Scratch buffer used for selector */
Expand Down
13 changes: 5 additions & 8 deletions drivers/base/regmap/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,12 @@ static int regcache_default_sync(struct regmap *map, unsigned int min,
{
unsigned int reg;

for (reg = min; reg <= max; reg++) {
for (reg = min; reg <= max; reg += map->reg_stride) {
unsigned int val;
int ret;

if (regmap_volatile(map, reg))
if (regmap_volatile(map, reg) ||
!regmap_writeable(map, reg))
continue;

ret = regcache_read(map, reg, &val);
Expand Down Expand Up @@ -312,10 +313,6 @@ int regcache_sync(struct regmap *map)
/* Apply any patch first */
map->cache_bypass = 1;
for (i = 0; i < map->patch_regs; i++) {
if (map->patch[i].reg % map->reg_stride) {
ret = -EINVAL;
goto out;
}
ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
if (ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
Expand Down Expand Up @@ -636,10 +633,10 @@ static int regcache_sync_block_raw_flush(struct regmap *map, const void **data,
if (*data == NULL)
return 0;

count = cur - base;
count = (cur - base) / map->reg_stride;

dev_dbg(map->dev, "Writing %zu bytes for %d registers from 0x%x-0x%x\n",
count * val_bytes, count, base, cur - 1);
count * val_bytes, count, base, cur - map->reg_stride);

map->cache_bypass = 1;

Expand Down
2 changes: 1 addition & 1 deletion drivers/base/regmap/regmap-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
debugfs_create_file("range", 0400, map->debugfs,
map, &regmap_reg_ranges_fops);

if (map->max_register) {
if (map->max_register || regmap_readable(map, 0)) {
debugfs_create_file("registers", 0400, map->debugfs,
map, &regmap_map_fops);
debugfs_create_file("access", 0400, map->debugfs,
Expand Down
6 changes: 3 additions & 3 deletions drivers/base/regmap/regmap-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,6 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
if (!d)
return -ENOMEM;

*data = d;

d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs,
GFP_KERNEL);
if (!d->status_buf)
Expand Down Expand Up @@ -506,6 +504,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
goto err_domain;
}

*data = d;

return 0;

err_domain:
Expand Down Expand Up @@ -533,7 +533,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
return;

free_irq(irq, d);
/* We should unmap the domain but... */
irq_domain_remove(d->domain);
kfree(d->wake_buf);
kfree(d->mask_buf_def);
kfree(d->mask_buf);
Expand Down
56 changes: 50 additions & 6 deletions drivers/base/regmap/regmap-mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,47 @@

struct regmap_mmio_context {
void __iomem *regs;
unsigned reg_bytes;
unsigned val_bytes;
unsigned pad_bytes;
struct clk *clk;
};

static inline void regmap_mmio_regsize_check(size_t reg_size)
{
switch (reg_size) {
case 1:
case 2:
case 4:
#ifdef CONFIG_64BIT
case 8:
#endif
break;
default:
BUG();
}
}

static int regmap_mmio_regbits_check(size_t reg_bits)
{
switch (reg_bits) {
case 8:
case 16:
case 32:
#ifdef CONFIG_64BIT
case 64:
#endif
return 0;
default:
return -EINVAL;
}
}

static inline void regmap_mmio_count_check(size_t count)
{
BUG_ON(count % 2 != 0);
}

static int regmap_mmio_gather_write(void *context,
const void *reg, size_t reg_size,
const void *val, size_t val_size)
Expand All @@ -38,7 +75,7 @@ static int regmap_mmio_gather_write(void *context,
u32 offset;
int ret;

BUG_ON(reg_size != 4);
regmap_mmio_regsize_check(reg_size);

if (!IS_ERR(ctx->clk)) {
ret = clk_enable(ctx->clk);
Expand Down Expand Up @@ -81,9 +118,13 @@ static int regmap_mmio_gather_write(void *context,

static int regmap_mmio_write(void *context, const void *data, size_t count)
{
BUG_ON(count < 4);
struct regmap_mmio_context *ctx = context;
u32 offset = ctx->reg_bytes + ctx->pad_bytes;

regmap_mmio_count_check(count);

return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4);
return regmap_mmio_gather_write(context, data, ctx->reg_bytes,
data + offset, count - offset);
}

static int regmap_mmio_read(void *context,
Expand All @@ -94,7 +135,7 @@ static int regmap_mmio_read(void *context,
u32 offset;
int ret;

BUG_ON(reg_size != 4);
regmap_mmio_regsize_check(reg_size);

if (!IS_ERR(ctx->clk)) {
ret = clk_enable(ctx->clk);
Expand Down Expand Up @@ -165,8 +206,9 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
int min_stride;
int ret;

if (config->reg_bits != 32)
return ERR_PTR(-EINVAL);
ret = regmap_mmio_regbits_check(config->reg_bits);
if (ret)
return ERR_PTR(ret);

if (config->pad_bits)
return ERR_PTR(-EINVAL);
Expand Down Expand Up @@ -209,6 +251,8 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,

ctx->regs = regs;
ctx->val_bytes = config->val_bits / 8;
ctx->reg_bytes = config->reg_bits / 8;
ctx->pad_bytes = config->pad_bits / 8;
ctx->clk = ERR_PTR(-ENODEV);

if (clk_id == NULL)
Expand Down
Loading

0 comments on commit c6b38ec

Please sign in to comment.