slimbus: Specify number of channels for the group in group handle

Use group handle instead of next element in channel's data structure
to identify how many channels were specified by a client in the group.
That way clients can specify different number of channels for shared
channels, and work with their own client-handle. Note that sequence of
channel still matters (so 2 clients sharing a channel should not
specify channels in different order, otherwise scheduling of the
channels will not be in the correct order)

CRs-Fixed: 415109
Change-Id: Idd636a500ee6449b16648a234b9e76fad21f2fcc
Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 72e5ff0..4e8312b 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1124,6 +1124,7 @@
 		u16 chh[40];
 		struct slim_ch prop;
 		u32 exp;
+		u16 *grph = NULL;
 		u8 coeff, cc;
 		u8 prrate = buf[6];
 		if (len <= 8)
@@ -1144,6 +1145,9 @@
 					return ret;
 				if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
 					sat->satch[j].req_def++;
+				/* First channel in group from satellite */
+				if (i == 8)
+					grph = &sat->satch[j].chanh;
 				continue;
 			}
 			if (sat->nsatch >= MSM_MAX_SATCH)
@@ -1155,6 +1159,8 @@
 			sat->satch[j].chanh = chh[i - 8];
 			if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
 				sat->satch[j].req_def++;
+			if (i == 8)
+				grph = &sat->satch[j].chanh;
 			sat->nsatch++;
 		}
 		prop.dataf = (enum slim_ch_dataf)((buf[3] & 0xE0) >> 5);
@@ -1175,10 +1181,12 @@
 					true, &chh[0]);
 		else
 			ret = slim_define_ch(&sat->satcl, &prop,
-					&chh[0], 1, false, NULL);
+					chh, 1, true, &chh[0]);
 		dev_dbg(dev->dev, "define sat grp returned:%d", ret);
 		if (ret)
 			return ret;
+		else if (grph)
+			*grph = chh[0];
 
 		/* part of group so activating 1 will take care of rest */
 		if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
@@ -1311,6 +1319,8 @@
 						slim_control_ch(&sat->satcl,
 							sat->satch[i].chanh,
 							SLIM_CH_REMOVE, true);
+						slim_dealloc_ch(&sat->satcl,
+							sat->satch[i].chanh);
 						sat->satch[i].reconf = false;
 					}
 				}
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 977e6f3..1a8cc0f 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -26,6 +26,7 @@
 #define SLIM_HDL_TO_PORT(hdl)	((u32)(hdl) & 0xFF)
 
 #define SLIM_HDL_TO_CHIDX(hdl)	((u16)(hdl) & 0xFF)
+#define SLIM_GRP_TO_NCHAN(hdl)	((u16)(hdl >> 8) & 0xFF)
 
 #define SLIM_SLAVE_PORT(p, la)	(((la)<<16) | (p))
 #define SLIM_MGR_PORT(p)	((0xFF << 16) | (p))
@@ -1838,7 +1839,7 @@
 	}
 
 	if (grp)
-		*grph = chanh[0];
+		*grph = ((nchan << 8) | SLIM_HDL_TO_CHIDX(chanh[0]));
 	for (i = 0; i < nchan; i++) {
 		u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
 		struct slim_ich *slc = &ctrl->chans[chan];
@@ -2861,6 +2862,7 @@
 	int ret = 0;
 	/* Get rid of the group flag in MSB if any */
 	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+	u8 nchan = 0;
 	struct slim_ich *slc = &ctrl->chans[chan];
 	if (!(slc->nextgrp & SLIM_START_GRP))
 		return -EINVAL;
@@ -2921,9 +2923,10 @@
 			}
 		}
 
-		if (!(slc->nextgrp & SLIM_END_GRP))
+		nchan++;
+		if (nchan < SLIM_GRP_TO_NCHAN(chanh))
 			chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
-	} while (!(slc->nextgrp & SLIM_END_GRP));
+	} while (nchan < SLIM_GRP_TO_NCHAN(chanh));
 	mutex_unlock(&ctrl->m_ctrl);
 	if (!ret && commit == true)
 		ret = slim_reconfigure_now(sb);