diff options
Diffstat (limited to 'sound/soc/codecs/wm_adsp.c')
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 67124783558a..720d6e852986 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -21,6 +21,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> +#include <linux/vmalloc.h> #include <linux/workqueue.h> #include <sound/core.h> #include <sound/pcm.h> @@ -169,11 +170,12 @@ static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, if (buf == NULL) return NULL; - buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA); + buf->buf = vmalloc(len); if (!buf->buf) { - kfree(buf); + vfree(buf); return NULL; } + memcpy(buf->buf, src, len); if (list) list_add_tail(&buf->list, list); @@ -188,7 +190,7 @@ static void wm_adsp_buf_free(struct list_head *list) struct wm_adsp_buf, list); list_del(&buf->list); - kfree(buf->buf); + vfree(buf->buf); kfree(buf); } } @@ -684,38 +686,24 @@ static int wm_adsp_load(struct wm_adsp *dsp) } if (reg) { - size_t to_write = PAGE_SIZE; - size_t remain = le32_to_cpu(region->len); - const u8 *data = region->data; - - while (remain > 0) { - if (remain < PAGE_SIZE) - to_write = remain; - - buf = wm_adsp_buf_alloc(data, - to_write, - &buf_list); - if (!buf) { - adsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; - } - - ret = regmap_raw_write_async(regmap, reg, - buf->buf, - to_write); - if (ret != 0) { - adsp_err(dsp, - "%s.%d: Failed to write %zd bytes at %d in %s: %d\n", - file, regions, - to_write, offset, - region_name, ret); - goto out_fw; - } + buf = wm_adsp_buf_alloc(region->data, + le32_to_cpu(region->len), + &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } - data += to_write; - reg += to_write / 2; - remain -= to_write; + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(region->len)); + if (ret != 0) { + adsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, + le32_to_cpu(region->len), offset, + region_name, ret); + goto out_fw; } } @@ -1065,8 +1053,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) be32_to_cpu(adsp1_alg[i].zm)); region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP1_DM; region->alg = be32_to_cpu(adsp1_alg[i].alg.id); region->base = be32_to_cpu(adsp1_alg[i].dm); @@ -1083,8 +1073,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) } region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP1_ZM; region->alg = be32_to_cpu(adsp1_alg[i].alg.id); region->base = be32_to_cpu(adsp1_alg[i].zm); @@ -1113,8 +1105,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) be32_to_cpu(adsp2_alg[i].zm)); region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP2_XM; region->alg = be32_to_cpu(adsp2_alg[i].alg.id); region->base = be32_to_cpu(adsp2_alg[i].xm); @@ -1131,8 +1125,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) } region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP2_YM; region->alg = be32_to_cpu(adsp2_alg[i].alg.id); region->base = be32_to_cpu(adsp2_alg[i].ym); @@ -1149,8 +1145,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) } region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP2_ZM; region->alg = be32_to_cpu(adsp2_alg[i].alg.id); region->base = be32_to_cpu(adsp2_alg[i].zm); @@ -1595,13 +1593,6 @@ static void wm_adsp2_boot_work(struct work_struct *work) if (ret != 0) goto err; - ret = regmap_update_bits_async(dsp->regmap, - dsp->base + ADSP2_CONTROL, - ADSP2_CORE_ENA, - ADSP2_CORE_ENA); - if (ret != 0) - goto err; - dsp->running = true; return; @@ -1651,8 +1642,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_START, - ADSP2_START); + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); if (ret != 0) goto err; break; |