diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c index ac2c09be7641..aced50bf7fda 100644 --- a/drivers/soc/qcom/dcc.c +++ b/drivers/soc/qcom/dcc.c @@ -253,7 +253,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata) uint32_t prev_addr, addr; uint32_t prev_off = 0, off; uint32_t link; - uint32_t pos; + uint32_t pos, total_len = 0; struct dcc_config_entry *entry; if (list_empty(&drvdata->config_head)) { @@ -272,6 +272,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata) addr = (entry->base >> 4) & BM(0, 27); addr |= BIT(31); off = entry->offset/4; + total_len += entry->len * 4; if (!prev_addr || prev_addr != addr || prev_off > off) { /* Check if we need to write link of prev entry */ @@ -289,7 +290,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata) prev_off = 0; } - if ((off - prev_off) > 0xFF || entry->len > 0x7F) { + if ((off - prev_off) > 0xFF || entry->len > MAX_DCC_LEN) { dev_err(drvdata->dev, "DCC: Progamming error! Base: 0x%x, offset 0x%x.\n", entry->base, entry->offset); @@ -339,8 +340,25 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata) dcc_sram_writel(drvdata, 0, sram_offset); sram_offset += 4; - drvdata->ram_cfg = (sram_offset / 4); + /* check if the data will overstep */ + if (drvdata->data_sink == DCC_DATA_SINK_SRAM + && drvdata->func_type == DCC_FUNC_TYPE_CAPTURE) { + if (sram_offset + total_len > drvdata->ram_size) { + sram_offset += total_len; + goto overstep; + } + } else { + if (sram_offset > drvdata->ram_size) + goto overstep; + } + drvdata->ram_cfg = (sram_offset / 4); + return 0; +overstep: + ret = -EINVAL; + memset_io(drvdata->ram_base, 0, drvdata->ram_size); + dev_err(drvdata->dev, "DCC SRAM oversteps, 0x%x (0x%x)\n", + sram_offset, drvdata->ram_size); err: return ret; }