From d8a3ed49a59fdf54ac3f311a75dca3e94b13eb26 Mon Sep 17 00:00:00 2001 From: Yunzhi Li Date: Tue, 23 Jun 2015 17:42:34 +0800 Subject: [PATCH] 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 Original-Commit-Id: 9238f87c065ba8a57bfb4a7e65fd1821ff2922f9 Original-Change-Id: I1e584aaf19efa14409bdfa26039c27fa7034b5f0 Original-Signed-off-by: Yunzhi Li Original-Reviewed-on: https://chromium-review.googlesource.com/281130 Original-Reviewed-by: Patrick Georgi Original-Tested-by: Lin Huang Original-Commit-Queue: Jeffy Chen Reviewed-on: http://review.coreboot.org/10770 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- payloads/libpayload/drivers/udc/dwc2.c | 34 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/payloads/libpayload/drivers/udc/dwc2.c b/payloads/libpayload/drivers/udc/dwc2.c index 99ee0b323b..ab3684448d 100644 --- a/payloads/libpayload/drivers/udc/dwc2.c +++ b/payloads/libpayload/drivers/udc/dwc2.c @@ -675,21 +675,10 @@ static int dwc2_check_irq(struct usbdev_ctrl *this) 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 @@ static void dwc2_shutdown(struct usbdev_ctrl *this) 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 @@ struct usbdev_ctrl *dwc2_udc_init(device_descriptor_t *dd) 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;