diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 679ae846f4..b5335811ee 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -989,6 +989,7 @@ bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx); void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, int val); +void hif_pm_runtime_check_and_request_resume(struct hif_opaque_softc *hif_ctx); void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx); qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx); @@ -1052,6 +1053,9 @@ static inline void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, int val) { return; } static inline void +hif_pm_runtime_check_and_request_resume(struct hif_opaque_softc *hif_ctx) +{ return; } +static inline void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx) {}; static inline int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx) diff --git a/hif/src/dispatcher/ipci_api.h b/hif/src/dispatcher/ipci_api.h index 1710b1d1b9..897e21e4e1 100644 --- a/hif/src/dispatcher/ipci_api.h +++ b/hif/src/dispatcher/ipci_api.h @@ -143,6 +143,30 @@ QDF_STATUS hif_ipci_enable_bus( */ void hif_ipci_disable_bus(struct hif_softc *scn); +#ifdef FEATURE_RUNTIME_PM +/** + * hif_ipci_get_rpm_ctx() - Map corresponding hif_runtime_pm_ctx + * @scn: hif context + * + * This function will map and return the corresponding + * hif_runtime_pm_ctx based on ipcie interface. + * + * Return: struct hif_runtime_pm_ctx pointer + */ +struct hif_runtime_pm_ctx *hif_ipci_get_rpm_ctx(struct hif_softc *hif_sc); + +/** + * hif_ipci_get_dev() - Map corresponding device structure + * @scn: hif context + * + * This function will map and return the corresponding + * device structure based on ipcie interface. + * + * Return: struct device pointer + */ +struct device *hif_ipci_get_dev(struct hif_softc *hif_sc); +#endif + /** * hif_ipci_bus_configure() - configure the pcie bus * @hif_sc: pointer to the hif context. diff --git a/hif/src/dispatcher/multibus_ipci.c b/hif/src/dispatcher/multibus_ipci.c index 7bd701379c..86625f8a0c 100644 --- a/hif/src/dispatcher/multibus_ipci.c +++ b/hif/src/dispatcher/multibus_ipci.c @@ -46,6 +46,10 @@ QDF_STATUS hif_initialize_ipci_ops(struct hif_softc *hif_sc) bus_ops->hif_nointrs = &hif_ipci_nointrs; bus_ops->hif_enable_bus = &hif_ipci_enable_bus; bus_ops->hif_disable_bus = &hif_ipci_disable_bus; +#ifdef FEATURE_RUNTIME_PM + bus_ops->hif_bus_get_rpm_ctx = &hif_ipci_get_rpm_ctx; + bus_ops->hif_bus_get_dev = &hif_ipci_get_dev; +#endif bus_ops->hif_bus_configure = &hif_ipci_bus_configure; bus_ops->hif_get_config_item = &hif_dummy_get_config_item; bus_ops->hif_set_mailbox_swap = &hif_dummy_set_mailbox_swap; diff --git a/hif/src/hif_runtime_pm.c b/hif/src/hif_runtime_pm.c index c3a0613fb4..7d0aae92c2 100644 --- a/hif/src/hif_runtime_pm.c +++ b/hif/src/hif_runtime_pm.c @@ -1704,6 +1704,24 @@ void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, qdf_atomic_set(&rpm_ctx->monitor_wake_intr, val); } +/** + * hif_pm_runtime_check_and_request_resume() - check if the device is runtime + * suspended and request resume. + * @hif_ctx: HIF context + * + * This function is to check if the device is runtime suspended and + * request for runtime resume. + * + * Return: void + */ +void hif_pm_runtime_check_and_request_resume(struct hif_opaque_softc *hif_ctx) +{ + if (hif_pm_runtime_get_monitor_wake_intr(hif_ctx)) { + hif_pm_runtime_set_monitor_wake_intr(hif_ctx, 0); + hif_pm_runtime_request_resume(hif_ctx); + } +} + /** * hif_pm_runtime_mark_dp_rx_busy() - Set last busy mark my data path * @hif_ctx: HIF context diff --git a/hif/src/ipcie/if_ipci.c b/hif/src/ipcie/if_ipci.c index 373bee411c..3bf96f154c 100644 --- a/hif/src/ipcie/if_ipci.c +++ b/hif/src/ipcie/if_ipci.c @@ -46,13 +46,31 @@ #include "ipci_api.h" +#ifdef FEATURE_RUNTIME_PM +inline struct hif_runtime_pm_ctx *hif_ipci_get_rpm_ctx(struct hif_softc *scn) +{ + struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(scn); + + return &sc->rpm_ctx; +} + +inline struct device *hif_ipci_get_dev(struct hif_softc *scn) +{ + struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(scn); + + return sc->dev; +} +#endif + void hif_ipci_enable_power_management(struct hif_softc *hif_sc, bool is_packet_log_enabled) { + hif_pm_runtime_start(hif_sc); } void hif_ipci_disable_power_management(struct hif_softc *hif_ctx) { + hif_pm_runtime_stop(hif_ctx); } void hif_ipci_display_stats(struct hif_softc *hif_ctx) @@ -76,6 +94,7 @@ QDF_STATUS hif_ipci_open(struct hif_softc *hif_ctx, enum qdf_bus_type bus_type) struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(hif_ctx); hif_ctx->bus_type = bus_type; + hif_pm_runtime_open(hif_ctx); qdf_spinlock_create(&sc->irq_lock); @@ -157,6 +176,7 @@ timer_free: void hif_ipci_close(struct hif_softc *hif_sc) { + hif_pm_runtime_close(hif_sc); hif_ce_close(hif_sc); } @@ -274,6 +294,7 @@ void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag) int errno; HIF_INFO("wlan: %s pcie power collapse", flag ? "disable" : "enable"); + hif_runtime_prevent_linkdown(scn, flag); errno = pld_wlan_pm_control(scn->qdf_dev->dev, flag); if (errno) @@ -284,6 +305,7 @@ void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag) void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag) { HIF_INFO("wlan: %s pcie power collapse", (flag ? "disable" : "enable")); + hif_runtime_prevent_linkdown(scn, flag); } #endif @@ -350,6 +372,8 @@ static irqreturn_t hif_ce_interrupt_handler(int irq, void *context) { struct ce_tasklet_entry *tasklet_entry = context; + hif_pm_runtime_check_and_request_resume( + GET_HIF_OPAQUE_HDL(tasklet_entry->hif_ce_state)); return ce_dispatch_interrupt(tasklet_entry->ce_id, tasklet_entry); } diff --git a/hif/src/ipcie/if_ipci.h b/hif/src/ipcie/if_ipci.h index 00a6ca0e2c..4c7f1966f0 100644 --- a/hif/src/ipcie/if_ipci.h +++ b/hif/src/ipcie/if_ipci.h @@ -26,6 +26,7 @@ #include "hif.h" #include "cepci.h" #include "ce_main.h" +#include "hif_runtime_pm.h" #ifdef FORCE_WAKE /** @@ -76,6 +77,9 @@ struct hif_ipci_softc { uint32_t register_window; qdf_spinlock_t register_access_lock; qdf_spinlock_t irq_lock; +#ifdef FEATURE_RUNTIME_PM + struct hif_runtime_pm_ctx rpm_ctx; +#endif void (*hif_ipci_get_soc_info)(struct hif_ipci_softc *sc, struct device *dev);