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

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

Merge "mhi: core: do not toggle PCIe low power mode in sleeping context"

parents a7cb773a 7e6b1086
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -768,3 +768,19 @@ int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl)

	return 0;
}

int mhi_arch_link_lpm_disable(struct mhi_controller *mhi_cntrl)
{
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);

	return msm_pcie_prevent_l1(mhi_dev->pci_dev);
}

int mhi_arch_link_lpm_enable(struct mhi_controller *mhi_cntrl)
{
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);

	msm_pcie_allow_l1(mhi_dev->pci_dev);

	return 0;
}
+2 −82
Original line number Diff line number Diff line
@@ -71,9 +71,6 @@ void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl)
	pm_runtime_dont_use_autosuspend(&pci_dev->dev);
	pm_runtime_disable(&pci_dev->dev);

	/* reset counter for lpm state changes */
	mhi_dev->lpm_disable_depth = 0;

	pci_free_irq_vectors(pci_dev);
	kfree(mhi_cntrl->irq);
	mhi_cntrl->irq = NULL;
@@ -448,89 +445,13 @@ static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv)
/* disable PCIe L1 */
static int mhi_lpm_disable(struct mhi_controller *mhi_cntrl, void *priv)
{
	struct mhi_dev *mhi_dev = priv;
	struct pci_dev *pci_dev = mhi_dev->pci_dev;
	int lnkctl = pci_dev->pcie_cap + PCI_EXP_LNKCTL;
	u8 val;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&mhi_dev->lpm_lock, flags);

	/* L1 is already disabled */
	if (mhi_dev->lpm_disable_depth) {
		mhi_dev->lpm_disable_depth++;
		goto lpm_disable_exit;
	}

	ret = pci_read_config_byte(pci_dev, lnkctl, &val);
	if (ret) {
		MHI_ERR("Error reading LNKCTL, ret:%d\n", ret);
		goto lpm_disable_exit;
	}

	/* L1 is not supported, do not increment lpm_disable_depth */
	if (unlikely(!(val & PCI_EXP_LNKCTL_ASPM_L1)))
		goto lpm_disable_exit;

	val &= ~PCI_EXP_LNKCTL_ASPM_L1;
	ret = pci_write_config_byte(pci_dev, lnkctl, val);
	if (ret) {
		MHI_ERR("Error writing LNKCTL to disable LPM, ret:%d\n", ret);
		goto lpm_disable_exit;
	}

	mhi_dev->lpm_disable_depth++;

lpm_disable_exit:
	spin_unlock_irqrestore(&mhi_dev->lpm_lock, flags);

	return ret;
	return mhi_arch_link_lpm_disable(mhi_cntrl);
}

/* enable PCIe L1 */
static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv)
{
	struct mhi_dev *mhi_dev = priv;
	struct pci_dev *pci_dev = mhi_dev->pci_dev;
	int lnkctl = pci_dev->pcie_cap + PCI_EXP_LNKCTL;
	u8 val;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&mhi_dev->lpm_lock, flags);

	/*
	 * Exit if L1 is not supported or is already disabled or
	 * decrementing lpm_disable_depth still keeps it above 0
	 */
	if (!mhi_dev->lpm_disable_depth)
		goto lpm_enable_exit;

	if (mhi_dev->lpm_disable_depth > 1) {
		mhi_dev->lpm_disable_depth--;
		goto lpm_enable_exit;
	}

	ret = pci_read_config_byte(pci_dev, lnkctl, &val);
	if (ret) {
		MHI_ERR("Error reading LNKCTL, ret:%d\n", ret);
		goto lpm_enable_exit;
	}

	val |= PCI_EXP_LNKCTL_ASPM_L1;
	ret = pci_write_config_byte(pci_dev, lnkctl, val);
	if (ret) {
		MHI_ERR("Error writing LNKCTL to enable LPM, ret:%d\n", ret);
		goto lpm_enable_exit;
	}

	mhi_dev->lpm_disable_depth = 0;

lpm_enable_exit:
	spin_unlock_irqrestore(&mhi_dev->lpm_lock, flags);

	return ret;
	return mhi_arch_link_lpm_enable(mhi_cntrl);
}

void mhi_qcom_store_hwinfo(struct mhi_controller *mhi_cntrl)
@@ -815,7 +736,6 @@ static struct mhi_controller *mhi_register_controller(struct pci_dev *pci_dev)
	}

	mhi_dev->pci_dev = pci_dev;
	spin_lock_init(&mhi_dev->lpm_lock);

	/* setup power management apis */
	mhi_cntrl->status_cb = mhi_status_cb;
+12 −4
Original line number Diff line number Diff line
@@ -58,10 +58,6 @@ struct mhi_dev {
	/* hardware info */
	u32 serial_num;
	u32 oem_pk_hash[MHI_BHI_OEMPKHASH_SEG];

	unsigned int lpm_disable_depth;
	/* lock to toggle low power modes */
	spinlock_t lpm_lock;
};

void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl);
@@ -71,6 +67,8 @@ void mhi_reg_write_work(struct work_struct *w);

#ifdef CONFIG_ARCH_QCOM

int mhi_arch_link_lpm_disable(struct mhi_controller *mhi_cntrl);
int mhi_arch_link_lpm_enable(struct mhi_controller *mhi_cntrl);
void mhi_arch_mission_mode_enter(struct mhi_controller *mhi_cntrl);
int mhi_arch_power_up(struct mhi_controller *mhi_cntrl);
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl);
@@ -108,6 +106,16 @@ static inline void mhi_arch_mission_mode_enter(struct mhi_controller *mhi_cntrl)
{
}

static inline int mhi_arch_link_lpm_disable(struct mhi_controller *mhi_cntrl)
{
	return 0;
}

static inline int mhi_arch_link_lpm_enable(struct mhi_controller *mhi_cntrl)
{
	return 0;
}

#endif

#endif /* _MHI_QCOM_ */
+5 −1
Original line number Diff line number Diff line
@@ -2576,11 +2576,14 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
		ret = -EIO;
		goto error_invalid_state;
	}
	read_unlock_bh(&mhi_cntrl->pm_lock);

	/* disable link level low power modes */
	ret = mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data);
	if (ret)
	if (ret) {
		read_lock_bh(&mhi_cntrl->pm_lock);
		goto error_invalid_state;
	}

	/*
	 * time critical code to fetch device times,
@@ -2598,6 +2601,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,

	mhi_cntrl->lpm_enable(mhi_cntrl, mhi_cntrl->priv_data);

	read_lock_bh(&mhi_cntrl->pm_lock);
error_invalid_state:
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);