Re: [PATCH v3 3/3] regmap: Add "no-bus" option for regmap API

2013-01-28 Thread Mark Brown
On Sun, Jan 27, 2013 at 10:49:05AM -0800, Andrey Smirnov wrote:
> This commit adds provision for "no-bus" usage of the regmap API. In
> this configuration user can provide API with two callbacks 'reg_read'
> and 'reg_write' which are to be called when reads and writes to one of
> device's registers is performed. This is useful for devices that
> expose registers but whose register access sequence does not fit the 'bus'
> abstraction.

Great, thanks for doing this work - I've applied this now.


signature.asc
Description: Digital signature


Re: [PATCH v3 3/3] regmap: Add no-bus option for regmap API

2013-01-28 Thread Mark Brown
On Sun, Jan 27, 2013 at 10:49:05AM -0800, Andrey Smirnov wrote:
 This commit adds provision for no-bus usage of the regmap API. In
 this configuration user can provide API with two callbacks 'reg_read'
 and 'reg_write' which are to be called when reads and writes to one of
 device's registers is performed. This is useful for devices that
 expose registers but whose register access sequence does not fit the 'bus'
 abstraction.

Great, thanks for doing this work - I've applied this now.


signature.asc
Description: Digital signature


[PATCH v3 3/3] regmap: Add "no-bus" option for regmap API

2013-01-27 Thread Andrey Smirnov
This commit adds provision for "no-bus" usage of the regmap API. In
this configuration user can provide API with two callbacks 'reg_read'
and 'reg_write' which are to be called when reads and writes to one of
device's registers is performed. This is useful for devices that
expose registers but whose register access sequence does not fit the 'bus'
abstraction.

Signed-off-by: Andrey Smirnov 
---
 drivers/base/regmap/internal.h |2 ++
 drivers/base/regmap/regmap.c   |   58 +++-
 include/linux/regmap.h |   18 -
 3 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 51f0574..b55fde5 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -77,6 +77,8 @@ struct regmap {
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
 
+   bool defer_caching;
+
u8 read_flag_mask;
u8 write_flag_mask;
 
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6845a07..9592030 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -379,7 +379,7 @@ struct regmap *regmap_init(struct device *dev,
enum regmap_endian reg_endian, val_endian;
int i, j;
 
-   if (!bus || !config)
+   if (!config)
goto err;
 
map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -393,7 +393,8 @@ struct regmap *regmap_init(struct device *dev,
map->unlock = config->unlock;
map->lock_arg = config->lock_arg;
} else {
-   if (bus->fast_io) {
+   if ((bus && bus->fast_io) ||
+   config->fast_io) {
spin_lock_init(>spinlock);
map->lock = regmap_lock_spinlock;
map->unlock = regmap_unlock_spinlock;
@@ -433,11 +434,19 @@ struct regmap *regmap_init(struct device *dev,
if (config->read_flag_mask || config->write_flag_mask) {
map->read_flag_mask = config->read_flag_mask;
map->write_flag_mask = config->write_flag_mask;
-   } else {
+   } else if (bus) {
map->read_flag_mask = bus->read_flag_mask;
}
 
-   map->reg_read = _regmap_bus_read;
+   if (!bus) {
+   map->reg_read  = config->reg_read;
+   map->reg_write = config->reg_write;
+
+   map->defer_caching = false;
+   goto skip_format_initialization;
+   } else {
+   map->reg_read  = _regmap_bus_read;
+   }
 
reg_endian = config->reg_format_endian;
if (reg_endian == REGMAP_ENDIAN_DEFAULT)
@@ -584,10 +593,15 @@ struct regmap *regmap_init(struct device *dev,
goto err_map;
}
 
-   if (map->format.format_write)
+   if (map->format.format_write) {
+   map->defer_caching = false;
map->reg_write = _regmap_bus_formatted_write;
-   else if (map->format.format_val)
+   } else if (map->format.format_val) {
+   map->defer_caching = true;
map->reg_write = _regmap_bus_raw_write;
+   }
+
+skip_format_initialization:
 
map->range_tree = RB_ROOT;
for (i = 0; i < config->num_ranges; i++) {
@@ -790,7 +804,7 @@ void regmap_exit(struct regmap *map)
regcache_exit(map);
regmap_debugfs_exit(map);
regmap_range_exit(map);
-   if (map->bus->free_context)
+   if (map->bus && map->bus->free_context)
map->bus->free_context(map->bus_context);
kfree(map->work_buf);
kfree(map);
@@ -893,6 +907,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned 
int reg,
size_t len;
int i;
 
+   BUG_ON(!map->bus);
+
/* Check for unwritable registers before we start */
if (map->writeable_reg)
for (i = 0; i < val_len / map->format.val_bytes; i++)
@@ -1002,7 +1018,7 @@ static int _regmap_bus_formatted_write(void *context, 
unsigned int reg,
struct regmap_range_node *range;
struct regmap *map = context;
 
-   BUG_ON(!map->format.format_write);
+   BUG_ON(!map->bus || !map->format.format_write);
 
range = _regmap_range_lookup(map, reg);
if (range) {
@@ -1028,7 +1044,7 @@ static int _regmap_bus_raw_write(void *context, unsigned 
int reg,
 {
struct regmap *map = context;
 
-   BUG_ON(!map->format.format_val);
+   BUG_ON(!map->bus || !map->format.format_val);
 
map->format.format_val(map->work_buf + map->format.reg_bytes
   + map->format.pad_bytes, val, 0);
@@ -1039,12 +1055,18 @@ static int _regmap_bus_raw_write(void *context, 
unsigned int reg,
 map->format.val_bytes);
 }
 
+static inline void *_regmap_map_get_context(struct regmap 

[PATCH v3 3/3] regmap: Add no-bus option for regmap API

2013-01-27 Thread Andrey Smirnov
This commit adds provision for no-bus usage of the regmap API. In
this configuration user can provide API with two callbacks 'reg_read'
and 'reg_write' which are to be called when reads and writes to one of
device's registers is performed. This is useful for devices that
expose registers but whose register access sequence does not fit the 'bus'
abstraction.

Signed-off-by: Andrey Smirnov andrew.smir...@gmail.com
---
 drivers/base/regmap/internal.h |2 ++
 drivers/base/regmap/regmap.c   |   58 +++-
 include/linux/regmap.h |   18 -
 3 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 51f0574..b55fde5 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -77,6 +77,8 @@ struct regmap {
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
 
+   bool defer_caching;
+
u8 read_flag_mask;
u8 write_flag_mask;
 
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6845a07..9592030 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -379,7 +379,7 @@ struct regmap *regmap_init(struct device *dev,
enum regmap_endian reg_endian, val_endian;
int i, j;
 
-   if (!bus || !config)
+   if (!config)
goto err;
 
map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -393,7 +393,8 @@ struct regmap *regmap_init(struct device *dev,
map-unlock = config-unlock;
map-lock_arg = config-lock_arg;
} else {
-   if (bus-fast_io) {
+   if ((bus  bus-fast_io) ||
+   config-fast_io) {
spin_lock_init(map-spinlock);
map-lock = regmap_lock_spinlock;
map-unlock = regmap_unlock_spinlock;
@@ -433,11 +434,19 @@ struct regmap *regmap_init(struct device *dev,
if (config-read_flag_mask || config-write_flag_mask) {
map-read_flag_mask = config-read_flag_mask;
map-write_flag_mask = config-write_flag_mask;
-   } else {
+   } else if (bus) {
map-read_flag_mask = bus-read_flag_mask;
}
 
-   map-reg_read = _regmap_bus_read;
+   if (!bus) {
+   map-reg_read  = config-reg_read;
+   map-reg_write = config-reg_write;
+
+   map-defer_caching = false;
+   goto skip_format_initialization;
+   } else {
+   map-reg_read  = _regmap_bus_read;
+   }
 
reg_endian = config-reg_format_endian;
if (reg_endian == REGMAP_ENDIAN_DEFAULT)
@@ -584,10 +593,15 @@ struct regmap *regmap_init(struct device *dev,
goto err_map;
}
 
-   if (map-format.format_write)
+   if (map-format.format_write) {
+   map-defer_caching = false;
map-reg_write = _regmap_bus_formatted_write;
-   else if (map-format.format_val)
+   } else if (map-format.format_val) {
+   map-defer_caching = true;
map-reg_write = _regmap_bus_raw_write;
+   }
+
+skip_format_initialization:
 
map-range_tree = RB_ROOT;
for (i = 0; i  config-num_ranges; i++) {
@@ -790,7 +804,7 @@ void regmap_exit(struct regmap *map)
regcache_exit(map);
regmap_debugfs_exit(map);
regmap_range_exit(map);
-   if (map-bus-free_context)
+   if (map-bus  map-bus-free_context)
map-bus-free_context(map-bus_context);
kfree(map-work_buf);
kfree(map);
@@ -893,6 +907,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned 
int reg,
size_t len;
int i;
 
+   BUG_ON(!map-bus);
+
/* Check for unwritable registers before we start */
if (map-writeable_reg)
for (i = 0; i  val_len / map-format.val_bytes; i++)
@@ -1002,7 +1018,7 @@ static int _regmap_bus_formatted_write(void *context, 
unsigned int reg,
struct regmap_range_node *range;
struct regmap *map = context;
 
-   BUG_ON(!map-format.format_write);
+   BUG_ON(!map-bus || !map-format.format_write);
 
range = _regmap_range_lookup(map, reg);
if (range) {
@@ -1028,7 +1044,7 @@ static int _regmap_bus_raw_write(void *context, unsigned 
int reg,
 {
struct regmap *map = context;
 
-   BUG_ON(!map-format.format_val);
+   BUG_ON(!map-bus || !map-format.format_val);
 
map-format.format_val(map-work_buf + map-format.reg_bytes
   + map-format.pad_bytes, val, 0);
@@ -1039,12 +1055,18 @@ static int _regmap_bus_raw_write(void *context, 
unsigned int reg,
 map-format.val_bytes);
 }
 
+static inline void *_regmap_map_get_context(struct regmap *map)
+{
+   return (map-bus) ? map :