regmap: add reg_read/reg_write callbacks to regmap_bus struct
authorBoris BREZILLON <boris.brezillon@free-electrons.com>
Thu, 17 Apr 2014 09:40:11 +0000 (11:40 +0200)
committerMark Brown <broonie@linaro.org>
Fri, 18 Apr 2014 15:07:22 +0000 (16:07 +0100)
Some busses do not support sending/receiving multiple registers in one go.
Such kind of busses just unpack the registers that have been previously
packed by the regmap core or pack registers that will be later unpacked by
the core code.

Add reg_write and reg_read callbacks in order to optimize access through
this kind of busses.

Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
drivers/base/regmap/regmap.c
include/linux/regmap.h

index 63e30ef096e2be5e16a1e989bba22dd3b6c69f8d..2209de0ceabcc6dc140eae86f56286dc06d3f331 100644 (file)
@@ -35,10 +35,14 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
                               unsigned int mask, unsigned int val,
                               bool *change);
 
+static int _regmap_bus_reg_read(void *context, unsigned int reg,
+                               unsigned int *val);
 static int _regmap_bus_read(void *context, unsigned int reg,
                            unsigned int *val);
 static int _regmap_bus_formatted_write(void *context, unsigned int reg,
                                       unsigned int val);
+static int _regmap_bus_reg_write(void *context, unsigned int reg,
+                                unsigned int val);
 static int _regmap_bus_raw_write(void *context, unsigned int reg,
                                 unsigned int val);
 
@@ -493,6 +497,12 @@ struct regmap *regmap_init(struct device *dev,
                map->reg_read  = config->reg_read;
                map->reg_write = config->reg_write;
 
+               map->defer_caching = false;
+               goto skip_format_initialization;
+       } else if (!bus->read || !bus->write) {
+               map->reg_read = _regmap_bus_reg_read;
+               map->reg_write = _regmap_bus_reg_write;
+
                map->defer_caching = false;
                goto skip_format_initialization;
        } else {
@@ -1284,6 +1294,14 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
        return ret;
 }
 
+static int _regmap_bus_reg_write(void *context, unsigned int reg,
+                                unsigned int val)
+{
+       struct regmap *map = context;
+
+       return map->bus->reg_write(map->bus_context, reg, val);
+}
+
 static int _regmap_bus_raw_write(void *context, unsigned int reg,
                                 unsigned int val)
 {
@@ -1925,6 +1943,14 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
        return ret;
 }
 
+static int _regmap_bus_reg_read(void *context, unsigned int reg,
+                               unsigned int *val)
+{
+       struct regmap *map = context;
+
+       return map->bus->reg_read(map->bus_context, reg, val);
+}
+
 static int _regmap_bus_read(void *context, unsigned int reg,
                            unsigned int *val)
 {
index 85691b9b4fa76a778db7f338874849c27d99d74c..7b0e4b425cdf3e66fb5163ae4557adc8c6a89f63 100644 (file)
@@ -276,6 +276,10 @@ typedef int (*regmap_hw_async_write)(void *context,
 typedef int (*regmap_hw_read)(void *context,
                              const void *reg_buf, size_t reg_size,
                              void *val_buf, size_t val_size);
+typedef int (*regmap_hw_reg_read)(void *context, unsigned int reg,
+                                 unsigned int *val);
+typedef int (*regmap_hw_reg_write)(void *context, unsigned int reg,
+                                  unsigned int val);
 typedef struct regmap_async *(*regmap_hw_async_alloc)(void);
 typedef void (*regmap_hw_free_context)(void *context);
 
@@ -309,7 +313,9 @@ struct regmap_bus {
        regmap_hw_write write;
        regmap_hw_gather_write gather_write;
        regmap_hw_async_write async_write;
+       regmap_hw_reg_write reg_write;
        regmap_hw_read read;
+       regmap_hw_reg_read reg_read;
        regmap_hw_free_context free_context;
        regmap_hw_async_alloc async_alloc;
        u8 read_flag_mask;