aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/internal.h1
-rw-r--r--drivers/base/regmap/regmap.c61
-rw-r--r--include/linux/regmap.h8
3 files changed, 69 insertions, 1 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index e46c279f8280..c994bc9bc04f 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -45,6 +45,7 @@ struct regmap {
45 struct regmap_format format; /* Buffer format */ 45 struct regmap_format format; /* Buffer format */
46 const struct regmap_bus *bus; 46 const struct regmap_bus *bus;
47 void *bus_context; 47 void *bus_context;
48 const char *name;
48 49
49#ifdef CONFIG_DEBUG_FS 50#ifdef CONFIG_DEBUG_FS
50 struct dentry *debugfs; 51 struct dentry *debugfs;
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ee4fea351220..618173e4c2b1 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -178,6 +178,15 @@ static void regmap_unlock_spinlock(struct regmap *map)
178 spin_unlock(&map->spinlock); 178 spin_unlock(&map->spinlock);
179} 179}
180 180
181static void dev_get_regmap_release(struct device *dev, void *res)
182{
183 /*
184 * We don't actually have anything to do here; the goal here
185 * is not to manage the regmap but to provide a simple way to
186 * get the regmap back given a struct device.
187 */
188}
189
181/** 190/**
182 * regmap_init(): Initialise register map 191 * regmap_init(): Initialise register map
183 * 192 *
@@ -195,7 +204,7 @@ struct regmap *regmap_init(struct device *dev,
195 void *bus_context, 204 void *bus_context,
196 const struct regmap_config *config) 205 const struct regmap_config *config)
197{ 206{
198 struct regmap *map; 207 struct regmap *map, **m;
199 int ret = -EINVAL; 208 int ret = -EINVAL;
200 209
201 if (!bus || !config) 210 if (!bus || !config)
@@ -230,6 +239,7 @@ struct regmap *regmap_init(struct device *dev,
230 map->volatile_reg = config->volatile_reg; 239 map->volatile_reg = config->volatile_reg;
231 map->precious_reg = config->precious_reg; 240 map->precious_reg = config->precious_reg;
232 map->cache_type = config->cache_type; 241 map->cache_type = config->cache_type;
242 map->name = config->name;
233 243
234 if (config->read_flag_mask || config->write_flag_mask) { 244 if (config->read_flag_mask || config->write_flag_mask) {
235 map->read_flag_mask = config->read_flag_mask; 245 map->read_flag_mask = config->read_flag_mask;
@@ -326,8 +336,19 @@ struct regmap *regmap_init(struct device *dev,
326 if (ret < 0) 336 if (ret < 0)
327 goto err_free_workbuf; 337 goto err_free_workbuf;
328 338
339 /* Add a devres resource for dev_get_regmap() */
340 m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
341 if (!m) {
342 ret = -ENOMEM;
343 goto err_cache;
344 }
345 *m = map;
346 devres_add(dev, m);
347
329 return map; 348 return map;
330 349
350err_cache:
351 regcache_exit(map);
331err_free_workbuf: 352err_free_workbuf:
332 kfree(map->work_buf); 353 kfree(map->work_buf);
333err_map: 354err_map:
@@ -431,6 +452,44 @@ void regmap_exit(struct regmap *map)
431} 452}
432EXPORT_SYMBOL_GPL(regmap_exit); 453EXPORT_SYMBOL_GPL(regmap_exit);
433 454
455static int dev_get_regmap_match(struct device *dev, void *res, void *data)
456{
457 struct regmap **r = res;
458 if (!r || !*r) {
459 WARN_ON(!r || !*r);
460 return 0;
461 }
462
463 /* If the user didn't specify a name match any */
464 if (data)
465 return (*r)->name == data;
466 else
467 return 1;
468}
469
470/**
471 * dev_get_regmap(): Obtain the regmap (if any) for a device
472 *
473 * @dev: Device to retrieve the map for
474 * @name: Optional name for the register map, usually NULL.
475 *
476 * Returns the regmap for the device if one is present, or NULL. If
477 * name is specified then it must match the name specified when
478 * registering the device, if it is NULL then the first regmap found
479 * will be used. Devices with multiple register maps are very rare,
480 * generic code should normally not need to specify a name.
481 */
482struct regmap *dev_get_regmap(struct device *dev, const char *name)
483{
484 struct regmap **r = devres_find(dev, dev_get_regmap_release,
485 dev_get_regmap_match, (void *)name);
486
487 if (!r)
488 return NULL;
489 return *r;
490}
491EXPORT_SYMBOL_GPL(dev_get_regmap);
492
434static int _regmap_raw_write(struct regmap *map, unsigned int reg, 493static int _regmap_raw_write(struct regmap *map, unsigned int reg,
435 const void *val, size_t val_len) 494 const void *val, size_t val_len)
436{ 495{
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index f6abc8d33d64..90a4652eaaea 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -156,6 +156,7 @@ struct regmap *devm_regmap_init_mmio(struct device *dev,
156void regmap_exit(struct regmap *map); 156void regmap_exit(struct regmap *map);
157int regmap_reinit_cache(struct regmap *map, 157int regmap_reinit_cache(struct regmap *map,
158 const struct regmap_config *config); 158 const struct regmap_config *config);
159struct regmap *dev_get_regmap(struct device *dev, const char *name);
159int regmap_write(struct regmap *map, unsigned int reg, unsigned int val); 160int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
160int regmap_raw_write(struct regmap *map, unsigned int reg, 161int regmap_raw_write(struct regmap *map, unsigned int reg,
161 const void *val, size_t val_len); 162 const void *val, size_t val_len);
@@ -340,6 +341,13 @@ static inline int regmap_register_patch(struct regmap *map,
340 return -EINVAL; 341 return -EINVAL;
341} 342}
342 343
344static inline struct regmap *dev_get_regmap(struct device *dev,
345 const char *name)
346{
347 WARN_ONCE(1, "regmap API is disabled");
348 return NULL;
349}
350
343#endif 351#endif
344 352
345#endif 353#endif