diff options
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 56 |
1 files changed, 22 insertions, 34 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f412a9911a75..0a08ef5e27c8 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/regmap.h> | 21 | #include <linux/regmap.h> |
22 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/vmalloc.h> | ||
24 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
25 | #include <sound/core.h> | 26 | #include <sound/core.h> |
26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
@@ -169,11 +170,12 @@ static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, | |||
169 | if (buf == NULL) | 170 | if (buf == NULL) |
170 | return NULL; | 171 | return NULL; |
171 | 172 | ||
172 | buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA); | 173 | buf->buf = vmalloc(len); |
173 | if (!buf->buf) { | 174 | if (!buf->buf) { |
174 | kfree(buf); | 175 | vfree(buf); |
175 | return NULL; | 176 | return NULL; |
176 | } | 177 | } |
178 | memcpy(buf->buf, src, len); | ||
177 | 179 | ||
178 | if (list) | 180 | if (list) |
179 | list_add_tail(&buf->list, list); | 181 | list_add_tail(&buf->list, list); |
@@ -188,7 +190,7 @@ static void wm_adsp_buf_free(struct list_head *list) | |||
188 | struct wm_adsp_buf, | 190 | struct wm_adsp_buf, |
189 | list); | 191 | list); |
190 | list_del(&buf->list); | 192 | list_del(&buf->list); |
191 | kfree(buf->buf); | 193 | vfree(buf->buf); |
192 | kfree(buf); | 194 | kfree(buf); |
193 | } | 195 | } |
194 | } | 196 | } |
@@ -684,38 +686,24 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
684 | } | 686 | } |
685 | 687 | ||
686 | if (reg) { | 688 | if (reg) { |
687 | size_t to_write = PAGE_SIZE; | 689 | buf = wm_adsp_buf_alloc(region->data, |
688 | size_t remain = le32_to_cpu(region->len); | 690 | le32_to_cpu(region->len), |
689 | const u8 *data = region->data; | 691 | &buf_list); |
690 | 692 | if (!buf) { | |
691 | while (remain > 0) { | 693 | adsp_err(dsp, "Out of memory\n"); |
692 | if (remain < PAGE_SIZE) | 694 | ret = -ENOMEM; |
693 | to_write = remain; | 695 | goto out_fw; |
694 | 696 | } | |
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 | } | ||
703 | |||
704 | ret = regmap_raw_write_async(regmap, reg, | ||
705 | buf->buf, | ||
706 | to_write); | ||
707 | if (ret != 0) { | ||
708 | adsp_err(dsp, | ||
709 | "%s.%d: Failed to write %zd bytes at %d in %s: %d\n", | ||
710 | file, regions, | ||
711 | to_write, offset, | ||
712 | region_name, ret); | ||
713 | goto out_fw; | ||
714 | } | ||
715 | 697 | ||
716 | data += to_write; | 698 | ret = regmap_raw_write_async(regmap, reg, buf->buf, |
717 | reg += to_write / 2; | 699 | le32_to_cpu(region->len)); |
718 | remain -= to_write; | 700 | if (ret != 0) { |
701 | adsp_err(dsp, | ||
702 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | ||
703 | file, regions, | ||
704 | le32_to_cpu(region->len), offset, | ||
705 | region_name, ret); | ||
706 | goto out_fw; | ||
719 | } | 707 | } |
720 | } | 708 | } |
721 | 709 | ||