Kaynağa Gözat

qcacld-3.0: Add force wake APIs support in PLD

As part of PCIe power management for new WLAN devices, it requires
asserting WAKE register before accessing any MMIO registers outside
first 4K range. Add the APIs support in PLD for WLAN host driver.

Change-Id: I307cc6688fca58a52a6eaf3982d675c7a85a6965
CRs-fixed: 2326459
Yue Ma 6 yıl önce
ebeveyn
işleme
fb3b78d7d2
3 değiştirilmiş dosya ile 121 ekleme ve 1 silme
  1. 3 1
      core/pld/inc/pld_common.h
  2. 88 0
      core/pld/src/pld_common.c
  3. 30 0
      core/pld/src/pld_pcie.h

+ 3 - 1
core/pld/inc/pld_common.h

@@ -513,7 +513,9 @@ int pld_get_sha_hash(struct device *dev, const u8 *data,
 void *pld_get_fw_ptr(struct device *dev);
 int pld_auto_suspend(struct device *dev);
 int pld_auto_resume(struct device *dev);
-
+int pld_force_wake_request(struct device *dev);
+int pld_is_device_awake(struct device *dev);
+int pld_force_wake_release(struct device *dev);
 int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
 		       irqreturn_t (*handler)(int, void *),
 		       unsigned long flags, const char *name, void *ctx);

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

@@ -895,6 +895,94 @@ int pld_auto_resume(struct device *dev)
 	return ret;
 }
 
+/**
+ * pld_force_wake_request() - Request vote to assert WAKE register
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_force_wake_request(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_force_wake_request(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_is_device_awake() - Check if it's ready to access MMIO registers
+ * @dev: device
+ *
+ * Return: True for device awake
+ *         False for device not awake
+ *         Negative failure code for errors
+ */
+int pld_is_device_awake(struct device *dev)
+{
+	int ret = true;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_is_device_awake(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_force_wake_release() - Release vote to assert WAKE register
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_force_wake_release(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_force_wake_release(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 /**
  * pld_ce_request_irq() - Register IRQ for CE
  * @dev: device

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

@@ -216,6 +216,21 @@ static inline int pld_pcie_auto_resume(struct device *dev)
 	return 0;
 }
 
+static inline int pld_pcie_force_wake_request(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_is_device_awake(struct device *dev)
+{
+	return true;
+}
+
+static inline int pld_pcie_force_wake_release(struct device *dev)
+{
+	return 0;
+}
+
 static inline void pld_pcie_lock_pm_sem(struct device *dev)
 {
 }
@@ -331,6 +346,21 @@ static inline int pld_pcie_auto_resume(struct device *dev)
 	return cnss_auto_resume(dev);
 }
 
+static inline int pld_pcie_force_wake_request(struct device *dev)
+{
+	return cnss_pci_force_wake_request(dev);
+}
+
+static inline int pld_pcie_is_device_awake(struct device *dev)
+{
+	return cnss_pci_is_device_awake(dev);
+}
+
+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);