Skip to content

Commit 72b39f6

Browse files
committed
regmap: Implement dev_get_regmap()
Use devres to implement dev_get_regmap(). This should mean that in almost all cases devices wishing to take advantage of framework features based on regmap shouldn't need to explicitly pass the regmap into the framework. This simplifies device setup a bit. Signed-off-by: Mark Brown <[email protected]>
1 parent 851960b commit 72b39f6

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

drivers/base/regmap/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct regmap {
4545
struct regmap_format format; /* Buffer format */
4646
const struct regmap_bus *bus;
4747
void *bus_context;
48+
const char *name;
4849

4950
#ifdef CONFIG_DEBUG_FS
5051
struct dentry *debugfs;

drivers/base/regmap/regmap.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ static void regmap_unlock_spinlock(struct regmap *map)
178178
spin_unlock(&map->spinlock);
179179
}
180180

181+
static 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+
181190
/**
182191
* regmap_init(): Initialise register map
183192
*
@@ -195,7 +204,7 @@ struct regmap *regmap_init(struct device *dev,
195204
void *bus_context,
196205
const struct regmap_config *config)
197206
{
198-
struct regmap *map;
207+
struct regmap *map, **m;
199208
int ret = -EINVAL;
200209

201210
if (!bus || !config)
@@ -230,6 +239,7 @@ struct regmap *regmap_init(struct device *dev,
230239
map->volatile_reg = config->volatile_reg;
231240
map->precious_reg = config->precious_reg;
232241
map->cache_type = config->cache_type;
242+
map->name = config->name;
233243

234244
if (config->read_flag_mask || config->write_flag_mask) {
235245
map->read_flag_mask = config->read_flag_mask;
@@ -326,8 +336,19 @@ struct regmap *regmap_init(struct device *dev,
326336
if (ret < 0)
327337
goto err_free_workbuf;
328338

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+
329348
return map;
330349

350+
err_cache:
351+
regcache_exit(map);
331352
err_free_workbuf:
332353
kfree(map->work_buf);
333354
err_map:
@@ -431,6 +452,44 @@ void regmap_exit(struct regmap *map)
431452
}
432453
EXPORT_SYMBOL_GPL(regmap_exit);
433454

455+
static 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+
*/
482+
struct 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+
}
491+
EXPORT_SYMBOL_GPL(dev_get_regmap);
492+
434493
static int _regmap_raw_write(struct regmap *map, unsigned int reg,
435494
const void *val, size_t val_len)
436495
{

include/linux/regmap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ struct regmap *devm_regmap_init_mmio(struct device *dev,
156156
void regmap_exit(struct regmap *map);
157157
int regmap_reinit_cache(struct regmap *map,
158158
const struct regmap_config *config);
159+
struct regmap *dev_get_regmap(struct device *dev, const char *name);
159160
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
160161
int regmap_raw_write(struct regmap *map, unsigned int reg,
161162
const void *val, size_t val_len);
@@ -340,6 +341,13 @@ static inline int regmap_register_patch(struct regmap *map,
340341
return -EINVAL;
341342
}
342343

344+
static 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+
343351
#endif
344352

345353
#endif

0 commit comments

Comments
 (0)