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

Commit d05bedc7 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: Ensure strict execution order of phy event processing"

parents ef9c21b3 f8d3ee8b
Loading
Loading
Loading
Loading
+33 −22
Original line number Diff line number Diff line
@@ -813,7 +813,7 @@ static enum hrtimer_restart msm_otg_timer_func(struct hrtimer *hrtimer)
	}

	pr_debug("expired %s timer\n", timer_string(motg->active_tmout));
	queue_work(system_nrt_wq, &motg->sm_work);
	queue_work(motg->otg_wq, &motg->sm_work);
	return HRTIMER_NORESTART;
}

@@ -856,7 +856,7 @@ static int msm_otg_start_hnp(struct usb_otg *otg)

	pr_debug("A-Host: HNP initiated\n");
	clear_bit(A_BUS_REQ, &motg->inputs);
	queue_work(system_nrt_wq, &motg->sm_work);
	queue_work(motg->otg_wq, &motg->sm_work);
	return 0;
}

@@ -946,7 +946,7 @@ static int msm_otg_set_suspend(struct usb_phy *phy, int suspend)
			clear_bit(A_BUS_REQ, &motg->inputs);
			if (!atomic_read(&motg->in_lpm) &&
					!test_bit(ID, &motg->inputs)) {
				queue_work(system_nrt_wq, &motg->sm_work);
				queue_work(motg->otg_wq, &motg->sm_work);
				/* Flush sm_work to avoid it race with
				 * subsequent calls of set_suspend.
				 */
@@ -959,7 +959,7 @@ static int msm_otg_set_suspend(struct usb_phy *phy, int suspend)
				break;
			set_bit(A_BUS_SUSPEND, &motg->inputs);
			if (!atomic_read(&motg->in_lpm))
				queue_delayed_work(system_nrt_wq,
				queue_delayed_work(motg->otg_wq,
					&motg->suspend_work,
					USB_SUSPEND_DELAY_TIME);
			break;
@@ -991,7 +991,7 @@ static int msm_otg_set_suspend(struct usb_phy *phy, int suspend)
				break;
			clear_bit(A_BUS_SUSPEND, &motg->inputs);
			if (atomic_read(&motg->in_lpm))
				queue_work(system_nrt_wq, &motg->sm_work);
				queue_work(motg->otg_wq, &motg->sm_work);
			break;
		default:
			break;
@@ -2049,7 +2049,7 @@ static int msm_otg_usbdev_notify(struct notifier_block *self,
				udev->bus->otg_vbus_off = 0;
				set_bit(A_BUS_DROP, &motg->inputs);
			}
			queue_work(system_nrt_wq, &motg->sm_work);
			queue_work(motg->otg_wq, &motg->sm_work);
		}
	default:
		break;
@@ -2136,7 +2136,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
			msm_hsusb_vbus_power(motg, 0);
			otg->host = NULL;
			otg->phy->state = OTG_STATE_UNDEFINED;
			queue_work(system_nrt_wq, &motg->sm_work);
			queue_work(motg->otg_wq, &motg->sm_work);
		} else {
			otg->host = NULL;
		}
@@ -2161,7 +2161,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
	 */
	if (motg->pdata->mode == USB_HOST || otg->gadget) {
		pm_runtime_get_sync(otg->phy->dev);
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
	}

	return 0;
@@ -2253,7 +2253,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg,
			msm_otg_start_peripheral(otg, 0);
			otg->gadget = NULL;
			otg->phy->state = OTG_STATE_UNDEFINED;
			queue_work(system_nrt_wq, &motg->sm_work);
			queue_work(motg->otg_wq, &motg->sm_work);
		} else {
			otg->gadget = NULL;
		}
@@ -2269,7 +2269,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg,
	 */
	if (motg->pdata->mode == USB_PERIPHERAL || otg->host) {
		pm_runtime_get_sync(otg->phy->dev);
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
	}

	return 0;
@@ -2434,7 +2434,7 @@ static void msm_otg_chg_check_timer_func(unsigned long data)
	if ((readl_relaxed(USB_PORTSC) & PORTSC_LS) == PORTSC_LS) {
		dev_dbg(otg->phy->dev, "DCP is detected as SDP\n");
		set_bit(B_FALSE_SDP, &motg->inputs);
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
	}
}

@@ -2605,7 +2605,7 @@ static void msm_otg_id_timer_func(unsigned long data)

	if (msm_chg_check_aca_intr(motg)) {
		dev_dbg(motg->phy.dev, "timer: aca work\n");
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
	}

out:
@@ -2849,6 +2849,8 @@ static void msm_chg_detect_work(struct work_struct *w)
		return;
	}

	/* resume the device first if at all it resumes */
	pm_runtime_resume(phy->dev);
	switch (motg->chg_state) {
	case USB_CHG_STATE_UNDEFINED:
		msm_chg_block_on(motg);
@@ -2863,7 +2865,7 @@ static void msm_chg_detect_work(struct work_struct *w)
			msm_chg_block_off(motg);
			motg->chg_state = USB_CHG_STATE_DETECTED;
			motg->chg_type = USB_INVALID_CHARGER;
			queue_work(system_nrt_wq, &motg->sm_work);
			queue_work(motg->otg_wq, &motg->sm_work);
			return;
		}
		is_aca = msm_chg_aca_detect(motg);
@@ -2972,13 +2974,13 @@ static void msm_chg_detect_work(struct work_struct *w)

		dev_dbg(phy->dev, "chg_type = %s\n",
			chg_to_string(motg->chg_type));
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
		return;
	default:
		return;
	}

	queue_delayed_work(system_nrt_wq, &motg->chg_work, delay);
	queue_delayed_work(motg->otg_wq, &motg->chg_work, delay);
}

#define VBUS_INIT_TIMEOUT	msecs_to_jiffies(5000)
@@ -3730,7 +3732,7 @@ static void msm_otg_sm_work(struct work_struct *w)
		break;
	}
	if (work)
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
}

static void msm_otg_suspend_work(struct work_struct *w)
@@ -3901,7 +3903,7 @@ static irqreturn_t msm_otg_irq(int irq, void *data)
		ret = IRQ_HANDLED;
	}
	if (work)
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);

	return ret;
}
@@ -3967,7 +3969,7 @@ out:
		motg->sm_work_pending = true;
	} else if (!motg->sm_work_pending) {
		/* process event only if previous one is not pending */
		queue_work(system_nrt_wq, &motg->sm_work);
		queue_work(motg->otg_wq, &motg->sm_work);
	}
}

@@ -4005,7 +4007,7 @@ static void msm_id_status_w(struct work_struct *w)
			motg->sm_work_pending = true;
		} else if (!motg->sm_work_pending) {
			/* process event only if previous one is not pending */
			queue_work(system_nrt_wq, &motg->sm_work);
			queue_work(motg->otg_wq, &motg->sm_work);
		}
	}

@@ -4024,7 +4026,7 @@ static irqreturn_t msm_id_irq(int irq, void *data)

	if (!aca_id_turned_on)
		/*schedule delayed work for 5msec for ID line state to settle*/
		queue_delayed_work(system_nrt_wq, &motg->id_status_work,
		queue_delayed_work(motg->otg_wq, &motg->id_status_work,
				msecs_to_jiffies(MSM_ID_STATUS_DELAY));

	return IRQ_HANDLED;
@@ -4047,7 +4049,7 @@ int msm_otg_pm_notify(struct notifier_block *notify_block,
		/* 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);
			queue_work(motg->otg_wq, &motg->sm_work);
		}
		break;

@@ -4156,7 +4158,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf,
	}

	pm_runtime_resume(phy->dev);
	queue_work(system_nrt_wq, &motg->sm_work);
	queue_work(motg->otg_wq, &motg->sm_work);
out:
	return status;
}
@@ -5422,6 +5424,13 @@ static int msm_otg_probe(struct platform_device *pdev)
				(unsigned long) motg);
	setup_timer(&motg->chg_check_timer, msm_otg_chg_check_timer_func,
				(unsigned long) motg);
	motg->otg_wq = alloc_ordered_workqueue("k_otg", 0);
	if (!motg->otg_wq) {
		pr_err("%s: Unable to create workqueue otg_wq\n",
			__func__);
		goto destroy_wlock;
	}

	ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
					"msm_otg", motg);
	if (ret) {
@@ -5646,6 +5655,7 @@ destroy_wlock:
	wake_lock_destroy(&motg->wlock);
	clk_disable_unprepare(motg->core_clk);
	msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
	destroy_workqueue(motg->otg_wq);
free_ldo_init:
	msm_hsusb_ldo_init(motg, 0);
free_hsusb_vdd:
@@ -5723,6 +5733,7 @@ static int msm_otg_remove(struct platform_device *pdev)
	cancel_delayed_work_sync(&motg->id_status_work);
	cancel_delayed_work_sync(&motg->suspend_work);
	cancel_work_sync(&motg->sm_work);
	destroy_workqueue(motg->otg_wq);

	pm_runtime_resume(&pdev->dev);

+2 −0
Original line number Diff line number Diff line
@@ -382,6 +382,7 @@ struct msm_otg_platform_data {
 * @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.
 * @otg_wq: Strict order otg workqueue for OTG works (SM/ID/SUSPEND).
 * @chg_work: Charger detection work.
 * @chg_state: The state of charger detection process.
 * @chg_type: The type of charger attached.
@@ -460,6 +461,7 @@ struct msm_otg {
	atomic_t set_fpr_with_lpm_exit;
	int async_int;
	unsigned cur_power;
	struct workqueue_struct *otg_wq;
	struct delayed_work chg_work;
	struct delayed_work id_status_work;
	struct delayed_work suspend_work;