dsb
        ldr     r0, [r6, r2] /* memory barrier */
 
+       cmp     r10, #TEGRA30
 halted:
        isb
        dsb
-       wfi     /* CPU should be power gated here */
+       wfine   /* CPU should be power gated here */
+       wfeeq
 
        /* !!!FIXME!!! Implement halt failure handler */
        b       halted
 
                reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
                /* clear wfi bitmap */
                reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
-               /* pwr gating on wfi */
-               reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+
+               if (tegra_get_chip_id() == TEGRA30) {
+                       /*
+                        * The wfi doesn't work well on Tegra30 because
+                        * CPU hangs under some odd circumstances after
+                        * power-gating (like memory running off PLLP),
+                        * hence use wfe that is working perfectly fine.
+                        * Note that Tegra30 TRM doc clearly stands that
+                        * wfi should be used for the "Cluster Switching",
+                        * while wfe for the power-gating, just like it
+                        * is done on Tegra20.
+                        */
+                       reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
+               } else {
+                       /* pwr gating on wfi */
+                       reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+               }
                break;
        }
        reg |= FLOW_CTRL_CSR_INTR_FLAG;                 /* clear intr flag */