From patchwork Wed Mar 7 09:39:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Virdi X-Patchwork-Id: 145174 X-Patchwork-Delegate: marek.vasut@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id DAB3EB6EE6 for ; Wed, 7 Mar 2012 20:40:11 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 248F92808C; Wed, 7 Mar 2012 10:40:09 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id H1IyYfwWdn49; Wed, 7 Mar 2012 10:40:08 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9B82A2809F; Wed, 7 Mar 2012 10:40:02 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 51B5D2808C for ; Wed, 7 Mar 2012 10:39:58 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Sz0DGa993Nk5 for ; Wed, 7 Mar 2012 10:39:57 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from eu1sys200aog103.obsmtp.com (eu1sys200aog103.obsmtp.com [207.126.144.115]) by theia.denx.de (Postfix) with ESMTPS id 7CA0428089 for ; Wed, 7 Mar 2012 10:39:54 +0100 (CET) Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob103.postini.com ([207.126.147.11]) with SMTP ID DSNKT1cs6Mnsqv1WNRMRHJexSVKSQTu/0TYw@postini.com; Wed, 07 Mar 2012 09:39:56 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 7B780108; Wed, 7 Mar 2012 09:31:24 +0000 (GMT) Received: from Webmail-ap.st.com (eapex1hubcas2.st.com [10.80.176.10]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 8BABAAEC; Wed, 7 Mar 2012 09:39:49 +0000 (GMT) Received: from localhost (10.199.7.86) by Webmail-ap.st.com (10.80.176.7) with Microsoft SMTP Server (TLS) id 8.3.192.1; Wed, 7 Mar 2012 17:39:20 +0800 From: Amit Virdi To: Date: Wed, 7 Mar 2012 15:09:38 +0530 Message-ID: <1331113181-2193-3-git-send-email-amit.virdi@st.com> X-Mailer: git-send-email 1.7.2.2 In-Reply-To: <1331113181-2193-1-git-send-email-amit.virdi@st.com> References: <1331113181-2193-1-git-send-email-amit.virdi@st.com> MIME-Version: 1.0 Cc: marex@denx.de, Amit Virdi , sr@denx.de, spear-devel@list.st.com Subject: [U-Boot] [PATCH V2 2/5] USB:gadget:designware Device controller bugfixes X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Vipin KUMAR This patch fixes a few bugs in USB device controller driver. The fixes are as follows 1. Adding error condition checks eg. NULL return 2. Endpoint other than endpoint 0 (control endpoint) are initialized only if usb state machine reaches STATE_ADDRESSED or above 3. Zero length packet handling corrected 4. Dead code removed 5. Bulk out endpoint returns after servicing 1 interrupt and returns back to service if more interrupts are pending Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Acked-by: Marek Vasut --- drivers/usb/gadget/designware_udc.c | 59 ++++++++++++++++++++++------------ 1 files changed, 38 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/designware_udc.c b/drivers/usb/gadget/designware_udc.c index aee44aa..3c20f3d 100644 --- a/drivers/usb/gadget/designware_udc.c +++ b/drivers/usb/gadget/designware_udc.c @@ -497,16 +497,24 @@ static void dw_udc_epn_tx(int ep) { struct usb_endpoint_instance *endpoint = dw_find_ep(ep); + if (!endpoint) + return; + /* * We need to transmit a terminating zero-length packet now if * we have sent all of the data in this URB and the transfer * size was an exact multiple of the packet size. */ - if (endpoint && endpoint->tx_urb && endpoint->tx_urb->actual_length) { - if (endpoint->last == endpoint->tx_packetSize) { - /* handle zero length packet here */ - writel(0x0, &inep_regs_p[ep].write_done); - } + if (endpoint->tx_urb && + (endpoint->last == endpoint->tx_packetSize) && + (endpoint->tx_urb->actual_length - endpoint->sent - + endpoint->last == 0)) { + /* handle zero length packet here */ + writel(0x0, &inep_regs_p[ep].write_done); + + } + + if (endpoint->tx_urb && endpoint->tx_urb->actual_length) { /* retire the data that was just sent */ usbd_tx_complete(endpoint); /* @@ -548,8 +556,6 @@ int udc_init(void) readl(&plug_regs_p->plug_pending); - udc_disconnect(); - for (i = 0; i < UDC_INIT_MDELAY; i++) udelay(1000); @@ -561,10 +567,9 @@ int udc_init(void) writel(~0x0, &udc_regs_p->endp_int_mask); writel(DEV_CONF_FS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW | - /* Dev_Conf_SYNCFRAME | */ DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf); - writel(0x0, &udc_regs_p->dev_cntl); + writel(DEV_CNTL_SOFTDISCONNECT, &udc_regs_p->dev_cntl); /* Clear all interrupts pending */ writel(DEV_INT_MSK, &udc_regs_p->dev_int); @@ -588,6 +593,9 @@ void udc_setup_ep(struct usb_device_instance *device, char *tt; u32 endp_intmask; + if ((ep != 0) && (udc_device->device_state < STATE_ADDRESSED)) + return; + tt = getenv("usbtty"); if (!tt) tt = "generic"; @@ -647,9 +655,6 @@ void udc_setup_ep(struct usb_device_instance *device, writel(packet_size | ((buffer_size / sizeof(int)) << 16), &out_p->endp_maxpacksize); - writel((packet_size << 19) | ENDP_EPTYPE_CNTL, - &udc_regs_p->udc_endp_reg[ep_num]); - } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { /* Setup the IN endpoint */ writel(0x0, &in_p->endp_status); @@ -708,7 +713,17 @@ void udc_setup_ep(struct usb_device_instance *device, /* Turn on the USB connection by enabling the pullup resistor */ void udc_connect(void) { - u32 plug_st; + u32 plug_st, dev_cntl; + + dev_cntl = readl(&udc_regs_p->dev_cntl); + dev_cntl |= DEV_CNTL_SOFTDISCONNECT; + writel(dev_cntl, &udc_regs_p->dev_cntl); + + udelay(1000); + + dev_cntl = readl(&udc_regs_p->dev_cntl); + dev_cntl &= ~DEV_CNTL_SOFTDISCONNECT; + writel(dev_cntl, &udc_regs_p->dev_cntl); plug_st = readl(&plug_regs_p->plug_state); plug_st &= ~(PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE); @@ -720,6 +735,8 @@ void udc_disconnect(void) { u32 plug_st; + writel(DEV_CNTL_SOFTDISCONNECT, &udc_regs_p->dev_cntl); + plug_st = readl(&plug_regs_p->plug_state); plug_st |= (PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE); writel(plug_st, &plug_regs_p->plug_state); @@ -789,11 +806,6 @@ void dw_udc_plug_irq(void) UDCDBG("device attached and powered"); udc_state_transition(udc_device->device_state, STATE_POWERED); } else { - /* - * USB cable detached - * Reset the PHY and switch the mode. - */ - udc_disconnect(); writel(~0x0, &udc_regs_p->dev_int_mask); UDCDBG("device detached or unpowered"); @@ -809,13 +821,18 @@ void dw_udc_dev_irq(void) if (readl(&udc_regs_p->dev_int) & DEV_INT_USBRESET) { writel(~0x0, &udc_regs_p->endp_int_mask); - udc_connect(); - writel(readl(&inep_regs_p[0].endp_cntl) | ENDP_CNTL_FLUSH, &inep_regs_p[0].endp_cntl); writel(DEV_INT_USBRESET, &udc_regs_p->dev_int); + /* + * This endpoint0 specific register can be programmed only + * after the phy clock is initialized + */ + writel((EP0_MAX_PACKET_SIZE << 19) | ENDP_EPTYPE_CNTL, + &udc_regs_p->udc_endp_reg[0]); + UDCDBG("device reset in progess"); udc_state_transition(udc_device->device_state, STATE_DEFAULT); } @@ -902,7 +919,7 @@ void dw_udc_endpoint_irq(void) writel(ENDP0_INT_CTRLIN, &udc_regs_p->endp_int); } - while (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) { + if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) { u32 epnum = 0; u32 ep_int = readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK;