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

Commit 40e679aa authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa
Browse files

USB: dwc3-msm: Add recovery mechanism for erratic error event



DWC3 controller will generate Erratic event if PHY doesn't respond to
PHY command sent by core within stipulated time. In normal case, this
should not happen. Due to this, USB functionality will break if not
added recovery mechanism for handling this erratic error event. Hence
add recovery mechanism by doing block reset whenever Erratic error
event is triggered by contoller.

CRs-Fixed: 535976
Change-Id: I5c8cc0c822a26c7fe4b8ac58b651d9a3267626ce
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
parent 76784e6b
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -201,6 +201,7 @@ struct dwc3_msm {
	bool			lpm_irq_seen;
	struct delayed_work	resume_work;
	struct work_struct	restart_usb_work;
	struct work_struct	usb_block_reset_work;
	struct dwc3_charger	charger;
	struct usb_phy		*otg_xceiv;
	struct delayed_work	chg_work;
@@ -1495,6 +1496,11 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event)
	case DWC3_CONTROLLER_ERROR_EVENT:
		dev_info(mdwc->dev, "DWC3_CONTROLLER_ERROR_EVENT received\n");
		dwc3_msm_dump_phy_info(mdwc);
		/*
		 * schedule work for doing block reset for recovery from erratic
		 * error event.
		 */
		queue_work(system_nrt_wq, &mdwc->usb_block_reset_work);
		break;
	case DWC3_CONTROLLER_RESET_EVENT:
		dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESET_EVENT received\n");
@@ -1537,6 +1543,16 @@ static void dwc3_msm_block_reset(struct dwc3_ext_xceiv *xceiv, bool core_reset)
	dwc3_msm_dbm_soft_reset(mdwc, 0);
}

static void dwc3_block_reset_usb_work(struct work_struct *w)
{
	struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm,
						usb_block_reset_work);

	dev_dbg(mdwc->dev, "%s\n", __func__);

	dwc3_msm_block_reset(&mdwc->ext_xceiv, true);
}

static void dwc3_chg_enable_secondary_det(struct dwc3_msm *mdwc)
{
	u32 chg_ctrl;
@@ -2699,6 +2715,7 @@ static int dwc3_msm_probe(struct platform_device *pdev)
	INIT_DELAYED_WORK(&mdwc->chg_work, dwc3_chg_detect_work);
	INIT_DELAYED_WORK(&mdwc->resume_work, dwc3_resume_work);
	INIT_WORK(&mdwc->restart_usb_work, dwc3_restart_usb_work);
	INIT_WORK(&mdwc->usb_block_reset_work, dwc3_block_reset_usb_work);
	INIT_WORK(&mdwc->id_work, dwc3_id_work);
	INIT_DELAYED_WORK(&mdwc->init_adc_work, dwc3_init_adc_work);
	init_completion(&mdwc->ext_chg_wait);
+0 −3
Original line number Diff line number Diff line
@@ -2811,9 +2811,6 @@ static void dwc3_dump_reg_info(struct dwc3 *dwc)
	dbg_print_reg("OSTS", dwc3_readl(dwc->regs, DWC3_OSTS));

	dwc3_notify_event(dwc, DWC3_CONTROLLER_ERROR_EVENT);

	panic("DWC3 Erratic error\n");

}

static void dwc3_gadget_interrupt(struct dwc3 *dwc,