u32 m_param)
 {
        dma_addr_t rx_dma;
-       enum geni_se_xfer_mode mode;
-       unsigned long time_left = XFER_TIMEOUT;
+       unsigned long time_left;
        void *dma_buf;
+       struct geni_se *se = &gi2c->se;
+       size_t len = msg->len;
 
-       gi2c->cur = msg;
-       mode = GENI_SE_FIFO;
        dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
        if (dma_buf)
-               mode = GENI_SE_DMA;
-
-       geni_se_select_mode(&gi2c->se, mode);
-       writel_relaxed(msg->len, gi2c->se.base + SE_I2C_RX_TRANS_LEN);
-       geni_se_setup_m_cmd(&gi2c->se, I2C_READ, m_param);
-       if (mode == GENI_SE_DMA) {
-               int ret;
-
-               ret = geni_se_rx_dma_prep(&gi2c->se, dma_buf, msg->len,
-                                                               &rx_dma);
-               if (ret) {
-                       mode = GENI_SE_FIFO;
-                       geni_se_select_mode(&gi2c->se, mode);
-                       i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-               }
+               geni_se_select_mode(se, GENI_SE_DMA);
+       else
+               geni_se_select_mode(se, GENI_SE_FIFO);
+
+       writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
+       geni_se_setup_m_cmd(se, I2C_READ, m_param);
+
+       if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
+               geni_se_select_mode(se, GENI_SE_FIFO);
+               i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+               dma_buf = NULL;
        }
 
        time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
                geni_i2c_abort_xfer(gi2c);
 
        gi2c->cur_rd = 0;
-       if (mode == GENI_SE_DMA) {
+       if (dma_buf) {
                if (gi2c->err)
                        geni_i2c_rx_fsm_rst(gi2c);
-               geni_se_rx_dma_unprep(&gi2c->se, rx_dma, msg->len);
+               geni_se_rx_dma_unprep(se, rx_dma, len);
                i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
        }
+
        return gi2c->err;
 }
 
                                u32 m_param)
 {
        dma_addr_t tx_dma;
-       enum geni_se_xfer_mode mode;
        unsigned long time_left;
        void *dma_buf;
+       struct geni_se *se = &gi2c->se;
+       size_t len = msg->len;
 
-       gi2c->cur = msg;
-       mode = GENI_SE_FIFO;
        dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
        if (dma_buf)
-               mode = GENI_SE_DMA;
-
-       geni_se_select_mode(&gi2c->se, mode);
-       writel_relaxed(msg->len, gi2c->se.base + SE_I2C_TX_TRANS_LEN);
-       geni_se_setup_m_cmd(&gi2c->se, I2C_WRITE, m_param);
-       if (mode == GENI_SE_DMA) {
-               int ret;
-
-               ret = geni_se_tx_dma_prep(&gi2c->se, dma_buf, msg->len,
-                                                               &tx_dma);
-               if (ret) {
-                       mode = GENI_SE_FIFO;
-                       geni_se_select_mode(&gi2c->se, mode);
-                       i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-               }
+               geni_se_select_mode(se, GENI_SE_DMA);
+       else
+               geni_se_select_mode(se, GENI_SE_FIFO);
+
+       writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
+       geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
+
+       if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
+               geni_se_select_mode(se, GENI_SE_FIFO);
+               i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+               dma_buf = NULL;
        }
 
-       if (mode == GENI_SE_FIFO) /* Get FIFO IRQ */
-               writel_relaxed(1, gi2c->se.base + SE_GENI_TX_WATERMARK_REG);
+       if (!dma_buf) /* Get FIFO IRQ */
+               writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);
 
        time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
        if (!time_left)
                geni_i2c_abort_xfer(gi2c);
 
        gi2c->cur_wr = 0;
-       if (mode == GENI_SE_DMA) {
+       if (dma_buf) {
                if (gi2c->err)
                        geni_i2c_tx_fsm_rst(gi2c);
-               geni_se_tx_dma_unprep(&gi2c->se, tx_dma, msg->len);
+               geni_se_tx_dma_unprep(se, tx_dma, len);
                i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
        }
+
        return gi2c->err;
 }
 
 
                m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK);
 
+               gi2c->cur = &msgs[i];
                if (msgs[i].flags & I2C_M_RD)
                        ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param);
                else