* [PATCH v2 1/5] regmap: Add missing comments about struct regmap_bus
2015-08-20 9:12 [PATCH v2 0/5] regmap: fixes Markus Pargmann
@ 2015-08-20 9:12 ` Markus Pargmann
2015-08-20 18:20 ` Mark Brown
2015-08-20 9:12 ` [PATCH v2 2/5] regmap: Fix regmap_bulk_write for bus writes Markus Pargmann
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Markus Pargmann @ 2015-08-20 9:12 UTC (permalink / raw)
To: linux-arm-kernel
There are some fields of this struct undocumented or old. This patch
updates the missing comments.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
include/linux/regmap.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 59c55ea0f0b5..915454a1b54e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -296,8 +296,11 @@ typedef void (*regmap_hw_free_context)(void *context);
* if not implemented on a given device.
* @async_write: Write operation which completes asynchronously, optional and
* must serialise with respect to non-async I/O.
+ * @reg_write: Write operation for a register. Writes value to register.
* @read: Read operation. Data is returned in the buffer used to transmit
* data.
+ * @reg_read: Read operation for a register. Reads a value from a register.
+ * @free_context: Free context.
* @async_alloc: Allocate a regmap_async() structure.
* @read_flag_mask: Mask to be set in the top byte of the register when doing
* a read.
@@ -307,7 +310,6 @@ typedef void (*regmap_hw_free_context)(void *context);
* @val_format_endian_default: Default endianness for formatted register
* values. Used when the regmap_config specifies DEFAULT. If this is
* DEFAULT, BIG is assumed.
- * @async_size: Size of struct used for async work.
*/
struct regmap_bus {
bool fast_io;
--
2.4.6
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 2/5] regmap: Fix regmap_bulk_write for bus writes
2015-08-20 9:12 [PATCH v2 0/5] regmap: fixes Markus Pargmann
2015-08-20 9:12 ` [PATCH v2 1/5] regmap: Add missing comments about struct regmap_bus Markus Pargmann
@ 2015-08-20 9:12 ` Markus Pargmann
2015-08-20 18:27 ` Mark Brown
2015-08-20 9:12 ` [PATCH v2 3/5] regmap: Split use_single_rw internally into use_single_read/write Markus Pargmann
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Markus Pargmann @ 2015-08-20 9:12 UTC (permalink / raw)
To: linux-arm-kernel
The regmap config does not prohibit val_bytes that are not powers of
two. But the current code of regmap_bulk_write for use_single_rw does
limit the possible val_bytes to 1, 2 and 4.
This patch fixes the behaviour to allow bus writes with non-standard
val_bytes sizes.
Cc: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/base/regmap/regmap.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a778cf943628..66a2fd42d77f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1680,7 +1680,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
* Some devices don't support bulk write, for
* them we have a series of single write operations.
*/
- if (!map->bus || map->use_single_rw) {
+ if (!map->bus) {
map->lock(map->lock_arg);
for (i = 0; i < val_count; i++) {
unsigned int ival;
@@ -1712,6 +1712,21 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
}
out:
map->unlock(map->lock_arg);
+ } else if (map->use_single_rw) {
+ /*
+ * We need to handle bus writes separate to support val_bytes
+ * that are not powers of 2.
+ */
+ map->lock(map->lock_arg);
+ for (i = 0; i < val_count; i++) {
+ ret = _regmap_raw_write(map,
+ reg + (i * map->reg_stride),
+ val + (i * val_bytes),
+ val_bytes);
+ if (ret)
+ break;
+ }
+ map->unlock(map->lock_arg);
} else {
void *wval;
--
2.4.6
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 3/5] regmap: Split use_single_rw internally into use_single_read/write
2015-08-20 9:12 [PATCH v2 0/5] regmap: fixes Markus Pargmann
2015-08-20 9:12 ` [PATCH v2 1/5] regmap: Add missing comments about struct regmap_bus Markus Pargmann
2015-08-20 9:12 ` [PATCH v2 2/5] regmap: Fix regmap_bulk_write for bus writes Markus Pargmann
@ 2015-08-20 9:12 ` Markus Pargmann
2015-08-20 18:28 ` Mark Brown
2015-08-20 9:12 ` [PATCH v2 4/5] regmap: regmap_raw_read return error on !bus->read Markus Pargmann
2015-08-20 9:12 ` [PATCH v2 5/5] regmap: No multi_write support if bus->write does not exist Markus Pargmann
4 siblings, 1 reply; 11+ messages in thread
From: Markus Pargmann @ 2015-08-20 9:12 UTC (permalink / raw)
To: linux-arm-kernel
use_single_rw currently reflects the capabilities of the connected
device. The capabilities of the bus are currently missing for this
variable.
As there are read only and write only buses we need seperate values for
use_single_rw to also reflect tha capabilities of the bus.
This patch splits use_single_rw into use_single_read and
use_single_write. The initialization is changed to check the
configuration for use_single_rw and to check the capabilities of the
used bus.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/base/regmap/internal.h | 6 ++++--
drivers/base/regmap/regcache.c | 2 +-
drivers/base/regmap/regmap-irq.c | 4 ++--
drivers/base/regmap/regmap.c | 9 +++++----
4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index b2b2849fc6d3..d744ae3926dd 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -139,8 +139,10 @@ struct regmap {
struct reg_default *patch;
int patch_regs;
- /* if set, converts bulk rw to single rw */
- bool use_single_rw;
+ /* if set, converts bulk read to single read */
+ bool use_single_read;
+ /* if set, converts bulk read to single read */
+ bool use_single_write;
/* if set, the device supports multi write mode */
bool can_multi_write;
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index b9862d741a56..6f8a13ec32a4 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -729,7 +729,7 @@ int regcache_sync_block(struct regmap *map, void *block,
unsigned int block_base, unsigned int start,
unsigned int end)
{
- if (regmap_can_raw_write(map) && !map->use_single_rw)
+ if (regmap_can_raw_write(map) && !map->use_single_write)
return regcache_sync_block_raw(map, block, cache_present,
block_base, start, end);
else
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 2597600a5d26..38d1f72d869c 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -209,7 +209,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
* Read in the statuses, using a single bulk read if possible
* in order to reduce the I/O overheads.
*/
- if (!map->use_single_rw && map->reg_stride == 1 &&
+ if (!map->use_single_read && map->reg_stride == 1 &&
data->irq_reg_stride == 1) {
u8 *buf8 = data->status_reg_buf;
u16 *buf16 = data->status_reg_buf;
@@ -398,7 +398,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
else
d->irq_reg_stride = 1;
- if (!map->use_single_rw && map->reg_stride == 1 &&
+ if (!map->use_single_read && map->reg_stride == 1 &&
d->irq_reg_stride == 1) {
d->status_reg_buf = kmalloc(map->format.val_bytes *
chip->num_regs, GFP_KERNEL);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 66a2fd42d77f..bb4e65e7a950 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -573,7 +573,8 @@ struct regmap *regmap_init(struct device *dev,
map->reg_stride = config->reg_stride;
else
map->reg_stride = 1;
- map->use_single_rw = config->use_single_rw;
+ map->use_single_read = config->use_single_rw || !bus || !bus->read;
+ map->use_single_write = config->use_single_rw || !bus || !bus->write;
map->can_multi_write = config->can_multi_write;
map->dev = dev;
map->bus = bus;
@@ -763,7 +764,7 @@ struct regmap *regmap_init(struct device *dev,
if ((reg_endian != REGMAP_ENDIAN_BIG) ||
(val_endian != REGMAP_ENDIAN_BIG))
goto err_map;
- map->use_single_rw = true;
+ map->use_single_write = true;
}
if (!map->format.format_write &&
@@ -1712,7 +1713,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
}
out:
map->unlock(map->lock_arg);
- } else if (map->use_single_rw) {
+ } else if (map->use_single_write) {
/*
* We need to handle bus writes separate to support val_bytes
* that are not powers of 2.
@@ -2308,7 +2309,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
* Some devices does not support bulk read, for
* them we have a series of single read operations.
*/
- if (map->use_single_rw) {
+ if (map->use_single_read) {
for (i = 0; i < val_count; i++) {
ret = regmap_raw_read(map,
reg + (i * map->reg_stride),
--
2.4.6
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 4/5] regmap: regmap_raw_read return error on !bus->read
2015-08-20 9:12 [PATCH v2 0/5] regmap: fixes Markus Pargmann
` (2 preceding siblings ...)
2015-08-20 9:12 ` [PATCH v2 3/5] regmap: Split use_single_rw internally into use_single_read/write Markus Pargmann
@ 2015-08-20 9:12 ` Markus Pargmann
2015-08-20 18:30 ` Mark Brown
2015-08-20 9:12 ` [PATCH v2 5/5] regmap: No multi_write support if bus->write does not exist Markus Pargmann
4 siblings, 1 reply; 11+ messages in thread
From: Markus Pargmann @ 2015-08-20 9:12 UTC (permalink / raw)
To: linux-arm-kernel
Return -ENOTSUPP if map->bus->read is not implemented and we do not use
the cache. This code path would directly use bus->read would run into an
NULL pointer for the read function.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/base/regmap/regmap.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index bb4e65e7a950..66efe25d64c9 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2201,6 +2201,11 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
map->cache_type == REGCACHE_NONE) {
+ if (!map->bus->read) {
+ ret = -ENOTSUPP;
+ goto out;
+ }
+
/* Physical block read if there's no cache involved */
ret = _regmap_raw_read(map, reg, val, val_len);
--
2.4.6
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 5/5] regmap: No multi_write support if bus->write does not exist
2015-08-20 9:12 [PATCH v2 0/5] regmap: fixes Markus Pargmann
` (3 preceding siblings ...)
2015-08-20 9:12 ` [PATCH v2 4/5] regmap: regmap_raw_read return error on !bus->read Markus Pargmann
@ 2015-08-20 9:12 ` Markus Pargmann
2015-08-20 18:32 ` Mark Brown
4 siblings, 1 reply; 11+ messages in thread
From: Markus Pargmann @ 2015-08-20 9:12 UTC (permalink / raw)
To: linux-arm-kernel
There is no multi_write support available if we cannot use raw_write.
This is the case if bus->write is not implemented.
This patch adds a condition that we need bus and bus->write so that
can_multi_write is true.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/base/regmap/regmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 66efe25d64c9..d43723bb3257 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -575,7 +575,7 @@ struct regmap *regmap_init(struct device *dev,
map->reg_stride = 1;
map->use_single_read = config->use_single_rw || !bus || !bus->read;
map->use_single_write = config->use_single_rw || !bus || !bus->write;
- map->can_multi_write = config->can_multi_write;
+ map->can_multi_write = config->can_multi_write && bus && bus->write;
map->dev = dev;
map->bus = bus;
map->bus_context = bus_context;
--
2.4.6
^ permalink raw reply related [flat|nested] 11+ messages in thread