MLK-22364 brcmfmac: double check the D3 ACK state when wait event timeout
authorFugang Duan <fugang.duan@nxp.com>
Tue, 6 Aug 2019 06:04:58 +0000 (14:04 +0800)
committerFugang Duan <fugang.duan@nxp.com>
Tue, 6 Aug 2019 09:29:46 +0000 (17:29 +0800)
When system suspend, pcie bus write BRCMF_H2D_HOST_D3_INFORM cmd
into tcm32 mem to let host enter D3 mode, and wait the D3 ACK
interrupt. But sometime, the interrupt is comming lately then
cause wait event timeout, so double check the D3 ACK state.

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Acked-by: Richard Zhu <hongxing.zhu@nxp.com>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c

index 5e289ea..6b85bd3 100644 (file)
@@ -1962,9 +1962,21 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
        wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed,
                           BRCMF_PCIE_MBDATA_TIMEOUT);
        if (!devinfo->mbdata_completed) {
-               brcmf_err("Timeout on response for entering D3 substate\n");
-               brcmf_bus_change_state(bus, BRCMF_BUS_UP);
-               return -EIO;
+               struct brcmf_pcie_shared_info *shared;
+               u32 addr;
+               u32 dtoh_mb_data;
+
+               shared = &devinfo->shared;
+               addr = shared->dtoh_mb_data_addr;
+               dtoh_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
+
+               if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) {
+                       brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n");
+                       devinfo->mbdata_completed = true;
+               }
+
+               if (!devinfo->mbdata_completed)
+                       brcmf_err("Timeout on response for entering D3 substate\n");
        }
 
        devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
@@ -1972,7 +1984,6 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
        return 0;
 }
 
-
 static int brcmf_pcie_pm_leave_D3(struct device *dev)
 {
        struct brcmf_pciedev_info *devinfo;