return -EAGAIN;
 }
 
+/*
+ * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
+ * need to be confirmed with a write to MCP_CONFIG_UPDATE
+ */
+static int cdns_update_config(struct sdw_cdns *cdns)
+{
+       int ret;
+
+       ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
+                            CDNS_MCP_CONFIG_UPDATE_BIT);
+       if (ret < 0)
+               dev_err(cdns->dev, "Config update timedout\n");
+
+       return ret;
+}
+
 /*
  * debugfs
  */
 /*
  * init routines
  */
-static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
+
+/**
+ * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
+{
+       /* program maximum length reset to be safe */
+       cdns_updatel(cdns, CDNS_MCP_CONTROL,
+                    CDNS_MCP_CONTROL_RST_DELAY,
+                    CDNS_MCP_CONTROL_RST_DELAY);
+
+       /* use hardware generated reset */
+       cdns_updatel(cdns, CDNS_MCP_CONTROL,
+                    CDNS_MCP_CONTROL_HW_RST,
+                    CDNS_MCP_CONTROL_HW_RST);
+
+       /* enable bus operations with clock and data */
+       cdns_updatel(cdns, CDNS_MCP_CONFIG,
+                    CDNS_MCP_CONFIG_OP,
+                    CDNS_MCP_CONFIG_OP_NORMAL);
+
+       /* commit changes */
+       return cdns_update_config(cdns);
+}
+EXPORT_SYMBOL(sdw_cdns_exit_reset);
+
+/**
+ * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 {
        u32 mask;
 
 
        cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 
-       return 0;
-}
-
-/**
- * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
- * @cdns: Cadence instance
- */
-int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
-{
-       int ret;
-
-       _cdns_enable_interrupt(cdns);
-       ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
-                            CDNS_MCP_CONFIG_UPDATE_BIT);
-       if (ret < 0)
-               dev_err(cdns->dev, "Config update timedout\n");
-
-       return ret;
+       /* commit changes */
+       return cdns_update_config(cdns);
 }
 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 
        cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
        cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
 
+       /* flush command FIFOs */
+       cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST,
+                    CDNS_MCP_CONTROL_CMD_RST);
+
        /* Set cmd accept mode */
        cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
                     CDNS_MCP_CONTROL_CMD_ACCEPT);
        /* Set cmd mode for Tx and Rx cmds */
        val &= ~CDNS_MCP_CONFIG_CMD;
 
-       /* Set operation to normal */
-       val &= ~CDNS_MCP_CONFIG_OP;
-       val |= CDNS_MCP_CONFIG_OP_NORMAL;
-
        cdns_writel(cdns, CDNS_MCP_CONFIG, val);
 
-       return 0;
+       /* commit changes */
+       return cdns_update_config(cdns);
 }
 EXPORT_SYMBOL(sdw_cdns_init);