diff --git a/core/hif/src/hif_main.c b/core/hif/src/hif_main.c index 0c32434665..e76c64c9a5 100644 --- a/core/hif/src/hif_main.c +++ b/core/hif/src/hif_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -292,7 +292,7 @@ void hif_vote_link_down(void) scn->linkstate_vote--; if (scn->linkstate_vote == 0) - hif_bus_prevent_linkdown(false); + hif_bus_prevent_linkdown(scn, false); } /** @@ -313,7 +313,7 @@ void hif_vote_link_up(void) scn->linkstate_vote++; if (scn->linkstate_vote == 1) - hif_bus_prevent_linkdown(true); + hif_bus_prevent_linkdown(scn, true); } /** diff --git a/core/hif/src/hif_main.h b/core/hif/src/hif_main.h index 812b763767..9544ef823d 100644 --- a/core/hif/src/hif_main.h +++ b/core/hif/src/hif_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -131,6 +131,6 @@ CDF_STATUS hif_bus_open(struct ol_softc *ol_sc, CDF_STATUS hif_enable_bus(struct ol_softc *ol_sc, struct device *dev, void *bdev, const hif_bus_id *bid, enum hif_enable_type type); void hif_disable_bus(void *bdev); -void hif_bus_prevent_linkdown(bool flag); +void hif_bus_prevent_linkdown(struct ol_softc *scn, bool flag); #endif /* __HIF_MAIN_H__ */ diff --git a/core/hif/src/pcie/if_pci.c b/core/hif/src/pcie/if_pci.c index af05003a80..8971bb3a88 100644 --- a/core/hif/src/pcie/if_pci.c +++ b/core/hif/src/pcie/if_pci.c @@ -1068,6 +1068,8 @@ static void hif_pm_runtime_open(struct hif_pci_softc *sc) spin_lock_init(&sc->runtime_lock); cdf_atomic_init(&sc->pm_state); + sc->prevent_linkdown_lock = + hif_runtime_lock_init("linkdown suspend disabled"); cdf_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_NONE); INIT_LIST_HEAD(&sc->prevent_suspend_list); } @@ -1621,6 +1623,30 @@ void hif_disable_bus(void *bdev) #define OL_ATH_PCI_PM_CONTROL 0x44 #ifdef CONFIG_CNSS + +#ifdef RUNTIME_PM +/** + * hif_runtime_prevent_linkdown() - prevent or allow a runtime pm from occuring + * @scn: hif context + * @flag: prevent linkdown if true otherwise allow + * + * this api should only be called as part of bus prevent linkdown + */ +static void hif_runtime_prevent_linkdown(struct ol_softc *scn, bool flag) +{ + struct hif_pci_softc *sc = scn->hif_sc; + + if (flag) + hif_pm_runtime_prevent_suspend(scn, sc->prevent_linkdown_lock); + else + hif_pm_runtime_allow_suspend(scn, sc->prevent_linkdown_lock); +} +#else +static void hif_runtime_prevent_linkdown(struct ol_softc *scn, bool flag) +{ +} +#endif + /** * hif_bus_prevent_linkdown(): allow or permit linkdown * @flag: true prevents linkdown, false allows @@ -1630,10 +1656,11 @@ void hif_disable_bus(void *bdev) * * Return: n/a */ -void hif_bus_prevent_linkdown(bool flag) +void hif_bus_prevent_linkdown(struct ol_softc *scn, bool flag) { HIF_ERROR("wlan: %s pcie power collapse", (flag ? "disable" : "enable")); + hif_runtime_prevent_linkdown(scn, flag); cnss_wlan_pm_control(flag); } #endif diff --git a/core/hif/src/pcie/if_pci.h b/core/hif/src/pcie/if_pci.h index b0d4651493..3c275ebf32 100644 --- a/core/hif/src/pcie/if_pci.h +++ b/core/hif/src/pcie/if_pci.h @@ -126,6 +126,7 @@ struct hif_pci_softc { struct timer_list runtime_timer; struct list_head prevent_suspend_list; unsigned long runtime_timer_expires; + struct hif_pm_runtime_lock *prevent_linkdown_lock; #ifdef WLAN_OPEN_SOURCE struct dentry *pm_dentry; #endif diff --git a/core/hif/src/snoc/if_snoc.c b/core/hif/src/snoc/if_snoc.c index c9dfa8c96d..f84b772b0d 100644 --- a/core/hif/src/snoc/if_snoc.c +++ b/core/hif/src/snoc/if_snoc.c @@ -47,7 +47,7 @@ * This is duplicated here because CONFIG_CNSS can be defined * even though it is not used for the snoc bus. */ -void hif_bus_prevent_linkdown(bool flag) +void hif_bus_prevent_linkdown(struct ol_softc *scn, bool flag) { HIF_ERROR("wlan: %s pcie power collapse ignored", (flag ? "disable" : "enable"));