ソースを参照

qcacld-3.0: Serialize psoc idle shutdown and restart via PLD

Serialize psoc interface inactivity idle shutdown and restart via PLD
such that platform driver can serialize psoc idle shutdown and restart
to driver unload and SSR events to avoid any race conditions.

Change-Id: I177a60eaf83b1c81f08cab2dc8a6bc1497484809
CRs-Fixed: 2776866
Arun Kumar Khandavalli 4 年 前
コミット
b2375e8ce9
3 ファイル変更107 行追加42 行削除
  1. 46 42
      core/pld/src/pld_common.c
  2. 41 0
      core/pld/src/pld_snoc.c
  3. 20 0
      core/pld/src/pld_snoc.h

+ 46 - 42
core/pld/src/pld_common.c

@@ -2836,27 +2836,29 @@ int pld_idle_shutdown(struct device *dev,
 
 	type = pld_get_bus_type(dev);
 	switch (type) {
-		case PLD_BUS_TYPE_SDIO:
-		case PLD_BUS_TYPE_USB:
-		case PLD_BUS_TYPE_SNOC:
-			errno = shutdown_cb(dev);
-			break;
-		case PLD_BUS_TYPE_PCIE:
-			errno = pld_pcie_idle_shutdown(dev);
-			break;
-		case PLD_BUS_TYPE_PCIE_FW_SIM:
-		case PLD_BUS_TYPE_IPCI_FW_SIM:
-			errno = pld_pcie_fw_sim_idle_shutdown(dev);
-			break;
-		case PLD_BUS_TYPE_SNOC_FW_SIM:
-			errno = pld_snoc_fw_sim_idle_shutdown(dev);
-			break;
-		case PLD_BUS_TYPE_IPCI:
-			errno = pld_ipci_idle_shutdown(dev);
-			break;
-		default:
-			pr_err("Invalid device type %d\n", type);
-			break;
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		errno = shutdown_cb(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		errno = pld_snoc_idle_shutdown(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		errno = pld_pcie_idle_shutdown(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE_FW_SIM:
+	case PLD_BUS_TYPE_IPCI_FW_SIM:
+		errno = pld_pcie_fw_sim_idle_shutdown(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC_FW_SIM:
+		errno = pld_snoc_fw_sim_idle_shutdown(dev);
+		break;
+	case PLD_BUS_TYPE_IPCI:
+		errno = pld_ipci_idle_shutdown(dev);
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		break;
 	}
 
 	return errno;
@@ -2873,27 +2875,29 @@ int pld_idle_restart(struct device *dev,
 
 	type = pld_get_bus_type(dev);
 	switch (type) {
-		case PLD_BUS_TYPE_SDIO:
-		case PLD_BUS_TYPE_USB:
-		case PLD_BUS_TYPE_SNOC:
-			errno = restart_cb(dev);
-			break;
-		case PLD_BUS_TYPE_PCIE:
-			errno = pld_pcie_idle_restart(dev);
-			break;
-		case PLD_BUS_TYPE_PCIE_FW_SIM:
-		case PLD_BUS_TYPE_IPCI_FW_SIM:
-			errno = pld_pcie_fw_sim_idle_restart(dev);
-			break;
-		case PLD_BUS_TYPE_SNOC_FW_SIM:
-			errno = pld_snoc_fw_sim_idle_restart(dev);
-			break;
-		case PLD_BUS_TYPE_IPCI:
-			errno = pld_ipci_idle_restart(dev);
-			break;
-		default:
-			pr_err("Invalid device type %d\n", type);
-			break;
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		errno = restart_cb(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		errno = pld_snoc_idle_restart(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		errno = pld_pcie_idle_restart(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE_FW_SIM:
+	case PLD_BUS_TYPE_IPCI_FW_SIM:
+		errno = pld_pcie_fw_sim_idle_restart(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC_FW_SIM:
+		errno = pld_snoc_fw_sim_idle_restart(dev);
+		break;
+	case PLD_BUS_TYPE_IPCI:
+		errno = pld_ipci_idle_restart(dev);
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		break;
 	}
 
 	return errno;

+ 41 - 0
core/pld/src/pld_snoc.c

@@ -34,6 +34,45 @@
 #include "osif_psoc_sync.h"
 
 #ifdef CONFIG_PLD_SNOC_ICNSS
+/**
+ * pld_snoc_idle_restart_cb() - Perform idle restart
+ * @pdev: platform device
+ *
+ * This function will be called if there is an idle restart request
+ *
+ * Return: int
+ **/
+static int pld_snoc_idle_restart_cb(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->idle_restart)
+		return pld_context->ops->idle_restart(dev, PLD_BUS_TYPE_SNOC);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_snoc_idle_shutdown_cb() - Perform idle shutdown
+ * @pdev: PCIE device
+ * @id: PCIE device ID
+ *
+ * This function will be called if there is an idle shutdown request
+ *
+ * Return: int
+ */
+static int pld_snoc_idle_shutdown_cb(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->shutdown)
+		return pld_context->ops->idle_shutdown(dev, PLD_BUS_TYPE_SNOC);
+
+	return -ENODEV;
+}
+
 /**
  * pld_snoc_probe() - Probe function for platform driver
  * @dev: device
@@ -357,6 +396,8 @@ struct icnss_driver_ops pld_snoc_ops = {
 	.suspend_noirq = pld_snoc_suspend_noirq,
 	.resume_noirq = pld_snoc_resume_noirq,
 	.uevent = pld_snoc_uevent,
+	.idle_restart  = pld_snoc_idle_restart_cb,
+	.idle_shutdown = pld_snoc_idle_shutdown_cb,
 };
 
 /**

+ 20 - 0
core/pld/src/pld_snoc.h

@@ -113,6 +113,16 @@ static inline void *pld_snoc_smmu_get_mapping(struct device *dev)
 }
 #endif
 
+static inline int pld_snoc_idle_restart(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_snoc_idle_shutdown(struct device *dev)
+{
+	return 0;
+}
+
 static inline int pld_snoc_smmu_map(struct device *dev, phys_addr_t paddr,
 				    uint32_t *iova_addr, size_t size)
 {
@@ -354,5 +364,15 @@ static inline void pld_snoc_block_shutdown(bool status)
 {
 	icnss_block_shutdown(status);
 }
+
+static inline int pld_snoc_idle_restart(struct device *dev)
+{
+	return icnss_idle_restart(dev);
+}
+
+static inline int pld_snoc_idle_shutdown(struct device *dev)
+{
+	return icnss_idle_shutdown(dev);
+}
 #endif
 #endif