summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/soc/qcom/dcc.c24
1 files changed, 21 insertions, 3 deletions
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;
}