mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] regmap: Allow drivers to reinitialise the register cache at runtime
@ 2011-12-05 11:44 Mark Brown
  2011-12-05 11:45 ` [PATCH 2/2] mfd: Initialise WM8994 register cache after reading chip ID registers Mark Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Brown @ 2011-12-05 11:44 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches, Mark Brown

Sometimes the register map information may change in ways that drivers can
discover at runtime. For example, new revisions of a device may add new
registers. Support runtime discovery by drivers by allowing the register
cache to be reinitialised with a new function regmap_reinit_cache() which
discards the existing cache and creates a new one.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/base/regmap/regmap.c |   33 +++++++++++++++++++++++++++++++++
 include/linux/regmap.h       |    2 ++
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index add5da6..be10a4f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -259,6 +259,39 @@ err:
 EXPORT_SYMBOL_GPL(regmap_init);
 
 /**
+ * regmap_reinit_cache(): Reinitialise the current register cache
+ *
+ * @map: Register map to operate on.
+ * @config: New configuration.  Only the cache data will be used.
+ *
+ * Discard any existing register cache for the map and initialize a
+ * new cache.  This can be used to restore the cache to defaults or to
+ * update the cache configuration to reflect runtime discovery of the
+ * hardware.
+ */
+int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
+{
+	int ret;
+
+	mutex_lock(&map->lock);
+
+	regcache_exit(map);
+
+	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->cache_type = config->cache_type;
+
+	ret = regcache_init(map, config);
+
+	mutex_unlock(&map->lock);
+
+	return ret;
+}
+
+/**
  * regmap_exit(): Free a previously allocated register map
  */
 void regmap_exit(struct regmap *map)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index a83e4a0..cfce3a3 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -128,6 +128,8 @@ struct regmap *regmap_init_spi(struct spi_device *dev,
 			       const struct regmap_config *config);
 
 void regmap_exit(struct regmap *map);
+int regmap_reinit_cache(struct regmap *map,
+			const struct regmap_config *config);
 int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
 int regmap_raw_write(struct regmap *map, unsigned int reg,
 		     const void *val, size_t val_len);
-- 
1.7.7.3


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

* [PATCH 2/2] mfd: Initialise WM8994 register cache after reading chip ID registers
  2011-12-05 11:44 [PATCH 1/2] regmap: Allow drivers to reinitialise the register cache at runtime Mark Brown
@ 2011-12-05 11:45 ` Mark Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2011-12-05 11:45 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches, Mark Brown

The different devices handled by the WM8994 can be distinguished using
their ID registers so we don't need to rely on the user having registered
the device correctly. Instead do the initial regmap setup with a minimal
configuration only supporting physical I/O and then configure the cache
once we have identified the device.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---

This depends on all the other 8994 regmap stuff - I'll add it to the
relevant branches.

 drivers/mfd/wm8994-core.c   |   41 ++++++++++++++++++++++++-----------------
 drivers/mfd/wm8994-regmap.c |    5 +++++
 drivers/mfd/wm8994.h        |    1 +
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 4549999..d1c73f8 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -349,6 +349,7 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
 static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 {
 	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+	struct regmap_config *regmap_config;
 	const char *devname;
 	int ret, i;
 	int pulls = 0;
@@ -487,6 +488,28 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 	dev_info(wm8994->dev, "%s revision %c\n", devname,
 		 'A' + wm8994->revision);
 
+	switch (wm8994->type) {
+	case WM1811:
+		regmap_config = &wm1811_regmap_config;
+		break;
+	case WM8994:
+		regmap_config = &wm8994_regmap_config;
+		break;
+	case WM8958:
+		regmap_config = &wm8958_regmap_config;
+		break;
+	default:
+		dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);
+		return -EINVAL;
+	}
+
+	ret = regmap_reinit_cache(wm8994->regmap, regmap_config);
+	if (ret != 0) {
+		dev_err(wm8994->dev, "Failed to reinit register cache: %d\n",
+			ret);
+		return ret;
+	}
+
 	if (pdata) {
 		wm8994->irq_base = pdata->irq_base;
 		wm8994->gpio_base = pdata->gpio_base;
@@ -578,7 +601,6 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct wm8994 *wm8994;
-	struct regmap_config *regmap_config;
 	int ret;
 
 	wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL);
@@ -590,22 +612,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
 	wm8994->irq = i2c->irq;
 	wm8994->type = id->driver_data;
 
-	switch (wm8994->type) {
-	case WM1811:
-		regmap_config = &wm1811_regmap_config;
-		break;
-	case WM8994:
-		regmap_config = &wm8994_regmap_config;
-		break;
-	case WM8958:
-		regmap_config = &wm8958_regmap_config;
-		break;
-	default:
-		dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);
-		return -EINVAL;
-	}
-
-	wm8994->regmap = regmap_init_i2c(i2c, regmap_config);
+	wm8994->regmap = regmap_init_i2c(i2c, &wm8994_base_regmap_config);
 	if (IS_ERR(wm8994->regmap)) {
 		ret = PTR_ERR(wm8994->regmap);
 		dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index 2fdefa124..c598ae6 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -1231,3 +1231,8 @@ struct regmap_config wm8958_regmap_config = {
 	.volatile_reg = wm8958_volatile_register,
 	.readable_reg = wm8958_readable_register,
 };
+
+struct regmap_config wm8994_base_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 16,
+};
diff --git a/drivers/mfd/wm8994.h b/drivers/mfd/wm8994.h
index bf2bdc1..6f39a84 100644
--- a/drivers/mfd/wm8994.h
+++ b/drivers/mfd/wm8994.h
@@ -20,5 +20,6 @@
 extern struct regmap_config wm1811_regmap_config;
 extern struct regmap_config wm8994_regmap_config;
 extern struct regmap_config wm8958_regmap_config;
+extern struct regmap_config wm8994_base_regmap_config;
 
 #endif
-- 
1.7.7.3


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

end of thread, other threads:[~2011-12-05 11:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-05 11:44 [PATCH 1/2] regmap: Allow drivers to reinitialise the register cache at runtime Mark Brown
2011-12-05 11:45 ` [PATCH 2/2] mfd: Initialise WM8994 register cache after reading chip ID registers Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome