Re: [PATCH net-next v3 1/2] regmap: Allow installing custom reg_update_bits function

2015-10-08 Thread David Miller
From: Mark Brown 
Date: Tue, 6 Oct 2015 17:30:11 +0100

> On Thu, Oct 01, 2015 at 12:38:07PM -0400, j...@ringle.org wrote:
>> From: Jon Ringle 
>> 
>> This commit allows installing a custom reg_update_bits function for cases 
>> where
>> the hardware provides a mechanism to set or clear register bits without a
>> read/modify/write cycle. Such is the case with the Microchip ENCX24J600.
> 
> Thanks, I've applied this.  I'll extend it so that individual devices
> can do this as well - I've not looked at your driver but it might be
> that this is a better option than regmap_bus for your driver (but both
> are supported so meh).  Dave, I've tagged the commit and there's a pull
> request for this below:
> 
> The following changes since commit 6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f:
> 
>   Linux 4.3-rc1 (2015-09-12 16:35:56 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git 
> tags/regmap-offload-update-bits

I've pulled this into my 'net-next' tree, thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-next v3 1/2] regmap: Allow installing custom reg_update_bits function

2015-10-06 Thread Mark Brown
On Thu, Oct 01, 2015 at 12:38:07PM -0400, j...@ringle.org wrote:
> From: Jon Ringle 
> 
> This commit allows installing a custom reg_update_bits function for cases 
> where
> the hardware provides a mechanism to set or clear register bits without a
> read/modify/write cycle. Such is the case with the Microchip ENCX24J600.

Thanks, I've applied this.  I'll extend it so that individual devices
can do this as well - I've not looked at your driver but it might be
that this is a better option than regmap_bus for your driver (but both
are supported so meh).  Dave, I've tagged the commit and there's a pull
request for this below:

The following changes since commit 6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f:

  Linux 4.3-rc1 (2015-09-12 16:35:56 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git 
tags/regmap-offload-update-bits

for you to fetch changes up to 77792b11409c9270d98e604b4314b85ce886ac7d:

  regmap: Allow installing custom reg_update_bits function (2015-10-06 16:12:34 
+0100)


regmap: Allow buses to provide a custom update_bits() operation

Some buses provide a native _update_bits() operation which for uncached
registers is faster than doing a read/modify/write cycle as it is a
single bus transaction.  Add support for implementing this to regmap.


Jon Ringle (1):
  regmap: Allow installing custom reg_update_bits function

 drivers/base/regmap/internal.h |  2 ++
 drivers/base/regmap/regmap.c   | 29 ++---
 include/linux/regmap.h |  3 +++
 3 files changed, 23 insertions(+), 11 deletions(-)


signature.asc
Description: Digital signature


[PATCH net-next v3 1/2] regmap: Allow installing custom reg_update_bits function

2015-10-01 Thread jon
From: Jon Ringle 

This commit allows installing a custom reg_update_bits function for cases where
the hardware provides a mechanism to set or clear register bits without a
read/modify/write cycle. Such is the case with the Microchip ENCX24J600.

If a custom reg_update_bits function is provided, it will only be used against
volatile registers.

Signed-off-by: Jon Ringle 
---

I am now only calling map->reg_update_bits() if the register is marked as being
volatile, and therefore should have no impact on the reg cache.

Jon

 drivers/base/regmap/internal.h |  2 ++
 drivers/base/regmap/regmap.c   | 29 ++---
 include/linux/regmap.h |  3 +++
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index cc55788..628ad7a 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -98,6 +98,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);
+   int (*reg_update_bits)(void *context, unsigned int reg,
+  unsigned int mask, unsigned int val);
 
bool defer_caching;
 
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index afaf562..8cd155a 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -619,6 +619,7 @@ struct regmap *__regmap_init(struct device *dev,
goto skip_format_initialization;
} else {
map->reg_read  = _regmap_bus_read;
+   map->reg_update_bits = bus->reg_update_bits;
}
 
reg_endian = regmap_get_reg_endian(bus, config);
@@ -2509,20 +2510,26 @@ static int _regmap_update_bits(struct regmap *map, 
unsigned int reg,
int ret;
unsigned int tmp, orig;
 
-   ret = _regmap_read(map, reg, );
-   if (ret != 0)
-   return ret;
+   if (change)
+   *change = false;
 
-   tmp = orig & ~mask;
-   tmp |= val & mask;
-
-   if (force_write || (tmp != orig)) {
-   ret = _regmap_write(map, reg, tmp);
-   if (change)
+   if (regmap_volatile(map, reg) && map->reg_update_bits) {
+   ret = map->reg_update_bits(map->bus_context, reg, mask, val);
+   if (ret == 0 && change)
*change = true;
} else {
-   if (change)
-   *change = false;
+   ret = _regmap_read(map, reg, );
+   if (ret != 0)
+   return ret;
+
+   tmp = orig & ~mask;
+   tmp |= val & mask;
+
+   if (force_write || (tmp != orig)) {
+   ret = _regmap_write(map, reg, tmp);
+   if (ret == 0 && change)
+   *change = true;
+   }
}
 
return ret;
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 8fc0bfd..b49d413 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -296,6 +296,8 @@ 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 int (*regmap_hw_reg_update_bits)(void *context, unsigned int reg,
+unsigned int mask, unsigned int val);
 typedef struct regmap_async *(*regmap_hw_async_alloc)(void);
 typedef void (*regmap_hw_free_context)(void *context);
 
@@ -335,6 +337,7 @@ struct regmap_bus {
regmap_hw_gather_write gather_write;
regmap_hw_async_write async_write;
regmap_hw_reg_write reg_write;
+   regmap_hw_reg_update_bits reg_update_bits;
regmap_hw_read read;
regmap_hw_reg_read reg_read;
regmap_hw_free_context free_context;
-- 
2.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html