Skip to content

Commit 70ee853

Browse files
rfvirgilbroonie
authored andcommitted
regmap: Add regmap_read_bypassed()
Add a regmap_read_bypassed() to allow reads from the hardware registers while the regmap is in cache-only mode. A typical use for this is to keep the cache in cache-only mode until the hardware has reached a valid state, but one or more status registers must be polled to determine when this state is reached. For example, firmware download on the cs35l56 can take several seconds if there are multiple amps sharing limited bus bandwidth. This is too long to block in probe() so it is done as a background task. The device must be soft-reset to reboot the firmware and during this time the registers are not accessible, so the cache should be in cache-only. But the driver must poll a register to detect when reboot has completed. Signed-off-by: Richard Fitzgerald <[email protected]> Fixes: 8a731fd ("ASoC: cs35l56: Move utility functions to shared file") Link: https://msgid.link/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent fec50db commit 70ee853

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

drivers/base/regmap/regmap.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,6 +2838,43 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
28382838
}
28392839
EXPORT_SYMBOL_GPL(regmap_read);
28402840

2841+
/**
2842+
* regmap_read_bypassed() - Read a value from a single register direct
2843+
* from the device, bypassing the cache
2844+
*
2845+
* @map: Register map to read from
2846+
* @reg: Register to be read from
2847+
* @val: Pointer to store read value
2848+
*
2849+
* A value of zero will be returned on success, a negative errno will
2850+
* be returned in error cases.
2851+
*/
2852+
int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val)
2853+
{
2854+
int ret;
2855+
bool bypass, cache_only;
2856+
2857+
if (!IS_ALIGNED(reg, map->reg_stride))
2858+
return -EINVAL;
2859+
2860+
map->lock(map->lock_arg);
2861+
2862+
bypass = map->cache_bypass;
2863+
cache_only = map->cache_only;
2864+
map->cache_bypass = true;
2865+
map->cache_only = false;
2866+
2867+
ret = _regmap_read(map, reg, val);
2868+
2869+
map->cache_bypass = bypass;
2870+
map->cache_only = cache_only;
2871+
2872+
map->unlock(map->lock_arg);
2873+
2874+
return ret;
2875+
}
2876+
EXPORT_SYMBOL_GPL(regmap_read_bypassed);
2877+
28412878
/**
28422879
* regmap_raw_read() - Read raw data from the device
28432880
*

include/linux/regmap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,7 @@ int regmap_multi_reg_write_bypassed(struct regmap *map,
12301230
int regmap_raw_write_async(struct regmap *map, unsigned int reg,
12311231
const void *val, size_t val_len);
12321232
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
1233+
int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val);
12331234
int regmap_raw_read(struct regmap *map, unsigned int reg,
12341235
void *val, size_t val_len);
12351236
int regmap_noinc_read(struct regmap *map, unsigned int reg,
@@ -1739,6 +1740,13 @@ static inline int regmap_read(struct regmap *map, unsigned int reg,
17391740
return -EINVAL;
17401741
}
17411742

1743+
static inline int regmap_read_bypassed(struct regmap *map, unsigned int reg,
1744+
unsigned int *val)
1745+
{
1746+
WARN_ONCE(1, "regmap API is disabled");
1747+
return -EINVAL;
1748+
}
1749+
17421750
static inline int regmap_raw_read(struct regmap *map, unsigned int reg,
17431751
void *val, size_t val_len)
17441752
{

0 commit comments

Comments
 (0)