diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2014-02-24 15:32:28 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2014-02-24 15:32:28 +1100 |
commit | 1fca17280e5791f7a0b3da451a4a129a8d508c58 (patch) | |
tree | 28d44f4c58669d5dc66cdcc686e393922714508b | |
parent | 4ea6c6074e0c12a06da56c5680d6d80747ee47d8 (diff) | |
parent | e73c4113b0bf8831f69eb287b67e7db2b2bab77d (diff) |
Merge remote-tracking branch 'regmap/for-next'
-rw-r--r-- | drivers/base/regmap/regcache.c | 8 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-debugfs.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 62 | ||||
-rw-r--r-- | include/linux/regmap.h | 2 |
5 files changed, 48 insertions, 28 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index d4dd77134814..c6b1ac1c5982 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -312,10 +312,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", @@ -636,10 +632,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; diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index c5471cd6ebb7..45d812c0ea77 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -511,7 +511,7 @@ void regmap_debugfs_init(struct regmap *map, const char *name) debugfs_create_file("range", 0400, map->debugfs, map, ®map_reg_ranges_fops); - if (map->max_register) { + if (map->max_register || regmap_readable(map, 0)) { debugfs_create_file("registers", 0400, map->debugfs, map, ®map_map_fops); debugfs_create_file("access", 0400, map->debugfs, diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 82692068d3cb..52ce0c17c68b 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -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); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 6a19515f8a45..2b4e72fa2f49 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -380,6 +380,28 @@ static void regmap_range_exit(struct regmap *map) kfree(map->selector_work_buf); } +int regmap_attach_dev(struct device *dev, struct regmap *map, + const struct regmap_config *config) +{ + struct regmap **m; + + map->dev = dev; + + regmap_debugfs_init(map, config->name); + + /* Add a devres resource for dev_get_regmap() */ + m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); + if (!m) { + regmap_debugfs_exit(map); + return -ENOMEM; + } + *m = map; + devres_add(dev, m); + + return 0; +} +EXPORT_SYMBOL_GPL(regmap_attach_dev); + /** * regmap_init(): Initialise register map * @@ -397,7 +419,7 @@ struct regmap *regmap_init(struct device *dev, void *bus_context, const struct regmap_config *config) { - struct regmap *map, **m; + struct regmap *map; int ret = -EINVAL; enum regmap_endian reg_endian, val_endian; int i, j; @@ -718,7 +740,7 @@ skip_format_initialization: new->window_start = range_cfg->window_start; new->window_len = range_cfg->window_len; - if (_regmap_range_add(map, new) == false) { + if (!_regmap_range_add(map, new)) { dev_err(map->dev, "Failed to add range %d\n", i); kfree(new); goto err_range; @@ -734,25 +756,18 @@ skip_format_initialization: } } - regmap_debugfs_init(map, config->name); - ret = regcache_init(map, config); if (ret != 0) goto err_range; - /* Add a devres resource for dev_get_regmap() */ - m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); - if (!m) { - ret = -ENOMEM; - goto err_debugfs; - } - *m = map; - devres_add(dev, m); + if (dev) + ret = regmap_attach_dev(dev, map, config); + if (ret != 0) + goto err_regcache; return map; -err_debugfs: - regmap_debugfs_exit(map); +err_regcache: regcache_exit(map); err_range: regmap_range_exit(map); @@ -1736,6 +1751,9 @@ static int _regmap_read(struct regmap *map, unsigned int reg, if (map->cache_only) return -EBUSY; + if (!regmap_readable(map, reg)) + return -EIO; + ret = map->reg_read(context, reg, val); if (ret == 0) { #ifdef LOG_DEVICE @@ -1966,9 +1984,11 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, if (tmp != orig) { ret = _regmap_write(map, reg, tmp); - *change = true; + if (change) + *change = true; } else { - *change = false; + if (change) + *change = false; } return ret; @@ -1987,11 +2007,10 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, int regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val) { - bool change; int ret; map->lock(map->lock_arg); - ret = _regmap_update_bits(map, reg, mask, val, &change); + ret = _regmap_update_bits(map, reg, mask, val, NULL); map->unlock(map->lock_arg); return ret; @@ -2016,14 +2035,13 @@ EXPORT_SYMBOL_GPL(regmap_update_bits); int regmap_update_bits_async(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val) { - bool change; int ret; map->lock(map->lock_arg); map->async = true; - ret = _regmap_update_bits(map, reg, mask, val, &change); + ret = _regmap_update_bits(map, reg, mask, val, NULL); map->async = false; @@ -2194,6 +2212,10 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, /* Write out first; it's useful to apply even if we fail later. */ for (i = 0; i < num_regs; i++) { + if (regs[i].reg % map->reg_stride) { + ret = -EINVAL; + goto out; + } ret = _regmap_write(map, regs[i].reg, regs[i].def); if (ret != 0) { dev_err(map->dev, "Failed to write %x = %x: %d\n", diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 4149f1a9b003..fa4d079fa44c 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -317,6 +317,8 @@ struct regmap *regmap_init(struct device *dev, const struct regmap_bus *bus, void *bus_context, const struct regmap_config *config); +int regmap_attach_dev(struct device *dev, struct regmap *map, + const struct regmap_config *config); struct regmap *regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config); struct regmap *regmap_init_spi(struct spi_device *dev, |