Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae120800 authored by Sarada Prasanna Garnayak's avatar Sarada Prasanna Garnayak Committed by Gerrit - the friendly Code Review server
Browse files

ath10k: synchronize WLAN ON/OFF cmd during system suspend



During system suspend/resume or WLAN interface up/down
by the network subsystem the ath10k SNOC WLAN driver
configure WLAN enable/disable cmd with the WLAN firmware
over QMI interface. The WLAN enable/disable cmd configuration
with the WLAN firmware during system suspend is preventing
the system suspend.

Register PM event notifier for the ath10k SNOC platform
driver and synchronize the WLAN HIF power down/up
configuration, WLAN enable/disable cmd configuration
with WLAN firmware according to the system power state.

CRs-Fixed: 2110607
Change-Id: I5eeda967ae11c21ab5164c18b3e0a3bf668c916a
Signed-off-by: default avatarSarada Prasanna Garnayak <sgarna@codeaurora.org>
parent 2b959333
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/suspend.h>
#include "core.h"
#include "debug.h"
#include "hif.h"
@@ -955,8 +956,12 @@ static int ath10k_snoc_init_pipes(struct ath10k *ar)

static void ath10k_snoc_hif_power_down(struct ath10k *ar)
{
	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);

	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
	msleep(SNOC_HIF_POWER_DOWN_DELAY);

	if (!atomic_read(&ar_snoc->pm_ops_inprogress))
		ath10k_snoc_qmi_wlan_disable(ar);
}

@@ -1141,10 +1146,18 @@ static int ath10k_snoc_claim(struct ath10k *ar)
static int ath10k_snoc_hif_power_up(struct ath10k *ar)
{
	int ret;
	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);

	ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
		   __func__, ar->state);

	if (atomic_read(&ar_snoc->pm_ops_inprogress)) {
		ath10k_dbg(ar, ATH10K_DBG_SNOC,
			   "%s: WLAN OFF CMD Reset on PM Resume\n", __func__);
		ath10k_snoc_qmi_wlan_disable(ar);
		atomic_set(&ar_snoc->pm_ops_inprogress, 0);
	}

	if (ar->state == ATH10K_STATE_ON ||
	    test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
		ret = ath10k_snoc_bus_configure(ar);
@@ -1208,6 +1221,33 @@ out:
	return ret;
}

static
int ath10k_snoc_pm_notifier(struct notifier_block *nb,
			    unsigned long pm_event, void *data)
{
	struct ath10k_snoc *ar_snoc =
			container_of(nb, struct ath10k_snoc, pm_notifier);
	struct ath10k *ar = ar_snoc->ar;

	ath10k_dbg(ar, ATH10K_DBG_SNOC,
		   "%s: PM Event: %lu\n", __func__, pm_event);

	switch (pm_event) {
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:
	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
	case PM_RESTORE_PREPARE:
	case PM_POST_RESTORE:
		atomic_set(&ar_snoc->pm_ops_inprogress, 1);
		break;
	default:
		break;
	}

	return NOTIFY_DONE;
}

static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
	.tx_sg			= ath10k_snoc_hif_tx_sg,
	.start			= ath10k_snoc_hif_start,
@@ -1306,6 +1346,9 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
	ath10k_snoc_modem_ssr_register_notifier(ar);
	ath10k_snoc_pd_restart_enable(ar);

	ar_snoc->pm_notifier.notifier_call = ath10k_snoc_pm_notifier;
	register_pm_notifier(&ar_snoc->pm_notifier);

	ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 probed\n", __func__);

	return 0;
@@ -1338,6 +1381,7 @@ static int ath10k_snoc_remove(struct platform_device *pdev)

	ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 removed\n", __func__);

	unregister_pm_notifier(&ar_snoc->pm_notifier);
	ath10k_core_unregister(ar);
	ath10k_snoc_pdr_unregister_notifier(ar);
	ath10k_snoc_modem_ssr_unregister_notifier(ar);
+2 −0
Original line number Diff line number Diff line
@@ -148,12 +148,14 @@ struct ath10k_snoc {
	u32 *vaddr_rri_on_ddr;
	bool is_driver_probed;
	struct notifier_block modem_ssr_nb;
	struct notifier_block pm_notifier;
	void *modem_notify_handler;
	struct ath10k_service_notifier_context *service_notifier;
	struct notifier_block service_notifier_nb;
	int total_domains;
	struct notifier_block get_service_nb;
	atomic_t fw_crashed;
	atomic_t pm_ops_inprogress;
	struct ath10k_snoc_qmi_config qmi_cfg;
};