qcacmn: Create new HIF function to handle PM no idle operations

Some areas in other components are directly calling the kernel api
functions to perform runtime PM no idle operations. Create a new HIF
function to handle runtime PM no idle operations.

Change-Id: I8328bc74ccc8e8acd35d7d73ec4cc21094b8f5b2
CRs-Fixed: 2607721
diff --git a/hif/inc/hif.h b/hif/inc/hif.h
index d9c7951..85e0591 100644
--- a/hif/inc/hif.h
+++ b/hif/inc/hif.h
@@ -875,6 +875,7 @@
 int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx);
 void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx);
 int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx);
+int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx);
 void hif_pm_runtime_mark_last_busy(struct hif_opaque_softc *hif_ctx);
 int hif_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name);
 void hif_runtime_lock_deinit(struct hif_opaque_softc *hif_ctx,
@@ -912,6 +913,8 @@
 { return 0; }
 static inline int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx)
 { return 0; }
+static inline int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx)
+{ return 0; }
 static inline void
 hif_pm_runtime_mark_last_busy(struct hif_opaque_softc *hif_ctx) {};
 static inline int hif_runtime_lock_init(qdf_runtime_lock_t *lock,
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index 79aa0ed..42b4ca9 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -4119,9 +4119,9 @@
 }
 
 /**
- * hif_pm_runtime_put() - do a put opperation on the device
+ * hif_pm_runtime_put() - do a put operation on the device
  *
- * A put opperation will allow a runtime suspend after a corresponding
+ * A put operation will allow a runtime suspend after a corresponding
  * get was done.  This api should be used when sending data.
  *
  * This api will return a failure if runtime pm is stopped
@@ -4170,6 +4170,46 @@
 	return 0;
 }
 
+/**
+ * hif_pm_runtime_put_noidle() - do a put operation with no idle
+ *
+ * This API will do a runtime put no idle operation
+ *
+ * @hif_ctx: pointer of HIF context
+ *
+ * Return: 0 for success otherwise an error code
+ */
+int hif_pm_runtime_put_noidle(struct hif_opaque_softc *hif_ctx)
+{
+	struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx);
+	int usage_count, pm_state;
+	char *err = NULL;
+
+	if (!sc)
+		return -EINVAL;
+
+	if (!pm_runtime_enabled(sc->dev))
+		return 0;
+
+	usage_count = atomic_read(&sc->dev->power.usage_count);
+	if (usage_count == 1) {
+		pm_state = qdf_atomic_read(&sc->pm_state);
+		if (pm_state == HIF_PM_RUNTIME_STATE_NONE)
+			err = "Ignore unexpected Put as runtime PM is disabled";
+	} else if (usage_count == 0) {
+		err = "Put without a Get Operation";
+	}
+
+	if (err) {
+		hif_pci_runtime_pm_warn(sc, err);
+		return -EINVAL;
+	}
+
+	sc->pm_stats.runtime_put++;
+	pm_runtime_put_noidle(sc->dev);
+
+	return 0;
+}
 
 /**
  * __hif_pm_runtime_prevent_suspend() - prevent runtime suspend for a protocol