diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 11eb0e3..b5af6f5 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -143,6 +143,7 @@ static void rsnd_dma_continue(struct rsnd_dma *dma)
 void rsnd_dma_start(struct rsnd_dma *dma)
 {
 	/* push both A and B plane*/
+	dma->offset = 0;
 	dma->submit_loop = 2;
 	__rsnd_dma_start(dma);
 }
@@ -157,12 +158,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma)
 static void rsnd_dma_complete(void *data)
 {
 	struct rsnd_dma *dma = (struct rsnd_dma *)data;
+	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
 	struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
+	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
 	unsigned long flags;
 
 	rsnd_lock(priv, flags);
 
-	dma->complete(dma);
+	/*
+	 * Renesas sound Gen1 needs 1 DMAC,
+	 * Gen2 needs 2 DMAC.
+	 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
+	 * But, Audio-DMAC-peri-peri doesn't have interrupt,
+	 * and this driver is assuming that here.
+	 *
+	 * If Audio-DMAC-peri-peri has interrpt,
+	 * rsnd_dai_pointer_update() will be called twice,
+	 * ant it will breaks io->byte_pos
+	 */
+
+	rsnd_dai_pointer_update(io, io->byte_per_period);
 
 	if (dma->submit_loop)
 		rsnd_dma_continue(dma);
@@ -172,17 +187,21 @@ static void rsnd_dma_complete(void *data)
 
 static void __rsnd_dma_start(struct rsnd_dma *dma)
 {
-	struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
+	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
+	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
+	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct dma_async_tx_descriptor *desc;
 	dma_addr_t buf;
-	size_t len;
+	size_t len = io->byte_per_period;
 	int i;
 
 	for (i = 0; i < dma->submit_loop; i++) {
 
-		if (dma->inquiry(dma, &buf, &len) < 0)
-			return;
+		buf = runtime->dma_addr +
+			rsnd_dai_pointer_offset(io, dma->offset + len);
+		dma->offset = len;
 
 		desc = dmaengine_prep_slave_single(
 			dma->chan, buf, len, dma->dir,
@@ -217,10 +236,7 @@ int rsnd_dma_available(struct rsnd_dma *dma)
 }
 
 int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
-		  int is_play, int id,
-		  int (*inquiry)(struct rsnd_dma *dma,
-				  dma_addr_t *buf, int *len),
-		  int (*complete)(struct rsnd_dma *dma))
+		  int is_play, int id)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct dma_slave_config cfg;
@@ -253,8 +269,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
 		goto rsnd_dma_init_err;
 
 	dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
-	dma->inquiry = inquiry;
-	dma->complete = complete;
 	INIT_WORK(&dma->work, rsnd_dma_do_work);
 
 	return 0;
@@ -307,6 +321,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
 	}
 
 	list_add_tail(&mod->list, &io->head);
+	mod->io = io;
 
 	return 0;
 }
@@ -314,6 +329,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
 int rsnd_dai_disconnect(struct rsnd_mod *mod)
 {
 	list_del_init(&mod->list);
+	mod->io = NULL;
 
 	return 0;
 }
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index c397dc8..b2c717d 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -100,19 +100,16 @@ struct rsnd_dma {
 	struct work_struct	work;
 	struct dma_chan		*chan;
 	enum dma_data_direction dir;
-	int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len);
-	int (*complete)(struct rsnd_dma *dma);
 
 	int submit_loop;
+	int offset; /* it cares A/B plane */
 };
 
 void rsnd_dma_start(struct rsnd_dma *dma);
 void rsnd_dma_stop(struct rsnd_dma *dma);
 int rsnd_dma_available(struct rsnd_dma *dma);
 int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
-	int is_play, int id,
-	int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len),
-	int (*complete)(struct rsnd_dma *dma));
+	int is_play, int id);
 void  rsnd_dma_quit(struct rsnd_priv *priv,
 		    struct rsnd_dma *dma);
 
@@ -137,17 +134,20 @@ struct rsnd_mod_ops {
 		    struct rsnd_dai_stream *io);
 };
 
+struct rsnd_dai_stream;
 struct rsnd_mod {
 	int id;
 	struct rsnd_priv *priv;
 	struct rsnd_mod_ops *ops;
 	struct list_head list; /* connect to rsnd_dai playback/capture */
 	struct rsnd_dma dma;
+	struct rsnd_dai_stream *io;
 };
 
 #define rsnd_mod_to_priv(mod) ((mod)->priv)
 #define rsnd_mod_to_dma(mod) (&(mod)->dma)
 #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
+#define rsnd_mod_to_io(mod) ((mod)->io)
 #define rsnd_mod_id(mod) ((mod)->id)
 #define for_each_rsnd_mod(pos, n, io)	\
 	list_for_each_entry_safe(pos, n, &(io)->head, list)
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index b7f464e..d3371d7 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -64,12 +64,10 @@ struct rsnd_ssi {
 	struct rsnd_mod mod;
 
 	struct rsnd_dai *rdai;
-	struct rsnd_dai_stream *io;
 	u32 cr_own;
 	u32 cr_clk;
 	u32 cr_etc;
 	int err;
-	int dma_offset;
 	unsigned int usrcnt;
 	unsigned int rate;
 };
@@ -286,7 +284,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
 	 * set ssi parameter
 	 */
 	ssi->rdai	= rdai;
-	ssi->io		= io;
 	ssi->cr_own	= cr;
 	ssi->err	= -1; /* ignore 1st error */
 
@@ -305,7 +302,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
 		dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err);
 
 	ssi->rdai	= NULL;
-	ssi->io		= NULL;
 	ssi->cr_own	= 0;
 	ssi->err	= 0;
 
@@ -329,8 +325,9 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
 static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
 {
 	struct rsnd_ssi *ssi = data;
-	struct rsnd_dai_stream *io = ssi->io;
-	u32 status = rsnd_mod_read(&ssi->mod, SSISR);
+	struct rsnd_mod *mod = &ssi->mod;
+	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
+	u32 status = rsnd_mod_read(mod, SSISR);
 	irqreturn_t ret = IRQ_NONE;
 
 	if (io && (status & DIRQ)) {
@@ -347,9 +344,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
 		 * see rsnd_ssi_init()
 		 */
 		if (rsnd_dai_is_play(rdai, io))
-			rsnd_mod_write(&ssi->mod, SSITDR, *buf);
+			rsnd_mod_write(mod, SSITDR, *buf);
 		else
-			*buf = rsnd_mod_read(&ssi->mod, SSIRDR);
+			*buf = rsnd_mod_read(mod, SSIRDR);
 
 		rsnd_dai_pointer_update(io, sizeof(*buf));
 
@@ -394,33 +391,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
 	.stop	= rsnd_ssi_pio_stop,
 };
 
-static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len)
-{
-	struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
-	struct rsnd_dai_stream *io = ssi->io;
-	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
-
-	*len = io->byte_per_period;
-	*buf = runtime->dma_addr +
-		rsnd_dai_pointer_offset(io, ssi->dma_offset + *len);
-	ssi->dma_offset = *len; /* it cares A/B plane */
-
-	return 0;
-}
-
-static int rsnd_ssi_dma_complete(struct rsnd_dma *dma)
-{
-	struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
-	struct rsnd_dai_stream *io = ssi->io;
-	u32 status = rsnd_mod_read(&ssi->mod, SSISR);
-
-	rsnd_ssi_record_error(ssi, status);
-
-	rsnd_dai_pointer_update(ssi->io, io->byte_per_period);
-
-	return 0;
-}
-
 static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
 			      struct rsnd_dai *rdai,
 			      struct rsnd_dai_stream *io)
@@ -430,7 +400,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
 
 	/* enable DMA transfer */
 	ssi->cr_etc = DMEN;
-	ssi->dma_offset = 0;
 
 	rsnd_dma_start(dma);
 
@@ -452,6 +421,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
 
 	ssi->cr_etc = 0;
 
+	rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
+
 	rsnd_ssi_hw_stop(ssi, rdai);
 
 	rsnd_dma_stop(dma);
@@ -585,9 +556,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
 			ret = rsnd_dma_init(
 				priv, rsnd_mod_to_dma(&ssi->mod),
 				rsnd_ssi_is_play(&ssi->mod),
-				pinfo->dma_id,
-				rsnd_ssi_dma_inquiry,
-				rsnd_ssi_dma_complete);
+				pinfo->dma_id);
 			if (ret < 0)
 				dev_info(dev, "SSI DMA failed. try PIO transter\n");
 			else
