aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-03-18 06:53:26 -0400
committerMark Brown <broonie@linaro.org>2014-03-18 08:21:35 -0400
commit56fb1c74f3bda1c0100fc3e9a7888c229174f9a4 (patch)
tree4cf163d91b52f07fec2fcde9c1d7f4867b794e2a /drivers/base
parent38dbfb59d1175ef458d006556061adeaa8751b72 (diff)
regmap: Ensure regmap_register_patch() is compatible with fast_io
With fast_io we use mutexes to lock the I/O operations so we would need to do GFP_ATOMIC allocations if we wanted to do allocations inside the lock as we do currently. Since it is unlikely that we will want to register a patch outside of init where concurrency shouldn't be an issue move the allocation of the patch data outside the lock. Reported-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6a19515f8a45..e5a5509160fe 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2173,6 +2173,9 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
2173 * apply them immediately. Typically this is used to apply 2173 * apply them immediately. Typically this is used to apply
2174 * corrections to be applied to the device defaults on startup, such 2174 * corrections to be applied to the device defaults on startup, such
2175 * as the updates some vendors provide to undocumented registers. 2175 * as the updates some vendors provide to undocumented registers.
2176 *
2177 * The caller must ensure that this function cannot be called
2178 * concurrently with either itself or regcache_sync().
2176 */ 2179 */
2177int regmap_register_patch(struct regmap *map, const struct reg_default *regs, 2180int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
2178 int num_regs) 2181 int num_regs)
@@ -2185,6 +2188,17 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
2185 num_regs)) 2188 num_regs))
2186 return 0; 2189 return 0;
2187 2190
2191 p = krealloc(map->patch,
2192 sizeof(struct reg_default) * (map->patch_regs + num_regs),
2193 GFP_KERNEL);
2194 if (p) {
2195 memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
2196 map->patch = p;
2197 map->patch_regs += num_regs;
2198 } else {
2199 return -ENOMEM;
2200 }
2201
2188 map->lock(map->lock_arg); 2202 map->lock(map->lock_arg);
2189 2203
2190 bypass = map->cache_bypass; 2204 bypass = map->cache_bypass;
@@ -2202,17 +2216,6 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
2202 } 2216 }
2203 } 2217 }
2204 2218
2205 p = krealloc(map->patch,
2206 sizeof(struct reg_default) * (map->patch_regs + num_regs),
2207 GFP_KERNEL);
2208 if (p) {
2209 memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
2210 map->patch = p;
2211 map->patch_regs += num_regs;
2212 } else {
2213 ret = -ENOMEM;
2214 }
2215
2216out: 2219out:
2217 map->async = false; 2220 map->async = false;
2218 map->cache_bypass = bypass; 2221 map->cache_bypass = bypass;