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

Commit 2083f488 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: phy-msm-usb: Process HOST disconnect only after system RESUME"

parents f238358a de9ed53e
Loading
Loading
Loading
Loading
+52 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include <linux/of.h>
#include <linux/dma-mapping.h>
#include <linux/clk/msm-clk.h>
@@ -3498,11 +3499,13 @@ static void msm_otg_set_vbus_state(int online)
		return;
	}

	if (atomic_read(&motg->pm_suspended))
	if (atomic_read(&motg->pm_suspended)) {
		motg->sm_work_pending = true;
	else
	} else if (!motg->sm_work_pending) {
		/* process event only if previous one is not pending */
		queue_work(system_nrt_wq, &motg->sm_work);
	}
}

static void msm_id_status_w(struct work_struct *w)
{
@@ -3511,6 +3514,8 @@ static void msm_id_status_w(struct work_struct *w)
	int work = 0;
	int id_state = 0;

	dev_dbg(motg->phy.dev, "ID status_w\n");

	if (motg->pdata->pmic_id_irq)
		id_state = msm_otg_read_pmic_id_state(motg);
	else if (motg->ext_id_irq)
@@ -3530,11 +3535,13 @@ static void msm_id_status_w(struct work_struct *w)
	}

	if (work && (motg->phy.state != OTG_STATE_UNDEFINED)) {
		if (atomic_read(&motg->pm_suspended))
		if (atomic_read(&motg->pm_suspended)) {
			motg->sm_work_pending = true;
		else
		} else if (!motg->sm_work_pending) {
			/* process event only if previous one is not pending */
			queue_work(system_nrt_wq, &motg->sm_work);
		}
	}

}

@@ -3557,6 +3564,34 @@ static irqreturn_t msm_id_irq(int irq, void *data)
	return IRQ_HANDLED;
}

int msm_otg_pm_notify(struct notifier_block *notify_block,
					unsigned long mode, void *unused)
{
	struct msm_otg *motg = container_of(
		notify_block, struct msm_otg, pm_notify);

	dev_dbg(motg->phy.dev, "OTG PM notify:%lx, sm_pending:%u\n", mode,
					motg->sm_work_pending);

	switch (mode) {
	case PM_POST_SUSPEND:
		/* OTG sm_work can be armed now */
		atomic_set(&motg->pm_suspended, 0);

		/* Handle any deferred wakeup events from USB during suspend */
		if (motg->sm_work_pending) {
			motg->sm_work_pending = false;
			queue_work(system_nrt_wq, &motg->sm_work);
		}
		break;

	default:
		break;
	}

	return NOTIFY_OK;
}

static int msm_otg_mode_show(struct seq_file *s, void *unused)
{
	struct msm_otg *motg = s->private;
@@ -4918,6 +4953,9 @@ static int msm_otg_probe(struct platform_device *pdev)
		}
	}

	motg->pm_notify.notifier_call = msm_otg_pm_notify;
	register_pm_notifier(&motg->pm_notify);

	return 0;

remove_cdev:
@@ -4993,6 +5031,8 @@ static int msm_otg_remove(struct platform_device *pdev)
	if (phy->otg->host || phy->otg->gadget)
		return -EBUSY;

	unregister_pm_notifier(&motg->pm_notify);

	if (!motg->ext_chg_device) {
		device_destroy(motg->ext_chg_class, motg->ext_chg_dev);
		cdev_del(&motg->ext_chg_cdev);
@@ -5161,7 +5201,9 @@ static int msm_otg_pm_resume(struct device *dev)
	dev_dbg(dev, "OTG PM resume\n");

	motg->pm_done = 0;
	if (!motg->host_bus_suspend)
		atomic_set(&motg->pm_suspended, 0);

	if (motg->async_int || motg->sm_work_pending ||
			!pm_runtime_suspended(dev)) {
		pm_runtime_get_noresume(dev);
@@ -5172,7 +5214,11 @@ static int msm_otg_pm_resume(struct device *dev)
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);

		if (motg->sm_work_pending) {
		/*
		 * Defer any host mode disconnect events until
		 * all devices are RESUMED
		 */
		if (motg->sm_work_pending && !motg->host_bus_suspend) {
			motg->sm_work_pending = false;
			queue_work(system_nrt_wq, &motg->sm_work);
		}
+5 −0
Original line number Diff line number Diff line
@@ -347,6 +347,10 @@ struct msm_otg_platform_data {
 * @usb_phy_ctrl_reg: relevant PHY_CTRL_REG register base address.
 * @inputs: OTG state machine inputs(Id, SessValid etc).
 * @sm_work: OTG state machine work.
 * @pm_suspended: OTG device is system(PM) suspended.
 * @pm_notify: Notifier to receive system wide PM transition events.
		It is used to defer wakeup events processing until
		system is RESUMED.
 * @in_lpm: indicates low power mode (LPM) state.
 * @async_int: IRQ line on which ASYNC interrupt arrived in LPM.
 * @cur_power: The amount of mA available from downstream port.
@@ -413,6 +417,7 @@ struct msm_otg {
	struct work_struct sm_work;
	bool sm_work_pending;
	atomic_t pm_suspended;
	struct notifier_block pm_notify;
	atomic_t in_lpm;
	atomic_t set_fpr_with_lpm_exit;
	int async_int;