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

Commit 64167852 authored by Yue Ma's avatar Yue Ma
Browse files

cnss2: Add force wake support



As part of PCIe power management for new WLAN devices, it requires
asserting WAKE register before accessing any MMIO registers outside
first 4K range. Add the support in CNSS driver and expose the APIs
for WLAN host driver.

Change-Id: I69688c229121c12575dde4938961d60bc067751f
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent 387632bf
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -1238,6 +1238,94 @@ int cnss_pm_request_resume(struct cnss_pci_data *pci_priv)
	return pm_request_resume(&pci_dev->dev);
}

#ifdef CONFIG_CNSS_QCA6390
int cnss_pci_force_wake_request(struct device *dev)
{
	struct pci_dev *pci_dev = to_pci_dev(dev);
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
	struct mhi_controller *mhi_ctrl;

	if (!pci_priv)
		return -ENODEV;

	if (pci_priv->device_id != QCA6390_DEVICE_ID)
		return 0;

	mhi_ctrl = pci_priv->mhi_ctrl;
	if (!mhi_ctrl)
		return -EINVAL;

	read_lock_bh(&mhi_ctrl->pm_lock);
	mhi_ctrl->wake_get(mhi_ctrl, true);
	read_unlock_bh(&mhi_ctrl->pm_lock);

	return 0;
}
EXPORT_SYMBOL(cnss_pci_force_wake_request);

int cnss_pci_is_device_awake(struct device *dev)
{
	struct pci_dev *pci_dev = to_pci_dev(dev);
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
	struct mhi_controller *mhi_ctrl;

	if (!pci_priv)
		return -ENODEV;

	if (pci_priv->device_id != QCA6390_DEVICE_ID)
		return true;

	mhi_ctrl = pci_priv->mhi_ctrl;
	if (!mhi_ctrl)
		return -EINVAL;

	return mhi_ctrl->dev_state == MHI_STATE_M0 ? true : false;
}
EXPORT_SYMBOL(cnss_pci_is_device_awake);

int cnss_pci_force_wake_release(struct device *dev)
{
	struct pci_dev *pci_dev = to_pci_dev(dev);
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
	struct mhi_controller *mhi_ctrl;

	if (!pci_priv)
		return -ENODEV;

	if (pci_priv->device_id != QCA6390_DEVICE_ID)
		return 0;

	mhi_ctrl = pci_priv->mhi_ctrl;
	if (!mhi_ctrl)
		return -EINVAL;

	read_lock_bh(&mhi_ctrl->pm_lock);
	mhi_ctrl->wake_put(mhi_ctrl, false);
	read_unlock_bh(&mhi_ctrl->pm_lock);

	return 0;
}
EXPORT_SYMBOL(cnss_pci_force_wake_release);
#else
int cnss_pci_force_wake_request(struct device *dev)
{
	return 0;
}
EXPORT_SYMBOL(cnss_pci_force_wake_request);

int cnss_pci_is_device_awake(struct device *dev)
{
	return true;
}
EXPORT_SYMBOL(cnss_pci_is_device_awake);

int cnss_pci_force_wake_release(struct device *dev)
{
	return 0;
}
EXPORT_SYMBOL(cnss_pci_force_wake_release);
#endif

int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv)
{
	struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
+3 −0
Original line number Diff line number Diff line
@@ -174,6 +174,9 @@ extern void cnss_release_pm_sem(struct device *dev);
extern int cnss_wlan_pm_control(struct device *dev, bool vote);
extern int cnss_auto_suspend(struct device *dev);
extern int cnss_auto_resume(struct device *dev);
extern int cnss_pci_force_wake_request(struct device *dev);
extern int cnss_pci_is_device_awake(struct device *dev);
extern int cnss_pci_force_wake_release(struct device *dev);
extern int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
					int *num_vectors,
					uint32_t *user_base_data,