diff options
author | Mark Brown <broonie@linaro.org> | 2014-03-18 06:53:26 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-03-18 08:21:35 -0400 |
commit | 56fb1c74f3bda1c0100fc3e9a7888c229174f9a4 (patch) | |
tree | 4cf163d91b52f07fec2fcde9c1d7f4867b794e2a /drivers/base | |
parent | 38dbfb59d1175ef458d006556061adeaa8751b72 (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.c | 25 |
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 | */ |
2177 | int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | 2180 | int 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 | |||
2216 | out: | 2219 | out: |
2217 | map->async = false; | 2220 | map->async = false; |
2218 | map->cache_bypass = bypass; | 2221 | map->cache_bypass = bypass; |