libpayload: udc: dwc2: support force_shutdown() routine

Add force_shutdown() routine for dwc2 udc driver to support
disconnect and reconnect case when fastboot receiving data.

BUG=chrome-os-partner:41687
BRANCH=None
TEST=None

Change-Id: I9ec204d8b7088cfafd3164c9779a6fd85d379dba
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 9238f87c065ba8a57bfb4a7e65fd1821ff2922f9
Original-Change-Id: I1e584aaf19efa14409bdfa26039c27fa7034b5f0
Original-Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/281130
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Tested-by: Lin Huang <hl@rock-chips.com>
Original-Commit-Queue: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-on: http://review.coreboot.org/10770
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/payloads/libpayload/drivers/udc/dwc2.c b/payloads/libpayload/drivers/udc/dwc2.c
index 99ee0b3..ab36844 100644
--- a/payloads/libpayload/drivers/udc/dwc2.c
+++ b/payloads/libpayload/drivers/udc/dwc2.c
@@ -675,21 +675,10 @@
 	return 1;
 }
 
-static void dwc2_shutdown(struct usbdev_ctrl *this)
+static void dwc2_force_shutdown(struct usbdev_ctrl *this)
 {
-	dwc2_pdata_t *p = DWC2_PDATA(this);
-	int i, j;
-	int is_empty = 0;
 	gusbcfg_t gusbcfg;
-
-	while (!is_empty) {
-		is_empty = 1;
-		this->poll(this);
-		for (i = 0; i < 16; i++)
-			for (j = 0; j < 2; j++)
-				if (!SIMPLEQ_EMPTY(&p->eps[i][j].job_queue))
-					is_empty = 0;
-	}
+	dwc2_pdata_t *p = DWC2_PDATA(this);
 
 	/* Disconnect */
 	dwc2_connect(this, 0);
@@ -704,6 +693,24 @@
 	free(this);
 }
 
+static void dwc2_shutdown(struct usbdev_ctrl *this)
+{
+	dwc2_pdata_t *p = DWC2_PDATA(this);
+	int i, j;
+	int is_empty = 0;
+
+	while (!is_empty) {
+		is_empty = 1;
+		this->poll(this);
+		for (i = 0; i < 16; i++)
+			for (j = 0; j < 2; j++)
+				if (!SIMPLEQ_EMPTY(&p->eps[i][j].job_queue))
+					is_empty = 0;
+	}
+
+	dwc2_force_shutdown(this);
+}
+
 static void dwc2_set_address(struct usbdev_ctrl *this, int address)
 {
 	dwc2_pdata_t *p = DWC2_PDATA(this);
@@ -910,6 +917,7 @@
 	ctrl->poll = dwc2_check_irq;
 	ctrl->add_gadget = udc_add_gadget;
 	ctrl->enqueue_packet = dwc2_enqueue_packet;
+	ctrl->force_shutdown = dwc2_force_shutdown;
 	ctrl->shutdown = dwc2_shutdown;
 	ctrl->set_address = dwc2_set_address;
 	ctrl->stall = dwc2_stall;