diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-01-07 14:03:17 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-01-07 14:13:35 -0500 |
commit | a76fefab5c82d0f51c1330e275476b2066fe7d73 (patch) | |
tree | 80ba425b3aab5643bf635d80c006da976e7ed4d5 /sound/soc | |
parent | d1c3ed669a2d452cacfb48c2d171a1f364dae2ed (diff) |
ASoC: wm_adsp: Ensure that block writes are from DMA aligned addresses
Otherwise we won't run correctly on systems that require this for larger
data transfers.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index ffc89fab96fb..7b198c38f3ef 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -169,6 +169,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
169 | const struct wm_adsp_region *mem; | 169 | const struct wm_adsp_region *mem; |
170 | const char *region_name; | 170 | const char *region_name; |
171 | char *file, *text; | 171 | char *file, *text; |
172 | void *buf; | ||
172 | unsigned int reg; | 173 | unsigned int reg; |
173 | int regions = 0; | 174 | int regions = 0; |
174 | int ret, offset, type, sizes; | 175 | int ret, offset, type, sizes; |
@@ -322,8 +323,18 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
322 | } | 323 | } |
323 | 324 | ||
324 | if (reg) { | 325 | if (reg) { |
325 | ret = regmap_raw_write(regmap, reg, region->data, | 326 | buf = kmemdup(region->data, le32_to_cpu(region->len), |
327 | GFP_KERNEL); | ||
328 | if (!buf) { | ||
329 | adsp_err(dsp, "Out of memory\n"); | ||
330 | return -ENOMEM; | ||
331 | } | ||
332 | |||
333 | ret = regmap_raw_write(regmap, reg, buf, | ||
326 | le32_to_cpu(region->len)); | 334 | le32_to_cpu(region->len)); |
335 | |||
336 | kfree(buf); | ||
337 | |||
327 | if (ret != 0) { | 338 | if (ret != 0) { |
328 | adsp_err(dsp, | 339 | adsp_err(dsp, |
329 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | 340 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", |
@@ -359,6 +370,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
359 | const char *region_name; | 370 | const char *region_name; |
360 | int ret, pos, blocks, type, offset, reg; | 371 | int ret, pos, blocks, type, offset, reg; |
361 | char *file; | 372 | char *file; |
373 | void *buf; | ||
362 | 374 | ||
363 | file = kzalloc(PAGE_SIZE, GFP_KERNEL); | 375 | file = kzalloc(PAGE_SIZE, GFP_KERNEL); |
364 | if (file == NULL) | 376 | if (file == NULL) |
@@ -426,6 +438,13 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
426 | } | 438 | } |
427 | 439 | ||
428 | if (reg) { | 440 | if (reg) { |
441 | buf = kmemdup(blk->data, le32_to_cpu(blk->len), | ||
442 | GFP_KERNEL); | ||
443 | if (!buf) { | ||
444 | adsp_err(dsp, "Out of memory\n"); | ||
445 | return -ENOMEM; | ||
446 | } | ||
447 | |||
429 | ret = regmap_raw_write(regmap, reg, blk->data, | 448 | ret = regmap_raw_write(regmap, reg, blk->data, |
430 | le32_to_cpu(blk->len)); | 449 | le32_to_cpu(blk->len)); |
431 | if (ret != 0) { | 450 | if (ret != 0) { |
@@ -433,6 +452,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
433 | "%s.%d: Failed to write to %x in %s\n", | 452 | "%s.%d: Failed to write to %x in %s\n", |
434 | file, blocks, reg, region_name); | 453 | file, blocks, reg, region_name); |
435 | } | 454 | } |
455 | |||
456 | kfree(buf); | ||
436 | } | 457 | } |
437 | 458 | ||
438 | pos += le32_to_cpu(blk->len) + sizeof(*blk); | 459 | pos += le32_to_cpu(blk->len) + sizeof(*blk); |