Loading drivers/base/regmap/internal.h +3 −2 Original line number Diff line number Diff line Loading @@ -105,8 +105,8 @@ struct regmap { bool defer_caching; u8 read_flag_mask; u8 write_flag_mask; unsigned long read_flag_mask; unsigned long write_flag_mask; /* number of bits to (left) shift the reg value when formatting*/ int reg_shift; Loading Loading @@ -173,6 +173,7 @@ struct regcache_ops { int (*drop)(struct regmap *map, unsigned int min, unsigned int max); }; bool regmap_cached(struct regmap *map, unsigned int reg); bool regmap_writeable(struct regmap *map, unsigned int reg); bool regmap_readable(struct regmap *map, unsigned int reg); bool regmap_volatile(struct regmap *map, unsigned int reg); Loading drivers/base/regmap/regmap-debugfs.c +13 −3 Original line number Diff line number Diff line Loading @@ -77,6 +77,17 @@ static void regmap_debugfs_free_dump_cache(struct regmap *map) } } static bool regmap_printable(struct regmap *map, unsigned int reg) { if (regmap_precious(map, reg)) return false; if (!regmap_readable(map, reg) && !regmap_cached(map, reg)) return false; return true; } /* * Work out where the start offset maps into register numbers, bearing * in mind that we suppress hidden registers. Loading Loading @@ -105,8 +116,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, if (list_empty(&map->debugfs_off_cache)) { for (; i <= map->max_register; i += map->reg_stride) { /* Skip unprinted registers, closing off cache entry */ if (!regmap_readable(map, i) || regmap_precious(map, i)) { if (!regmap_printable(map, i)) { if (c) { c->max = p - 1; c->max_reg = i - map->reg_stride; Loading Loading @@ -204,7 +214,7 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p); for (i = start_reg; i <= to; i += map->reg_stride) { if (!regmap_readable(map, i)) if (!regmap_readable(map, i) && !regmap_cached(map, i)) continue; if (regmap_precious(map, i)) Loading drivers/base/regmap/regmap.c +51 −13 Original line number Diff line number Diff line Loading @@ -93,6 +93,29 @@ bool regmap_writeable(struct regmap *map, unsigned int reg) return true; } bool regmap_cached(struct regmap *map, unsigned int reg) { int ret; unsigned int val; if (map->cache == REGCACHE_NONE) return false; if (!map->cache_ops) return false; if (map->max_register && reg > map->max_register) return false; map->lock(map->lock_arg); ret = regcache_read(map, reg, &val); map->unlock(map->lock_arg); if (ret) return false; return true; } bool regmap_readable(struct regmap *map, unsigned int reg) { if (!map->reg_read) Loading Loading @@ -749,6 +772,9 @@ struct regmap *__regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_reg = regmap_format_16_be; break; case REGMAP_ENDIAN_LITTLE: map->format.format_reg = regmap_format_16_le; break; case REGMAP_ENDIAN_NATIVE: map->format.format_reg = regmap_format_16_native; break; Loading @@ -768,6 +794,9 @@ struct regmap *__regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_reg = regmap_format_32_be; break; case REGMAP_ENDIAN_LITTLE: map->format.format_reg = regmap_format_32_le; break; case REGMAP_ENDIAN_NATIVE: map->format.format_reg = regmap_format_32_native; break; Loading @@ -782,6 +811,9 @@ struct regmap *__regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_reg = regmap_format_64_be; break; case REGMAP_ENDIAN_LITTLE: map->format.format_reg = regmap_format_64_le; break; case REGMAP_ENDIAN_NATIVE: map->format.format_reg = regmap_format_64_native; break; Loading Loading @@ -1296,12 +1328,26 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, return 0; } static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes, unsigned long mask) { u8 *buf; int i; if (!mask || !map->work_buf) return; buf = map->work_buf; for (i = 0; i < max_bytes; i++) buf[i] |= (mask >> (8 * i)) & 0xff; } int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { struct regmap_range_node *range; unsigned long flags; u8 *u8 = map->work_buf; void *work_val = map->work_buf + map->format.reg_bytes + map->format.pad_bytes; void *buf; Loading Loading @@ -1370,8 +1416,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, } map->format.format_reg(map->work_buf, reg, map->reg_shift); u8[0] |= map->write_flag_mask; regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, map->write_flag_mask); /* * Essentially all I/O mechanisms will be faster with a single Loading Loading @@ -2251,7 +2297,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, unsigned int val_len) { struct regmap_range_node *range; u8 *u8 = map->work_buf; int ret; WARN_ON(!map->bus); Loading @@ -2268,15 +2313,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, } map->format.format_reg(map->work_buf, reg, map->reg_shift); /* * Some buses or devices flag reads by setting the high bits in the * register address; since it's always the high bits for all * current formats we can do this here rather than in * formatting. This may break if we get interesting formats. */ u8[0] |= map->read_flag_mask; regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, map->read_flag_mask); trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); ret = map->bus->read(map->bus_context, map->work_buf, Loading include/linux/regmap.h +4 −4 Original line number Diff line number Diff line Loading @@ -241,9 +241,9 @@ typedef void (*regmap_unlock)(void *); * register cache support). * @num_reg_defaults: Number of elements in reg_defaults. * * @read_flag_mask: Mask to be set in the top byte of the register when doing * @read_flag_mask: Mask to be set in the top bytes of the register when doing * a read. * @write_flag_mask: Mask to be set in the top byte of the register when doing * @write_flag_mask: Mask to be set in the top bytes of the register when doing * a write. If both read_flag_mask and write_flag_mask are * empty the regmap_bus default masks are used. * @use_single_rw: If set, converts the bulk read and write operations into Loading Loading @@ -299,8 +299,8 @@ struct regmap_config { const void *reg_defaults_raw; unsigned int num_reg_defaults_raw; u8 read_flag_mask; u8 write_flag_mask; unsigned long read_flag_mask; unsigned long write_flag_mask; bool use_single_rw; bool can_multi_write; Loading Loading
drivers/base/regmap/internal.h +3 −2 Original line number Diff line number Diff line Loading @@ -105,8 +105,8 @@ struct regmap { bool defer_caching; u8 read_flag_mask; u8 write_flag_mask; unsigned long read_flag_mask; unsigned long write_flag_mask; /* number of bits to (left) shift the reg value when formatting*/ int reg_shift; Loading Loading @@ -173,6 +173,7 @@ struct regcache_ops { int (*drop)(struct regmap *map, unsigned int min, unsigned int max); }; bool regmap_cached(struct regmap *map, unsigned int reg); bool regmap_writeable(struct regmap *map, unsigned int reg); bool regmap_readable(struct regmap *map, unsigned int reg); bool regmap_volatile(struct regmap *map, unsigned int reg); Loading
drivers/base/regmap/regmap-debugfs.c +13 −3 Original line number Diff line number Diff line Loading @@ -77,6 +77,17 @@ static void regmap_debugfs_free_dump_cache(struct regmap *map) } } static bool regmap_printable(struct regmap *map, unsigned int reg) { if (regmap_precious(map, reg)) return false; if (!regmap_readable(map, reg) && !regmap_cached(map, reg)) return false; return true; } /* * Work out where the start offset maps into register numbers, bearing * in mind that we suppress hidden registers. Loading Loading @@ -105,8 +116,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, if (list_empty(&map->debugfs_off_cache)) { for (; i <= map->max_register; i += map->reg_stride) { /* Skip unprinted registers, closing off cache entry */ if (!regmap_readable(map, i) || regmap_precious(map, i)) { if (!regmap_printable(map, i)) { if (c) { c->max = p - 1; c->max_reg = i - map->reg_stride; Loading Loading @@ -204,7 +214,7 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p); for (i = start_reg; i <= to; i += map->reg_stride) { if (!regmap_readable(map, i)) if (!regmap_readable(map, i) && !regmap_cached(map, i)) continue; if (regmap_precious(map, i)) Loading
drivers/base/regmap/regmap.c +51 −13 Original line number Diff line number Diff line Loading @@ -93,6 +93,29 @@ bool regmap_writeable(struct regmap *map, unsigned int reg) return true; } bool regmap_cached(struct regmap *map, unsigned int reg) { int ret; unsigned int val; if (map->cache == REGCACHE_NONE) return false; if (!map->cache_ops) return false; if (map->max_register && reg > map->max_register) return false; map->lock(map->lock_arg); ret = regcache_read(map, reg, &val); map->unlock(map->lock_arg); if (ret) return false; return true; } bool regmap_readable(struct regmap *map, unsigned int reg) { if (!map->reg_read) Loading Loading @@ -749,6 +772,9 @@ struct regmap *__regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_reg = regmap_format_16_be; break; case REGMAP_ENDIAN_LITTLE: map->format.format_reg = regmap_format_16_le; break; case REGMAP_ENDIAN_NATIVE: map->format.format_reg = regmap_format_16_native; break; Loading @@ -768,6 +794,9 @@ struct regmap *__regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_reg = regmap_format_32_be; break; case REGMAP_ENDIAN_LITTLE: map->format.format_reg = regmap_format_32_le; break; case REGMAP_ENDIAN_NATIVE: map->format.format_reg = regmap_format_32_native; break; Loading @@ -782,6 +811,9 @@ struct regmap *__regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_reg = regmap_format_64_be; break; case REGMAP_ENDIAN_LITTLE: map->format.format_reg = regmap_format_64_le; break; case REGMAP_ENDIAN_NATIVE: map->format.format_reg = regmap_format_64_native; break; Loading Loading @@ -1296,12 +1328,26 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, return 0; } static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes, unsigned long mask) { u8 *buf; int i; if (!mask || !map->work_buf) return; buf = map->work_buf; for (i = 0; i < max_bytes; i++) buf[i] |= (mask >> (8 * i)) & 0xff; } int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { struct regmap_range_node *range; unsigned long flags; u8 *u8 = map->work_buf; void *work_val = map->work_buf + map->format.reg_bytes + map->format.pad_bytes; void *buf; Loading Loading @@ -1370,8 +1416,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, } map->format.format_reg(map->work_buf, reg, map->reg_shift); u8[0] |= map->write_flag_mask; regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, map->write_flag_mask); /* * Essentially all I/O mechanisms will be faster with a single Loading Loading @@ -2251,7 +2297,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, unsigned int val_len) { struct regmap_range_node *range; u8 *u8 = map->work_buf; int ret; WARN_ON(!map->bus); Loading @@ -2268,15 +2313,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, } map->format.format_reg(map->work_buf, reg, map->reg_shift); /* * Some buses or devices flag reads by setting the high bits in the * register address; since it's always the high bits for all * current formats we can do this here rather than in * formatting. This may break if we get interesting formats. */ u8[0] |= map->read_flag_mask; regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, map->read_flag_mask); trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); ret = map->bus->read(map->bus_context, map->work_buf, Loading
include/linux/regmap.h +4 −4 Original line number Diff line number Diff line Loading @@ -241,9 +241,9 @@ typedef void (*regmap_unlock)(void *); * register cache support). * @num_reg_defaults: Number of elements in reg_defaults. * * @read_flag_mask: Mask to be set in the top byte of the register when doing * @read_flag_mask: Mask to be set in the top bytes of the register when doing * a read. * @write_flag_mask: Mask to be set in the top byte of the register when doing * @write_flag_mask: Mask to be set in the top bytes of the register when doing * a write. If both read_flag_mask and write_flag_mask are * empty the regmap_bus default masks are used. * @use_single_rw: If set, converts the bulk read and write operations into Loading Loading @@ -299,8 +299,8 @@ struct regmap_config { const void *reg_defaults_raw; unsigned int num_reg_defaults_raw; u8 read_flag_mask; u8 write_flag_mask; unsigned long read_flag_mask; unsigned long write_flag_mask; bool use_single_rw; bool can_multi_write; Loading