diff options
Diffstat (limited to 'sound/soc/codecs/wm_adsp.c')
| -rw-r--r-- | sound/soc/codecs/wm_adsp.c | 25 | 
1 files changed, 23 insertions, 2 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index ffc89fab96f..b6b65483758 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)  	const struct wm_adsp_region *mem;  	const char *region_name;  	char *file, *text; +	void *buf;  	unsigned int reg;  	int regions = 0;  	int ret, offset, type, sizes; @@ -322,8 +323,18 @@ static int wm_adsp_load(struct wm_adsp *dsp)  		}  		if (reg) { -			ret = regmap_raw_write(regmap, reg, region->data, +			buf = kmemdup(region->data, le32_to_cpu(region->len), +				      GFP_KERNEL | GFP_DMA); +			if (!buf) { +				adsp_err(dsp, "Out of memory\n"); +				return -ENOMEM; +			} + +			ret = regmap_raw_write(regmap, reg, buf,  					       le32_to_cpu(region->len)); + +			kfree(buf); +  			if (ret != 0) {  				adsp_err(dsp,  					"%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)  	const char *region_name;  	int ret, pos, blocks, type, offset, reg;  	char *file; +	void *buf;  	file = kzalloc(PAGE_SIZE, GFP_KERNEL);  	if (file == NULL) @@ -384,7 +396,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)  	hdr = (void*)&firmware->data[0];  	if (memcmp(hdr->magic, "WMDR", 4) != 0) {  		adsp_err(dsp, "%s: invalid magic\n", file); -		return -EINVAL; +		goto out_fw;  	}  	adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, @@ -426,6 +438,13 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)  		}  		if (reg) { +			buf = kmemdup(blk->data, le32_to_cpu(blk->len), +				      GFP_KERNEL | GFP_DMA); +			if (!buf) { +				adsp_err(dsp, "Out of memory\n"); +				return -ENOMEM; +			} +  			ret = regmap_raw_write(regmap, reg, blk->data,  					       le32_to_cpu(blk->len));  			if (ret != 0) { @@ -433,6 +452,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)  					"%s.%d: Failed to write to %x in %s\n",  					file, blocks, reg, region_name);  			} + +			kfree(buf);  		}  		pos += le32_to_cpu(blk->len) + sizeof(*blk);  |