diff options
author | Charles Keepax <ckeepax@opensource.wolfsonmicro.com> | 2014-03-05 09:28:16 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-03-05 23:34:31 -0500 |
commit | c1a7898d655fd265feefcf6fe82ab0096e6d078e (patch) | |
tree | ec35b473c4dc2dfa7eeb0f949a10203dd20dd05d /sound/soc/codecs/wm_adsp.c | |
parent | 055bbe2df957343fece60fe1f60553a9c1005217 (diff) |
ASoC: wm_adsp: Split firmware load into smaller chunks
The firmware files can be quite large and allocating the whole firmware
a single DMA safe buffer can be problematic if the system is under a
high memory load. Ease the requirements slightly by writing the firmware
out in page sized chunks.
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/codecs/wm_adsp.c')
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f9fd56444a14..937af6f31ffa 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -684,24 +684,38 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
684 | } | 684 | } |
685 | 685 | ||
686 | if (reg) { | 686 | if (reg) { |
687 | buf = wm_adsp_buf_alloc(region->data, | 687 | size_t to_write = PAGE_SIZE; |
688 | le32_to_cpu(region->len), | 688 | size_t remain = le32_to_cpu(region->len); |
689 | &buf_list); | 689 | const u8 *data = region->data; |
690 | if (!buf) { | 690 | |
691 | adsp_err(dsp, "Out of memory\n"); | 691 | while (remain > 0) { |
692 | ret = -ENOMEM; | 692 | if (remain < PAGE_SIZE) |
693 | goto out_fw; | 693 | to_write = remain; |
694 | } | 694 | |
695 | buf = wm_adsp_buf_alloc(data, | ||
696 | to_write, | ||
697 | &buf_list); | ||
698 | if (!buf) { | ||
699 | adsp_err(dsp, "Out of memory\n"); | ||
700 | ret = -ENOMEM; | ||
701 | goto out_fw; | ||
702 | } | ||
695 | 703 | ||
696 | ret = regmap_raw_write_async(regmap, reg, buf->buf, | 704 | ret = regmap_raw_write_async(regmap, reg, |
697 | le32_to_cpu(region->len)); | 705 | buf->buf, |
698 | if (ret != 0) { | 706 | to_write); |
699 | adsp_err(dsp, | 707 | if (ret != 0) { |
700 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | 708 | adsp_err(dsp, |
701 | file, regions, | 709 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", |
702 | le32_to_cpu(region->len), offset, | 710 | file, regions, |
703 | region_name, ret); | 711 | to_write, offset, |
704 | goto out_fw; | 712 | region_name, ret); |
713 | goto out_fw; | ||
714 | } | ||
715 | |||
716 | data += to_write; | ||
717 | reg += to_write / 2; | ||
718 | remain -= to_write; | ||
705 | } | 719 | } |
706 | } | 720 | } |
707 | 721 | ||