diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/pci.c | 1 |
3 files changed, 54 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index e1c0eca773fc..cde009c3bdaf 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1136,7 +1136,7 @@ int ath11k_core_suspend(struct ath11k_base *ab) if (ret <= 0) return ret; - if (ab->pm_policy == ATH11K_PM_WOW) + if (ab->actual_pm_policy == ATH11K_PM_WOW) return ath11k_core_suspend_wow(ab); return ath11k_core_suspend_default(ab); @@ -1151,7 +1151,7 @@ int ath11k_core_suspend_late(struct ath11k_base *ab) if (ret <= 0) return ret; - if (ab->pm_policy == ATH11K_PM_WOW) + if (ab->actual_pm_policy == ATH11K_PM_WOW) return 0; ath11k_hif_irq_disable(ab); @@ -1171,7 +1171,7 @@ int ath11k_core_resume_early(struct ath11k_base *ab) if (ret <= 0) return ret; - if (ab->pm_policy == ATH11K_PM_WOW) + if (ab->actual_pm_policy == ATH11K_PM_WOW) return 0; reinit_completion(&ab->restart_completed); @@ -1240,7 +1240,7 @@ int ath11k_core_resume(struct ath11k_base *ab) if (ret <= 0) return ret; - if (ab->pm_policy == ATH11K_PM_WOW) + if (ab->actual_pm_policy == ATH11K_PM_WOW) return ath11k_core_resume_wow(ab); return ath11k_core_resume_default(ab); @@ -2500,6 +2500,43 @@ int ath11k_core_pre_init(struct ath11k_base *ab) } EXPORT_SYMBOL(ath11k_core_pre_init); +static int ath11k_core_pm_notify(struct notifier_block *nb, + unsigned long action, void *nouse) +{ + struct ath11k_base *ab = container_of(nb, struct ath11k_base, + pm_nb); + + switch (action) { + case PM_SUSPEND_PREPARE: + ab->actual_pm_policy = ab->pm_policy; + break; + case PM_HIBERNATION_PREPARE: + ab->actual_pm_policy = ATH11K_PM_DEFAULT; + break; + default: + break; + } + + return NOTIFY_OK; +} + +static int ath11k_core_pm_notifier_register(struct ath11k_base *ab) +{ + ab->pm_nb.notifier_call = ath11k_core_pm_notify; + return register_pm_notifier(&ab->pm_nb); +} + +void ath11k_core_pm_notifier_unregister(struct ath11k_base *ab) +{ + int ret; + + ret = unregister_pm_notifier(&ab->pm_nb); + if (ret) + /* just warn here, there is nothing can be done in fail case */ + ath11k_warn(ab, "failed to unregister PM notifier %d\n", ret); +} +EXPORT_SYMBOL(ath11k_core_pm_notifier_unregister); + int ath11k_core_init(struct ath11k_base *ab) { const struct dmi_system_id *dmi_id; @@ -2513,6 +2550,12 @@ int ath11k_core_init(struct ath11k_base *ab) ath11k_dbg(ab, ATH11K_DBG_BOOT, "pm policy %u\n", ab->pm_policy); + ret = ath11k_core_pm_notifier_register(ab); + if (ret) { + ath11k_err(ab, "failed to register PM notifier: %d\n", ret); + return ret; + } + ret = ath11k_core_soc_create(ab); if (ret) { ath11k_err(ab, "failed to create soc core: %d\n", ret); @@ -2535,6 +2578,7 @@ void ath11k_core_deinit(struct ath11k_base *ab) ath11k_hif_power_down(ab, false); ath11k_mac_destroy(ab); ath11k_core_soc_destroy(ab); + ath11k_core_pm_notifier_unregister(ab); } EXPORT_SYMBOL(ath11k_core_deinit); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 7a9354e0eadb..339d4fca1ed5 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -16,6 +16,7 @@ #include <linux/rhashtable.h> #include <linux/average.h> #include <linux/firmware.h> +#include <linux/suspend.h> #include "qmi.h" #include "htc.h" @@ -1066,6 +1067,8 @@ struct ath11k_base { #endif enum ath11k_pm_policy pm_policy; + enum ath11k_pm_policy actual_pm_policy; + struct notifier_block pm_nb; /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); @@ -1333,4 +1336,6 @@ static inline const char *ath11k_bus_str(enum ath11k_bus bus) return "unknown"; } +void ath11k_core_pm_notifier_unregister(struct ath11k_base *ab); + #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 37f5ed7f74f2..630df6b1d82d 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -1164,6 +1164,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev) ath11k_pci_power_down(ab, false); ath11k_debugfs_soc_destroy(ab); ath11k_qmi_deinit_service(ab); + ath11k_core_pm_notifier_unregister(ab); goto qmi_fail; } |