Merge "soc: qcom: dcc_v2: Avoid dcc_sram_writel overstep"
diff --git a/drivers/soc/qcom/dcc_v2.c b/drivers/soc/qcom/dcc_v2.c
index ac50996..279461d 100644
--- a/drivers/soc/qcom/dcc_v2.c
+++ b/drivers/soc/qcom/dcc_v2.c
@@ -35,8 +35,6 @@
 #define dcc_readl(drvdata, off)						\
 	__raw_readl(drvdata->base + off)
 
-#define dcc_sram_writel(drvdata, val, off)				\
-	__raw_writel((val), drvdata->ram_base + off)
 #define dcc_sram_readl(drvdata, off)					\
 	__raw_readl(drvdata->ram_base + off)
 
@@ -153,6 +151,17 @@
 	uint8_t			cti_trig;
 };
 
+static int dcc_sram_writel(struct dcc_drvdata *drvdata,
+					uint32_t val, uint32_t off)
+{
+	if (unlikely(off > (drvdata->ram_size - 4)))
+		return -EINVAL;
+
+	__raw_writel((val), drvdata->ram_base + off);
+
+	return 0;
+}
+
 static bool dcc_ready(struct dcc_drvdata *drvdata)
 {
 	uint32_t val;
@@ -252,7 +261,10 @@
 				 * processing the list
 				 */
 				link |= ((0x1 << 8) & BM(8, 14));
-				dcc_sram_writel(drvdata, link, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+							link, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 				/* Reset link and prev_off */
 				addr = 0x00;
@@ -262,13 +274,21 @@
 			}
 
 			addr = DCC_RD_MOD_WR_DESCRIPTOR;
-			dcc_sram_writel(drvdata, addr, sram_offset);
+			ret = dcc_sram_writel(drvdata, addr, sram_offset);
+			if (ret)
+				goto overstep;
 				sram_offset += 4;
 
-			dcc_sram_writel(drvdata, entry->mask, sram_offset);
+			ret = dcc_sram_writel(drvdata,
+					entry->mask, sram_offset);
+			if (ret)
+				goto overstep;
 				sram_offset += 4;
 
-			dcc_sram_writel(drvdata, entry->write_val, sram_offset);
+			ret = dcc_sram_writel(drvdata,
+					entry->write_val, sram_offset);
+			if (ret)
+				goto overstep;
 				sram_offset += 4;
 			addr = 0;
 			break;
@@ -278,7 +298,10 @@
 		{
 			/* Check if we need to write link of prev entry */
 			if (link) {
-				dcc_sram_writel(drvdata, link, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+						link, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 			}
 
@@ -288,7 +311,10 @@
 				loop |= DCC_LOOP_DESCRIPTOR;
 				total_len += (total_len - loop_len) * loop_cnt;
 
-				dcc_sram_writel(drvdata, loop, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+						loop, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 
 				loop_start = false;
@@ -317,7 +343,10 @@
 				 * processing the list
 				 */
 				link |= ((0x1 << 8) & BM(8, 14));
-				dcc_sram_writel(drvdata, link, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+						link, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 				/* Reset link and prev_off */
 				addr = 0x00;
@@ -340,13 +369,20 @@
 				addr |= DCC_ADDR_DESCRIPTOR | DCC_WRITE_IND
 					| DCC_AHB_IND;
 
-			dcc_sram_writel(drvdata, addr, sram_offset);
+			ret = dcc_sram_writel(drvdata, addr, sram_offset);
+			if (ret)
+				goto overstep;
 				sram_offset += 4;
 
-			dcc_sram_writel(drvdata, link, sram_offset);
+			ret = dcc_sram_writel(drvdata, link, sram_offset);
+			if (ret)
+				goto overstep;
 				sram_offset += 4;
 
-			dcc_sram_writel(drvdata, entry->write_val, sram_offset);
+			ret = dcc_sram_writel(drvdata,
+				entry->write_val, sram_offset);
+			if (ret)
+				goto overstep;
 				sram_offset += 4;
 			addr = 0x00;
 			link = 0;
@@ -370,8 +406,10 @@
 			if (!prev_addr || prev_addr != addr || prev_off > off) {
 				/* Check if we need to write prev link entry */
 				if (link) {
-					dcc_sram_writel(drvdata,
+					ret = dcc_sram_writel(drvdata,
 							link, sram_offset);
+					if (ret)
+						goto overstep;
 					sram_offset += 4;
 				}
 				dev_dbg(drvdata->dev,
@@ -379,7 +417,10 @@
 					sram_offset);
 
 				/* Write address */
-				dcc_sram_writel(drvdata, addr, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+						addr, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 
 				/* Reset link and prev_off */
@@ -422,7 +463,10 @@
 			link |= DCC_LINK_DESCRIPTOR;
 
 			if (pos) {
-				dcc_sram_writel(drvdata, link, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+						link, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 				link = 0;
 			}
@@ -434,7 +478,9 @@
 	}
 
 	if (link) {
-		dcc_sram_writel(drvdata, link, sram_offset);
+		ret = dcc_sram_writel(drvdata, link, sram_offset);
+		if (ret)
+			goto overstep;
 		sram_offset += 4;
 	}
 
@@ -450,13 +496,17 @@
 		addr = (0xC105E) & BM(0, 27);
 		addr |= DCC_ADDR_DESCRIPTOR;
 
-		dcc_sram_writel(drvdata, addr, sram_offset);
+		ret = dcc_sram_writel(drvdata, addr, sram_offset);
+		if (ret)
+			goto overstep;
 		sram_offset += 4;
 	}
 
 	/* Setting zero to indicate end of the list */
 	link = DCC_LINK_DESCRIPTOR;
-	dcc_sram_writel(drvdata, link, sram_offset);
+	ret = dcc_sram_writel(drvdata, link, sram_offset);
+	if (ret)
+		goto overstep;
 	sram_offset += 4;
 
 	/* Update ram_cfg and check if the data will overstep */