Re: [PATCH v2] [RFC] regmap: Add no-"bus" configuration possibility

2012-12-02 Thread Mark Brown
On Fri, Nov 23, 2012 at 01:25:24PM -0800, Andrey Smirnov wrote:
> Second version of the patch with incorporated suggestions form
> Mark(hopefully):
>https://lkml.org/lkml/2012/11/20/249
> 
> Once again at this point this patch is for illustrative purposes. If
> the overall structure and nature of the change is agreed upon, I'll
> work on properly implementing it and testing it with my driver code(SI476X).

This looks basically good  - I'd like to see the refactoring changes
split out from the new API (and in general done in smaller hunks) as
it's a very big and invasive change but the top level API and the basic
idea look good.


signature.asc
Description: Digital signature


Re: [PATCH v2] [RFC] regmap: Add no-bus configuration possibility

2012-12-02 Thread Mark Brown
On Fri, Nov 23, 2012 at 01:25:24PM -0800, Andrey Smirnov wrote:
 Second version of the patch with incorporated suggestions form
 Mark(hopefully):
https://lkml.org/lkml/2012/11/20/249
 
 Once again at this point this patch is for illustrative purposes. If
 the overall structure and nature of the change is agreed upon, I'll
 work on properly implementing it and testing it with my driver code(SI476X).

This looks basically good  - I'd like to see the refactoring changes
split out from the new API (and in general done in smaller hunks) as
it's a very big and invasive change but the top level API and the basic
idea look good.


signature.asc
Description: Digital signature


[PATCH v2] [RFC] regmap: Add no-"bus" configuration possibility

2012-11-23 Thread Andrey Smirnov
Second version of the patch with incorporated suggestions form
Mark(hopefully):
   https://lkml.org/lkml/2012/11/20/249

Once again at this point this patch is for illustrative purposes. If
the overall structure and nature of the change is agreed upon, I'll
work on properly implementing it and testing it with my driver code(SI476X).

Original description of the first version:

This patch proposes extension to the API that was suggested by Mark in
the following thread:
http://article.gmane.org/gmane.linux.kernel/1383734

The idea behind extensions is to allow the devices that expose some
register-like interface but whose protocol for reading or writing
those registers could not be simplified to serialized bytestream
writes to be used within 'regmap' framework

This patch adds two callbacks to the 'regmap' configuration which user
is expected to set with their implementation of read and write
functionality for the device.

I am not very well versed with the code of the remap framework so I
apologize if my proposal has some glaring mistakes and I would
welcome any suggestion or criticism on how to either improve the code
or implement the proposal in a better way.

This commit has only purpose of illustrating the proposed extension of
the 'regmap' API. It has never been compiled or tested.
---
 drivers/base/regmap/internal.h |4 +
 drivers/base/regmap/regmap.c   |  172 
 include/linux/regmap.h |   12 ++-
 3 files changed, 137 insertions(+), 51 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 80f9ab9..2bb5f8e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -58,6 +58,10 @@ struct regmap {
bool (*volatile_reg)(struct device *dev, unsigned int reg);
bool (*precious_reg)(struct device *dev, unsigned int reg);
 
+   int (*reg_read)(struct regmap *map, unsigned int reg, unsigned int 
*val);
+   int (*reg_write)(struct regmap *map, unsigned int reg, unsigned int 
val);
+   int (*reg_cache)(struct regmap *map, unsigned int reg, unsigned int 
val);
+
u8 read_flag_mask;
u8 write_flag_mask;
 
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index c241ae2..4ecb4b8 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -326,7 +326,8 @@ struct regmap *regmap_init(struct device *dev,
enum regmap_endian reg_endian, val_endian;
int i, j;
 
-   if (!bus || !config)
+   if (!config ||
+   (!bus && !config->reg_read && !config->reg_write))
goto err;
 
map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -335,15 +336,16 @@ struct regmap *regmap_init(struct device *dev,
goto err;
}
 
-   if (bus->fast_io) {
-   spin_lock_init(>spinlock);
-   map->lock = regmap_lock_spinlock;
-   map->unlock = regmap_unlock_spinlock;
-   } else {
+   if (!bus || !bus->fast_io) {
mutex_init(>mutex);
map->lock = regmap_lock_mutex;
map->unlock = regmap_unlock_mutex;
+   } else {
+   spin_lock_init(>spinlock);
+   map->lock = regmap_lock_spinlock;
+   map->unlock = regmap_unlock_spinlock;
}
+
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
map->format.pad_bytes = config->pad_bits / 8;
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
@@ -355,14 +357,16 @@ struct regmap *regmap_init(struct device *dev,
else
map->reg_stride = 1;
map->use_single_rw = config->use_single_rw;
-   map->dev = dev;
map->bus = bus;
+   map->dev = dev;
map->bus_context = bus_context;
map->max_register = config->max_register;
map->writeable_reg = config->writeable_reg;
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+   map->reg_read = config->reg_read;
+   map->reg_write = config->reg_write;
map->cache_type = config->cache_type;
map->name = config->name;
 
@@ -373,6 +377,11 @@ struct regmap *regmap_init(struct device *dev,
map->read_flag_mask = bus->read_flag_mask;
}
 
+   if (!bus)
+   goto skip_format_initialization;
+   else
+   map->reg_read = _regmap_bus_read;
+
reg_endian = config->reg_format_endian;
if (reg_endian == REGMAP_ENDIAN_DEFAULT)
reg_endian = bus->reg_format_endian_default;
@@ -512,6 +521,15 @@ struct regmap *regmap_init(struct device *dev,
!(map->format.format_reg && map->format.format_val))
goto err_map;
 
+skip_format_initialization:
+   if (map->format.format_write) {
+   map->reg_cache = _regmap_reg_cache;
+   map->reg_write = 

[PATCH v2] [RFC] regmap: Add no-bus configuration possibility

2012-11-23 Thread Andrey Smirnov
Second version of the patch with incorporated suggestions form
Mark(hopefully):
   https://lkml.org/lkml/2012/11/20/249

Once again at this point this patch is for illustrative purposes. If
the overall structure and nature of the change is agreed upon, I'll
work on properly implementing it and testing it with my driver code(SI476X).

Original description of the first version:

This patch proposes extension to the API that was suggested by Mark in
the following thread:
http://article.gmane.org/gmane.linux.kernel/1383734

The idea behind extensions is to allow the devices that expose some
register-like interface but whose protocol for reading or writing
those registers could not be simplified to serialized bytestream
writes to be used within 'regmap' framework

This patch adds two callbacks to the 'regmap' configuration which user
is expected to set with their implementation of read and write
functionality for the device.

I am not very well versed with the code of the remap framework so I
apologize if my proposal has some glaring mistakes and I would
welcome any suggestion or criticism on how to either improve the code
or implement the proposal in a better way.

This commit has only purpose of illustrating the proposed extension of
the 'regmap' API. It has never been compiled or tested.
---
 drivers/base/regmap/internal.h |4 +
 drivers/base/regmap/regmap.c   |  172 
 include/linux/regmap.h |   12 ++-
 3 files changed, 137 insertions(+), 51 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 80f9ab9..2bb5f8e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -58,6 +58,10 @@ struct regmap {
bool (*volatile_reg)(struct device *dev, unsigned int reg);
bool (*precious_reg)(struct device *dev, unsigned int reg);
 
+   int (*reg_read)(struct regmap *map, unsigned int reg, unsigned int 
*val);
+   int (*reg_write)(struct regmap *map, unsigned int reg, unsigned int 
val);
+   int (*reg_cache)(struct regmap *map, unsigned int reg, unsigned int 
val);
+
u8 read_flag_mask;
u8 write_flag_mask;
 
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index c241ae2..4ecb4b8 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -326,7 +326,8 @@ struct regmap *regmap_init(struct device *dev,
enum regmap_endian reg_endian, val_endian;
int i, j;
 
-   if (!bus || !config)
+   if (!config ||
+   (!bus  !config-reg_read  !config-reg_write))
goto err;
 
map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -335,15 +336,16 @@ struct regmap *regmap_init(struct device *dev,
goto err;
}
 
-   if (bus-fast_io) {
-   spin_lock_init(map-spinlock);
-   map-lock = regmap_lock_spinlock;
-   map-unlock = regmap_unlock_spinlock;
-   } else {
+   if (!bus || !bus-fast_io) {
mutex_init(map-mutex);
map-lock = regmap_lock_mutex;
map-unlock = regmap_unlock_mutex;
+   } else {
+   spin_lock_init(map-spinlock);
+   map-lock = regmap_lock_spinlock;
+   map-unlock = regmap_unlock_spinlock;
}
+
map-format.reg_bytes = DIV_ROUND_UP(config-reg_bits, 8);
map-format.pad_bytes = config-pad_bits / 8;
map-format.val_bytes = DIV_ROUND_UP(config-val_bits, 8);
@@ -355,14 +357,16 @@ struct regmap *regmap_init(struct device *dev,
else
map-reg_stride = 1;
map-use_single_rw = config-use_single_rw;
-   map-dev = dev;
map-bus = bus;
+   map-dev = dev;
map-bus_context = bus_context;
map-max_register = config-max_register;
map-writeable_reg = config-writeable_reg;
map-readable_reg = config-readable_reg;
map-volatile_reg = config-volatile_reg;
map-precious_reg = config-precious_reg;
+   map-reg_read = config-reg_read;
+   map-reg_write = config-reg_write;
map-cache_type = config-cache_type;
map-name = config-name;
 
@@ -373,6 +377,11 @@ struct regmap *regmap_init(struct device *dev,
map-read_flag_mask = bus-read_flag_mask;
}
 
+   if (!bus)
+   goto skip_format_initialization;
+   else
+   map-reg_read = _regmap_bus_read;
+
reg_endian = config-reg_format_endian;
if (reg_endian == REGMAP_ENDIAN_DEFAULT)
reg_endian = bus-reg_format_endian_default;
@@ -512,6 +521,15 @@ struct regmap *regmap_init(struct device *dev,
!(map-format.format_reg  map-format.format_val))
goto err_map;
 
+skip_format_initialization:
+   if (map-format.format_write) {
+   map-reg_cache = _regmap_reg_cache;
+   map-reg_write = _regmap_bus_formatted_write;
+   } else if