All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] regmap: Check stride of register patch as we register it
@ 2014-02-21 19:37 Charles Keepax
  2014-02-21 19:37 ` [PATCH 2/3] regmap: Add API call apply but not register a patch file Charles Keepax
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Charles Keepax @ 2014-02-21 19:37 UTC (permalink / raw)
  To: broonie; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

Currently, we check the registers in the patch are aligned to the
register stride everytime we sync the cache and the first time the patch
is written out is unchecked.

This patch checks the register patch when we first register it so the
first writes are no longer unchecked and then doesn't check on
subsequent syncs as the patch will be unchanged.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/base/regmap/regcache.c |    4 ----
 drivers/base/regmap/regmap.c   |    4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index dd56177..c6b1ac1 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -312,10 +312,6 @@ int regcache_sync(struct regmap *map)
 	/* Apply any patch first */
 	map->cache_bypass = 1;
 	for (i = 0; i < map->patch_regs; i++) {
-		if (map->patch[i].reg % map->reg_stride) {
-			ret = -EINVAL;
-			goto out;
-		}
 		ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
 		if (ret != 0) {
 			dev_err(map->dev, "Failed to write %x = %x: %d\n",
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index c766f5f..c2ba89a 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2212,6 +2212,10 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
 
 	/* Write out first; it's useful to apply even if we fail later. */
 	for (i = 0; i < num_regs; i++) {
+		if (regs[i].reg % map->reg_stride) {
+			ret = -EINVAL;
+			goto out;
+		}
 		ret = _regmap_write(map, regs[i].reg, regs[i].def);
 		if (ret != 0) {
 			dev_err(map->dev, "Failed to write %x = %x: %d\n",
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] regmap: Add API call apply but not register a patch file
  2014-02-21 19:37 [PATCH 1/3] regmap: Check stride of register patch as we register it Charles Keepax
@ 2014-02-21 19:37 ` Charles Keepax
  2014-02-22  2:10   ` Mark Brown
  2014-02-21 19:37 ` [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch Charles Keepax
  2014-02-22  2:15 ` [PATCH 1/3] regmap: Check stride of register patch as we register it Mark Brown
  2 siblings, 1 reply; 10+ messages in thread
From: Charles Keepax @ 2014-02-21 19:37 UTC (permalink / raw)
  To: broonie; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

This patch provides a new regmap API call that allows a patch to be
applied but not registered with the regmap core. Common code between
this and the existing regmap_register_patch function is factored out to
reduce duplication.

This can be helpful when devices have more complex boot proceedures and
the patch file must be applied manually during the boot process.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/base/regmap/regmap.c |   85 +++++++++++++++++++++++++++++++-----------
 include/linux/regmap.h       |    2 +
 2 files changed, 65 insertions(+), 22 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index c2ba89a..faed8f1 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2178,24 +2178,9 @@ int regmap_async_complete(struct regmap *map)
 }
 EXPORT_SYMBOL_GPL(regmap_async_complete);
 
-/**
- * regmap_register_patch: Register and apply register updates to be applied
- *                        on device initialistion
- *
- * @map: Register map to apply updates to.
- * @regs: Values to update.
- * @num_regs: Number of entries in regs.
- *
- * Register a set of register updates to be applied to the device
- * whenever the device registers are synchronised with the cache and
- * apply them immediately.  Typically this is used to apply
- * corrections to be applied to the device defaults on startup, such
- * as the updates some vendors provide to undocumented registers.
- */
-int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
-			  int num_regs)
+int _regmap_apply_patch(struct regmap *map, const struct reg_default *regs,
+		       int num_regs)
 {
-	struct reg_default *p;
 	int i, ret;
 	bool bypass;
 
@@ -2203,8 +2188,6 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
 	    num_regs))
 		return 0;
 
-	map->lock(map->lock_arg);
-
 	bypass = map->cache_bypass;
 
 	map->cache_bypass = true;
@@ -2224,6 +2207,67 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
 		}
 	}
 
+out:
+	map->async = false;
+	map->cache_bypass = bypass;
+
+	return ret;
+}
+
+/**
+ * regmap_apply_patch: Apply register patch updates
+ *
+ * @map: Register map to apply updates to.
+ * @regs: Values to update.
+ * @num_regs: Number of entries in regs.
+ *
+ * Immediately applies a set of register updates to the device, but does
+ * not register them so they won't be reapplied on subsequent boots of
+ * the device.
+ */
+int regmap_apply_patch(struct regmap *map, const struct reg_default *regs,
+		       int num_regs)
+{
+	int ret;
+
+	map->lock(map->lock_arg);
+
+	ret = _regmap_apply_patch(map, regs, num_regs);
+
+	map->unlock(map->lock_arg);
+
+	regmap_async_complete(map);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_apply_patch);
+
+/**
+ * regmap_register_patch: Register and apply register updates to be applied
+ *                        on device initialistion
+ *
+ * @map: Register map to apply updates to.
+ * @regs: Values to update.
+ * @num_regs: Number of entries in regs.
+ *
+ * Register a set of register updates to be applied to the device
+ * whenever the device registers are synchronised with the cache and
+ * apply them immediately.  Typically this is used to apply
+ * corrections to be applied to the device defaults on startup, such
+ * as the updates some vendors provide to undocumented registers.
+ */
+int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
+			  int num_regs)
+{
+	struct reg_default *p;
+	int ret;
+
+	map->lock(map->lock_arg);
+
+	ret = _regmap_apply_patch(map, regs, num_regs);
+	if (ret != 0)
+		goto out;
+
 	p = krealloc(map->patch,
 		     sizeof(struct reg_default) * (map->patch_regs + num_regs),
 		     GFP_KERNEL);
@@ -2236,9 +2280,6 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
 	}
 
 out:
-	map->async = false;
-	map->cache_bypass = bypass;
-
 	map->unlock(map->lock_arg);
 
 	regmap_async_complete(map);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index fa4d079..c6d638a 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -423,6 +423,8 @@ void regcache_mark_dirty(struct regmap *map);
 bool regmap_check_range_table(struct regmap *map, unsigned int reg,
 			      const struct regmap_access_table *table);
 
+int regmap_apply_patch(struct regmap *map, const struct reg_default *regs,
+			  int num_regs);
 int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
 			  int num_regs);
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch
  2014-02-21 19:37 [PATCH 1/3] regmap: Check stride of register patch as we register it Charles Keepax
  2014-02-21 19:37 ` [PATCH 2/3] regmap: Add API call apply but not register a patch file Charles Keepax
@ 2014-02-21 19:37 ` Charles Keepax
  2014-02-24 16:10   ` Lee Jones
  2014-02-22  2:15 ` [PATCH 1/3] regmap: Check stride of register patch as we register it Mark Brown
  2 siblings, 1 reply; 10+ messages in thread
From: Charles Keepax @ 2014-02-21 19:37 UTC (permalink / raw)
  To: broonie; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

On the wm5102 the register patches are applied manually, rather than by
the regmap core. This application is wrapped in calls to
regcache_cache_bypass. However, this is dangerous as other threads may
be accessing the hardware at the same time as the pm_runtime operations
and if they do so during the period whilst cache_bypass is enabled those
writes will miss the cache when they shouldn't.

Apply the register patch using the new regmap_apply_patch function to
avoid this problem. Also remove the call to regcache_cache_bypass from
the hardware patch application as it is unneeded there and creates a
similar window for writes to miss the cache.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c  |    4 ----
 drivers/mfd/wm5102-tables.c |   19 ++-----------------
 2 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index a45aab9..1c3ae57 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -251,8 +251,6 @@ static int arizona_apply_hardware_patch(struct arizona* arizona)
 	unsigned int fll, sysclk;
 	int ret, err;
 
-	regcache_cache_bypass(arizona->regmap, true);
-
 	/* Cache existing FLL and SYSCLK settings */
 	ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll);
 	if (ret != 0) {
@@ -322,8 +320,6 @@ err_fll:
 			err);
 	}
 
-	regcache_cache_bypass(arizona->regmap, false);
-
 	if (ret != 0)
 		return ret;
 	else
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 1e9a4b2..237020d 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -80,8 +80,7 @@ static const struct reg_default wm5102_revb_patch[] = {
 int wm5102_patch(struct arizona *arizona)
 {
 	const struct reg_default *wm5102_patch;
-	int ret = 0;
-	int i, patch_size;
+	int patch_size;
 
 	switch (arizona->rev) {
 	case 0:
@@ -92,21 +91,7 @@ int wm5102_patch(struct arizona *arizona)
 		patch_size = ARRAY_SIZE(wm5102_revb_patch);
 	}
 
-	regcache_cache_bypass(arizona->regmap, true);
-
-	for (i = 0; i < patch_size; i++) {
-		ret = regmap_write(arizona->regmap, wm5102_patch[i].reg,
-				   wm5102_patch[i].def);
-		if (ret != 0) {
-			dev_err(arizona->dev, "Failed to write %x = %x: %d\n",
-				wm5102_patch[i].reg, wm5102_patch[i].def, ret);
-			goto out;
-		}
-	}
-
-out:
-	regcache_cache_bypass(arizona->regmap, false);
-	return ret;
+	return regmap_apply_patch(arizona->regmap, wm5102_patch, patch_size);
 }
 
 static const struct regmap_irq wm5102_aod_irqs[ARIZONA_NUM_IRQ] = {
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] regmap: Add API call apply but not register a patch file
  2014-02-21 19:37 ` [PATCH 2/3] regmap: Add API call apply but not register a patch file Charles Keepax
@ 2014-02-22  2:10   ` Mark Brown
  2014-02-23 16:11     ` Charles Keepax
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2014-02-22  2:10 UTC (permalink / raw)
  To: Charles Keepax; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

[-- Attachment #1: Type: text/plain, Size: 559 bytes --]

On Fri, Feb 21, 2014 at 07:37:11PM +0000, Charles Keepax wrote:
> This patch provides a new regmap API call that allows a patch to be
> applied but not registered with the regmap core. Common code between
> this and the existing regmap_register_patch function is factored out to
> reduce duplication.

This is just regmap_multi_reg_write() I think?  That already exists, the
theory was that we're going to get an optimised version of that for some
hardware which can stream things and cut out some overheads though that
doesn't seem to have materialised yet.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] regmap: Check stride of register patch as we register it
  2014-02-21 19:37 [PATCH 1/3] regmap: Check stride of register patch as we register it Charles Keepax
  2014-02-21 19:37 ` [PATCH 2/3] regmap: Add API call apply but not register a patch file Charles Keepax
  2014-02-21 19:37 ` [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch Charles Keepax
@ 2014-02-22  2:15 ` Mark Brown
  2 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2014-02-22  2:15 UTC (permalink / raw)
  To: Charles Keepax; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]

On Fri, Feb 21, 2014 at 07:37:10PM +0000, Charles Keepax wrote:
> Currently, we check the registers in the patch are aligned to the
> register stride everytime we sync the cache and the first time the patch
> is written out is unchecked.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] regmap: Add API call apply but not register a patch file
  2014-02-22  2:10   ` Mark Brown
@ 2014-02-23 16:11     ` Charles Keepax
  2014-02-24  1:24       ` Mark Brown
  0 siblings, 1 reply; 10+ messages in thread
From: Charles Keepax @ 2014-02-23 16:11 UTC (permalink / raw)
  To: Mark Brown; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

On Sat, Feb 22, 2014 at 11:10:48AM +0900, Mark Brown wrote:
> On Fri, Feb 21, 2014 at 07:37:11PM +0000, Charles Keepax wrote:
> > This patch provides a new regmap API call that allows a patch to be
> > applied but not registered with the regmap core. Common code between
> > this and the existing regmap_register_patch function is factored out to
> > reduce duplication.
> 
> This is just regmap_multi_reg_write() I think?  That already exists, the
> theory was that we're going to get an optimised version of that for some
> hardware which can stream things and cut out some overheads though that
> doesn't seem to have materialised yet.

I had missed regmap_multi_reg_write but the difference here is that we
apply cache bypass, and that the cache bypass is only applied whilst the
regmap lock is held. This allows users to be sure that no writes
from other threads will accidentally have the bypass applied to them.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] regmap: Add API call apply but not register a patch file
  2014-02-23 16:11     ` Charles Keepax
@ 2014-02-24  1:24       ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2014-02-24  1:24 UTC (permalink / raw)
  To: Charles Keepax; +Cc: gregkh, sameo, lee.jones, linux-kernel, patches

[-- Attachment #1: Type: text/plain, Size: 788 bytes --]

On Sun, Feb 23, 2014 at 04:11:59PM +0000, Charles Keepax wrote:
> On Sat, Feb 22, 2014 at 11:10:48AM +0900, Mark Brown wrote:

> > This is just regmap_multi_reg_write() I think?  That already exists, the
> > theory was that we're going to get an optimised version of that for some
> > hardware which can stream things and cut out some overheads though that
> > doesn't seem to have materialised yet.

> I had missed regmap_multi_reg_write but the difference here is that we
> apply cache bypass, and that the cache bypass is only applied whilst the
> regmap lock is held. This allows users to be sure that no writes
> from other threads will accidentally have the bypass applied to them.

Right, OK - but it should still be a wrapper for a core implementation
and share interface/naming.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch
  2014-02-21 19:37 ` [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch Charles Keepax
@ 2014-02-24 16:10   ` Lee Jones
  2014-02-25  9:37     ` Charles Keepax
  0 siblings, 1 reply; 10+ messages in thread
From: Lee Jones @ 2014-02-24 16:10 UTC (permalink / raw)
  To: Charles Keepax; +Cc: broonie, gregkh, sameo, linux-kernel, patches

> On the wm5102 the register patches are applied manually, rather than by
> the regmap core. This application is wrapped in calls to
> regcache_cache_bypass. However, this is dangerous as other threads may
> be accessing the hardware at the same time as the pm_runtime operations
> and if they do so during the period whilst cache_bypass is enabled those
> writes will miss the cache when they shouldn't.
> 
> Apply the register patch using the new regmap_apply_patch function to
> avoid this problem. Also remove the call to regcache_cache_bypass from
> the hardware patch application as it is unneeded there and creates a
> similar window for writes to miss the cache.
> 
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
>  drivers/mfd/arizona-core.c  |    4 ----
>  drivers/mfd/wm5102-tables.c |   19 ++-----------------
>  2 files changed, 2 insertions(+), 21 deletions(-)

Applied, thanks.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch
  2014-02-24 16:10   ` Lee Jones
@ 2014-02-25  9:37     ` Charles Keepax
  2014-02-25 10:02       ` Lee Jones
  0 siblings, 1 reply; 10+ messages in thread
From: Charles Keepax @ 2014-02-25  9:37 UTC (permalink / raw)
  To: Lee Jones; +Cc: broonie, gregkh, sameo, linux-kernel, patches

On Mon, Feb 24, 2014 at 04:10:42PM +0000, Lee Jones wrote:
> > On the wm5102 the register patches are applied manually, rather than by
> > the regmap core. This application is wrapped in calls to
> > regcache_cache_bypass. However, this is dangerous as other threads may
> > be accessing the hardware at the same time as the pm_runtime operations
> > and if they do so during the period whilst cache_bypass is enabled those
> > writes will miss the cache when they shouldn't.
> > 
> > Apply the register patch using the new regmap_apply_patch function to
> > avoid this problem. Also remove the call to regcache_cache_bypass from
> > the hardware patch application as it is unneeded there and creates a
> > similar window for writes to miss the cache.
> > 
> > Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> > ---
> >  drivers/mfd/arizona-core.c  |    4 ----
> >  drivers/mfd/wm5102-tables.c |   19 ++-----------------
> >  2 files changed, 2 insertions(+), 21 deletions(-)
> 
> Applied, thanks.

Apologies this patch depends on the previous patch I am still
working Mark's comments for. So this can't really be applied at
the moment.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch
  2014-02-25  9:37     ` Charles Keepax
@ 2014-02-25 10:02       ` Lee Jones
  0 siblings, 0 replies; 10+ messages in thread
From: Lee Jones @ 2014-02-25 10:02 UTC (permalink / raw)
  To: Charles Keepax; +Cc: broonie, gregkh, sameo, linux-kernel, patches

> > > On the wm5102 the register patches are applied manually, rather than by
> > > the regmap core. This application is wrapped in calls to
> > > regcache_cache_bypass. However, this is dangerous as other threads may
> > > be accessing the hardware at the same time as the pm_runtime operations
> > > and if they do so during the period whilst cache_bypass is enabled those
> > > writes will miss the cache when they shouldn't.
> > > 
> > > Apply the register patch using the new regmap_apply_patch function to
> > > avoid this problem. Also remove the call to regcache_cache_bypass from
> > > the hardware patch application as it is unneeded there and creates a
> > > similar window for writes to miss the cache.
> > > 
> > > Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> > > ---
> > >  drivers/mfd/arizona-core.c  |    4 ----
> > >  drivers/mfd/wm5102-tables.c |   19 ++-----------------
> > >  2 files changed, 2 insertions(+), 21 deletions(-)
> > 
> > Applied, thanks.
> 
> Apologies this patch depends on the previous patch I am still
> working Mark's comments for. So this can't really be applied at
> the moment.

It's a good idea to let us know about any inter-patch dependencies, so
we may act accordingly. I'll remove this from my -next branch for now.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-02-25 10:02 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-21 19:37 [PATCH 1/3] regmap: Check stride of register patch as we register it Charles Keepax
2014-02-21 19:37 ` [PATCH 2/3] regmap: Add API call apply but not register a patch file Charles Keepax
2014-02-22  2:10   ` Mark Brown
2014-02-23 16:11     ` Charles Keepax
2014-02-24  1:24       ` Mark Brown
2014-02-21 19:37 ` [PATCH 3/3] mfd: arizona: Use new regmap features for manual register patch Charles Keepax
2014-02-24 16:10   ` Lee Jones
2014-02-25  9:37     ` Charles Keepax
2014-02-25 10:02       ` Lee Jones
2014-02-22  2:15 ` [PATCH 1/3] regmap: Check stride of register patch as we register it Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.