#else
        esdhc_write32(®s->xfertyp, xfertyp);
 #endif
+
+       /* Mask all irqs */
+       esdhc_write32(®s->irqsigen, 0);
+
        /* Wait for the command to complete */
-       while (!(esdhc_read32(®s->irqstat) & IRQSTAT_CC))
+       while (!(esdhc_read32(®s->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
                ;
 
        irqstat = esdhc_read32(®s->irqstat);
        esdhc_write32(®s->irqstat, irqstat);
 
+       /* Reset CMD and DATA portions on error */
+       if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
+               esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) |
+                             SYSCTL_RSTC);
+               while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC)
+                       ;
+
+               if (data) {
+                       esdhc_write32(®s->sysctl,
+                                     esdhc_read32(®s->sysctl) |
+                                     SYSCTL_RSTD);
+                       while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD))
+                               ;
+               }
+       }
+
        if (irqstat & CMD_ERR)
                return COMM_ERR;
 
        if (irqstat & IRQSTAT_CTOE)
                return TIMEOUT;
 
+       /* Workaround for ESDHC errata ENGcm03648 */
+       if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
+               int timeout = 2500;
+
+               /* Poll on DATA0 line for cmd with busy signal for 250 ms */
+               while (timeout > 0 && !(esdhc_read32(®s->prsstat) &
+                                       PRSSTAT_DAT0)) {
+                       udelay(100);
+                       timeout--;
+               }
+
+               if (timeout <= 0) {
+                       printf("Timeout waiting for DAT0 to go high!\n");
+                       return TIMEOUT;
+               }
+       }
+
        /* Copy the response to the response buffer */
        if (cmd->resp_type & MMC_RSP_136) {
                u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
 
 #define SYSCTL_INITA           0x08000000
 #define SYSCTL_TIMEOUT_MASK    0x000f0000
 #define SYSCTL_CLOCK_MASK      0x0000fff0
-#define SYSCTL_RSTA            0x01000000
 #define SYSCTL_CKEN            0x00000008
 #define SYSCTL_PEREN           0x00000004
 #define SYSCTL_HCKEN           0x00000002
 #define SYSCTL_IPGEN           0x00000001
 #define SYSCTL_RSTA            0x01000000
+#define SYSCTL_RSTC            0x02000000
+#define SYSCTL_RSTD            0x04000000
 
 #define IRQSTAT                        0x0002e030
 #define IRQSTAT_DMAE           (0x10000000)
 #define IRQSTATEN_CC           (0x00000001)
 
 #define PRSSTAT                        0x0002e024
+#define PRSSTAT_DAT0           (0x01000000)
 #define PRSSTAT_CLSL           (0x00800000)
 #define PRSSTAT_WPSPL          (0x00080000)
 #define PRSSTAT_CDPL           (0x00040000)