Skip to content

Commit d77e745

Browse files
Marek Vasutbroonie
authored andcommitted
regmap: Add bulk read/write callbacks into regmap_config
Currently the regmap_config structure only allows the user to implement single element register read/write using .reg_read/.reg_write callbacks. The regmap_bus already implements bulk counterparts of both, and is being misused as a workaround for the missing bulk read/write callbacks in regmap_config by a couple of drivers. To stop this misuse, add the bulk read/write callbacks to regmap_config and call them from the regmap core code. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Jagan Teki <jagan@amarulasolutions.com> Cc: Mark Brown <broonie@kernel.org> Cc: Maxime Ripard <maxime@cerno.tech> Cc: Robert Foss <robert.foss@linaro.org> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Thomas Zimmermann <tzimmermann@suse.de> To: dri-devel@lists.freedesktop.org Link: https://lore.kernel.org/r/20220430025145.640305-1-marex@denx.de Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 3123109 commit d77e745

3 files changed

Lines changed: 56 additions & 36 deletions

File tree

drivers/base/regmap/internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ struct regmap {
110110
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
111111
int (*reg_update_bits)(void *context, unsigned int reg,
112112
unsigned int mask, unsigned int val);
113+
/* Bulk read/write */
114+
int (*read)(void *context, const void *reg_buf, size_t reg_size,
115+
void *val_buf, size_t val_size);
116+
int (*write)(void *context, const void *data, size_t count);
113117

114118
bool defer_caching;
115119

drivers/base/regmap/regmap.c

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -838,12 +838,15 @@ struct regmap *__regmap_init(struct device *dev,
838838
map->reg_stride_order = ilog2(map->reg_stride);
839839
else
840840
map->reg_stride_order = -1;
841-
map->use_single_read = config->use_single_read || !bus || !bus->read;
842-
map->use_single_write = config->use_single_write || !bus || !bus->write;
843-
map->can_multi_write = config->can_multi_write && bus && bus->write;
841+
map->use_single_read = config->use_single_read || !(config->read || (bus && bus->read));
842+
map->use_single_write = config->use_single_write || !(config->write || (bus && bus->write));
843+
map->can_multi_write = config->can_multi_write && (config->write || (bus && bus->write));
844844
if (bus) {
845845
map->max_raw_read = bus->max_raw_read;
846846
map->max_raw_write = bus->max_raw_write;
847+
} else if (config->max_raw_read && config->max_raw_write) {
848+
map->max_raw_read = config->max_raw_read;
849+
map->max_raw_write = config->max_raw_write;
847850
}
848851
map->dev = dev;
849852
map->bus = bus;
@@ -877,7 +880,16 @@ struct regmap *__regmap_init(struct device *dev,
877880
map->read_flag_mask = bus->read_flag_mask;
878881
}
879882

880-
if (!bus) {
883+
if (config && config->read && config->write) {
884+
map->reg_read = _regmap_bus_read;
885+
886+
/* Bulk read/write */
887+
map->read = config->read;
888+
map->write = config->write;
889+
890+
reg_endian = REGMAP_ENDIAN_NATIVE;
891+
val_endian = REGMAP_ENDIAN_NATIVE;
892+
} else if (!bus) {
881893
map->reg_read = config->reg_read;
882894
map->reg_write = config->reg_write;
883895
map->reg_update_bits = config->reg_update_bits;
@@ -894,10 +906,13 @@ struct regmap *__regmap_init(struct device *dev,
894906
} else {
895907
map->reg_read = _regmap_bus_read;
896908
map->reg_update_bits = bus->reg_update_bits;
897-
}
909+
/* Bulk read/write */
910+
map->read = bus->read;
911+
map->write = bus->write;
898912

899-
reg_endian = regmap_get_reg_endian(bus, config);
900-
val_endian = regmap_get_val_endian(dev, bus, config);
913+
reg_endian = regmap_get_reg_endian(bus, config);
914+
val_endian = regmap_get_val_endian(dev, bus, config);
915+
}
901916

902917
switch (config->reg_bits + map->reg_shift) {
903918
case 2:
@@ -1671,8 +1686,6 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
16711686
size_t len;
16721687
int i;
16731688

1674-
WARN_ON(!map->bus);
1675-
16761689
/* Check for unwritable or noinc registers in range
16771690
* before we start
16781691
*/
@@ -1754,7 +1767,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
17541767
val = work_val;
17551768
}
17561769

1757-
if (map->async && map->bus->async_write) {
1770+
if (map->async && map->bus && map->bus->async_write) {
17581771
struct regmap_async *async;
17591772

17601773
trace_regmap_async_write_start(map, reg, val_len);
@@ -1822,10 +1835,10 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
18221835
* write.
18231836
*/
18241837
if (val == work_val)
1825-
ret = map->bus->write(map->bus_context, map->work_buf,
1826-
map->format.reg_bytes +
1827-
map->format.pad_bytes +
1828-
val_len);
1838+
ret = map->write(map->bus_context, map->work_buf,
1839+
map->format.reg_bytes +
1840+
map->format.pad_bytes +
1841+
val_len);
18291842
else if (map->bus->gather_write)
18301843
ret = map->bus->gather_write(map->bus_context, map->work_buf,
18311844
map->format.reg_bytes +
@@ -1844,7 +1857,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
18441857
memcpy(buf, map->work_buf, map->format.reg_bytes);
18451858
memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
18461859
val, val_len);
1847-
ret = map->bus->write(map->bus_context, buf, len);
1860+
ret = map->write(map->bus_context, buf, len);
18481861

18491862
kfree(buf);
18501863
} else if (ret != 0 && !map->cache_bypass && map->format.parse_val) {
@@ -1901,7 +1914,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
19011914
struct regmap_range_node *range;
19021915
struct regmap *map = context;
19031916

1904-
WARN_ON(!map->bus || !map->format.format_write);
1917+
WARN_ON(!map->format.format_write);
19051918

19061919
range = _regmap_range_lookup(map, reg);
19071920
if (range) {
@@ -1916,8 +1929,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
19161929

19171930
trace_regmap_hw_write_start(map, reg, 1);
19181931

1919-
ret = map->bus->write(map->bus_context, map->work_buf,
1920-
map->format.buf_size);
1932+
ret = map->write(map->bus_context, map->work_buf, map->format.buf_size);
19211933

19221934
trace_regmap_hw_write_done(map, reg, 1);
19231935

@@ -1937,7 +1949,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
19371949
{
19381950
struct regmap *map = context;
19391951

1940-
WARN_ON(!map->bus || !map->format.format_val);
1952+
WARN_ON(!map->format.format_val);
19411953

19421954
map->format.format_val(map->work_buf + map->format.reg_bytes
19431955
+ map->format.pad_bytes, val, 0);
@@ -1951,7 +1963,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
19511963

19521964
static inline void *_regmap_map_get_context(struct regmap *map)
19531965
{
1954-
return (map->bus) ? map : map->bus_context;
1966+
return (map->bus || (!map->bus && map->read)) ? map : map->bus_context;
19551967
}
19561968

19571969
int _regmap_write(struct regmap *map, unsigned int reg,
@@ -2363,7 +2375,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
23632375
u8 = buf;
23642376
*u8 |= map->write_flag_mask;
23652377

2366-
ret = map->bus->write(map->bus_context, buf, len);
2378+
ret = map->write(map->bus_context, buf, len);
23672379

23682380
kfree(buf);
23692381

@@ -2669,9 +2681,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
26692681
struct regmap_range_node *range;
26702682
int ret;
26712683

2672-
WARN_ON(!map->bus);
2673-
2674-
if (!map->bus || !map->bus->read)
2684+
if (!map->read)
26752685
return -EINVAL;
26762686

26772687
range = _regmap_range_lookup(map, reg);
@@ -2689,9 +2699,9 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
26892699
map->read_flag_mask);
26902700
trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
26912701

2692-
ret = map->bus->read(map->bus_context, map->work_buf,
2693-
map->format.reg_bytes + map->format.pad_bytes,
2694-
val, val_len);
2702+
ret = map->read(map->bus_context, map->work_buf,
2703+
map->format.reg_bytes + map->format.pad_bytes,
2704+
val, val_len);
26952705

26962706
trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes);
26972707

@@ -2802,8 +2812,6 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
28022812
unsigned int v;
28032813
int ret, i;
28042814

2805-
if (!map->bus)
2806-
return -EINVAL;
28072815
if (val_len % map->format.val_bytes)
28082816
return -EINVAL;
28092817
if (!IS_ALIGNED(reg, map->reg_stride))
@@ -2818,7 +2826,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
28182826
size_t chunk_count, chunk_bytes;
28192827
size_t chunk_regs = val_count;
28202828

2821-
if (!map->bus->read) {
2829+
if (!map->read) {
28222830
ret = -ENOTSUPP;
28232831
goto out;
28242832
}
@@ -2878,7 +2886,7 @@ EXPORT_SYMBOL_GPL(regmap_raw_read);
28782886
* @val: Pointer to data buffer
28792887
* @val_len: Length of output buffer in bytes.
28802888
*
2881-
* The regmap API usually assumes that bulk bus read operations will read a
2889+
* The regmap API usually assumes that bulk read operations will read a
28822890
* range of registers. Some devices have certain registers for which a read
28832891
* operation read will read from an internal FIFO.
28842892
*
@@ -2896,10 +2904,6 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg,
28962904
size_t read_len;
28972905
int ret;
28982906

2899-
if (!map->bus)
2900-
return -EINVAL;
2901-
if (!map->bus->read)
2902-
return -ENOTSUPP;
29032907
if (val_len % map->format.val_bytes)
29042908
return -EINVAL;
29052909
if (!IS_ALIGNED(reg, map->reg_stride))
@@ -3013,7 +3017,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
30133017
if (val_count == 0)
30143018
return -EINVAL;
30153019

3016-
if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {
3020+
if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {
30173021
ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
30183022
if (ret != 0)
30193023
return ret;

include/linux/regmap.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ typedef void (*regmap_unlock)(void *);
299299
* if the function require special handling with lock and reg
300300
* handling and the operation cannot be represented as a simple
301301
* update_bits operation on a bus such as SPI, I2C, etc.
302+
* @read: Optional callback that if filled will be used to perform all the
303+
* bulk reads from the registers. Data is returned in the buffer used
304+
* to transmit data.
305+
* @write: Same as above for writing.
306+
* @max_raw_read: Max raw read size that can be used on the device.
307+
* @max_raw_write: Max raw write size that can be used on the device.
302308
* @fast_io: Register IO is fast. Use a spinlock instead of a mutex
303309
* to perform locking. This field is ignored if custom lock/unlock
304310
* functions are used (see fields lock/unlock of struct regmap_config).
@@ -385,6 +391,12 @@ struct regmap_config {
385391
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
386392
int (*reg_update_bits)(void *context, unsigned int reg,
387393
unsigned int mask, unsigned int val);
394+
/* Bulk read/write */
395+
int (*read)(void *context, const void *reg_buf, size_t reg_size,
396+
void *val_buf, size_t val_size);
397+
int (*write)(void *context, const void *data, size_t count);
398+
size_t max_raw_read;
399+
size_t max_raw_write;
388400

389401
bool fast_io;
390402

0 commit comments

Comments
 (0)