Jelajahi Sumber

qcacld-3.0: Use PM wakelock to protect firmware downloading

To protect firmware not downloaded in system suspend, acquire/release
the cnss semaphore cnss_pm_sem. It is complex, and cnss function
cnss_pm_notify may trigger dead lock issue once PM_POST_SUSPEND is
ahead of PM_SUSPEND_PREPARE.

Optimize code to use PM wakelock API to protect firmware downloading.

Change-Id: I533c373b85f554fbcceb562d9f56c6b88e5155bb
CRs-Fixed: 3280247
Yu Ouyang 2 tahun lalu
induk
melakukan
cc2bf81627

+ 4 - 0
core/bmi/src/bmi.c

@@ -559,6 +559,9 @@ QDF_STATUS ol_cds_init(qdf_device_t qdf_dev, void *hif_ctx)
 	qdf_create_work(qdf_dev, &ol_info->fw_indication_work,
 			fw_indication_work_handler, ol_info);
 
+	qdf_wake_lock_create(&ol_info->fw_dl_wakelock,
+			     "fw_download_wakelock");
+
 	return status;
 }
 
@@ -574,5 +577,6 @@ void ol_cds_free(void)
 	if (NO_BMI)
 		return;
 
+	qdf_wake_lock_destroy(&ol_info->fw_dl_wakelock);
 	cds_free_context(QDF_MODULE_ID_BMI, ol_info);
 }

+ 2 - 0
core/bmi/src/i_bmi.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -165,6 +166,7 @@ struct ol_context {
 	qdf_device_t qdf_dev;
 	qdf_work_t ramdump_work;
 	qdf_work_t fw_indication_work;
+	qdf_wake_lock_t fw_dl_wakelock;
 	struct hif_opaque_softc *scn;
 	struct targetdef_t {
 		struct targetdef_s *targetdef;

+ 4 - 4
core/bmi/src/ol_fw.c

@@ -518,15 +518,15 @@ static int
 ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file,
 		     uint32_t address, bool compressed)
 {
+#define MAX_WAKELOCK_FOR_FW_DOWNLOAD 1000	//1s
 	int ret;
-	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
 
-	/* Wait until suspend and resume are completed before loading FW */
-	pld_lock_pm_sem(qdf_dev->dev);
+	qdf_wake_lock_timeout_acquire(&ol_ctx->fw_dl_wakelock,
+				      MAX_WAKELOCK_FOR_FW_DOWNLOAD);
 
 	ret = __ol_transfer_bin_file(ol_ctx, file, address, compressed);
 
-	pld_release_pm_sem(qdf_dev->dev);
+	qdf_wake_lock_release(&ol_ctx->fw_dl_wakelock, 0);
 
 	return ret;
 }

+ 0 - 2
core/pld/inc/pld_common.h

@@ -854,8 +854,6 @@ int pld_get_mhi_state(struct device *dev);
 int pld_is_pci_ep_awake(struct device *dev);
 int pld_get_ce_id(struct device *dev, int irq);
 int pld_get_irq(struct device *dev, int ce_id);
-void pld_lock_pm_sem(struct device *dev);
-void pld_release_pm_sem(struct device *dev);
 void pld_lock_reg_window(struct device *dev, unsigned long *flags);
 void pld_unlock_reg_window(struct device *dev, unsigned long *flags);
 int pld_get_pci_slot(struct device *dev);

+ 0 - 56
core/pld/src/pld_common.c

@@ -1717,62 +1717,6 @@ int pld_get_irq(struct device *dev, int ce_id)
 	return ret;
 }
 
-/**
- * pld_lock_pm_sem() - Lock PM semaphore
- * @dev: device
- *
- * Return: void
- */
-void pld_lock_pm_sem(struct device *dev)
-{
-	switch (pld_get_bus_type(dev)) {
-	case PLD_BUS_TYPE_PCIE:
-		pld_pcie_lock_pm_sem(dev);
-		break;
-	case PLD_BUS_TYPE_PCIE_FW_SIM:
-	case PLD_BUS_TYPE_IPCI_FW_SIM:
-	case PLD_BUS_TYPE_SNOC_FW_SIM:
-	case PLD_BUS_TYPE_SNOC:
-	case PLD_BUS_TYPE_IPCI:
-		break;
-	case PLD_BUS_TYPE_SDIO:
-		break;
-	case PLD_BUS_TYPE_USB:
-		break;
-	default:
-		pr_err("Invalid device type\n");
-		break;
-	}
-}
-
-/**
- * pld_release_pm_sem() - Release PM semaphore
- * @dev: device
- *
- * Return: void
- */
-void pld_release_pm_sem(struct device *dev)
-{
-	switch (pld_get_bus_type(dev)) {
-	case PLD_BUS_TYPE_PCIE:
-		pld_pcie_release_pm_sem(dev);
-		break;
-	case PLD_BUS_TYPE_PCIE_FW_SIM:
-	case PLD_BUS_TYPE_IPCI_FW_SIM:
-	case PLD_BUS_TYPE_SNOC_FW_SIM:
-	case PLD_BUS_TYPE_SNOC:
-	case PLD_BUS_TYPE_IPCI:
-		break;
-	case PLD_BUS_TYPE_SDIO:
-		break;
-	case PLD_BUS_TYPE_USB:
-		break;
-	default:
-		pr_err("Invalid device type\n");
-		break;
-	}
-}
-
 /**
  * pld_lock_reg_window() - Lock register window spinlock
  * @dev: device pointer

+ 0 - 18
core/pld/src/pld_pcie.h

@@ -330,14 +330,6 @@ static inline int pld_pcie_force_wake_release(struct device *dev)
 	return 0;
 }
 
-static inline void pld_pcie_lock_pm_sem(struct device *dev)
-{
-}
-
-static inline void pld_pcie_release_pm_sem(struct device *dev)
-{
-}
-
 static inline void pld_pcie_lock_reg_window(struct device *dev,
 					    unsigned long *flags)
 {
@@ -634,16 +626,6 @@ static inline int pld_pcie_force_wake_release(struct device *dev)
 	return cnss_pci_force_wake_release(dev);
 }
 
-static inline void pld_pcie_lock_pm_sem(struct device *dev)
-{
-	cnss_lock_pm_sem(dev);
-}
-
-static inline void pld_pcie_release_pm_sem(struct device *dev)
-{
-	cnss_release_pm_sem(dev);
-}
-
 static inline void pld_pcie_lock_reg_window(struct device *dev,
 					    unsigned long *flags)
 {