ath11k_dbg(ab, ATH11K_DBG_PCI, "soc reset cause:%d\n", val);
 }
 
+static void ath11k_pci_enable_ltssm(struct ath11k_base *ab)
+{
+       u32 val;
+       int i;
+
+       val = ath11k_pci_read32(ab, PCIE_PCIE_PARF_LTSSM);
+
+       /* PCIE link seems very unstable after the Hot Reset*/
+       for (i = 0; val != PARM_LTSSM_VALUE && i < 5; i++) {
+               if (val == 0xffffffff)
+                       mdelay(5);
+
+               ath11k_pci_write32(ab, PCIE_PCIE_PARF_LTSSM, PARM_LTSSM_VALUE);
+               val = ath11k_pci_read32(ab, PCIE_PCIE_PARF_LTSSM);
+       }
+
+       ath11k_dbg(ab, ATH11K_DBG_PCI, "pci ltssm 0x%x\n", val);
+
+       val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST);
+       val |= GCC_GCC_PCIE_HOT_RST_VAL | 0x10;
+       ath11k_pci_write32(ab, GCC_GCC_PCIE_HOT_RST, val);
+       val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST);
+
+       ath11k_dbg(ab, ATH11K_DBG_PCI, "pci pcie_hot_rst 0x%x\n", val);
+
+       mdelay(5);
+}
+
+static void ath11k_pci_clear_all_intrs(struct ath11k_base *ab)
+{
+       /* This is a WAR for PCIE Hotreset.
+        * When target receive Hotreset, but will set the interrupt.
+        * So when download SBL again, SBL will open Interrupt and
+        * receive it, and crash immediately.
+        */
+       ath11k_pci_write32(ab, PCIE_PCIE_INT_ALL_CLEAR, PCIE_INT_CLEAR_ALL);
+}
+
 static void ath11k_pci_force_wake(struct ath11k_base *ab)
 {
        ath11k_pci_write32(ab, PCIE_SOC_WAKE_PCIE_LOCAL_REG, 1);
        mdelay(5);
 }
 
-static void ath11k_pci_sw_reset(struct ath11k_base *ab)
+static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)
 {
-       ath11k_pci_soc_global_reset(ab);
+       if (power_on) {
+               ath11k_pci_enable_ltssm(ab);
+               ath11k_pci_clear_all_intrs(ab);
+       }
+
        ath11k_mhi_clear_vector(ab);
        ath11k_pci_soc_global_reset(ab);
        ath11k_mhi_set_mhictrl_reset(ab);
 
        ab_pci->register_window = 0;
        clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
-       ath11k_pci_sw_reset(ab_pci->ab);
+       ath11k_pci_sw_reset(ab_pci->ab, true);
 
        ret = ath11k_mhi_start(ab_pci);
        if (ret) {
 {
        struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
 
+       ath11k_pci_force_wake(ab_pci->ab);
        ath11k_mhi_stop(ab_pci);
        clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
-       ath11k_pci_force_wake(ab_pci->ab);
-       ath11k_pci_sw_reset(ab_pci->ab);
+       ath11k_pci_sw_reset(ab_pci->ab, false);
 }
 
 static void ath11k_pci_kill_tasklets(struct ath11k_base *ab)