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

Commit 1d99b259 authored by Chandana Kishori Chiluveru's avatar Chandana Kishori Chiluveru
Browse files

USB: ci13xxx_msm_hsic: Resume hardware from system resume path when needed



If HSIC wakeup interrupt occurs in system suspend then instead of
requesting runtime_pm to resume the device defer it until pm_resume.
This is required due to runtime PM of a device is disabled until pm_resume.

If the bus is instead runtime suspended (and not system suspended) when a
wakeup event occurs, then normal runtime resume will bring the
hardware out of low power mode.

Change-Id: I692c5e46b21f92272f4baf4b9d35ca5b7afa7332
Signed-off-by: default avatarChandana Kishori Chiluveru <cchiluve@codeaurora.org>
parent b2b64139
Loading
Loading
Loading
Loading
+37 −3
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ struct msm_hsic_per {
	enum usb_vdd_type		vdd_type;
	bool				connected;
	bool				disable_on_boot;
	bool				sm_work_pending;
	atomic_t			pm_suspended;

};

#define NONE 0
@@ -581,22 +584,49 @@ skip_phy_resume:
static int msm_hsic_pm_suspend(struct device *dev)
{
	struct msm_hsic_per *mhsic = dev_get_drvdata(dev);
	int ret = 0;

	dev_dbg(dev, "MSM HSIC Peripheral PM suspend\n");

	return msm_hsic_suspend(mhsic);
	if (!atomic_read(&mhsic->in_lpm)) {
		dev_err(dev, "Abort PM suspend!! (HSIC-USB is outside LPM)\n");
		return -EBUSY;
	}

	atomic_set(&mhsic->pm_suspended, 1);
	ret = msm_hsic_suspend(mhsic);
	if (ret)
		atomic_set(&mhsic->pm_suspended, 0);

	return ret;
}

#ifdef CONFIG_PM_RUNTIME
static int msm_hsic_pm_resume(struct device *dev)
{
	struct msm_hsic_per *mhsic = dev_get_drvdata(dev);
	int ret = 0;

	dev_dbg(dev, "MSM HSIC Peripheral PM resume\n");

	atomic_set(&mhsic->pm_suspended, 0);
	if (mhsic->sm_work_pending) {
		dev_dbg(dev, "MSM HSIC PM resume by USB\n");
		mhsic->sm_work_pending = false;
		pm_runtime_get_noresume(dev);
		ret = msm_hsic_resume(mhsic);

		/* Update runtime PM status */
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}

	/*
	 * Do not resume hardware as part of system resume,
	 * rather, wait for the ASYNC INT from the h/w
	 */
	return 0;
	return ret;
}
#else
static int msm_hsic_pm_resume(struct device *dev)
@@ -687,7 +717,11 @@ static irqreturn_t msm_udc_hsic_irq(int irq, void *data)
		pr_debug("%s(): HSIC IRQ:%d in LPM\n", __func__, irq);
		disable_irq_nosync(irq);
		mhsic->async_int = irq;
		if (atomic_read(&mhsic->pm_suspended))
			mhsic->sm_work_pending = true;
		else
			pm_request_resume(mhsic->dev);

		return IRQ_HANDLED;
	}