regmap: Implement managed regmap_init()
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 30 Jan 2012 19:56:52 +0000 (19:56 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 30 Jan 2012 21:06:43 +0000 (21:06 +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>
drivers/base/regmap/regmap-i2c.c
drivers/base/regmap/regmap-spi.c
drivers/base/regmap/regmap.c
include/linux/regmap.h

index 38621ec87c05bd0c13f2058380549a7ff4ac5b83..9a3a8c5643892b3e81b2f0c99871f20a1ed9baec 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 2560658de344ddee800eaeaf8b506c9728a2715f..7c0c35a39c331afa9e5c5d940e8bf16354aa4a10 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 be10a4ff660915625454375ce9fb30a97d5b7ef9..839cc82bd176ebabbef528e22f9d8673df25f981 100644 (file)
@@ -258,6 +258,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 eb93921cdd30252b1c960cf6872585e308c9e9fc..195db51ec79bc412dbf0b20589ed628e151261ce 100644 (file)
@@ -127,6 +127,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);