From 5b5238a050625787cdf5ad28b42fdea4fbcce0d7 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Thu, 1 Aug 2019 19:34:10 -0700 Subject: [PATCH] qcacmn: Add runtime PM put sync API Runtime PM put sync API will make sure runtime PM suspend happen right away if usage count is 0. Change-Id: I70f6fe4ed015195874ef4cac61de9ef5d739b689 CRs-fixed: 2502382 --- hif/inc/hif.h | 4 ++++ hif/src/pcie/if_pci.c | 47 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 7d190a1dcd62..ff9595f102e2 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -845,6 +845,7 @@ void hif_clear_stats(struct hif_opaque_softc *hif_ctx); struct hif_pm_runtime_lock; void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx); +int hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_request_resume(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx); void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx); @@ -871,6 +872,9 @@ static inline void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx) {} static inline int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) { return 0; } static inline int +hif_pm_runtime_put_sync_suspend(struct hif_opaque_softc *hif_ctx) +{ return 0; } +static inline int hif_pm_runtime_request_resume(struct hif_opaque_softc *hif_ctx) { return 0; } static inline void hif_pm_runtime_get_noresume(struct hif_opaque_softc *hif_ctx) diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index c7c1a63cfa0c..96d04f5b83cb 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -3868,9 +3868,9 @@ void hif_pci_irq_disable(struct hif_softc *scn, int ce_id) #ifdef FEATURE_RUNTIME_PM /** - * hif_pm_runtime_get_sync() - do a get opperation with sync resume + * hif_pm_runtime_get_sync() - do a get operation with sync resume * - * A get opperation will prevent a runtime suspend until a corresponding + * A get operation will prevent a runtime suspend until a corresponding * put is done. Unlike hif_pm_runtime_get(), this API will do a sync * resume instead of requesting a resume if it is runtime PM suspended * so it can only be called in non-atomic context. @@ -3882,11 +3882,17 @@ void hif_pci_irq_disable(struct hif_softc *scn, int ce_id) int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) { struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + int pm_state; int ret; if (!sc) return -EINVAL; + pm_state = qdf_atomic_read(&sc->pm_state); + if (pm_state == HIF_PM_RUNTIME_STATE_SUSPENDED) + HIF_INFO("Runtime PM resume is requested by %ps", + (void *)_RET_IP_); + sc->pm_stats.runtime_get++; ret = pm_runtime_get_sync(sc->dev); @@ -3906,6 +3912,43 @@ int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx) return ret; } +/** + * hif_pm_runtime_put_sync_suspend() - do a put operation with sync suspend + * + * This API will do a runtime put operation followed by a sync suspend if usage + * count is 0 so it can only be called in non-atomic context. + * + * @hif_ctx: pointer of HIF context + * + * Return: 0 for success otherwise an error code + */ +int hif_pm_runtime_put_sync_suspend(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; + + 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++; + return pm_runtime_put_sync_suspend(sc->dev); +} + int hif_pm_runtime_request_resume(struct hif_opaque_softc *hif_ctx) { struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx);