struct rsnd_kctrl_cfg_s sen;  /* sync convert enable */
        struct rsnd_kctrl_cfg_s sync; /* sync convert */
        u32 convert_rate; /* sampling rate convert */
-       int err;
        int irq;
 };
 
        rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val);
 }
 
-static bool rsnd_src_record_error(struct rsnd_mod *mod)
+static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        u32 val0, val1;
                val0 = val0 & 0xffff;
 
        if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) ||
-           (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1)) {
-               struct rsnd_src *src = rsnd_mod_to_src(mod);
-
-               src->err++;
+           (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1))
                ret = true;
-       }
 
        return ret;
 }
 
        rsnd_src_irq_enable(mod);
 
-       src->err = 0;
-
        /* reset sync convert_rate */
        src->sync.val = 0;
 
                         struct rsnd_priv *priv)
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
-       struct device *dev = rsnd_priv_to_dev(priv);
 
        rsnd_src_irq_disable(mod);
 
 
        rsnd_mod_power_off(mod);
 
-       if (src->err)
-               dev_warn(dev, "%s[%d] under/over flow err = %d\n",
-                        rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
-
        src->convert_rate = 0;
 
        /* reset sync convert_rate */
                                 struct rsnd_dai_stream *io)
 {
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-       struct rsnd_src *src = rsnd_mod_to_src(mod);
-       struct device *dev = rsnd_priv_to_dev(priv);
+       bool stop = false;
 
        spin_lock(&priv->lock);
 
        if (!rsnd_io_is_working(io))
                goto rsnd_src_interrupt_out;
 
-       if (rsnd_src_record_error(mod)) {
-
-               dev_dbg(dev, "%s[%d] restart\n",
-                       rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-               rsnd_src_stop(mod, io, priv);
-               rsnd_src_start(mod, io, priv);
-       }
-
-       if (src->err > 1024) {
-               rsnd_src_irq_disable(mod);
-
-               dev_warn(dev, "no more %s[%d] restart\n",
-                        rsnd_mod_name(mod), rsnd_mod_id(mod));
-       }
+       if (rsnd_src_error_occurred(mod))
+               stop = true;
 
        rsnd_src_status_clear(mod);
 rsnd_src_interrupt_out:
 
        spin_unlock(&priv->lock);
+
+       if (stop)
+               snd_pcm_stop_xrun(io->substream);
 }
 
 static irqreturn_t rsnd_src_interrupt(int irq, void *data)
 
        u32 wsr;
        int chan;
        int rate;
-       int err;
        int irq;
        unsigned int usrcnt;
 };
        if (ret < 0)
                return ret;
 
-       ssi->err        = -1; /* ignore 1st error */
-
        /* clear error status */
        rsnd_ssi_status_clear(mod);
 
        }
 
        if (!rsnd_ssi_is_parent(mod, io)) {
-               if (ssi->err > 0)
-                       dev_warn(dev, "%s[%d] under/over flow err = %d\n",
-                                rsnd_mod_name(mod), rsnd_mod_id(mod),
-                                ssi->err);
-
                ssi->cr_own     = 0;
-               ssi->err        = 0;
 
                rsnd_ssi_irq_disable(mod);
        }
        return 0;
 }
 
-static u32 rsnd_ssi_record_error(struct rsnd_ssi *ssi)
-{
-       struct rsnd_mod *mod = rsnd_mod_get(ssi);
-       u32 status = rsnd_ssi_status_get(mod);
-
-       /* under/over flow error */
-       if (status & (UIRQ | OIRQ))
-               ssi->err++;
-
-       return status;
-}
-
-static int __rsnd_ssi_start(struct rsnd_mod *mod,
-                           struct rsnd_dai_stream *io,
-                           struct rsnd_priv *priv)
+static int rsnd_ssi_start(struct rsnd_mod *mod,
+                         struct rsnd_dai_stream *io,
+                         struct rsnd_priv *priv)
 {
        struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
        u32 cr;
        return 0;
 }
 
-static int rsnd_ssi_start(struct rsnd_mod *mod,
-                         struct rsnd_dai_stream *io,
-                         struct rsnd_priv *priv)
+static int rsnd_ssi_stop(struct rsnd_mod *mod,
+                        struct rsnd_dai_stream *io,
+                        struct rsnd_priv *priv)
 {
+       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+       u32 cr;
+
        /*
-        * no limit to start
+        * don't stop if not last user
         * see also
-        *      rsnd_ssi_stop
+        *      rsnd_ssi_start
         *      rsnd_ssi_interrupt
         */
-       return __rsnd_ssi_start(mod, io, priv);
-}
-
-static int __rsnd_ssi_stop(struct rsnd_mod *mod,
-                          struct rsnd_dai_stream *io,
-                          struct rsnd_priv *priv)
-{
-       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
-       u32 cr;
+       if (ssi->usrcnt > 1)
+               return 0;
 
        /*
         * disable all IRQ,
        return 0;
 }
 
-static int rsnd_ssi_stop(struct rsnd_mod *mod,
-                        struct rsnd_dai_stream *io,
-                        struct rsnd_priv *priv)
-{
-       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
-
-       /*
-        * don't stop if not last user
-        * see also
-        *      rsnd_ssi_start
-        *      rsnd_ssi_interrupt
-        */
-       if (ssi->usrcnt > 1)
-               return 0;
-
-       return __rsnd_ssi_stop(mod, io, priv);
-}
-
 static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
                                 struct rsnd_dai_stream *io)
 {
-       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-       struct device *dev = rsnd_priv_to_dev(priv);
        int is_dma = rsnd_ssi_is_dma_mode(mod);
        u32 status;
        bool elapsed = false;
+       bool stop = false;
 
        spin_lock(&priv->lock);
 
        if (!rsnd_io_is_working(io))
                goto rsnd_ssi_interrupt_out;
 
-       status = rsnd_ssi_record_error(ssi);
+       status = rsnd_ssi_status_get(mod);
 
        /* PIO only */
        if (!is_dma && (status & DIRQ)) {
        }
 
        /* DMA only */
-       if (is_dma && (status & (UIRQ | OIRQ))) {
-               /*
-                * restart SSI
-                */
-               dev_dbg(dev, "%s[%d] restart\n",
-                       rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-               __rsnd_ssi_stop(mod, io, priv);
-               __rsnd_ssi_start(mod, io, priv);
-       }
-
-       if (ssi->err > 1024) {
-               rsnd_ssi_irq_disable(mod);
-
-               dev_warn(dev, "no more %s[%d] restart\n",
-                        rsnd_mod_name(mod), rsnd_mod_id(mod));
-       }
+       if (is_dma && (status & (UIRQ | OIRQ)))
+               stop = true;
 
        rsnd_ssi_status_clear(mod);
 rsnd_ssi_interrupt_out:
 
        if (elapsed)
                rsnd_dai_period_elapsed(io);
+
+       if (stop)
+               snd_pcm_stop_xrun(io->substream);
+
 }
 
 static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)