Browse Source

cnss2: Support conditional power off in the LPM for HST/HSP

Should power off HST/HSP if it only finished pcie
enumeration without WLAN driver load before do
LPM. Otherwise, it will cause the mhi state switch
from INIT to SUSPEND failure that block LPM.

Change-Id: Ia2c5fbf0a2bf9c088be548eb533d7836f45a3cfd
CRs-Fixed: 3283893
Chaoli Zhou 2 years ago
parent
commit
8fdf81fea5
1 changed files with 22 additions and 1 deletions
  1. 22 1
      cnss2/pci.c

+ 22 - 1
cnss2/pci.c

@@ -672,6 +672,7 @@ static struct cnss_print_optimize print_optimize;
 
 static int cnss_pci_update_fw_name(struct cnss_pci_data *pci_priv);
 static void cnss_pci_suspend_pwroff(struct pci_dev *pci_dev);
+static bool cnss_should_suspend_pwroff(struct pci_dev *pci_dev);
 
 
 #if IS_ENABLED(CONFIG_MHI_BUS_MISC)
@@ -3612,7 +3613,8 @@ out:
 static int cnss_pci_suspend(struct device *dev)
 {
 	int ret = 0;
-	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
 	struct cnss_plat_data *plat_priv;
 
 	if (!pci_priv)
@@ -3625,6 +3627,25 @@ static int cnss_pci_suspend(struct device *dev)
 	if (!cnss_is_device_powered_on(plat_priv))
 		goto out;
 
+	/* No mhi state bit set if only finish pcie enumeration,
+	 * so test_bit is not applicable to check if it is INIT state.
+	 */
+	if (pci_priv->mhi_state == CNSS_MHI_INIT) {
+		bool suspend = cnss_should_suspend_pwroff(pci_dev);
+
+		/* Do PCI link suspend and power off in the LPM case
+		 * if chipset didn't do that after pcie enumeration.
+		 */
+		if (!suspend) {
+			ret = cnss_suspend_pci_link(pci_priv);
+			if (ret)
+				cnss_pr_err("Failed to suspend PCI link, err = %d\n",
+					    ret);
+			cnss_power_off_device(plat_priv);
+			goto out;
+		}
+	}
+
 	if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks) &&
 	    pci_priv->drv_supported) {
 		pci_priv->drv_connected_last =