#define rsnd_ssi_of_node(priv) \
        of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
 
-int rsnd_ssi_use_busif(struct rsnd_mod *mod)
+int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
 {
        struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
        int use_busif = 0;
 
        if (!rsnd_ssi_is_dma_mode(mod))
                rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
 }
 
-static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
+static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
 {
        struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod);
        struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
        struct device *dev = rsnd_priv_to_dev(priv);
        u32 cr;
                        struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
 
                        if (ssi_parent)
-                               rsnd_ssi_hw_stop(ssi_parent);
+                               rsnd_ssi_hw_stop(io, ssi_parent);
                        else
                                rsnd_ssi_master_clk_stop(ssi);
                }
 {
        struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
 
-       rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(mod));
+       rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io, mod));
 
        rsnd_ssi_hw_start(ssi, io);
 
 
        rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
 
-       rsnd_ssi_hw_stop(ssi);
+       rsnd_ssi_hw_stop(io, ssi);
 
        rsnd_src_ssiu_stop(mod, io);
 
        return 0;
 }
 
-static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
+static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
+                                struct rsnd_dai_stream *io)
 {
-       struct rsnd_ssi *ssi = data;
-       struct rsnd_mod *mod = &ssi->mod;
+       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
        int is_dma = rsnd_ssi_is_dma_mode(mod);
        u32 status;
        bool elapsed = false;
 
        if (elapsed)
                rsnd_dai_period_elapsed(io);
+}
+
+static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
+{
+       struct rsnd_mod *mod = data;
+
+       rsnd_mod_interrupt(mod, __rsnd_ssi_interrupt);
 
        return IRQ_HANDLED;
 }
        ret = devm_request_irq(dev, ssi->info->irq,
                               rsnd_ssi_interrupt,
                               IRQF_SHARED,
-                              dev_name(dev), ssi);
+                              dev_name(dev), mod);
 
        return ret;
 }
        ret = devm_request_irq(dev, ssi->info->irq,
                               rsnd_ssi_interrupt,
                               IRQF_SHARED,
-                              dev_name(dev), ssi);
+                              dev_name(dev), mod);
        if (ret)
                return ret;
 
        int is_play = rsnd_io_is_play(io);
        char *name;
 
-       if (rsnd_ssi_use_busif(mod))
+       if (rsnd_ssi_use_busif(io, mod))
                name = is_play ? "rxu" : "txu";
        else
                name = is_play ? "rx" : "tx";