diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 86e46cbf9e14..475f8cb14492 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -38,6 +38,12 @@ struct asoc_simple_jack {
 	struct snd_soc_jack_gpio gpio;
 };
 
+struct prop_nums {
+	int cpus;
+	int codecs;
+	int platforms;
+};
+
 struct asoc_simple_priv {
 	struct snd_soc_card snd_card;
 	struct simple_dai_props {
@@ -48,6 +54,7 @@ struct asoc_simple_priv {
 		struct snd_soc_dai_link_component *platforms;
 		struct asoc_simple_data adata;
 		struct snd_soc_codec_conf *codec_conf;
+		struct prop_nums num;
 		unsigned int mclk_fs;
 	} *dai_props;
 	struct asoc_simple_jack hp_jack;
@@ -71,6 +78,7 @@ struct link_info {
 	int link; /* number of link */
 	int conf; /* number of codec_conf */
 	int cpu;  /* turn for CPU / Codec */
+	struct prop_nums num[SNDRV_MINOR_DEVICES];
 };
 
 int asoc_simple_parse_daifmt(struct device *dev,
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index ee1d924d68e5..a3ca9a99fccd 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -628,6 +628,15 @@ static int graph_count_noml(struct asoc_simple_priv *priv,
 {
 	struct device *dev = simple_priv_to_dev(priv);
 
+	if (li->link >= SNDRV_MINOR_DEVICES) {
+		dev_err(dev, "too many links\n");
+		return -EINVAL;
+	}
+
+	li->num[li->link].cpus		= 1;
+	li->num[li->link].codecs	= 1;
+	li->num[li->link].platforms	= 1;
+
 	li->link += 1; /* 1xCPU-Codec */
 	li->dais += 2; /* 1xCPU + 1xCodec */
 
@@ -643,10 +652,23 @@ static int graph_count_dpcm(struct asoc_simple_priv *priv,
 {
 	struct device *dev = simple_priv_to_dev(priv);
 
+	if (li->link >= SNDRV_MINOR_DEVICES) {
+		dev_err(dev, "too many links\n");
+		return -EINVAL;
+	}
+
 	if (li->cpu) {
+		li->num[li->link].cpus		= 1;
+		li->num[li->link].codecs	= 1;
+		li->num[li->link].platforms	= 1;
+
 		li->link++; /* 1xCPU-dummy */
 		li->dais++; /* 1xCPU */
 	} else {
+		li->num[li->link].cpus		= 1;
+		li->num[li->link].codecs	= 1;
+		li->num[li->link].platforms	= 1;
+
 		li->link++; /* 1xdummy-Codec */
 		li->conf++; /* 1xdummy-Codec */
 		li->dais++; /* 1xCodec */
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 3010ff63c71d..1606b9bc6b71 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -604,13 +604,27 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
 	struct asoc_simple_dai *dais;
 	struct snd_soc_dai_link_component *dlcs;
 	struct snd_soc_codec_conf *cconf = NULL;
-	int i;
+	int i, dai_num = 0, dlc_num = 0;
 
 	dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL);
 	dai_link  = devm_kcalloc(dev, li->link, sizeof(*dai_link),  GFP_KERNEL);
-	dais      = devm_kcalloc(dev, li->dais, sizeof(*dais),      GFP_KERNEL);
-	dlcs      = devm_kcalloc(dev, li->link * 3, sizeof(*dai_props), GFP_KERNEL);
-	if (!dai_props || !dai_link || !dais || !dlcs)
+	if (!dai_props || !dai_link)
+		return -ENOMEM;
+
+	/*
+	 * dais (= CPU+Codec)
+	 * dlcs (= CPU+Codec+Platform)
+	 */
+	for (i = 0; i < li->link; i++) {
+		int cc = li->num[i].cpus + li->num[i].codecs;
+
+		dai_num += cc;
+		dlc_num += cc + li->num[i].platforms;
+	}
+
+	dais = devm_kcalloc(dev, dai_num, sizeof(*dais),      GFP_KERNEL);
+	dlcs = devm_kcalloc(dev, dlc_num, sizeof(*dai_props), GFP_KERNEL);
+	if (!dais || !dlcs)
 		return -ENOMEM;
 
 	if (li->conf) {
@@ -619,24 +633,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
 			return -ENOMEM;
 	}
 
-	/*
-	 * "platform" might be removed
-	 * see
-	 *	simple-card-utils.c :: asoc_simple_canonicalize_platform()
-	 */
-	for (i = 0; i < li->link; i++) {
-		dai_props[i].cpus	= dlcs + (3 * i) + 0;
-		dai_props[i].codecs	= dlcs + (3 * i) + 1;
-		dai_props[i].platforms	= dlcs + (3 * i) + 2;
-
-		dai_link[i].cpus		= dai_props[i].cpus;
-		dai_link[i].num_cpus		= 1;
-		dai_link[i].codecs		= dai_props[i].codecs;
-		dai_link[i].num_codecs		= 1;
-		dai_link[i].platforms		= dai_props[i].platforms;
-		dai_link[i].num_platforms	= 1;
-	}
-
 	priv->dai_props		= dai_props;
 	priv->dai_link		= dai_link;
 	priv->dais		= dais;
@@ -648,6 +644,38 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
 	card->codec_conf	= cconf;
 	card->num_configs	= li->conf;
 
+	for (i = 0; i < li->link; i++) {
+		if (li->num[i].cpus) {
+			/* Normal CPU */
+			dai_props[i].cpus	=
+			dai_link[i].cpus	= dlcs;
+			dai_props[i].num.cpus	=
+			dai_link[i].num_cpus	= li->num[i].cpus;
+
+			dlcs += li->num[i].cpus;
+		}
+
+		if (li->num[i].codecs) {
+			/* Normal Codec */
+			dai_props[i].codecs	=
+			dai_link[i].codecs	= dlcs;
+			dai_props[i].num.codecs	=
+			dai_link[i].num_codecs	= li->num[i].codecs;
+
+			dlcs += li->num[i].codecs;
+		}
+
+		if (li->num[i].platforms) {
+			/* Have Platform */
+			dai_props[i].platforms		=
+			dai_link[i].platforms		= dlcs;
+			dai_props[i].num.platforms	=
+			dai_link[i].num_platforms	= li->num[i].platforms;
+
+			dlcs += li->num[i].platforms;
+		}
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(asoc_simple_init_priv);
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 41aa40765a8d..f60e809d723b 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -499,6 +499,17 @@ static int simple_count_noml(struct asoc_simple_priv *priv,
 			     struct device_node *codec,
 			     struct link_info *li, bool is_top)
 {
+	if (li->link >= SNDRV_MINOR_DEVICES) {
+		struct device *dev = simple_priv_to_dev(priv);
+
+		dev_err(dev, "too many links\n");
+		return -EINVAL;
+	}
+
+	li->num[li->link].cpus		= 1;
+	li->num[li->link].codecs	= 1;
+	li->num[li->link].platforms	= 1;
+
 	li->link += 1;
 	li->dais += 2;
 
@@ -510,10 +521,25 @@ static int simple_count_dpcm(struct asoc_simple_priv *priv,
 			     struct device_node *codec,
 			     struct link_info *li, bool is_top)
 {
+	if (li->link >= SNDRV_MINOR_DEVICES) {
+		struct device *dev = simple_priv_to_dev(priv);
+
+		dev_err(dev, "too many links\n");
+		return -EINVAL;
+	}
+
 	if (li->cpu) {
+		li->num[li->link].cpus		= 1;
+		li->num[li->link].codecs	= 1;
+		li->num[li->link].platforms	= 1;
+
 		li->link++; /* CPU-dummy */
 		li->dais++;
 	} else {
+		li->num[li->link].cpus		= 1;
+		li->num[li->link].codecs	= 1;
+		li->num[li->link].platforms	= 1;
+
 		li->link++; /* dummy-Codec */
 		li->dais++;
 		li->conf++;
@@ -575,6 +601,10 @@ static void simple_get_dais_count(struct asoc_simple_priv *priv,
 	 *	=> 1 ccnf  = 1xdummy-Codec
 	 */
 	if (!top) {
+		li->num[0].cpus		= 1;
+		li->num[0].codecs	= 1;
+		li->num[0].platforms	= 1;
+
 		li->link = 1;
 		li->dais = 2;
 		li->conf = 0;
