diff options
| author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-30 14:56:52 -0500 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-30 16:06:43 -0500 |
| commit | c0eb46766d395da8d62148bda2e59bad5e6ee2f2 (patch) | |
| tree | 9b808ba04041f4f10d08b384b4ad8c608a86df4c | |
| parent | 567e47935a7cddd8e823c73bb8ee0b2805cd4940 (diff) | |
regmap: Implement managed regmap_init()
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>
| -rw-r--r-- | drivers/base/regmap/regmap-i2c.c | 17 | ||||
| -rw-r--r-- | drivers/base/regmap/regmap-spi.c | 17 | ||||
| -rw-r--r-- | drivers/base/regmap/regmap.c | 39 | ||||
| -rw-r--r-- | include/linux/regmap.h | 8 |
4 files changed, 81 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 38621ec87c05..9a3a8c564389 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c | |||
| @@ -111,4 +111,21 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, | |||
| 111 | } | 111 | } |
| 112 | EXPORT_SYMBOL_GPL(regmap_init_i2c); | 112 | EXPORT_SYMBOL_GPL(regmap_init_i2c); |
| 113 | 113 | ||
| 114 | /** | ||
| 115 | * devm_regmap_init_i2c(): Initialise managed register map | ||
| 116 | * | ||
| 117 | * @i2c: Device that will be interacted with | ||
| 118 | * @config: Configuration for register map | ||
| 119 | * | ||
| 120 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
| 121 | * to a struct regmap. The regmap will be automatically freed by the | ||
| 122 | * device management code. | ||
| 123 | */ | ||
| 124 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, | ||
| 125 | const struct regmap_config *config) | ||
| 126 | { | ||
| 127 | return devm_regmap_init(&i2c->dev, ®map_i2c, config); | ||
| 128 | } | ||
| 129 | EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); | ||
| 130 | |||
| 114 | MODULE_LICENSE("GPL"); | 131 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 2560658de344..7c0c35a39c33 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c | |||
| @@ -70,4 +70,21 @@ struct regmap *regmap_init_spi(struct spi_device *spi, | |||
| 70 | } | 70 | } |
| 71 | EXPORT_SYMBOL_GPL(regmap_init_spi); | 71 | EXPORT_SYMBOL_GPL(regmap_init_spi); |
| 72 | 72 | ||
| 73 | /** | ||
| 74 | * devm_regmap_init_spi(): Initialise register map | ||
| 75 | * | ||
| 76 | * @spi: Device that will be interacted with | ||
| 77 | * @config: Configuration for register map | ||
| 78 | * | ||
| 79 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
| 80 | * to a struct regmap. The map will be automatically freed by the | ||
| 81 | * device management code. | ||
| 82 | */ | ||
| 83 | struct regmap *devm_regmap_init_spi(struct spi_device *spi, | ||
| 84 | const struct regmap_config *config) | ||
| 85 | { | ||
| 86 | return devm_regmap_init(&spi->dev, ®map_spi, config); | ||
| 87 | } | ||
| 88 | EXPORT_SYMBOL_GPL(devm_regmap_init_spi); | ||
| 89 | |||
| 73 | MODULE_LICENSE("GPL"); | 90 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff6609..839cc82bd176 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
| @@ -258,6 +258,45 @@ err: | |||
| 258 | } | 258 | } |
| 259 | EXPORT_SYMBOL_GPL(regmap_init); | 259 | EXPORT_SYMBOL_GPL(regmap_init); |
| 260 | 260 | ||
| 261 | static void devm_regmap_release(struct device *dev, void *res) | ||
| 262 | { | ||
| 263 | regmap_exit(*(struct regmap **)res); | ||
| 264 | } | ||
| 265 | |||
| 266 | /** | ||
| 267 | * devm_regmap_init(): Initialise managed register map | ||
| 268 | * | ||
| 269 | * @dev: Device that will be interacted with | ||
| 270 | * @bus: Bus-specific callbacks to use with device | ||
| 271 | * @config: Configuration for register map | ||
| 272 | * | ||
| 273 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
| 274 | * to a struct regmap. This function should generally not be called | ||
| 275 | * directly, it should be called by bus-specific init functions. The | ||
| 276 | * map will be automatically freed by the device management code. | ||
| 277 | */ | ||
| 278 | struct regmap *devm_regmap_init(struct device *dev, | ||
| 279 | const struct regmap_bus *bus, | ||
| 280 | const struct regmap_config *config) | ||
| 281 | { | ||
| 282 | struct regmap **ptr, *regmap; | ||
| 283 | |||
| 284 | ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL); | ||
| 285 | if (!ptr) | ||
| 286 | return ERR_PTR(-ENOMEM); | ||
| 287 | |||
| 288 | regmap = regmap_init(dev, bus, config); | ||
| 289 | if (!IS_ERR(regmap)) { | ||
| 290 | *ptr = regmap; | ||
| 291 | devres_add(dev, ptr); | ||
| 292 | } else { | ||
| 293 | devres_free(ptr); | ||
| 294 | } | ||
| 295 | |||
| 296 | return regmap; | ||
| 297 | } | ||
| 298 | EXPORT_SYMBOL_GPL(devm_regmap_init); | ||
| 299 | |||
| 261 | /** | 300 | /** |
| 262 | * regmap_reinit_cache(): Reinitialise the current register cache | 301 | * regmap_reinit_cache(): Reinitialise the current register cache |
| 263 | * | 302 | * |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd30..195db51ec79b 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
| @@ -127,6 +127,14 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, | |||
| 127 | struct regmap *regmap_init_spi(struct spi_device *dev, | 127 | struct regmap *regmap_init_spi(struct spi_device *dev, |
| 128 | const struct regmap_config *config); | 128 | const struct regmap_config *config); |
| 129 | 129 | ||
| 130 | struct regmap *devm_regmap_init(struct device *dev, | ||
| 131 | const struct regmap_bus *bus, | ||
| 132 | const struct regmap_config *config); | ||
| 133 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, | ||
| 134 | const struct regmap_config *config); | ||
| 135 | struct regmap *devm_regmap_init_spi(struct spi_device *dev, | ||
| 136 | const struct regmap_config *config); | ||
| 137 | |||
| 130 | void regmap_exit(struct regmap *map); | 138 | void regmap_exit(struct regmap *map); |
| 131 | int regmap_reinit_cache(struct regmap *map, | 139 | int regmap_reinit_cache(struct regmap *map, |
| 132 | const struct regmap_config *config); | 140 | const struct regmap_config *config); |
