From cc272ebeefcd97053d4779aa4ce0a745f210e338 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 4 May 2012 14:17:08 +0200 Subject: [PATCH] --- yaml --- r: 303824 b: refs/heads/master c: 12a1f4dc0dfe4c72e565dc02d6a1c021f3f98b61 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/usb/gadget/s3c-hsotg.c | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index 619593ec5cb9..8feb7b2bf2c9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5e891342fd0761fed36c187587115e706c0fa358 +refs/heads/master: 12a1f4dc0dfe4c72e565dc02d6a1c021f3f98b61 diff --git a/trunk/drivers/usb/gadget/s3c-hsotg.c b/trunk/drivers/usb/gadget/s3c-hsotg.c index 7e3b59106e67..ca9041634c04 100644 --- a/trunk/drivers/usb/gadget/s3c-hsotg.c +++ b/trunk/drivers/usb/gadget/s3c-hsotg.c @@ -148,6 +148,7 @@ struct s3c_hsotg_ep { * @ctrl_buff: Buffer for EP0 control requests. * @ctrl_req: Request for EP0 control packets. * @setup: NAK management for EP0 SETUP + * @last_rst: Time of last reset * @eps: The endpoints being supplied to the gadget framework */ struct s3c_hsotg { @@ -175,6 +176,7 @@ struct s3c_hsotg { struct usb_gadget gadget; unsigned int setup; + unsigned long last_rst; struct s3c_hsotg_ep eps[]; }; @@ -2377,23 +2379,26 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) } if (gintsts & S3C_GINTSTS_USBRst) { + + u32 usb_status = readl(hsotg->regs + S3C_GOTGCTL); + dev_info(hsotg->dev, "%s: USBRst\n", __func__); dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", readl(hsotg->regs + S3C_GNPTXSTS)); writel(S3C_GINTSTS_USBRst, hsotg->regs + S3C_GINTSTS); - kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true); + if (usb_status & S3C_GOTGCTL_BSESVLD) { + if (time_after(jiffies, hsotg->last_rst + + msecs_to_jiffies(200))) { - /* it seems after a reset we can end up with a situation - * where the TXFIFO still has data in it... the docs - * suggest resetting all the fifos, so use the init_fifo - * code to relayout and flush the fifos. - */ + kill_all_requests(hsotg, &hsotg->eps[0], + -ECONNRESET, true); - s3c_hsotg_init_fifo(hsotg); - - s3c_hsotg_enqueue_setup(hsotg); + s3c_hsotg_core_init(hsotg); + hsotg->last_rst = jiffies; + } + } } /* check both FIFOs */ @@ -2436,6 +2441,7 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) writel(S3C_GINTSTS_USBSusp, hsotg->regs + S3C_GINTSTS); call_gadget(hsotg, suspend); + s3c_hsotg_disconnect(hsotg); } if (gintsts & S3C_GINTSTS_WkUpInt) { @@ -2448,6 +2454,8 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) if (gintsts & S3C_GINTSTS_ErlySusp) { dev_dbg(hsotg->dev, "S3C_GINTSTS_ErlySusp\n"); writel(S3C_GINTSTS_ErlySusp, hsotg->regs + S3C_GINTSTS); + + s3c_hsotg_disconnect(hsotg); } /* these next two seem to crop-up occasionally causing the core @@ -2823,7 +2831,7 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver, } s3c_hsotg_core_init(hsotg); - + hsotg->last_rst = jiffies; dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); return 0;