diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/regmap/regmap-debugfs.c | 4 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 25 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 21 |
3 files changed, 39 insertions, 11 deletions
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 53495753fbdb..6c2652a8ad50 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -85,8 +85,8 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, unsigned int reg_offset; /* Suppress the cache if we're using a subrange */ - if (from) - return from; + if (base) + return base; /* * If we don't have a cache build one so we don't have to do a diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 1643e889bafc..d10456ffd811 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -418,6 +418,31 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, reg, ret); goto err_alloc; } + + if (!chip->init_ack_masked) + continue; + + /* Ack masked but set interrupts */ + reg = chip->status_base + + (i * map->reg_stride * d->irq_reg_stride); + ret = regmap_read(map, reg, &d->status_buf[i]); + if (ret != 0) { + dev_err(map->dev, "Failed to read IRQ status: %d\n", + ret); + goto err_alloc; + } + + if (d->status_buf[i] && chip->ack_base) { + reg = chip->ack_base + + (i * map->reg_stride * d->irq_reg_stride); + ret = regmap_write(map, reg, + d->status_buf[i] & d->mask_buf[i]); + if (ret != 0) { + dev_err(map->dev, "Failed to ack 0x%x: %d\n", + reg, ret); + goto err_alloc; + } + } } /* Wake is disabled by default */ diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 0e85367e504d..aaf4e1372980 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -687,6 +687,10 @@ skip_format_initialization: unsigned win_max = win_min + config->ranges[j].window_len - 1; + /* Allow data window inside its own virtual range */ + if (j == i) + continue; + if (range_cfg->range_min <= sel_reg && sel_reg <= range_cfg->range_max) { dev_err(map->dev, @@ -1891,13 +1895,10 @@ EXPORT_SYMBOL_GPL(regmap_async_complete); int regmap_register_patch(struct regmap *map, const struct reg_default *regs, int num_regs) { + struct reg_default *p; int i, ret; bool bypass; - /* If needed the implementation can be extended to support this */ - if (map->patch) - return -EBUSY; - map->lock(map->lock_arg); bypass = map->cache_bypass; @@ -1914,11 +1915,13 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, } } - map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL); - if (map->patch != NULL) { - memcpy(map->patch, regs, - num_regs * sizeof(struct reg_default)); - map->patch_regs = num_regs; + p = krealloc(map->patch, + sizeof(struct reg_default) * (map->patch_regs + num_regs), + GFP_KERNEL); + if (p) { + memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs)); + map->patch = p; + map->patch_regs += num_regs; } else { ret = -ENOMEM; } |