aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/internal.h5
-rw-r--r--drivers/base/regmap/regmap-debugfs.c16
-rw-r--r--drivers/base/regmap/regmap.c64
-rw-r--r--include/linux/regmap.h8
4 files changed, 71 insertions, 22 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index a0380338946a..2a4435d76028 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -105,8 +105,8 @@ struct regmap {
105 105
106 bool defer_caching; 106 bool defer_caching;
107 107
108 u8 read_flag_mask; 108 unsigned long read_flag_mask;
109 u8 write_flag_mask; 109 unsigned long write_flag_mask;
110 110
111 /* number of bits to (left) shift the reg value when formatting*/ 111 /* number of bits to (left) shift the reg value when formatting*/
112 int reg_shift; 112 int reg_shift;
@@ -173,6 +173,7 @@ struct regcache_ops {
173 int (*drop)(struct regmap *map, unsigned int min, unsigned int max); 173 int (*drop)(struct regmap *map, unsigned int min, unsigned int max);
174}; 174};
175 175
176bool regmap_cached(struct regmap *map, unsigned int reg);
176bool regmap_writeable(struct regmap *map, unsigned int reg); 177bool regmap_writeable(struct regmap *map, unsigned int reg);
177bool regmap_readable(struct regmap *map, unsigned int reg); 178bool regmap_readable(struct regmap *map, unsigned int reg);
178bool regmap_volatile(struct regmap *map, unsigned int reg); 179bool regmap_volatile(struct regmap *map, unsigned int reg);
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 1ee3d40861c7..36ce3511c733 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -77,6 +77,17 @@ static void regmap_debugfs_free_dump_cache(struct regmap *map)
77 } 77 }
78} 78}
79 79
80static bool regmap_printable(struct regmap *map, unsigned int reg)
81{
82 if (regmap_precious(map, reg))
83 return false;
84
85 if (!regmap_readable(map, reg) && !regmap_cached(map, reg))
86 return false;
87
88 return true;
89}
90
80/* 91/*
81 * Work out where the start offset maps into register numbers, bearing 92 * Work out where the start offset maps into register numbers, bearing
82 * in mind that we suppress hidden registers. 93 * in mind that we suppress hidden registers.
@@ -105,8 +116,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
105 if (list_empty(&map->debugfs_off_cache)) { 116 if (list_empty(&map->debugfs_off_cache)) {
106 for (; i <= map->max_register; i += map->reg_stride) { 117 for (; i <= map->max_register; i += map->reg_stride) {
107 /* Skip unprinted registers, closing off cache entry */ 118 /* Skip unprinted registers, closing off cache entry */
108 if (!regmap_readable(map, i) || 119 if (!regmap_printable(map, i)) {
109 regmap_precious(map, i)) {
110 if (c) { 120 if (c) {
111 c->max = p - 1; 121 c->max = p - 1;
112 c->max_reg = i - map->reg_stride; 122 c->max_reg = i - map->reg_stride;
@@ -204,7 +214,7 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
204 start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p); 214 start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
205 215
206 for (i = start_reg; i <= to; i += map->reg_stride) { 216 for (i = start_reg; i <= to; i += map->reg_stride) {
207 if (!regmap_readable(map, i)) 217 if (!regmap_readable(map, i) && !regmap_cached(map, i))
208 continue; 218 continue;
209 219
210 if (regmap_precious(map, i)) 220 if (regmap_precious(map, i))
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e964d068874d..ae63bb0875ea 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -93,6 +93,29 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
93 return true; 93 return true;
94} 94}
95 95
96bool regmap_cached(struct regmap *map, unsigned int reg)
97{
98 int ret;
99 unsigned int val;
100
101 if (map->cache == REGCACHE_NONE)
102 return false;
103
104 if (!map->cache_ops)
105 return false;
106
107 if (map->max_register && reg > map->max_register)
108 return false;
109
110 map->lock(map->lock_arg);
111 ret = regcache_read(map, reg, &val);
112 map->unlock(map->lock_arg);
113 if (ret)
114 return false;
115
116 return true;
117}
118
96bool regmap_readable(struct regmap *map, unsigned int reg) 119bool regmap_readable(struct regmap *map, unsigned int reg)
97{ 120{
98 if (!map->reg_read) 121 if (!map->reg_read)
@@ -749,6 +772,9 @@ struct regmap *__regmap_init(struct device *dev,
749 case REGMAP_ENDIAN_BIG: 772 case REGMAP_ENDIAN_BIG:
750 map->format.format_reg = regmap_format_16_be; 773 map->format.format_reg = regmap_format_16_be;
751 break; 774 break;
775 case REGMAP_ENDIAN_LITTLE:
776 map->format.format_reg = regmap_format_16_le;
777 break;
752 case REGMAP_ENDIAN_NATIVE: 778 case REGMAP_ENDIAN_NATIVE:
753 map->format.format_reg = regmap_format_16_native; 779 map->format.format_reg = regmap_format_16_native;
754 break; 780 break;
@@ -768,6 +794,9 @@ struct regmap *__regmap_init(struct device *dev,
768 case REGMAP_ENDIAN_BIG: 794 case REGMAP_ENDIAN_BIG:
769 map->format.format_reg = regmap_format_32_be; 795 map->format.format_reg = regmap_format_32_be;
770 break; 796 break;
797 case REGMAP_ENDIAN_LITTLE:
798 map->format.format_reg = regmap_format_32_le;
799 break;
771 case REGMAP_ENDIAN_NATIVE: 800 case REGMAP_ENDIAN_NATIVE:
772 map->format.format_reg = regmap_format_32_native; 801 map->format.format_reg = regmap_format_32_native;
773 break; 802 break;
@@ -782,6 +811,9 @@ struct regmap *__regmap_init(struct device *dev,
782 case REGMAP_ENDIAN_BIG: 811 case REGMAP_ENDIAN_BIG:
783 map->format.format_reg = regmap_format_64_be; 812 map->format.format_reg = regmap_format_64_be;
784 break; 813 break;
814 case REGMAP_ENDIAN_LITTLE:
815 map->format.format_reg = regmap_format_64_le;
816 break;
785 case REGMAP_ENDIAN_NATIVE: 817 case REGMAP_ENDIAN_NATIVE:
786 map->format.format_reg = regmap_format_64_native; 818 map->format.format_reg = regmap_format_64_native;
787 break; 819 break;
@@ -1296,12 +1328,26 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
1296 return 0; 1328 return 0;
1297} 1329}
1298 1330
1331static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes,
1332 unsigned long mask)
1333{
1334 u8 *buf;
1335 int i;
1336
1337 if (!mask || !map->work_buf)
1338 return;
1339
1340 buf = map->work_buf;
1341
1342 for (i = 0; i < max_bytes; i++)
1343 buf[i] |= (mask >> (8 * i)) & 0xff;
1344}
1345
1299int _regmap_raw_write(struct regmap *map, unsigned int reg, 1346int _regmap_raw_write(struct regmap *map, unsigned int reg,
1300 const void *val, size_t val_len) 1347 const void *val, size_t val_len)
1301{ 1348{
1302 struct regmap_range_node *range; 1349 struct regmap_range_node *range;
1303 unsigned long flags; 1350 unsigned long flags;
1304 u8 *u8 = map->work_buf;
1305 void *work_val = map->work_buf + map->format.reg_bytes + 1351 void *work_val = map->work_buf + map->format.reg_bytes +
1306 map->format.pad_bytes; 1352 map->format.pad_bytes;
1307 void *buf; 1353 void *buf;
@@ -1370,8 +1416,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
1370 } 1416 }
1371 1417
1372 map->format.format_reg(map->work_buf, reg, map->reg_shift); 1418 map->format.format_reg(map->work_buf, reg, map->reg_shift);
1373 1419 regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
1374 u8[0] |= map->write_flag_mask; 1420 map->write_flag_mask);
1375 1421
1376 /* 1422 /*
1377 * Essentially all I/O mechanisms will be faster with a single 1423 * Essentially all I/O mechanisms will be faster with a single
@@ -2251,7 +2297,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2251 unsigned int val_len) 2297 unsigned int val_len)
2252{ 2298{
2253 struct regmap_range_node *range; 2299 struct regmap_range_node *range;
2254 u8 *u8 = map->work_buf;
2255 int ret; 2300 int ret;
2256 2301
2257 WARN_ON(!map->bus); 2302 WARN_ON(!map->bus);
@@ -2268,15 +2313,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2268 } 2313 }
2269 2314
2270 map->format.format_reg(map->work_buf, reg, map->reg_shift); 2315 map->format.format_reg(map->work_buf, reg, map->reg_shift);
2271 2316 regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
2272 /* 2317 map->read_flag_mask);
2273 * Some buses or devices flag reads by setting the high bits in the
2274 * register address; since it's always the high bits for all
2275 * current formats we can do this here rather than in
2276 * formatting. This may break if we get interesting formats.
2277 */
2278 u8[0] |= map->read_flag_mask;
2279
2280 trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); 2318 trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
2281 2319
2282 ret = map->bus->read(map->bus_context, map->work_buf, 2320 ret = map->bus->read(map->bus_context, map->work_buf,
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 2c12cc5af744..9adc7b21903d 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -241,9 +241,9 @@ typedef void (*regmap_unlock)(void *);
241 * register cache support). 241 * register cache support).
242 * @num_reg_defaults: Number of elements in reg_defaults. 242 * @num_reg_defaults: Number of elements in reg_defaults.
243 * 243 *
244 * @read_flag_mask: Mask to be set in the top byte of the register when doing 244 * @read_flag_mask: Mask to be set in the top bytes of the register when doing
245 * a read. 245 * a read.
246 * @write_flag_mask: Mask to be set in the top byte of the register when doing 246 * @write_flag_mask: Mask to be set in the top bytes of the register when doing
247 * a write. If both read_flag_mask and write_flag_mask are 247 * a write. If both read_flag_mask and write_flag_mask are
248 * empty the regmap_bus default masks are used. 248 * empty the regmap_bus default masks are used.
249 * @use_single_rw: If set, converts the bulk read and write operations into 249 * @use_single_rw: If set, converts the bulk read and write operations into
@@ -299,8 +299,8 @@ struct regmap_config {
299 const void *reg_defaults_raw; 299 const void *reg_defaults_raw;
300 unsigned int num_reg_defaults_raw; 300 unsigned int num_reg_defaults_raw;
301 301
302 u8 read_flag_mask; 302 unsigned long read_flag_mask;
303 u8 write_flag_mask; 303 unsigned long write_flag_mask;
304 304
305 bool use_single_rw; 305 bool use_single_rw;
306 bool can_multi_write; 306 bool can_multi_write;