regmap: Implement managed regmap_init()
Mark Brown [Mon, 30 Jan 2012 19:56:52 +0000 (19:56 +0000)]
Save error handling and unwinding code in drivers by providing managed
versions of the regmap init functions, simplifying usage.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
(cherry picked from commit c0eb46766d395da8d62148bda2e59bad5e6ee2f2)

Change-Id: I6df96ae10ad8a882feb7da908dd46c2f56a28f9f
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/87585

Rebase-Id: Rb1406525cbc449bc5a6726b171d0531ef7f3db61

drivers/base/regmap/regmap-i2c.c
drivers/base/regmap/regmap-spi.c
drivers/base/regmap/regmap.c
include/linux/regmap.h

index 38621ec..9a3a8c5 100644 (file)
@@ -111,4 +111,21 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c,
 }
 EXPORT_SYMBOL_GPL(regmap_init_i2c);
 
+/**
+ * devm_regmap_init_i2c(): Initialise managed register map
+ *
+ * @i2c: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
+                                   const struct regmap_config *config)
+{
+       return devm_regmap_init(&i2c->dev, &regmap_i2c, config);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
+
 MODULE_LICENSE("GPL");
index 2560658..7c0c35a 100644 (file)
@@ -70,4 +70,21 @@ struct regmap *regmap_init_spi(struct spi_device *spi,
 }
 EXPORT_SYMBOL_GPL(regmap_init_spi);
 
+/**
+ * devm_regmap_init_spi(): Initialise register map
+ *
+ * @spi: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The map will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_spi(struct spi_device *spi,
+                                   const struct regmap_config *config)
+{
+       return devm_regmap_init(&spi->dev, &regmap_spi, config);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
+
 MODULE_LICENSE("GPL");
index 8def4a8..a42fd5f 100644 (file)
@@ -281,6 +281,45 @@ err:
 }
 EXPORT_SYMBOL_GPL(regmap_init);
 
+static void devm_regmap_release(struct device *dev, void *res)
+{
+       regmap_exit(*(struct regmap **)res);
+}
+
+/**
+ * devm_regmap_init(): Initialise managed register map
+ *
+ * @dev: Device that will be interacted with
+ * @bus: Bus-specific callbacks to use with device
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  This function should generally not be called
+ * directly, it should be called by bus-specific init functions.  The
+ * map will be automatically freed by the device management code.
+ */
+struct regmap *devm_regmap_init(struct device *dev,
+                               const struct regmap_bus *bus,
+                               const struct regmap_config *config)
+{
+       struct regmap **ptr, *regmap;
+
+       ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       regmap = regmap_init(dev, bus, config);
+       if (!IS_ERR(regmap)) {
+               *ptr = regmap;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return regmap;
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init);
+
 /**
  * regmap_reinit_cache(): Reinitialise the current register cache
  *
index e8a31a3..5d26599 100644 (file)
@@ -129,6 +129,14 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c,
 struct regmap *regmap_init_spi(struct spi_device *dev,
                               const struct regmap_config *config);
 
+struct regmap *devm_regmap_init(struct device *dev,
+                               const struct regmap_bus *bus,
+                               const struct regmap_config *config);
+struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
+                                   const struct regmap_config *config);
+struct regmap *devm_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);