Re: [PATCH v2] [RFC] regmap: Add no-"bus" configuration possibility
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
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
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
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