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

Commit 7bad60ee 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 e71b7c16 f18e944a
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -734,3 +734,19 @@ int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl)


	return 0;
	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 Original line 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_dont_use_autosuspend(&pci_dev->dev);
	pm_runtime_disable(&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);
	pci_free_irq_vectors(pci_dev);
	kfree(mhi_cntrl->irq);
	kfree(mhi_cntrl->irq);
	mhi_cntrl->irq = NULL;
	mhi_cntrl->irq = NULL;
@@ -448,89 +445,13 @@ static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv)
/* disable PCIe L1 */
/* disable PCIe L1 */
static int mhi_lpm_disable(struct mhi_controller *mhi_cntrl, void *priv)
static int mhi_lpm_disable(struct mhi_controller *mhi_cntrl, void *priv)
{
{
	struct mhi_dev *mhi_dev = priv;
	return mhi_arch_link_lpm_disable(mhi_cntrl);
	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;
}
}


/* enable PCIe L1 */
/* enable PCIe L1 */
static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv)
static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv)
{
{
	struct mhi_dev *mhi_dev = priv;
	return mhi_arch_link_lpm_enable(mhi_cntrl);
	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;
}
}


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


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


	/* setup power management apis */
	/* setup power management apis */
	mhi_cntrl->status_cb = mhi_status_cb;
	mhi_cntrl->status_cb = mhi_status_cb;
+12 −4
Original line number Original line Diff line number Diff line
@@ -57,10 +57,6 @@ struct mhi_dev {
	/* hardware info */
	/* hardware info */
	u32 serial_num;
	u32 serial_num;
	u32 oem_pk_hash[MHI_BHI_OEMPKHASH_SEG];
	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);
void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl);
@@ -70,6 +66,8 @@ void mhi_reg_write_work(struct work_struct *w);


#ifdef CONFIG_ARCH_QCOM
#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);
void mhi_arch_mission_mode_enter(struct mhi_controller *mhi_cntrl);
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl);
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl);
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl);
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl);
@@ -101,6 +99,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


#endif /* _MHI_QCOM_ */
#endif /* _MHI_QCOM_ */
+2 −0
Original line number Original line Diff line number Diff line
@@ -2534,6 +2534,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
		ret = -EIO;
		ret = -EIO;
		goto error_invalid_state;
		goto error_invalid_state;
	}
	}
	read_unlock_bh(&mhi_cntrl->pm_lock);


	/* disable link level low power modes */
	/* disable link level low power modes */
	ret = mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data);
	ret = mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data);
@@ -2556,6 +2557,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,


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


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