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

Commit 808e2a7d authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: retry mhi suspend in case packets are pending in MHI layer"

parents 4abf7b76 98468677
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */

#include <linux/cma.h>
#include <linux/firmware.h>
@@ -79,6 +79,8 @@ static DEFINE_SPINLOCK(time_sync_lock);
#define HST_HANG_DATA_OFFSET		((3 * 1024 * 1024) - HANG_DATA_LENGTH)
#define HSP_HANG_DATA_OFFSET		((2 * 1024 * 1024) - HANG_DATA_LENGTH)

#define MHI_SUSPEND_RETRY_CNT		3

static struct cnss_pci_reg ce_src[] = {
	{ "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET },
	{ "SRC_RING_BASE_MSB", QCA6390_CE_SRC_RING_BASE_MSB_OFFSET },
@@ -1100,6 +1102,7 @@ static int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,
				  enum cnss_mhi_state mhi_state)
{
	int ret = 0;
	u8 retry = 0;

	if (pci_priv->device_id == QCA6174_DEVICE_ID)
		return 0;
@@ -1147,10 +1150,21 @@ static int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,
		break;
	case CNSS_MHI_SUSPEND:
		mutex_lock(&pci_priv->mhi_ctrl->pm_mutex);
		if (pci_priv->drv_connected_last)
		if (pci_priv->drv_connected_last) {
			ret = mhi_pm_fast_suspend(pci_priv->mhi_ctrl, true);
		else
		} else {
			ret = mhi_pm_suspend(pci_priv->mhi_ctrl);
			/* in some corner case, when cnss try to suspend,
			 * there is still packets pending in mhi layer,
			 * so retry suspend to save roll back effort.
			 */
			while (ret == -EBUSY && retry < MHI_SUSPEND_RETRY_CNT) {
				usleep_range(5000, 6000);
				retry++;
				cnss_pr_err("mhi is busy, retry #%u", retry);
				ret = mhi_pm_suspend(pci_priv->mhi_ctrl);
			}
		}
		mutex_unlock(&pci_priv->mhi_ctrl->pm_mutex);
		break;
	case CNSS_MHI_RESUME:
@@ -1179,8 +1193,8 @@ static int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,
	return 0;

out:
	cnss_pr_err("Failed to set MHI state: %s(%d)\n",
		    cnss_mhi_state_to_str(mhi_state), mhi_state);
	cnss_pr_err("Failed to set MHI state: %s(%d) ret: %d\n",
		    cnss_mhi_state_to_str(mhi_state), mhi_state, ret);

	if (mhi_state == CNSS_MHI_RESUME)
		cnss_force_fw_assert_async(&pci_priv->pci_dev->dev);