diff options
Diffstat (limited to 'meta/packages/linux/linux-omap-2.6.29/musb')
29 files changed, 0 insertions, 4957 deletions
diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0001-USB-musb-only-turn-off-vbus-in-OTG-hosts.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0001-USB-musb-only-turn-off-vbus-in-OTG-hosts.patch deleted file mode 100644 index a7898d1440..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0001-USB-musb-only-turn-off-vbus-in-OTG-hosts.patch +++ /dev/null @@ -1,43 +0,0 @@ -From a9199e8ab6d6fb105aa251d6bf2192e7eafac8ee Mon Sep 17 00:00:00 2001 -From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org> -Date: Tue, 24 Mar 2009 17:22:53 -0700 -Subject: [PATCH] USB: musb: only turn off vbus in OTG hosts - -Except on DaVinci, VBUS is now switched off as part of idling the -USB link (after a_wait_bcon) whenever a device is disconnected -from host. This is correct for OTG hosts, where either SRP or -an ID interrupt could turn VBUS on again. - -However, for non-OTG hosts there's no way to turn VBUS on again, -so the host becomes unusable. And the procfs entry which once -allowed a manual workaround for this is now gone. - -This patch adds an is_otg_enabled() check before scheduling the -switch-off timer in disconnect path, supporting a "classic host" -mode where SRP is unavailable. - -[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: tweak patch description ] - -Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org> ---- - drivers/usb/musb/musb_core.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index af77e46..338cd16 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -769,7 +769,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - case OTG_STATE_A_SUSPEND: - usb_hcd_resume_root_hub(musb_to_hcd(musb)); - musb_root_disconnect(musb); -- if (musb->a_wait_bcon != 0) -+ if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) - musb_platform_try_idle(musb, jiffies - + msecs_to_jiffies(musb->a_wait_bcon)); - break; --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0002-USB-composite-avoid-inconsistent-lock-state.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0002-USB-composite-avoid-inconsistent-lock-state.patch deleted file mode 100644 index 5cb7bcb065..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0002-USB-composite-avoid-inconsistent-lock-state.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 83eb44b1c84f99d9a5c67612bd94b4ed7c43f64c Mon Sep 17 00:00:00 2001 -From: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Date: Tue, 24 Mar 2009 17:22:49 -0700 -Subject: [PATCH] USB: composite: avoid inconsistent lock state - -Avoid the following INFO from lock debugging: - -[ 369.126112] ================================= -[ 369.132063] [ INFO: inconsistent lock state ] -[ 369.136457] 2.6.28-maemo1 #1 -[ 369.139387] --------------------------------- -[ 369.143782] inconsistent {hardirq-on-W} -> {in-hardirq-W} usage. -[ 369.149855] swapper/0 [HC1[1]:SC0[0]:HE0:SE1] takes: -[ 369.154890] (&cdev->lock){+-..}, at: [<bf1979f0>] composite_disconnect+0x1c/0] -[ 369.163404] {hardirq-on-W} state was registered at: -[ 369.168348] [<c00788a8>] __lock_acquire+0x5d0/0x7d8 -[ 369.173506] [<c0078b14>] lock_acquire+0x64/0x78 -[ 369.178266] [<c0263a34>] _spin_lock+0x4c/0x80 -[ 369.182905] [<bf19597c>] usb_function_deactivate+0x20/0x70 [g_nokia] -[ 369.189527] [<bf1a0a88>] 0xbf1a0a88 -[ 369.193281] [<bf19f450>] 0xbf19f450 -[ 369.197004] [<bf19fa3c>] 0xbf19fa3c -[ 369.200758] [<bf1a03a0>] 0xbf1a03a0 -[ 369.204481] [<bf19f254>] 0xbf19f254 -[ 369.208204] [<bf1a0158>] 0xbf1a0158 -[ 369.211927] [<bf1a130c>] 0xbf1a130c -[ 369.215650] [<c01c21f0>] usb_gadget_register_driver+0x12c/0x28c -[ 369.221846] [<bf1a06bc>] 0xbf1a06bc -[ 369.225569] [<bf1a06e8>] 0xbf1a06e8 -[ 369.229322] [<c002c2dc>] __exception_text_end+0x64/0x19c -[ 369.234877] [<c0081628>] sys_init_module+0x9c/0x194 -[ 369.240004] [<c002c8e0>] ret_fast_syscall+0x0/0x2c -[ 369.245039] [<ffffffff>] 0xffffffff -[ 369.248793] irq event stamp: 218356 -[ 369.252302] hardirqs last enabled at (218355): [<c003a77c>] omap3_enter_idle+8 -[ 369.260420] hardirqs last disabled at (218356): [<c0264774>] __irq_svc+0x34/0x0 -[ 369.267927] softirqs last enabled at (218348): [<c00585a4>] __do_softirq+0x134 -[ 369.275892] softirqs last disabled at (218335): [<c005899c>] irq_exit+0x60/0xb0 -[ 369.283308] -[ 369.283308] other info that might help us debug this: -[ 369.289930] no locks held by swapper/0. - -Cc: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> -Signed-off-by: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org> ---- - drivers/usb/gadget/composite.c | 5 +++-- - 1 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c -index 5d11c29..40f1da7 100644 ---- a/drivers/usb/gadget/composite.c -+++ b/drivers/usb/gadget/composite.c -@@ -149,16 +149,17 @@ done: - int usb_function_deactivate(struct usb_function *function) - { - struct usb_composite_dev *cdev = function->config->cdev; -+ unsigned long flags; - int status = 0; - -- spin_lock(&cdev->lock); -+ spin_lock_irqsave(&cdev->lock, flags); - - if (cdev->deactivations == 0) - status = usb_gadget_disconnect(cdev->gadget); - if (status == 0) - cdev->deactivations++; - -- spin_unlock(&cdev->lock); -+ spin_unlock_irqrestore(&cdev->lock, flags); - return status; - } - --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch deleted file mode 100644 index fadad9e44a..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0003-USB-musb-NAK-timeout-scheme-on-bulk-RX-endpoint.patch +++ /dev/null @@ -1,218 +0,0 @@ -From ba7b26e69f4bb41f10be444c5fded853330f82b5 Mon Sep 17 00:00:00 2001 -From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org> -Date: Tue, 24 Mar 2009 17:22:51 -0700 -Subject: [PATCH] USB: musb: NAK timeout scheme on bulk RX endpoint - -Fixes endpoint starvation issue when more than one bulk QH is -multiplexed on the reserved bulk RX endpoint, which is normal -for cases like serial and ethernet adapters. - -This patch sets the NAK timeout interval for such QHs, and when -a timeout triggers the next QH will be scheduled. (This resembles -the bulk scheduling done in hardware by EHCI, OHCI, and UHCI.) - -This scheme doesn't work for devices which are connected to a -high to full speed tree (transaction translator) as there is -no NAK timeout interrupt from the musb controller from such -devices. - -Tested with PIO, Inventra DMA, CPPI DMA. - -[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: fold in start_urb() update; - clarify only for bulk RX; don't accidentally clear WZC bits ] - -Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org> -Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 112 ++++++++++++++++++++++++++++++++---------- - 1 files changed, 85 insertions(+), 27 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index 6dbbd07..bd1d5ae 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -64,11 +64,8 @@ - * - * - DMA (Mentor/OMAP) ...has at least toggle update problems - * -- * - Still no traffic scheduling code to make NAKing for bulk or control -- * transfers unable to starve other requests; or to make efficient use -- * of hardware with periodic transfers. (Note that network drivers -- * commonly post bulk reads that stay pending for a long time; these -- * would make very visible trouble.) -+ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet -+ * starvation ... nothing yet for TX, interrupt, or bulk. - * - * - Not tested with HNP, but some SRP paths seem to behave. - * -@@ -88,11 +85,8 @@ - * - * CONTROL transfers all go through ep0. BULK ones go through dedicated IN - * and OUT endpoints ... hardware is dedicated for those "async" queue(s). -- * - * (Yes, bulk _could_ use more of the endpoints than that, and would even -- * benefit from it ... one remote device may easily be NAKing while others -- * need to perform transfers in that same direction. The same thing could -- * be done in software though, assuming dma cooperates.) -+ * benefit from it.) - * - * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints. - * So far that scheduling is both dumb and optimistic: the endpoint will be -@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - len = urb->iso_frame_desc[0].length; - break; - default: /* bulk, interrupt */ -- buf = urb->transfer_buffer; -- len = urb->transfer_buffer_length; -+ /* actual_length may be nonzero on retry paths */ -+ buf = urb->transfer_buffer + urb->actual_length; -+ len = urb->transfer_buffer_length - urb->actual_length; - } - - DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", -@@ -1045,7 +1040,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) - - /* NOTE: this code path would be a good place to PAUSE a - * control transfer, if another one is queued, so that -- * ep0 is more likely to stay busy. -+ * ep0 is more likely to stay busy. That's already done -+ * for bulk RX transfers. - * - * if (qh->ring.next != &musb->control), then - * we have a candidate... NAKing is *NOT* an error -@@ -1197,6 +1193,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) - /* NOTE: this code path would be a good place to PAUSE a - * transfer, if there's some other (nonperiodic) tx urb - * that could use this fifo. (dma complicates it...) -+ * That's already done for bulk RX transfers. - * - * if (bulk && qh->ring.next != &musb->out_bulk), then - * we have a candidate... NAKing is *NOT* an error -@@ -1358,6 +1355,50 @@ finish: - - #endif - -+/* Schedule next QH from musb->in_bulk and move the current qh to -+ * the end; avoids starvation for other endpoints. -+ */ -+static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep) -+{ -+ struct dma_channel *dma; -+ struct urb *urb; -+ void __iomem *mbase = musb->mregs; -+ void __iomem *epio = ep->regs; -+ struct musb_qh *cur_qh, *next_qh; -+ u16 rx_csr; -+ -+ musb_ep_select(mbase, ep->epnum); -+ dma = is_dma_capable() ? ep->rx_channel : NULL; -+ -+ /* clear nak timeout bit */ -+ rx_csr = musb_readw(epio, MUSB_RXCSR); -+ rx_csr |= MUSB_RXCSR_H_WZC_BITS; -+ rx_csr &= ~MUSB_RXCSR_DATAERROR; -+ musb_writew(epio, MUSB_RXCSR, rx_csr); -+ -+ cur_qh = first_qh(&musb->in_bulk); -+ if (cur_qh) { -+ urb = next_urb(cur_qh); -+ if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { -+ dma->status = MUSB_DMA_STATUS_CORE_ABORT; -+ musb->dma_controller->channel_abort(dma); -+ urb->actual_length += dma->actual_len; -+ dma->actual_len = 0L; -+ } -+ musb_save_toggle(ep, 1, urb); -+ -+ /* move cur_qh to end of queue */ -+ list_move_tail(&cur_qh->ring, &musb->in_bulk); -+ -+ /* get the next qh from musb->in_bulk */ -+ next_qh = first_qh(&musb->in_bulk); -+ -+ /* set rx_reinit and schedule the next qh */ -+ ep->rx_reinit = 1; -+ musb_start_urb(musb, 1, next_qh); -+ } -+} -+ - /* - * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso, - * and high-bandwidth IN transfer cases. -@@ -1421,18 +1462,26 @@ void musb_host_rx(struct musb *musb, u8 epnum) - } else if (rx_csr & MUSB_RXCSR_DATAERROR) { - - if (USB_ENDPOINT_XFER_ISOC != qh->type) { -- /* NOTE this code path would be a good place to PAUSE a -- * transfer, if there's some other (nonperiodic) rx urb -- * that could use this fifo. (dma complicates it...) -+ DBG(6, "RX end %d NAK timeout\n", epnum); -+ -+ /* NOTE: NAKing is *NOT* an error, so we want to -+ * continue. Except ... if there's a request for -+ * another QH, use that instead of starving it. - * -- * if (bulk && qh->ring.next != &musb->in_bulk), then -- * we have a candidate... NAKing is *NOT* an error -+ * Devices like Ethernet and serial adapters keep -+ * reads posted at all times, which will starve -+ * other devices without this logic. - */ -- DBG(6, "RX end %d NAK timeout\n", epnum); -+ if (usb_pipebulk(urb->pipe) -+ && qh->mux == 1 -+ && !list_is_singular(&musb->in_bulk)) { -+ musb_bulk_rx_nak_timeout(musb, hw_ep); -+ return; -+ } - musb_ep_select(mbase, epnum); -- musb_writew(epio, MUSB_RXCSR, -- MUSB_RXCSR_H_WZC_BITS -- | MUSB_RXCSR_H_REQPKT); -+ rx_csr |= MUSB_RXCSR_H_WZC_BITS; -+ rx_csr &= ~MUSB_RXCSR_DATAERROR; -+ musb_writew(epio, MUSB_RXCSR, rx_csr); - - goto finish; - } else { -@@ -1756,6 +1805,17 @@ static int musb_schedule( - head = &musb->in_bulk; - else - head = &musb->out_bulk; -+ -+ /* Enable bulk RX NAK timeout scheme when bulk requests are -+ * multiplexed. This scheme doen't work in high speed to full -+ * speed scenario as NAK interrupts are not coming from a -+ * full speed device connected to a high speed device. -+ * NAK timeout interval is 8 (128 uframe or 16ms) for HS and -+ * 4 (8 frame or 8ms) for FS device. -+ */ -+ if (is_in && qh->dev) -+ qh->intv_reg = -+ (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4; - goto success; - } else if (best_end < 0) { - return -ENOSPC; -@@ -1888,13 +1948,11 @@ static int musb_urb_enqueue( - * - * The downside of disabling this is that transfer scheduling - * gets VERY unfair for nonperiodic transfers; a misbehaving -- * peripheral could make that hurt. Or for reads, one that's -- * perfectly normal: network and other drivers keep reads -- * posted at all times, having one pending for a week should -- * be perfectly safe. -+ * peripheral could make that hurt. That's perfectly normal -+ * for reads from network or serial adapters ... so we have -+ * partial NAKlimit support for bulk RX. - * -- * The upside of disabling it is avoidng transfer scheduling -- * code to put this aside for while. -+ * The upside of disabling it is simpler transfer scheduling. - */ - interval = 0; - } --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0004-USB-musb-rewrite-host-periodic-endpoint-allocation.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0004-USB-musb-rewrite-host-periodic-endpoint-allocation.patch deleted file mode 100644 index 438f11cf7a..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0004-USB-musb-rewrite-host-periodic-endpoint-allocation.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 9ebf351bcd28a89a0b1ba8d0496fffbc72421611 Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Tue, 24 Mar 2009 17:22:50 -0700 -Subject: [PATCH] USB: musb: rewrite host periodic endpoint allocation - -The current MUSB host code doesn't make use of all the available -FIFOs in for periodic transfers since it wrongly assumes the RX -and TX sides of any given hw_ep always share one FIFO. - -Change: use 'in_qh' and 'out_qh' fields of the 'struct musb_hw_ep' -to check the endpoint's business; get rid of the now-unused 'periodic' -array in the 'struct musb'. Also optimize a loop induction variable -in the endpoint lookup code. - -(Based on a previous patch from Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>) - -[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: clarify description and origin - of this fix; whitespace ] - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org> ---- - drivers/usb/musb/musb_core.h | 1 - - drivers/usb/musb/musb_host.c | 28 +++++++++++----------------- - 2 files changed, 11 insertions(+), 18 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h -index 630946a..adf1806 100644 ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -331,7 +331,6 @@ struct musb { - struct list_head control; /* of musb_qh */ - struct list_head in_bulk; /* of musb_qh */ - struct list_head out_bulk; /* of musb_qh */ -- struct musb_qh *periodic[32]; /* tree of interrupt+iso */ - #endif - - /* called with IRQs blocked; ON/nonzero implies starting a session, -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index bd1d5ae..499c431 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -390,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) - * de-allocated if it's tracked and allocated; - * and where we'd update the schedule tree... - */ -- musb->periodic[ep->epnum] = NULL; - kfree(qh); - qh = NULL; - break; -@@ -1760,31 +1759,27 @@ static int musb_schedule( - - /* else, periodic transfers get muxed to other endpoints */ - -- /* FIXME this doesn't consider direction, so it can only -- * work for one half of the endpoint hardware, and assumes -- * the previous cases handled all non-shared endpoints... -- */ -- -- /* we know this qh hasn't been scheduled, so all we need to do -+ /* -+ * We know this qh hasn't been scheduled, so all we need to do - * is choose which hardware endpoint to put it on ... - * - * REVISIT what we really want here is a regular schedule tree -- * like e.g. OHCI uses, but for now musb->periodic is just an -- * array of the _single_ logical endpoint associated with a -- * given physical one (identity mapping logical->physical). -- * -- * that simplistic approach makes TT scheduling a lot simpler; -- * there is none, and thus none of its complexity... -+ * like e.g. OHCI uses. - */ - best_diff = 4096; - best_end = -1; - -- for (epnum = 1; epnum < musb->nr_endpoints; epnum++) { -+ for (epnum = 1, hw_ep = musb->endpoints + 1; -+ epnum < musb->nr_endpoints; -+ epnum++, hw_ep++) { - int diff; - -- if (musb->periodic[epnum]) -+ if (is_in || hw_ep->is_shared_fifo) { -+ if (hw_ep->in_qh != NULL) -+ continue; -+ } else if (hw_ep->out_qh != NULL) - continue; -- hw_ep = &musb->endpoints[epnum]; -+ - if (hw_ep == musb->bulk_ep) - continue; - -@@ -1824,7 +1819,6 @@ static int musb_schedule( - idle = 1; - qh->mux = 0; - hw_ep = musb->endpoints + best_end; -- musb->periodic[best_end] = qh; - DBG(4, "qh %p periodic slot %d\n", qh, best_end); - success: - if (head) { --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0005-USB-TWL-disable-VUSB-regulators-when-cable-unplugg.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0005-USB-TWL-disable-VUSB-regulators-when-cable-unplugg.patch deleted file mode 100644 index db3481b87b..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0005-USB-TWL-disable-VUSB-regulators-when-cable-unplugg.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 60e7ce93befe795357db05001fe4caab522a421d Mon Sep 17 00:00:00 2001 -From: Jouni Hogander <jouni.hogander-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Date: Tue, 24 Mar 2009 17:22:57 -0700 -Subject: [PATCH] USB: TWL: disable VUSB regulators when cable unplugged - -This patch disables USB regulators VUSB1V5, VUSB1V8, and VUSB3V1 -when the USB cable is unplugged to reduce power consumption. -Added a depencency from twl4030 usb driver to TWL_REGULATOR. - -Signed-off-by: Jouni Hogander <jouni.hogander-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi-sMOQStClEysAvxtiuMwx3w@public.gmane.org> -Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org> ---- - drivers/usb/otg/Kconfig | 2 +- - drivers/usb/otg/twl4030-usb.c | 73 ++++++++++++++++++++++++++++++++++++----- - 2 files changed, 65 insertions(+), 10 deletions(-) - -diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig -index ee55b44..5790a5b 100644 ---- a/drivers/usb/otg/Kconfig -+++ b/drivers/usb/otg/Kconfig -@@ -43,7 +43,7 @@ config ISP1301_OMAP - - config TWL4030_USB - tristate "TWL4030 USB Transceiver Driver" -- depends on TWL4030_CORE -+ depends on TWL4030_CORE && REGULATOR_TWL4030 - select USB_OTG_UTILS - help - Enable this to support the USB OTG transceiver on TWL4030 -diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c -index 416e441..d9478d0 100644 ---- a/drivers/usb/otg/twl4030-usb.c -+++ b/drivers/usb/otg/twl4030-usb.c -@@ -34,6 +34,8 @@ - #include <linux/delay.h> - #include <linux/usb/otg.h> - #include <linux/i2c/twl4030.h> -+#include <linux/regulator/consumer.h> -+#include <linux/err.h> - - - /* Register defines */ -@@ -246,6 +248,11 @@ struct twl4030_usb { - struct otg_transceiver otg; - struct device *dev; - -+ /* TWL4030 internal USB regulator supplies */ -+ struct regulator *usb1v5; -+ struct regulator *usb1v8; -+ struct regulator *usb3v1; -+ - /* for vbus reporting with irqs disabled */ - spinlock_t lock; - -@@ -434,6 +441,18 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) - - pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); - if (on) { -+ regulator_enable(twl->usb3v1); -+ regulator_enable(twl->usb1v8); -+ /* -+ * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP -+ * in twl4030) resets the VUSB_DEDICATED2 register. This reset -+ * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to -+ * SLEEP. We work around this by clearing the bit after usv3v1 -+ * is re-activated. This ensures that VUSB3V1 is really active. -+ */ -+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, -+ VUSB_DEDICATED2); -+ regulator_enable(twl->usb1v5); - pwr &= ~PHY_PWR_PHYPWD; - WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); - twl4030_usb_write(twl, PHY_CLK_CTRL, -@@ -443,6 +462,9 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) - } else { - pwr |= PHY_PWR_PHYPWD; - WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); -+ regulator_disable(twl->usb1v5); -+ regulator_disable(twl->usb1v8); -+ regulator_disable(twl->usb3v1); - } - } - -@@ -468,7 +490,7 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) - twl->asleep = 0; - } - --static void twl4030_usb_ldo_init(struct twl4030_usb *twl) -+static int twl4030_usb_ldo_init(struct twl4030_usb *twl) - { - /* Enable writing to power configuration registers */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); -@@ -480,20 +502,45 @@ static void twl4030_usb_ldo_init(struct twl4030_usb *twl) - /* input to VUSB3V1 LDO is from VBAT, not VBUS */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); - -- /* turn on 3.1V regulator */ -- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB3V1_DEV_GRP); -+ /* Initialize 3.1V regulator */ -+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); -+ -+ twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); -+ if (IS_ERR(twl->usb3v1)) -+ return -ENODEV; -+ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); - -- /* turn on 1.5V regulator */ -- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V5_DEV_GRP); -+ /* Initialize 1.5V regulator */ -+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); -+ -+ twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); -+ if (IS_ERR(twl->usb1v5)) -+ goto fail1; -+ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); - -- /* turn on 1.8V regulator */ -- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V8_DEV_GRP); -+ /* Initialize 1.8V regulator */ -+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); -+ -+ twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); -+ if (IS_ERR(twl->usb1v8)) -+ goto fail2; -+ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); - - /* disable access to power configuration registers */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); -+ -+ return 0; -+ -+fail2: -+ regulator_put(twl->usb1v5); -+ twl->usb1v5 = NULL; -+fail1: -+ regulator_put(twl->usb3v1); -+ twl->usb3v1 = NULL; -+ return -ENODEV; - } - - static ssize_t twl4030_usb_vbus_show(struct device *dev, -@@ -598,7 +645,7 @@ static int __init twl4030_usb_probe(struct platform_device *pdev) - { - struct twl4030_usb_data *pdata = pdev->dev.platform_data; - struct twl4030_usb *twl; -- int status; -+ int status, err; - - if (!pdata) { - dev_dbg(&pdev->dev, "platform_data not available\n"); -@@ -622,7 +669,12 @@ static int __init twl4030_usb_probe(struct platform_device *pdev) - /* init spinlock for workqueue */ - spin_lock_init(&twl->lock); - -- twl4030_usb_ldo_init(twl); -+ err = twl4030_usb_ldo_init(twl); -+ if (err) { -+ dev_err(&pdev->dev, "ldo init failed\n"); -+ kfree(twl); -+ return err; -+ } - otg_set_transceiver(&twl->otg); - - platform_set_drvdata(pdev, twl); -@@ -688,6 +740,9 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) - twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - - twl4030_phy_power(twl, 0); -+ regulator_put(twl->usb1v5); -+ regulator_put(twl->usb1v8); -+ regulator_put(twl->usb3v1); - - kfree(twl); - --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0006-USB-gadget-composite-device-level-suspend-resume-h.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0006-USB-gadget-composite-device-level-suspend-resume-h.patch deleted file mode 100644 index 3f49a4d636..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0006-USB-gadget-composite-device-level-suspend-resume-h.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 7eef82d231578140c6000d04846a48bdaf341a65 Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Tue, 24 Mar 2009 17:23:19 -0700 -Subject: [PATCH] USB: gadget: composite device-level suspend/resume hooks - -Address one open question in the composite gadget framework: -Yes, we should have device-level suspend/resume callbacks -in addition to the function-level ones. We have at least one -scenario (with gadget zero in OTG test mode) that's awkward -to handle without it. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> -Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org> ---- - drivers/usb/gadget/composite.c | 8 ++++++-- - include/linux/usb/composite.h | 8 ++++++++ - 2 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c -index 40f1da7..59e8523 100644 ---- a/drivers/usb/gadget/composite.c -+++ b/drivers/usb/gadget/composite.c -@@ -1014,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget) - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_function *f; - -- /* REVISIT: should we have config and device level -+ /* REVISIT: should we have config level - * suspend/resume callbacks? - */ - DBG(cdev, "suspend\n"); -@@ -1024,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget) - f->suspend(f); - } - } -+ if (composite->suspend) -+ composite->suspend(cdev); - } - - static void -@@ -1032,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget) - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_function *f; - -- /* REVISIT: should we have config and device level -+ /* REVISIT: should we have config level - * suspend/resume callbacks? - */ - DBG(cdev, "resume\n"); -+ if (composite->resume) -+ composite->resume(cdev); - if (cdev->config) { - list_for_each_entry(f, &cdev->config->functions, list) { - if (f->resume) -diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h -index 935c380..acd7b0f 100644 ---- a/include/linux/usb/composite.h -+++ b/include/linux/usb/composite.h -@@ -244,6 +244,10 @@ int usb_add_config(struct usb_composite_dev *, - * value; it should return zero on successful initialization. - * @unbind: Reverses @bind(); called as a side effect of unregistering - * this driver. -+ * @suspend: Notifies when the host stops sending USB traffic, -+ * after function notifications -+ * @resume: Notifies configuration when the host restarts USB traffic, -+ * before function notifications - * - * Devices default to reporting self powered operation. Devices which rely - * on bus powered operation should report this in their @bind() method. -@@ -268,6 +272,10 @@ struct usb_composite_driver { - - int (*bind)(struct usb_composite_dev *); - int (*unbind)(struct usb_composite_dev *); -+ -+ /* global suspend hooks */ -+ void (*suspend)(struct usb_composite_dev *); -+ void (*resume)(struct usb_composite_dev *); - }; - - extern int usb_composite_register(struct usb_composite_driver *); --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0007-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0007-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch deleted file mode 100644 index a89bc2ff5c..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0007-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 00c4bd07a64061ec9ab9c35f5bf01ec6187138f4 Mon Sep 17 00:00:00 2001 -From: Jonathan McDowell <noodles-4QvXXjU8Dv4@public.gmane.org> -Date: Thu, 26 Mar 2009 00:45:27 -0700 -Subject: [PATCH] usb gadget: fix ethernet link reports to ethtool - -The g_ether USB gadget driver currently decides whether or not there's a -link to report back for eth_get_link based on if the USB link speed is -set. The USB gadget speed is however often set even before the device is -enumerated. It seems more sensible to only report a "link" if we're -actually connected to a host that wants to talk to us. The patch below -does this for me - tested with the PXA27x UDC driver. - -Signed-Off-By: Jonathan McDowell <noodles-4QvXXjU8Dv4@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/gadget/u_ether.c | 8 +------- - 1 files changed, 1 insertions(+), 7 deletions(-) - -diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c -index 96d65ca..4007770 100644 ---- a/drivers/usb/gadget/u_ether.c -+++ b/drivers/usb/gadget/u_ether.c -@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) - strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); - } - --static u32 eth_get_link(struct net_device *net) --{ -- struct eth_dev *dev = netdev_priv(net); -- return dev->gadget->speed != USB_SPEED_UNKNOWN; --} -- - /* REVISIT can also support: - * - WOL (by tracking suspends and issuing remote wakeup) - * - msglevel (implies updated messaging) -@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net) - - static struct ethtool_ops ops = { - .get_drvinfo = eth_get_drvinfo, -- .get_link = eth_get_link -+ .get_link = ethtool_op_get_link, - }; - - static void defer_kevent(struct eth_dev *dev, int flag) --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch deleted file mode 100644 index 8627825b5a..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch +++ /dev/null @@ -1,60 +0,0 @@ -From c3b527a21104b6bb61558fba6c65aa80f63e0772 Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Thu, 26 Mar 2009 17:36:57 -0700 -Subject: [PATCH] usb: musb_host, minor enqueue locking fix (v2) - -Someone noted that the enqueue path used an unlocked access -for usb_host_endpoint->hcpriv ... fix that, by being safe -and always accessing it under spinlock protection. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 17 ++++++++--------- - 1 files changed, 8 insertions(+), 9 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index 499c431..ff09595 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -1841,7 +1841,7 @@ static int musb_urb_enqueue( - unsigned long flags; - struct musb *musb = hcd_to_musb(hcd); - struct usb_host_endpoint *hep = urb->ep; -- struct musb_qh *qh = hep->hcpriv; -+ struct musb_qh *qh; - struct usb_endpoint_descriptor *epd = &hep->desc; - int ret; - unsigned type_reg; -@@ -1853,22 +1853,21 @@ static int musb_urb_enqueue( - - spin_lock_irqsave(&musb->lock, flags); - ret = usb_hcd_link_urb_to_ep(hcd, urb); -+ qh = ret ? NULL : hep->hcpriv; -+ if (qh) -+ urb->hcpriv = qh; - spin_unlock_irqrestore(&musb->lock, flags); -- if (ret) -- return ret; - - /* DMA mapping was already done, if needed, and this urb is on -- * hep->urb_list ... so there's little to do unless hep wasn't -- * yet scheduled onto a live qh. -+ * hep->urb_list now ... so we're done, unless hep wasn't yet -+ * scheduled onto a live qh. - * - * REVISIT best to keep hep->hcpriv valid until the endpoint gets - * disabled, testing for empty qh->ring and avoiding qh setup costs - * except for the first urb queued after a config change. - */ -- if (qh) { -- urb->hcpriv = qh; -- return 0; -- } -+ if (qh || ret) -+ return ret; - - /* Allocate and initialize qh, minimizing the work done each time - * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch deleted file mode 100644 index 09fc0a17d0..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 48ce47b15bfd420982ee275c595a9139eb6fabf7 Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Thu, 26 Mar 2009 17:38:30 -0700 -Subject: [PATCH] usb: musb_host, fix ep0 fifo flushing - -The MUSB host side can't share generic TX FIFO flush logic -with EP0; the EP0 TX status register bits are different -from those for other entpoints. - -Resolve this issue by providing a new EP0-specific routine -to flush and reset the FIFO, which pays careful attention to -restrictions listed in the latest programmer's guide. This -gets rid of an open issue whereby the usbtest control write -test (#14) failed. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 38 +++++++++++++++++++++++++------------- - 1 files changed, 25 insertions(+), 13 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index ff09595..a5d75aa 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -125,6 +125,29 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) - } - } - -+static void musb_h_ep0_flush_fifo(struct musb_hw_ep *ep) -+{ -+ void __iomem *epio = ep->regs; -+ u16 csr; -+ int retries = 5; -+ -+ /* scrub any data left in the fifo */ -+ do { -+ csr = musb_readw(epio, MUSB_TXCSR); -+ if (!(csr & (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_RXPKTRDY))) -+ break; -+ musb_writew(epio, MUSB_TXCSR, MUSB_CSR0_FLUSHFIFO); -+ csr = musb_readw(epio, MUSB_TXCSR); -+ udelay(10); -+ } while (--retries); -+ -+ WARN(!retries, "Could not flush host TX%d fifo: csr: %04x\n", -+ ep->epnum, csr); -+ -+ /* and reset for the next transfer */ -+ musb_writew(epio, MUSB_TXCSR, 0); -+} -+ - /* - * Start transmit. Caller is responsible for locking shared resources. - * musb must be locked. -@@ -693,11 +716,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - musb_writew(epio, MUSB_TXCSR, csr); - csr = musb_readw(epio, MUSB_TXCSR); - } else { -- /* endpoint 0: just flush */ -- musb_writew(epio, MUSB_CSR0, -- csr | MUSB_CSR0_FLUSHFIFO); -- musb_writew(epio, MUSB_CSR0, -- csr | MUSB_CSR0_FLUSHFIFO); -+ musb_h_ep0_flush_fifo(hw_ep); - } - - /* target addr and (for multipoint) hub addr/port */ -@@ -1063,11 +1082,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) - csr &= ~MUSB_CSR0_H_NAKTIMEOUT; - musb_writew(epio, MUSB_CSR0, csr); - } else { -- csr |= MUSB_CSR0_FLUSHFIFO; -- musb_writew(epio, MUSB_CSR0, csr); -- musb_writew(epio, MUSB_CSR0, csr); -- csr &= ~MUSB_CSR0_H_NAKTIMEOUT; -- musb_writew(epio, MUSB_CSR0, csr); -+ musb_h_ep0_flush_fifo(hw_ep); - } - - musb_writeb(epio, MUSB_NAKLIMIT0, 0); -@@ -1081,9 +1096,6 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) - * SHOULD NEVER HAPPEN! */ - ERR("no URB for end 0\n"); - -- musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); -- musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); -- musb_writew(epio, MUSB_CSR0, 0); - - goto done; - } --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch deleted file mode 100644 index bcbe3bbe39..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch +++ /dev/null @@ -1,361 +0,0 @@ -From c99f4a68268801a2e2ffbef9766c3ac89e4fb22c Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Thu, 26 Mar 2009 18:27:47 -0700 -Subject: [PATCH] musb: sanitize clearing TXCSR DMA bits (take 2) - -The MUSB code clears TXCSR_DMAMODE incorrectly in several -places, either asserting that TXCSR_DMAENAB is clear (when -sometimes it isn't) or clearing both bits together. Recent -versions of the programmer's guide require DMAENAB to be -cleared first, although some older ones didn't. - -Fix this and while at it: - - - In musb_gadget::txstate(), stop clearing the AUTOSET - and DMAMODE bits for the CPPI case since they never - get set anyway (the former bit is reserved on DaVinci); - but do clear the DMAENAB bit on the DMA error path. - - - In musb_host::musb_ep_program(), remove the duplicate - DMA controller specific code code clearing the TXCSR - previous state, add the code to clear TXCSR DMA bits - on the Inventra DMA error path, to replace such code - (executed late) on the PIO path. - - - In musbhsdma::dma_channel_abort()/dma_controller_irq(), - add/use the 'offset' variable to avoid MUSB_EP_OFFSET() - invocations on every RXCSR/TXCSR access. - -[dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: don't introduce CamelCase, -shrink diff] - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_gadget.c | 33 +++++++++++------ - drivers/usb/musb/musb_host.c | 79 ++++++++++++++++------------------------ - drivers/usb/musb/musbhsdma.c | 59 ++++++++++++++++++------------ - 3 files changed, 90 insertions(+), 81 deletions(-) - -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index c7ebd08..f79440c 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -165,9 +165,15 @@ static void nuke(struct musb_ep *ep, const int status) - if (is_dma_capable() && ep->dma) { - struct dma_controller *c = ep->musb->dma_controller; - int value; -+ - if (ep->is_in) { -+ /* -+ * The programming guide says that we must not clear -+ * the DMAMODE bit before DMAENAB, so we only -+ * clear it in the second write... -+ */ - musb_writew(epio, MUSB_TXCSR, -- 0 | MUSB_TXCSR_FLUSHFIFO); -+ MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO); - musb_writew(epio, MUSB_TXCSR, - 0 | MUSB_TXCSR_FLUSHFIFO); - } else { -@@ -230,7 +236,7 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep) - | IN token(s) are recd from Host. - | -> DMA interrupt on completion - | calls TxAvail. -- | -> stop DMA, ~DmaEenab, -+ | -> stop DMA, ~DMAENAB, - | -> set TxPktRdy for last short pkt or zlp - | -> Complete Request - | -> Continue next request (call txstate) -@@ -315,9 +321,17 @@ static void txstate(struct musb *musb, struct musb_request *req) - request->dma, request_size); - if (use_dma) { - if (musb_ep->dma->desired_mode == 0) { -- /* ASSERT: DMAENAB is clear */ -- csr &= ~(MUSB_TXCSR_AUTOSET | -- MUSB_TXCSR_DMAMODE); -+ /* -+ * We must not clear the DMAMODE bit -+ * before the DMAENAB bit -- and the -+ * latter doesn't always get cleared -+ * before we get here... -+ */ -+ csr &= ~(MUSB_TXCSR_AUTOSET -+ | MUSB_TXCSR_DMAENAB); -+ musb_writew(epio, MUSB_TXCSR, csr -+ | MUSB_TXCSR_P_WZC_BITS); -+ csr &= ~MUSB_TXCSR_DMAMODE; - csr |= (MUSB_TXCSR_DMAENAB | - MUSB_TXCSR_MODE); - /* against programming guide */ -@@ -334,10 +348,7 @@ static void txstate(struct musb *musb, struct musb_request *req) - - #elif defined(CONFIG_USB_TI_CPPI_DMA) - /* program endpoint CSR first, then setup DMA */ -- csr &= ~(MUSB_TXCSR_AUTOSET -- | MUSB_TXCSR_DMAMODE -- | MUSB_TXCSR_P_UNDERRUN -- | MUSB_TXCSR_TXPKTRDY); -+ csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); - csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB; - musb_writew(epio, MUSB_TXCSR, - (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) -@@ -364,8 +375,8 @@ static void txstate(struct musb *musb, struct musb_request *req) - if (!use_dma) { - c->channel_release(musb_ep->dma); - musb_ep->dma = NULL; -- /* ASSERT: DMAENAB clear */ -- csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE); -+ csr &= ~MUSB_TXCSR_DMAENAB; -+ musb_writew(epio, MUSB_TXCSR, csr); - /* invariant: prequest->buf is non-null */ - } - #elif defined(CONFIG_USB_TUSB_OMAP_DMA) -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index a5d75aa..6591282 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -590,10 +590,17 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) - csr = musb_readw(ep->regs, MUSB_TXCSR); - if (csr & MUSB_TXCSR_MODE) { - musb_h_tx_flush_fifo(ep); -+ csr = musb_readw(ep->regs, MUSB_TXCSR); - musb_writew(ep->regs, MUSB_TXCSR, -- MUSB_TXCSR_FRCDATATOG); -+ csr | MUSB_TXCSR_FRCDATATOG); - } -- /* clear mode (and everything else) to enable Rx */ -+ -+ /* -+ * Clear the MODE bit (and everything else) to enable Rx. -+ * NOTE: we mustn't clear the DMAMODE bit before DMAENAB. -+ */ -+ if (csr & MUSB_TXCSR_DMAMODE) -+ musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE); - musb_writew(ep->regs, MUSB_TXCSR, 0); - - /* scrub all previous state, clearing toggle */ -@@ -690,12 +697,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - - /* general endpoint setup */ - if (epnum) { -- /* ASSERT: TXCSR_DMAENAB was already cleared */ -- - /* flush all old state, set default */ - musb_h_tx_flush_fifo(hw_ep); -+ -+ /* -+ * We must not clear the DMAMODE bit before or in -+ * the same cycle with the DMAENAB bit, so we clear -+ * the latter first... -+ */ - csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT -- | MUSB_TXCSR_DMAMODE -+ | MUSB_TXCSR_AUTOSET -+ | MUSB_TXCSR_DMAENAB - | MUSB_TXCSR_FRCDATATOG - | MUSB_TXCSR_H_RXSTALL - | MUSB_TXCSR_H_ERROR -@@ -703,16 +715,15 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - ); - csr |= MUSB_TXCSR_MODE; - -- if (usb_gettoggle(urb->dev, -- qh->epnum, 1)) -+ if (usb_gettoggle(urb->dev, qh->epnum, 1)) - csr |= MUSB_TXCSR_H_WR_DATATOGGLE - | MUSB_TXCSR_H_DATATOGGLE; - else - csr |= MUSB_TXCSR_CLRDATATOG; - -- /* twice in case of double packet buffering */ - musb_writew(epio, MUSB_TXCSR, csr); - /* REVISIT may need to clear FLUSHFIFO ... */ -+ csr &= ~MUSB_TXCSR_DMAMODE; - musb_writew(epio, MUSB_TXCSR, csr); - csr = musb_readw(epio, MUSB_TXCSR); - } else { -@@ -755,34 +766,19 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - - #ifdef CONFIG_USB_INVENTRA_DMA - if (dma_channel) { -- -- /* clear previous state */ -- csr = musb_readw(epio, MUSB_TXCSR); -- csr &= ~(MUSB_TXCSR_AUTOSET -- | MUSB_TXCSR_DMAMODE -- | MUSB_TXCSR_DMAENAB); -- csr |= MUSB_TXCSR_MODE; -- musb_writew(epio, MUSB_TXCSR, -- csr | MUSB_TXCSR_MODE); -- - qh->segsize = min(len, dma_channel->max_len); -- - if (qh->segsize <= packet_sz) - dma_channel->desired_mode = 0; - else - dma_channel->desired_mode = 1; - -- - if (dma_channel->desired_mode == 0) { -- csr &= ~(MUSB_TXCSR_AUTOSET -- | MUSB_TXCSR_DMAMODE); -+ /* Against the programming guide */ - csr |= (MUSB_TXCSR_DMAENAB); -- /* against programming guide */ - } else - csr |= (MUSB_TXCSR_AUTOSET - | MUSB_TXCSR_DMAENAB - | MUSB_TXCSR_DMAMODE); -- - musb_writew(epio, MUSB_TXCSR, csr); - - dma_ok = dma_controller->channel_program( -@@ -799,6 +795,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - else - hw_ep->rx_channel = NULL; - dma_channel = NULL; -+ -+ /* -+ * The programming guide says that we must -+ * clear the DMAENAB bit before DMAMODE... -+ */ -+ csr = musb_readw(epio, MUSB_TXCSR); -+ csr &= ~(MUSB_TXCSR_DMAENAB -+ | MUSB_TXCSR_AUTOSET); -+ musb_writew(epio, MUSB_TXCSR, csr); -+ csr &= ~MUSB_TXCSR_DMAMODE; -+ musb_writew(epio, MUSB_TXCSR, csr); - } - } - #endif -@@ -806,18 +813,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - /* candidate for DMA */ - if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { - -- /* program endpoint CSRs first, then setup DMA. -- * assume CPPI setup succeeds. -- * defer enabling dma. -- */ -- csr = musb_readw(epio, MUSB_TXCSR); -- csr &= ~(MUSB_TXCSR_AUTOSET -- | MUSB_TXCSR_DMAMODE -- | MUSB_TXCSR_DMAENAB); -- csr |= MUSB_TXCSR_MODE; -- musb_writew(epio, MUSB_TXCSR, -- csr | MUSB_TXCSR_MODE); -- -+ /* Defer enabling DMA */ - dma_channel->actual_len = 0L; - qh->segsize = len; - -@@ -846,20 +842,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - } - - if (load_count) { -- /* ASSERT: TXCSR_DMAENAB was already cleared */ -- - /* PIO to load FIFO */ - qh->segsize = load_count; - musb_write_fifo(hw_ep, load_count, buf); -- csr = musb_readw(epio, MUSB_TXCSR); -- csr &= ~(MUSB_TXCSR_DMAENAB -- | MUSB_TXCSR_DMAMODE -- | MUSB_TXCSR_AUTOSET); -- /* write CSR */ -- csr |= MUSB_TXCSR_MODE; -- -- if (epnum) -- musb_writew(epio, MUSB_TXCSR, csr); - } - - /* re-enable interrupt */ -diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c -index 8662e9e..40709c3 100644 ---- a/drivers/usb/musb/musbhsdma.c -+++ b/drivers/usb/musb/musbhsdma.c -@@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel) - void __iomem *mbase = musb_channel->controller->base; - - u8 bchannel = musb_channel->idx; -+ int offset; - u16 csr; - - if (channel->status == MUSB_DMA_STATUS_BUSY) { - if (musb_channel->transmit) { -- -- csr = musb_readw(mbase, -- MUSB_EP_OFFSET(musb_channel->epnum, -- MUSB_TXCSR)); -- csr &= ~(MUSB_TXCSR_AUTOSET | -- MUSB_TXCSR_DMAENAB | -- MUSB_TXCSR_DMAMODE); -- musb_writew(mbase, -- MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR), -- csr); -+ offset = MUSB_EP_OFFSET(musb_channel->epnum, -+ MUSB_TXCSR); -+ -+ /* -+ * The programming guide says that we must clear -+ * the DMAENAB bit before the DMAMODE bit... -+ */ -+ csr = musb_readw(mbase, offset); -+ csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB); -+ musb_writew(mbase, offset, csr); -+ csr &= ~MUSB_TXCSR_DMAMODE; -+ musb_writew(mbase, offset, csr); - } else { -- csr = musb_readw(mbase, -- MUSB_EP_OFFSET(musb_channel->epnum, -- MUSB_RXCSR)); -+ offset = MUSB_EP_OFFSET(musb_channel->epnum, -+ MUSB_RXCSR); -+ -+ csr = musb_readw(mbase, offset); - csr &= ~(MUSB_RXCSR_AUTOCLEAR | - MUSB_RXCSR_DMAENAB | - MUSB_RXCSR_DMAMODE); -- musb_writew(mbase, -- MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR), -- csr); -+ musb_writew(mbase, offset, csr); - } - - musb_writew(mbase, -@@ -296,14 +298,25 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) - && ((channel->desired_mode == 0) - || (channel->actual_len & - (musb_channel->max_packet_sz - 1))) -- ) { -+ ) { -+ u8 epnum = musb_channel->epnum; -+ int offset = MUSB_EP_OFFSET(epnum, -+ MUSB_TXCSR); -+ u16 txcsr; -+ -+ /* -+ * The programming guide says that we -+ * must clear DMAENAB before DMAMODE. -+ */ -+ musb_ep_select(mbase, epnum); -+ txcsr = musb_readw(mbase, offset); -+ txcsr &= ~(MUSB_TXCSR_DMAENAB -+ | MUSB_TXCSR_AUTOSET); -+ musb_writew(mbase, offset, txcsr); - /* Send out the packet */ -- musb_ep_select(mbase, -- musb_channel->epnum); -- musb_writew(mbase, MUSB_EP_OFFSET( -- musb_channel->epnum, -- MUSB_TXCSR), -- MUSB_TXCSR_TXPKTRDY); -+ txcsr &= ~MUSB_TXCSR_DMAMODE; -+ txcsr |= MUSB_TXCSR_TXPKTRDY; -+ musb_writew(mbase, offset, txcsr); - } else { - musb_dma_completion( - musb, --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0011-musb-fix-isochronous-TXDMA-take-2.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0011-musb-fix-isochronous-TXDMA-take-2.patch deleted file mode 100644 index 7d546e10b0..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0011-musb-fix-isochronous-TXDMA-take-2.patch +++ /dev/null @@ -1,417 +0,0 @@ -From 035cd4a26e9b1638b4b0419b98409026176563ca Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Thu, 26 Mar 2009 18:29:19 -0700 -Subject: [PATCH] musb: fix isochronous TXDMA (take 2) - -Multi-frame isochronous TX URBs transfers in DMA mode never -complete with CPPI DMA because musb_host_tx() doesn't restart -DMA on the second frame, only emitting a debug message. -With Inventra DMA they complete, but in PIO mode. To fix: - - - Factor out programming of the DMA transfer from - musb_ep_program() into musb_tx_dma_program(); - - - Reorder the code at the end of musb_host_tx() to - facilitate the fallback to PIO iff DMA fails; - - - Handle the buffer offset consistently for both - PIO and DMA modes; - - - Add an argument to musb_ep_program() for the same - reason (it only worked correctly with non-zero - offset of the first frame in PIO mode); - - - Set the completed isochronous frame descriptor's - 'actual_length' and 'status' fields correctly in - DMA mode. - -Also, since CPPI reportedly doesn't like sending isochronous -packets in the RNDIS mode, change the criterion for this -mode to be used only for multi-packet transfers. (There's -no need for that mode in the single-packet case anyway.) - -[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: split comment paragraph -into bullet list, shrink patch delta, style tweaks ] - -Signed-off-by: Pavel Kiryukhin <pkiryukhin-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/cppi_dma.c | 1 + - drivers/usb/musb/musb_host.c | 227 +++++++++++++++++++----------------------- - 2 files changed, 105 insertions(+), 123 deletions(-) - -diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c -index 569ef0f..ac7227c 100644 ---- a/drivers/usb/musb/cppi_dma.c -+++ b/drivers/usb/musb/cppi_dma.c -@@ -579,6 +579,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) - * trigger the "send a ZLP?" confusion. - */ - rndis = (maxpacket & 0x3f) == 0 -+ && length > maxpacket - && length < 0xffff - && (length % maxpacket) != 0; - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index 6591282..f6e84a0 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -96,8 +96,8 @@ - - - static void musb_ep_program(struct musb *musb, u8 epnum, -- struct urb *urb, unsigned int nOut, -- u8 *buf, u32 len); -+ struct urb *urb, int is_out, -+ u8 *buf, u32 offset, u32 len); - - /* - * Clear TX fifo. Needed to avoid BABBLE errors. -@@ -189,9 +189,10 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - { - u16 frame; - u32 len; -- void *buf; - void __iomem *mbase = musb->mregs; - struct urb *urb = next_urb(qh); -+ void *buf = urb->transfer_buffer; -+ u32 offset = 0; - struct musb_hw_ep *hw_ep = qh->hw_ep; - unsigned pipe = urb->pipe; - u8 address = usb_pipedevice(pipe); -@@ -214,7 +215,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - case USB_ENDPOINT_XFER_ISOC: - qh->iso_idx = 0; - qh->frame = 0; -- buf = urb->transfer_buffer + urb->iso_frame_desc[0].offset; -+ offset = urb->iso_frame_desc[0].offset; - len = urb->iso_frame_desc[0].length; - break; - default: /* bulk, interrupt */ -@@ -232,14 +233,14 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; - default: s = "-intr"; break; - }; s; }), -- epnum, buf, len); -+ epnum, buf + offset, len); - - /* Configure endpoint */ - if (is_in || hw_ep->is_shared_fifo) - hw_ep->in_qh = qh; - else - hw_ep->out_qh = qh; -- musb_ep_program(musb, epnum, urb, !is_in, buf, len); -+ musb_ep_program(musb, epnum, urb, !is_in, buf, offset, len); - - /* transmit may have more work: start it when it is time */ - if (is_in) -@@ -250,7 +251,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - case USB_ENDPOINT_XFER_ISOC: - case USB_ENDPOINT_XFER_INT: - DBG(3, "check whether there's still time for periodic Tx\n"); -- qh->iso_idx = 0; - frame = musb_readw(mbase, MUSB_FRAME); - /* FIXME this doesn't implement that scheduling policy ... - * or handle framecounter wrapping -@@ -631,14 +631,68 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) - ep->rx_reinit = 0; - } - -+static bool musb_tx_dma_program(struct dma_controller *dma, -+ struct musb_hw_ep *hw_ep, struct musb_qh *qh, -+ struct urb *urb, u32 offset, u32 length) -+{ -+ struct dma_channel *channel = hw_ep->tx_channel; -+ void __iomem *epio = hw_ep->regs; -+ u16 pkt_size = qh->maxpacket; -+ u16 csr; -+ u8 mode; -+ -+#ifdef CONFIG_USB_INVENTRA_DMA -+ if (length > channel->max_len) -+ length = channel->max_len; -+ -+ csr = musb_readw(epio, MUSB_TXCSR); -+ if (length > pkt_size) { -+ mode = 1; -+ csr |= MUSB_TXCSR_AUTOSET -+ | MUSB_TXCSR_DMAMODE -+ | MUSB_TXCSR_DMAENAB; -+ } else { -+ mode = 0; -+ csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE); -+ csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */ -+ } -+ channel->desired_mode = mode; -+ musb_writew(epio, MUSB_TXCSR, csr); -+#else -+ if (!is_cppi_enabled() && !tusb_dma_omap()) -+ return false; -+ -+ channel->actual_len = 0; -+ -+ /* -+ * TX uses "RNDIS" mode automatically but needs help -+ * to identify the zero-length-final-packet case. -+ */ -+ mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; -+#endif -+ -+ qh->segsize = length; -+ -+ if (!dma->channel_program(channel, pkt_size, mode, -+ urb->transfer_dma + offset, length)) { -+ dma->channel_release(channel); -+ hw_ep->tx_channel = NULL; -+ -+ csr = musb_readw(epio, MUSB_TXCSR); -+ csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB); -+ musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_H_WZC_BITS); -+ return false; -+ } -+ return true; -+} - - /* - * Program an HDRC endpoint as per the given URB - * Context: irqs blocked, controller lock held - */ - static void musb_ep_program(struct musb *musb, u8 epnum, -- struct urb *urb, unsigned int is_out, -- u8 *buf, u32 len) -+ struct urb *urb, int is_out, -+ u8 *buf, u32 offset, u32 len) - { - struct dma_controller *dma_controller; - struct dma_channel *dma_channel; -@@ -764,82 +818,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - else - load_count = min((u32) packet_sz, len); - --#ifdef CONFIG_USB_INVENTRA_DMA -- if (dma_channel) { -- qh->segsize = min(len, dma_channel->max_len); -- if (qh->segsize <= packet_sz) -- dma_channel->desired_mode = 0; -- else -- dma_channel->desired_mode = 1; -- -- if (dma_channel->desired_mode == 0) { -- /* Against the programming guide */ -- csr |= (MUSB_TXCSR_DMAENAB); -- } else -- csr |= (MUSB_TXCSR_AUTOSET -- | MUSB_TXCSR_DMAENAB -- | MUSB_TXCSR_DMAMODE); -- musb_writew(epio, MUSB_TXCSR, csr); -- -- dma_ok = dma_controller->channel_program( -- dma_channel, packet_sz, -- dma_channel->desired_mode, -- urb->transfer_dma, -- qh->segsize); -- if (dma_ok) { -- load_count = 0; -- } else { -- dma_controller->channel_release(dma_channel); -- if (is_out) -- hw_ep->tx_channel = NULL; -- else -- hw_ep->rx_channel = NULL; -- dma_channel = NULL; -- -- /* -- * The programming guide says that we must -- * clear the DMAENAB bit before DMAMODE... -- */ -- csr = musb_readw(epio, MUSB_TXCSR); -- csr &= ~(MUSB_TXCSR_DMAENAB -- | MUSB_TXCSR_AUTOSET); -- musb_writew(epio, MUSB_TXCSR, csr); -- csr &= ~MUSB_TXCSR_DMAMODE; -- musb_writew(epio, MUSB_TXCSR, csr); -- } -- } --#endif -- -- /* candidate for DMA */ -- if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { -- -- /* Defer enabling DMA */ -- dma_channel->actual_len = 0L; -- qh->segsize = len; -- -- /* TX uses "rndis" mode automatically, but needs help -- * to identify the zero-length-final-packet case. -- */ -- dma_ok = dma_controller->channel_program( -- dma_channel, packet_sz, -- (urb->transfer_flags -- & URB_ZERO_PACKET) -- == URB_ZERO_PACKET, -- urb->transfer_dma, -- qh->segsize); -- if (dma_ok) { -- load_count = 0; -- } else { -- dma_controller->channel_release(dma_channel); -- hw_ep->tx_channel = NULL; -- dma_channel = NULL; -- -- /* REVISIT there's an error path here that -- * needs handling: can't do dma, but -- * there's no pio buffer address... -- */ -- } -- } -+ if (dma_channel && musb_tx_dma_program(dma_controller, -+ hw_ep, qh, urb, offset, len)) -+ load_count = 0; - - if (load_count) { - /* PIO to load FIFO */ -@@ -899,7 +880,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - dma_channel, packet_sz, - !(urb->transfer_flags - & URB_SHORT_NOT_OK), -- urb->transfer_dma, -+ urb->transfer_dma + offset, - qh->segsize); - if (!dma_ok) { - dma_controller->channel_release( -@@ -1142,8 +1123,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) - int pipe; - bool done = false; - u16 tx_csr; -- size_t wLength = 0; -- u8 *buf = NULL; -+ size_t length = 0; -+ size_t offset = 0; - struct urb *urb; - struct musb_hw_ep *hw_ep = musb->endpoints + epnum; - void __iomem *epio = hw_ep->regs; -@@ -1161,7 +1142,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) - /* with CPPI, DMA sometimes triggers "extra" irqs */ - if (!urb) { - DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); -- goto finish; -+ return; - } - - pipe = urb->pipe; -@@ -1198,7 +1179,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) - musb_writew(epio, MUSB_TXCSR, - MUSB_TXCSR_H_WZC_BITS - | MUSB_TXCSR_TXPKTRDY); -- goto finish; -+ return; - } - - if (status) { -@@ -1230,29 +1211,28 @@ void musb_host_tx(struct musb *musb, u8 epnum) - /* second cppi case */ - if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { - DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); -- goto finish; -- -+ return; - } - -- /* REVISIT this looks wrong... */ - if (!status || dma || usb_pipeisoc(pipe)) { - if (dma) -- wLength = dma->actual_len; -+ length = dma->actual_len; - else -- wLength = qh->segsize; -- qh->offset += wLength; -+ length = qh->segsize; -+ qh->offset += length; - - if (usb_pipeisoc(pipe)) { - struct usb_iso_packet_descriptor *d; - - d = urb->iso_frame_desc + qh->iso_idx; -- d->actual_length = qh->segsize; -+ d->actual_length = length; -+ d->status = status; - if (++qh->iso_idx >= urb->number_of_packets) { - done = true; - } else { - d++; -- buf = urb->transfer_buffer + d->offset; -- wLength = d->length; -+ offset = d->offset; -+ length = d->length; - } - } else if (dma) { - done = true; -@@ -1265,10 +1245,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) - & URB_ZERO_PACKET)) - done = true; - if (!done) { -- buf = urb->transfer_buffer -- + qh->offset; -- wLength = urb->transfer_buffer_length -- - qh->offset; -+ offset = qh->offset; -+ length = urb->transfer_buffer_length - offset; - } - } - } -@@ -1287,28 +1265,31 @@ void musb_host_tx(struct musb *musb, u8 epnum) - urb->status = status; - urb->actual_length = qh->offset; - musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); -+ return; -+ } else if (usb_pipeisoc(pipe) && dma) { -+ if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, -+ offset, length)) -+ return; -+ } else if (tx_csr & MUSB_TXCSR_DMAENAB) { -+ DBG(1, "not complete, but DMA enabled?\n"); -+ return; -+ } - -- } else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) { -- /* WARN_ON(!buf); */ -- -- /* REVISIT: some docs say that when hw_ep->tx_double_buffered, -- * (and presumably, fifo is not half-full) we should write TWO -- * packets before updating TXCSR ... other docs disagree ... -- */ -- /* PIO: start next packet in this URB */ -- if (wLength > qh->maxpacket) -- wLength = qh->maxpacket; -- musb_write_fifo(hw_ep, wLength, buf); -- qh->segsize = wLength; -- -- musb_ep_select(mbase, epnum); -- musb_writew(epio, MUSB_TXCSR, -- MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); -- } else -- DBG(1, "not complete, but dma enabled?\n"); -+ /* -+ * PIO: start next packet in this URB. -+ * -+ * REVISIT: some docs say that when hw_ep->tx_double_buffered, -+ * (and presumably, FIFO is not half-full) we should write *two* -+ * packets before updating TXCSR; other docs disagree... -+ */ -+ if (length > qh->maxpacket) -+ length = qh->maxpacket; -+ musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset); -+ qh->segsize = length; - --finish: -- return; -+ musb_ep_select(mbase, epnum); -+ musb_writew(epio, MUSB_TXCSR, -+ MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); - } - - --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0012-musb-fix-possible-panic-while-resuming.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0012-musb-fix-possible-panic-while-resuming.patch deleted file mode 100644 index 2bbde84c16..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0012-musb-fix-possible-panic-while-resuming.patch +++ /dev/null @@ -1,56 +0,0 @@ -From b9a61b80ea89d9d6d78a23d96a28df94fd612298 Mon Sep 17 00:00:00 2001 -From: Kim Kyuwon <q1.kim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> -Date: Thu, 26 Mar 2009 18:56:51 -0700 -Subject: [PATCH] musb: fix possible panic while resuming - -During driver resume processing, musb could cause a kernel panic. -Fix by enabling the clock earlier, with the resume_early method. - -Signed-off-by: Kim Kyuwon <q1.kim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_core.c | 8 ++------ - 1 files changed, 2 insertions(+), 6 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index 338cd16..3019725 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -2170,16 +2170,13 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message) - return 0; - } - --static int musb_resume(struct platform_device *pdev) -+static int musb_resume_early(struct platform_device *pdev) - { -- unsigned long flags; - struct musb *musb = dev_to_musb(&pdev->dev); - - if (!musb->clock) - return 0; - -- spin_lock_irqsave(&musb->lock, flags); -- - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - else -@@ -2189,7 +2186,6 @@ static int musb_resume(struct platform_device *pdev) - * unless for some reason the whole soc powered down and we're - * not treating that as a whole-system restart (e.g. swsusp) - */ -- spin_unlock_irqrestore(&musb->lock, flags); - return 0; - } - -@@ -2207,7 +2203,7 @@ static struct platform_driver musb_driver = { - .remove = __devexit_p(musb_remove), - .shutdown = musb_shutdown, - .suspend = musb_suspend, -- .resume = musb_resume, -+ .resume_early = musb_resume_early, - }; - - /*-------------------------------------------------------------------------*/ --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0013-musb_host-refactor-musb_save_toggle-take-2.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0013-musb_host-refactor-musb_save_toggle-take-2.patch deleted file mode 100644 index 0202871d41..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0013-musb_host-refactor-musb_save_toggle-take-2.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 2658f7c9029967501cd4d749364f2e02d02eebd5 Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:54:21 -0700 -Subject: [PATCH] musb_host: refactor musb_save_toggle() (take 2) - -Refactor musb_save_toggle() as follows: - - - replace 'struct musb_hw_ep *ep' parameter by 'struct - musb_qh *qh' to avoid re-calculating this value - - - move usb_settogle() call out of the *if* operator. - -This is a net minor shrink of source and object code. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 35 ++++++++++++----------------------- - 1 files changed, 12 insertions(+), 23 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index f6e84a0..dc32ce4 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -318,35 +318,24 @@ __acquires(musb->lock) - spin_lock(&musb->lock); - } - --/* for bulk/interrupt endpoints only */ --static inline void --musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) -+/* For bulk/interrupt endpoints only */ -+static inline void musb_save_toggle(struct musb_qh *qh, int is_in, -+ struct urb *urb) - { -- struct usb_device *udev = urb->dev; -+ void __iomem *epio = qh->hw_ep->regs; - u16 csr; -- void __iomem *epio = ep->regs; -- struct musb_qh *qh; - -- /* FIXME: the current Mentor DMA code seems to have -+ /* -+ * FIXME: the current Mentor DMA code seems to have - * problems getting toggle correct. - */ - -- if (is_in || ep->is_shared_fifo) -- qh = ep->in_qh; -+ if (is_in) -+ csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE; - else -- qh = ep->out_qh; -+ csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE; - -- if (!is_in) { -- csr = musb_readw(epio, MUSB_TXCSR); -- usb_settoggle(udev, qh->epnum, 1, -- (csr & MUSB_TXCSR_H_DATATOGGLE) -- ? 1 : 0); -- } else { -- csr = musb_readw(epio, MUSB_RXCSR); -- usb_settoggle(udev, qh->epnum, 0, -- (csr & MUSB_RXCSR_H_DATATOGGLE) -- ? 1 : 0); -- } -+ usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0); - } - - /* caller owns controller lock, irqs are blocked */ -@@ -362,7 +351,7 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) - switch (qh->type) { - case USB_ENDPOINT_XFER_BULK: - case USB_ENDPOINT_XFER_INT: -- musb_save_toggle(ep, is_in, urb); -+ musb_save_toggle(qh, is_in, urb); - break; - case USB_ENDPOINT_XFER_ISOC: - if (status == 0 && urb->error_count) -@@ -1362,7 +1351,7 @@ static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep) - urb->actual_length += dma->actual_len; - dma->actual_len = 0L; - } -- musb_save_toggle(ep, 1, urb); -+ musb_save_toggle(cur_qh, 1, urb); - - /* move cur_qh to end of queue */ - list_move_tail(&cur_qh->ring, &musb->in_bulk); --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0014-musb_gadget-suppress-parasitic-TX-interrupts-with.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0014-musb_gadget-suppress-parasitic-TX-interrupts-with.patch deleted file mode 100644 index 08e08a8538..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0014-musb_gadget-suppress-parasitic-TX-interrupts-with.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7766f2ea909b73f56d21746485069e02839b75f1 Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:53:32 -0700 -Subject: [PATCH] musb_gadget: suppress "parasitic" TX interrupts with CPPI - -Suppress "parasitic" endpoint interrupts in the DMA mode -when using CPPI DMA driver; they're caused by the MUSB gadget -driver using the DMA request mode 0 instead of the mode 1. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_gadget.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index f79440c..bc197b2 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -349,7 +349,8 @@ static void txstate(struct musb *musb, struct musb_request *req) - #elif defined(CONFIG_USB_TI_CPPI_DMA) - /* program endpoint CSR first, then setup DMA */ - csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); -- csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB; -+ csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE | -+ MUSB_TXCSR_MODE; - musb_writew(epio, MUSB_TXCSR, - (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) - | csr); --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0015-musb_gadget-fix-unhandled-endpoint-0-IRQs.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0015-musb_gadget-fix-unhandled-endpoint-0-IRQs.patch deleted file mode 100644 index 7115b152d9..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0015-musb_gadget-fix-unhandled-endpoint-0-IRQs.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 5424305125492a2417bde7c6d23ee4b84e25f6be Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:52:43 -0700 -Subject: [PATCH] musb_gadget: fix unhandled endpoint 0 IRQs - -The gadget EP0 code routinely ignores an interrupt at end of -the data phase because of musb_g_ep0_giveback() resetting the -state machine to "idle, waiting for SETUP" phase prematurely. - -The driver also prematurely leaves the status phase on -receiving the SetupEnd interrupt. - -As there were still unhandled endpoint 0 interrupts happening -from time to time after fixing these issues, there turned to -be yet another culprit: two distinct gadget states collapsed -into one. - -The (missing) state that comes after STATUS IN/OUT states was -typically indiscernible from them since the corresponding -interrupts tend to happen within too little period of time -(due to only a zero-length status packet in between) and so -they got coalesced; yet this state is not the same as the next -one which is associated with the reception of a SETUP packet. - -Adding this extra state seems to have fixed the rest of the -unhandled interrupts that generic_interrupt() and -davinci_interrupt() hid by faking their result and only -emitting a debug message -- so, stop doing that. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/davinci.c | 7 +---- - drivers/usb/musb/musb_core.c | 8 +----- - drivers/usb/musb/musb_core.h | 3 +- - drivers/usb/musb/musb_gadget_ep0.c | 45 +++++++++++++++++++++++++++++++---- - 4 files changed, 43 insertions(+), 20 deletions(-) - -diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c -index 2dc7606..399c435 100644 ---- a/drivers/usb/musb/davinci.c -+++ b/drivers/usb/musb/davinci.c -@@ -357,12 +357,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) - - spin_unlock_irqrestore(&musb->lock, flags); - -- /* REVISIT we sometimes get unhandled IRQs -- * (e.g. ep0). not clear why... -- */ -- if (retval != IRQ_HANDLED) -- DBG(5, "unhandled? %08x\n", tmp); -- return IRQ_HANDLED; -+ return retval; - } - - int musb_platform_set_mode(struct musb *musb, u8 mode) -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index 3019725..a1de43b 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -1481,13 +1481,7 @@ static irqreturn_t generic_interrupt(int irq, void *__hci) - - spin_unlock_irqrestore(&musb->lock, flags); - -- /* REVISIT we sometimes get spurious IRQs on g_ep0 -- * not clear why... -- */ -- if (retval != IRQ_HANDLED) -- DBG(5, "spurious?\n"); -- -- return IRQ_HANDLED; -+ return retval; - } - - #else -diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h -index adf1806..f56a56c 100644 ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -171,7 +171,8 @@ enum musb_h_ep0_state { - - /* peripheral side ep0 states */ - enum musb_g_ep0_state { -- MUSB_EP0_STAGE_SETUP, /* idle, waiting for setup */ -+ MUSB_EP0_STAGE_IDLE, /* idle, waiting for SETUP */ -+ MUSB_EP0_STAGE_SETUP, /* received SETUP */ - MUSB_EP0_STAGE_TX, /* IN data */ - MUSB_EP0_STAGE_RX, /* OUT data */ - MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */ -diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c -index 3f5e30d..ec0e899 100644 ---- a/drivers/usb/musb/musb_gadget_ep0.c -+++ b/drivers/usb/musb/musb_gadget_ep0.c -@@ -4,6 +4,7 @@ - * Copyright 2005 Mentor Graphics Corporation - * Copyright (C) 2005-2006 by Texas Instruments - * Copyright (C) 2006-2007 Nokia Corporation -+ * Copyright (C) 2008-2009 MontaVista Software, Inc. <source-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License -@@ -58,7 +59,8 @@ - static char *decode_ep0stage(u8 stage) - { - switch (stage) { -- case MUSB_EP0_STAGE_SETUP: return "idle"; -+ case MUSB_EP0_STAGE_IDLE: return "idle"; -+ case MUSB_EP0_STAGE_SETUP: return "setup"; - case MUSB_EP0_STAGE_TX: return "in"; - case MUSB_EP0_STAGE_RX: return "out"; - case MUSB_EP0_STAGE_ACKWAIT: return "wait"; -@@ -628,7 +630,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) - musb_writew(regs, MUSB_CSR0, - csr & ~MUSB_CSR0_P_SENTSTALL); - retval = IRQ_HANDLED; -- musb->ep0_state = MUSB_EP0_STAGE_SETUP; -+ musb->ep0_state = MUSB_EP0_STAGE_IDLE; - csr = musb_readw(regs, MUSB_CSR0); - } - -@@ -636,7 +638,18 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) - if (csr & MUSB_CSR0_P_SETUPEND) { - musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND); - retval = IRQ_HANDLED; -- musb->ep0_state = MUSB_EP0_STAGE_SETUP; -+ /* Transition into the early status phase */ -+ switch (musb->ep0_state) { -+ case MUSB_EP0_STAGE_TX: -+ musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT; -+ break; -+ case MUSB_EP0_STAGE_RX: -+ musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; -+ break; -+ default: -+ ERR("SetupEnd came in a wrong ep0stage %s", -+ decode_ep0stage(musb->ep0_state)); -+ } - csr = musb_readw(regs, MUSB_CSR0); - /* NOTE: request may need completion */ - } -@@ -697,11 +710,31 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) - if (req) - musb_g_ep0_giveback(musb, req); - } -+ -+ /* -+ * In case when several interrupts can get coalesced, -+ * check to see if we've already received a SETUP packet... -+ */ -+ if (csr & MUSB_CSR0_RXPKTRDY) -+ goto setup; -+ -+ retval = IRQ_HANDLED; -+ musb->ep0_state = MUSB_EP0_STAGE_IDLE; -+ break; -+ -+ case MUSB_EP0_STAGE_IDLE: -+ /* -+ * This state is typically (but not always) indiscernible -+ * from the status states since the corresponding interrupts -+ * tend to happen within too little period of time (with only -+ * a zero-length packet in between) and so get coalesced... -+ */ - retval = IRQ_HANDLED; - musb->ep0_state = MUSB_EP0_STAGE_SETUP; - /* FALLTHROUGH */ - - case MUSB_EP0_STAGE_SETUP: -+setup: - if (csr & MUSB_CSR0_RXPKTRDY) { - struct usb_ctrlrequest setup; - int handled = 0; -@@ -783,7 +816,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) - stall: - DBG(3, "stall (%d)\n", handled); - musb->ackpend |= MUSB_CSR0_P_SENDSTALL; -- musb->ep0_state = MUSB_EP0_STAGE_SETUP; -+ musb->ep0_state = MUSB_EP0_STAGE_IDLE; - finish: - musb_writew(regs, MUSB_CSR0, - musb->ackpend); -@@ -803,7 +836,7 @@ finish: - /* "can't happen" */ - WARN_ON(1); - musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL); -- musb->ep0_state = MUSB_EP0_STAGE_SETUP; -+ musb->ep0_state = MUSB_EP0_STAGE_IDLE; - break; - } - -@@ -959,7 +992,7 @@ static int musb_g_ep0_halt(struct usb_ep *e, int value) - - csr |= MUSB_CSR0_P_SENDSTALL; - musb_writew(regs, MUSB_CSR0, csr); -- musb->ep0_state = MUSB_EP0_STAGE_SETUP; -+ musb->ep0_state = MUSB_EP0_STAGE_IDLE; - musb->ackpend = 0; - break; - default: --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0016-musb_host-factor-out-musb_ep_-get-set-_qh.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0016-musb_host-factor-out-musb_ep_-get-set-_qh.patch deleted file mode 100644 index a2f54ff47b..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0016-musb_host-factor-out-musb_ep_-get-set-_qh.patch +++ /dev/null @@ -1,146 +0,0 @@ -From f9ca8154cf395ec00129f12016697ef610a826ff Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:55:16 -0700 -Subject: [PATCH] musb_host: factor out musb_ep_{get|set}_qh() - -Factor out the often used code to get/set the active 'qh' -pointer for the hardware endpoint. Change the way the case -of a shared FIFO is handled by setting *both* 'in_qh' and -'out_qh' fields of 'struct musb_hw_ep'. That seems more -consistent and makes getting to the current 'qh' easy when -the code knows the direction beforehand. - -While at it, turn some assignments into intializers and -fix declaration style in the vicinity. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 56 ++++++++++++++++------------------------- - 1 files changed, 22 insertions(+), 34 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index dc32ce4..bc89079 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -178,6 +178,19 @@ static inline void cppi_host_txdma_start(struct musb_hw_ep *ep) - musb_writew(ep->regs, MUSB_TXCSR, txcsr); - } - -+static void musb_ep_set_qh(struct musb_hw_ep *ep, int is_in, struct musb_qh *qh) -+{ -+ if (is_in != 0 || ep->is_shared_fifo) -+ ep->in_qh = qh; -+ if (is_in == 0 || ep->is_shared_fifo) -+ ep->out_qh = qh; -+} -+ -+static struct musb_qh *musb_ep_get_qh(struct musb_hw_ep *ep, int is_in) -+{ -+ return is_in ? ep->in_qh : ep->out_qh; -+} -+ - /* - * Start the URB at the front of an endpoint's queue - * end must be claimed from the caller. -@@ -207,7 +220,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - case USB_ENDPOINT_XFER_CONTROL: - /* control transfers always start with SETUP */ - is_in = 0; -- hw_ep->out_qh = qh; - musb->ep0_stage = MUSB_EP0_START; - buf = urb->setup_packet; - len = 8; -@@ -236,10 +248,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) - epnum, buf + offset, len); - - /* Configure endpoint */ -- if (is_in || hw_ep->is_shared_fifo) -- hw_ep->in_qh = qh; -- else -- hw_ep->out_qh = qh; -+ musb_ep_set_qh(hw_ep, is_in, qh); - musb_ep_program(musb, epnum, urb, !is_in, buf, offset, len); - - /* transmit may have more work: start it when it is time */ -@@ -374,11 +383,8 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) - else - ep->tx_reinit = 1; - -- /* clobber old pointers to this qh */ -- if (is_in || ep->is_shared_fifo) -- ep->in_qh = NULL; -- else -- ep->out_qh = NULL; -+ /* Clobber old pointers to this qh */ -+ musb_ep_set_qh(ep, is_in, NULL); - qh->hep->hcpriv = NULL; - - switch (qh->type) { -@@ -421,12 +427,7 @@ static void - musb_advance_schedule(struct musb *musb, struct urb *urb, - struct musb_hw_ep *hw_ep, int is_in) - { -- struct musb_qh *qh; -- -- if (is_in || hw_ep->is_shared_fifo) -- qh = hw_ep->in_qh; -- else -- qh = hw_ep->out_qh; -+ struct musb_qh *qh = musb_ep_get_qh(hw_ep, is_in); - - if (urb->status == -EINPROGRESS) - qh = musb_giveback(qh, urb, 0); -@@ -689,15 +690,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum, - void __iomem *mbase = musb->mregs; - struct musb_hw_ep *hw_ep = musb->endpoints + epnum; - void __iomem *epio = hw_ep->regs; -- struct musb_qh *qh; -- u16 packet_sz; -- -- if (!is_out || hw_ep->is_shared_fifo) -- qh = hw_ep->in_qh; -- else -- qh = hw_ep->out_qh; -- -- packet_sz = qh->maxpacket; -+ struct musb_qh *qh = musb_ep_get_qh(hw_ep, !is_out); -+ u16 packet_sz = qh->maxpacket; - - DBG(3, "%s hw%d urb %p spd%d dev%d ep%d%s " - "h_addr%02x h_port%02x bytes %d\n", -@@ -1114,17 +1108,14 @@ void musb_host_tx(struct musb *musb, u8 epnum) - u16 tx_csr; - size_t length = 0; - size_t offset = 0; -- struct urb *urb; - struct musb_hw_ep *hw_ep = musb->endpoints + epnum; - void __iomem *epio = hw_ep->regs; -- struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh -- : hw_ep->out_qh; -+ struct musb_qh *qh = hw_ep->out_qh; -+ struct urb *urb = next_urb(qh); - u32 status = 0; - void __iomem *mbase = musb->mregs; - struct dma_channel *dma; - -- urb = next_urb(qh); -- - musb_ep_select(mbase, epnum); - tx_csr = musb_readw(epio, MUSB_TXCSR); - -@@ -1741,10 +1732,7 @@ static int musb_schedule( - epnum++, hw_ep++) { - int diff; - -- if (is_in || hw_ep->is_shared_fifo) { -- if (hw_ep->in_qh != NULL) -- continue; -- } else if (hw_ep->out_qh != NULL) -+ if (musb_ep_get_qh(hw_ep, is_in) != NULL) - continue; - - if (hw_ep == musb->bulk_ep) --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0017-musb_host-refactor-URB-giveback.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0017-musb_host-refactor-URB-giveback.patch deleted file mode 100644 index 4a520dff87..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0017-musb_host-refactor-URB-giveback.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 013056a09afd324e729d64b9a0e66a004604e1d6 Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:58:31 -0700 -Subject: [PATCH] musb_host: refactor URB giveback - -As musb_advance_schedule() is now the only remaning -caller of musb_giveback() (and the only valid context -of such call), just fold the latter into the former -and then rename __musb_giveback() into musb_giveback(). - -This is a net minor shrink. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 54 +++++++++++++++-------------------------- - 1 files changed, 20 insertions(+), 34 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index bc89079..e833959 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -292,9 +292,8 @@ start: - } - } - --/* caller owns controller lock, irqs are blocked */ --static void --__musb_giveback(struct musb *musb, struct urb *urb, int status) -+/* Context: caller owns controller lock, IRQs are blocked */ -+static void musb_giveback(struct musb *musb, struct urb *urb, int status) - __releases(musb->lock) - __acquires(musb->lock) - { -@@ -347,14 +346,22 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in, - usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0); - } - --/* caller owns controller lock, irqs are blocked */ --static struct musb_qh * --musb_giveback(struct musb_qh *qh, struct urb *urb, int status) -+/* -+ * Advance this hardware endpoint's queue, completing the specified URB and -+ * advancing to either the next URB queued to that qh, or else invalidating -+ * that qh and advancing to the next qh scheduled after the current one. -+ * -+ * Context: caller owns controller lock, IRQs are blocked -+ */ -+static void musb_advance_schedule(struct musb *musb, struct urb *urb, -+ struct musb_hw_ep *hw_ep, int is_in) - { -+ struct musb_qh *qh = musb_ep_get_qh(hw_ep, is_in); - struct musb_hw_ep *ep = qh->hw_ep; -- struct musb *musb = ep->musb; -- int is_in = usb_pipein(urb->pipe); - int ready = qh->is_ready; -+ int status; -+ -+ status = (urb->status == -EINPROGRESS) ? 0 : urb->status; - - /* save toggle eagerly, for paranoia */ - switch (qh->type) { -@@ -363,13 +370,13 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) - musb_save_toggle(qh, is_in, urb); - break; - case USB_ENDPOINT_XFER_ISOC: -- if (status == 0 && urb->error_count) -+ if (urb->error_count) - status = -EXDEV; - break; - } - - qh->is_ready = 0; -- __musb_giveback(musb, urb, status); -+ musb_giveback(musb, urb, status); - qh->is_ready = ready; - - /* reclaim resources (and bandwidth) ASAP; deschedule it, and -@@ -413,31 +420,10 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) - break; - } - } -- return qh; --} -- --/* -- * Advance this hardware endpoint's queue, completing the specified urb and -- * advancing to either the next urb queued to that qh, or else invalidating -- * that qh and advancing to the next qh scheduled after the current one. -- * -- * Context: caller owns controller lock, irqs are blocked -- */ --static void --musb_advance_schedule(struct musb *musb, struct urb *urb, -- struct musb_hw_ep *hw_ep, int is_in) --{ -- struct musb_qh *qh = musb_ep_get_qh(hw_ep, is_in); -- -- if (urb->status == -EINPROGRESS) -- qh = musb_giveback(qh, urb, 0); -- else -- qh = musb_giveback(qh, urb, urb->status); - - if (qh != NULL && qh->is_ready) { - DBG(4, "... next ep%d %cX urb %p\n", -- hw_ep->epnum, is_in ? 'R' : 'T', -- next_urb(qh)); -+ hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); - musb_start_urb(musb, is_in, qh); - } - } -@@ -2080,7 +2066,7 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) - - ret = 0; - qh->is_ready = 0; -- __musb_giveback(musb, urb, 0); -+ musb_giveback(musb, urb, 0); - qh->is_ready = ready; - - /* If nothing else (usually musb_giveback) is using it -@@ -2164,7 +2150,7 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - * will activate any of these as it advances. - */ - while (!list_empty(&hep->urb_list)) -- __musb_giveback(musb, next_urb(qh), -ESHUTDOWN); -+ musb_giveback(musb, next_urb(qh), -ESHUTDOWN); - - hep->hcpriv = NULL; - list_del(&qh->ring); --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch deleted file mode 100644 index bf3d6e7021..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch +++ /dev/null @@ -1,167 +0,0 @@ -From b91b067c531c9322f3719951b07303e790b13475 Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:59:46 -0700 -Subject: [PATCH] musb: split out CPPI interrupt handler - -As DaVinci DM646x has a dedicated CPPI DMA interrupt, replace -cppi_completion() (which has always been kind of layering -violation) by a complete CPPI interrupt handler. - -[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: only cppi_dma.c needs platform -device header, not cppi_dma.h ] - -Signed-off-by: Dmitry Krivoschekov <dkrivoschekov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/cppi_dma.c | 34 +++++++++++++++++++++++++++++++--- - drivers/usb/musb/cppi_dma.h | 6 ++++-- - drivers/usb/musb/davinci.c | 14 ++++---------- - 3 files changed, 39 insertions(+), 15 deletions(-) - -diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c -index ac7227c..6ff3c67 100644 ---- a/drivers/usb/musb/cppi_dma.c -+++ b/drivers/usb/musb/cppi_dma.c -@@ -6,6 +6,7 @@ - * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci. - */ - -+#include <linux/platform_device.h> - #include <linux/usb.h> - - #include "musb_core.h" -@@ -1145,17 +1146,27 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) - return completed; - } - --void cppi_completion(struct musb *musb, u32 rx, u32 tx) -+irqreturn_t cppi_interrupt(int irq, void *dev_id) - { -- void __iomem *tibase; -- int i, index; -+ struct musb *musb = dev_id; - struct cppi *cppi; -+ void __iomem *tibase; - struct musb_hw_ep *hw_ep = NULL; -+ u32 rx, tx; -+ int i, index; - - cppi = container_of(musb->dma_controller, struct cppi, controller); - - tibase = musb->ctrl_base; - -+ tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); -+ rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); -+ -+ if (!tx && !rx) -+ return IRQ_NONE; -+ -+ DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx); -+ - /* process TX channels */ - for (index = 0; tx; tx = tx >> 1, index++) { - struct cppi_channel *tx_ch; -@@ -1293,6 +1304,8 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx) - - /* write to CPPI EOI register to re-enable interrupts */ - musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); -+ -+ return IRQ_HANDLED; - } - - /* Instantiate a software object representing a DMA controller. */ -@@ -1300,6 +1313,9 @@ struct dma_controller *__init - dma_controller_create(struct musb *musb, void __iomem *mregs) - { - struct cppi *controller; -+ struct device *dev = musb->controller; -+ struct platform_device *pdev = to_platform_device(dev); -+ int irq = platform_get_irq(pdev, 1); - - controller = kzalloc(sizeof *controller, GFP_KERNEL); - if (!controller) -@@ -1330,6 +1346,15 @@ dma_controller_create(struct musb *musb, void __iomem *mregs) - return NULL; - } - -+ if (irq > 0) { -+ if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) { -+ dev_err(dev, "request_irq %d failed!\n", irq); -+ dma_controller_destroy(&controller->controller); -+ return NULL; -+ } -+ controller->irq = irq; -+ } -+ - return &controller->controller; - } - -@@ -1342,6 +1367,9 @@ void dma_controller_destroy(struct dma_controller *c) - - cppi = container_of(c, struct cppi, controller); - -+ if (cppi->irq) -+ free_irq(cppi->irq, cppi->musb); -+ - /* assert: caller stopped the controller first */ - dma_pool_destroy(cppi->pool); - -diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h -index 729b407..8a39de3 100644 ---- a/drivers/usb/musb/cppi_dma.h -+++ b/drivers/usb/musb/cppi_dma.h -@@ -119,6 +119,8 @@ struct cppi { - void __iomem *mregs; /* Mentor regs */ - void __iomem *tibase; /* TI/CPPI regs */ - -+ int irq; -+ - struct cppi_channel tx[4]; - struct cppi_channel rx[4]; - -@@ -127,7 +129,7 @@ struct cppi { - struct list_head tx_complete; - }; - --/* irq handling hook */ --extern void cppi_completion(struct musb *, u32 rx, u32 tx); -+/* CPPI IRQ handler */ -+extern irqreturn_t cppi_interrupt(int, void *); - - #endif /* end of ifndef _CPPI_DMA_H_ */ -diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c -index 399c435..9fd74bf 100644 ---- a/drivers/usb/musb/davinci.c -+++ b/drivers/usb/musb/davinci.c -@@ -250,6 +250,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) - irqreturn_t retval = IRQ_NONE; - struct musb *musb = __hci; - void __iomem *tibase = musb->ctrl_base; -+ struct cppi *cppi; - u32 tmp; - - spin_lock_irqsave(&musb->lock, flags); -@@ -266,16 +267,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) - /* CPPI interrupts share the same IRQ line, but have their own - * mask, state, "vector", and EOI registers. - */ -- if (is_cppi_enabled()) { -- u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); -- u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); -- -- if (cppi_tx || cppi_rx) { -- DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx); -- cppi_completion(musb, cppi_rx, cppi_tx); -- retval = IRQ_HANDLED; -- } -- } -+ cppi = container_of(musb->dma_controller, struct cppi, controller); -+ if (is_cppi_enabled() && musb->dma_controller && !cppi->irq) -+ retval = cppi_interrupt(irq, __hci); - - /* ack and handle non-CPPI interrupts */ - tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch deleted file mode 100644 index c0e57155c8..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 69242ddd26151d45f46011cf7abc581b14699fb2 Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:56:26 -0700 -Subject: [PATCH] musb_host: simplify check for active URB - -The existance of the scheduling list shouldn't matter in -determining whether there's currectly an URB executing on a -hardware endpoint. What should actually matter is the 'in_qh' -or 'out_qh' fields of the 'struct musb_hw_ep' -- those are -set in musb_start_urb() and cleared in musb_giveback() when -the endpoint's URB list drains. Hence we should be able to -replace the big *switch* statements in musb_urb_dequeue() -and musb_h_disable() with mere musb_ep_get_qh() calls... - -While at it, do some more changes: - - - add 'is_in' variable to musb_urb_dequeue(); - - - remove the unnecessary 'epnum' variable from musb_h_disable(); - - - fix the comment style in the vicinity. - -This is a minor shrink of source and object code. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 72 ++++++++--------------------------------- - 1 files changed, 14 insertions(+), 58 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index e833959..e121e0e 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -2008,14 +2008,14 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) - { - struct musb *musb = hcd_to_musb(hcd); - struct musb_qh *qh; -- struct list_head *sched; - unsigned long flags; -+ int is_in = usb_pipein(urb->pipe); - int ret; - - DBG(4, "urb=%p, dev%d ep%d%s\n", urb, - usb_pipedevice(urb->pipe), - usb_pipeendpoint(urb->pipe), -- usb_pipein(urb->pipe) ? "in" : "out"); -+ is_in ? "in" : "out"); - - spin_lock_irqsave(&musb->lock, flags); - ret = usb_hcd_check_unlink_urb(hcd, urb, status); -@@ -2026,45 +2026,23 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) - if (!qh) - goto done; - -- /* Any URB not actively programmed into endpoint hardware can be -+ /* -+ * Any URB not actively programmed into endpoint hardware can be - * immediately given back; that's any URB not at the head of an - * endpoint queue, unless someday we get real DMA queues. And even - * if it's at the head, it might not be known to the hardware... - * -- * Otherwise abort current transfer, pending dma, etc.; urb->status -+ * Otherwise abort current transfer, pending DMA, etc.; urb->status - * has already been updated. This is a synchronous abort; it'd be - * OK to hold off until after some IRQ, though. -+ * -+ * NOTE: qh is invalid unless !list_empty(&hep->urb_list) - */ -- if (!qh->is_ready || urb->urb_list.prev != &qh->hep->urb_list) -- ret = -EINPROGRESS; -- else { -- switch (qh->type) { -- case USB_ENDPOINT_XFER_CONTROL: -- sched = &musb->control; -- break; -- case USB_ENDPOINT_XFER_BULK: -- if (qh->mux == 1) { -- if (usb_pipein(urb->pipe)) -- sched = &musb->in_bulk; -- else -- sched = &musb->out_bulk; -- break; -- } -- default: -- /* REVISIT when we get a schedule tree, periodic -- * transfers won't always be at the head of a -- * singleton queue... -- */ -- sched = NULL; -- break; -- } -- } -- -- /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ -- if (ret < 0 || (sched && qh != first_qh(sched))) { -+ if (!qh->is_ready -+ || urb->urb_list.prev != &qh->hep->urb_list -+ || musb_ep_get_qh(qh->hw_ep, is_in) != qh) { - int ready = qh->is_ready; - -- ret = 0; - qh->is_ready = 0; - musb_giveback(musb, urb, 0); - qh->is_ready = ready; -@@ -2088,13 +2066,11 @@ done: - static void - musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - { -- u8 epnum = hep->desc.bEndpointAddress; -+ u8 is_in = hep->desc.bEndpointAddress & USB_DIR_IN; - unsigned long flags; - struct musb *musb = hcd_to_musb(hcd); -- u8 is_in = epnum & USB_DIR_IN; - struct musb_qh *qh; - struct urb *urb; -- struct list_head *sched; - - spin_lock_irqsave(&musb->lock, flags); - -@@ -2102,31 +2078,11 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - if (qh == NULL) - goto exit; - -- switch (qh->type) { -- case USB_ENDPOINT_XFER_CONTROL: -- sched = &musb->control; -- break; -- case USB_ENDPOINT_XFER_BULK: -- if (qh->mux == 1) { -- if (is_in) -- sched = &musb->in_bulk; -- else -- sched = &musb->out_bulk; -- break; -- } -- default: -- /* REVISIT when we get a schedule tree, periodic transfers -- * won't always be at the head of a singleton queue... -- */ -- sched = NULL; -- break; -- } -- -- /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ -+ /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ - -- /* kick first urb off the hardware, if needed */ -+ /* Kick the first URB off the hardware, if needed */ - qh->is_ready = 0; -- if (!sched || qh == first_qh(sched)) { -+ if (musb_ep_get_qh(qh->hw_ep, is_in) == qh) { - urb = next_urb(qh); - - /* make software (then hardware) stop ASAP */ --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0020-musb_host-streamline-musb_cleanup_urb-calls.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0020-musb_host-streamline-musb_cleanup_urb-calls.patch deleted file mode 100644 index d89eaadd61..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0020-musb_host-streamline-musb_cleanup_urb-calls.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d408894fa4263440ed8a9e68566bacea7e6f6bed Mon Sep 17 00:00:00 2001 -From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Date: Fri, 27 Mar 2009 12:57:50 -0700 -Subject: [PATCH] musb_host: streamline musb_cleanup_urb() calls - -The argument for the 'is_in' parameter of musb_cleanup_urb() -is always extracted from an URB that's passed to the function. -So that parameter is superfluous; remove it. - -Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_host.c | 9 +++++---- - 1 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index e121e0e..71e835e 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -1950,14 +1950,15 @@ done: - * called with controller locked, irqs blocked - * that hardware queue advances to the next transfer, unless prevented - */ --static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) -+static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) - { - struct musb_hw_ep *ep = qh->hw_ep; - void __iomem *epio = ep->regs; - unsigned hw_end = ep->epnum; - void __iomem *regs = ep->musb->mregs; -- u16 csr; -+ int is_in = usb_pipein(urb->pipe); - int status = 0; -+ u16 csr; - - musb_ep_select(regs, hw_end); - -@@ -2056,7 +2057,7 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) - kfree(qh); - } - } else -- ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); -+ ret = musb_cleanup_urb(urb, qh); - done: - spin_unlock_irqrestore(&musb->lock, flags); - return ret; -@@ -2090,7 +2091,7 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - urb->status = -ESHUTDOWN; - - /* cleanup */ -- musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); -+ musb_cleanup_urb(urb, qh); - - /* Then nuke all the others ... and advance the - * queue on hw_ep (e.g. bulk ring) when we're done. --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0021-twl4030-usb-fix-minor-reporting-goofage.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0021-twl4030-usb-fix-minor-reporting-goofage.patch deleted file mode 100644 index d9733f92b0..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0021-twl4030-usb-fix-minor-reporting-goofage.patch +++ /dev/null @@ -1,70 +0,0 @@ -From c4804e5a447275553c55bbb0ab1748954cb8fbfc Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Tue, 31 Mar 2009 12:26:10 -0700 -Subject: [PATCH] twl4030-usb: fix minor reporting goofage - -Fix a reporting glitch in the twl4030 USB transceiver code. -It wasn't properly distinguishing the two types of active -USB link: ID grounded, vs not. In the current code that -distinction doesn't much matter; in the future this bugfix -should help support better USB controller communications. - -Provide a comment sorting out some of the cryptic bits of -the manual: different sections use different names for -key signals, and the register definitions don't help much -without the explanations and diagrams. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/otg/twl4030-usb.c | 26 +++++++++++++++++++------- - 1 files changed, 19 insertions(+), 7 deletions(-) - -diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c -index d9478d0..f740390 100644 ---- a/drivers/usb/otg/twl4030-usb.c -+++ b/drivers/usb/otg/twl4030-usb.c -@@ -217,6 +217,7 @@ - - /* In module TWL4030_MODULE_PM_MASTER */ - #define PROTECT_KEY 0x0E -+#define STS_HW_CONDITIONS 0x0F - - /* In module TWL4030_MODULE_PM_RECEIVER */ - #define VUSB_DEDICATED1 0x7D -@@ -351,15 +352,26 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) - int status; - int linkstat = USB_LINK_UNKNOWN; - -- /* STS_HW_CONDITIONS */ -- status = twl4030_readb(twl, TWL4030_MODULE_PM_MASTER, 0x0f); -+ /* -+ * For ID/VBUS sensing, see manual section 15.4.8 ... -+ * except when using only battery backup power, two -+ * comparators produce VBUS_PRES and ID_PRES signals, -+ * which don't match docs elsewhere. But ... BIT(7) -+ * and BIT(2) of STS_HW_CONDITIONS, respectively, do -+ * seem to match up. If either is true the USB_PRES -+ * signal is active, the OTG module is activated, and -+ * its interrupt may be raised (may wake the system). -+ */ -+ status = twl4030_readb(twl, TWL4030_MODULE_PM_MASTER, -+ STS_HW_CONDITIONS); - if (status < 0) - dev_err(twl->dev, "USB link status err %d\n", status); -- else if (status & BIT(7)) -- linkstat = USB_LINK_VBUS; -- else if (status & BIT(2)) -- linkstat = USB_LINK_ID; -- else -+ else if (status & (BIT(7) | BIT(2))) { -+ if (status & BIT(2)) -+ linkstat = USB_LINK_ID; -+ else -+ linkstat = USB_LINK_VBUS; -+ } else - linkstat = USB_LINK_NONE; - - dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0022-musb-use-dma-mode-1-for-TX-if-transfer-size-equals.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0022-musb-use-dma-mode-1-for-TX-if-transfer-size-equals.patch deleted file mode 100644 index 16b5b9908b..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0022-musb-use-dma-mode-1-for-TX-if-transfer-size-equals.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ba59a0812ba0e223bd0af8f4dea6c971b6289696 Mon Sep 17 00:00:00 2001 -From: Anand Gadiyar <gadiyar-l0cyMroinI0@public.gmane.org> -Date: Thu, 2 Apr 2009 12:07:08 -0700 -Subject: [PATCH] musb: use dma mode 1 for TX if transfer size equals maxpacket (v2) - -Currently, with Inventra DMA, we use Mode 0 if transfer size is less -than or equal to the endpoint's maxpacket size. This requires that -we explicitly set TXPKTRDY for that transfer. - -However the musb_g_tx code will not set TXPKTRDY twice if the last -transfer is exactly equal to maxpacket, even if request->zero is set. -Using Mode 1 will solve this; a better fix might be in musb_g_tx(). - -Without this change, musb will not correctly send out a ZLP if the -last transfer is the maxpacket size and request->zero is set. - -Signed-off-by: Anand Gadiyar <gadiyar-l0cyMroinI0@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_gadget.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index bc197b2..e8f920c 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -310,7 +310,7 @@ static void txstate(struct musb *musb, struct musb_request *req) - /* setup DMA, then program endpoint CSR */ - request_size = min(request->length, - musb_ep->dma->max_len); -- if (request_size <= musb_ep->packet_sz) -+ if (request_size < musb_ep->packet_sz) - musb_ep->dma->desired_mode = 0; - else - musb_ep->dma->desired_mode = 1; --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch deleted file mode 100644 index 3038dd171d..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 2e049a88b729ae2fdc0ecdabad1857810bd62737 Mon Sep 17 00:00:00 2001 -From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org> -Date: Fri, 3 Apr 2009 16:16:17 -0700 -Subject: [PATCH] musb: add high bandwidth ISO support - -Tested on OMAP3 host side with Creative (Live! Cam Optia) USB camera -which uses high bandwidth isochronous IN endpoints. FIFO mode 4 is -updated to provide the needed 4K endpoint buffer without breaking -the g_nokia composite gadget configuration. (This is the only -gadget driver known to use enough endpoints to notice the change.) - -Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org> -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_core.c | 19 ++++++++--------- - drivers/usb/musb/musb_core.h | 3 ++ - drivers/usb/musb/musb_host.c | 47 +++++++++++++++++++++++++++++++---------- - drivers/usb/musb/musb_host.h | 1 + - 4 files changed, 48 insertions(+), 22 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index a1de43b..d953305 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -1068,14 +1068,13 @@ static struct fifo_cfg __initdata mode_4_cfg[] = { - { .hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 512, }, - { .hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 512, }, - { .hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 512, }, --{ .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 512, }, --{ .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 512, }, --{ .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 512, }, --{ .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 512, }, --{ .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 512, }, --{ .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 512, }, --{ .hw_ep_num = 13, .style = FIFO_TX, .maxpacket = 512, }, --{ .hw_ep_num = 13, .style = FIFO_RX, .maxpacket = 512, }, -+{ .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 256, }, -+{ .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 64, }, -+{ .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 256, }, -+{ .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 64, }, -+{ .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 256, }, -+{ .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 64, }, -+{ .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 4096, }, - { .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, }, - { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, }, - }; -@@ -1335,11 +1334,11 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) - } - if (reg & MUSB_CONFIGDATA_HBRXE) { - strcat(aInfo, ", HB-ISO Rx"); -- strcat(aInfo, " (X)"); /* no driver support */ -+ musb->hb_iso_rx = true; - } - if (reg & MUSB_CONFIGDATA_HBTXE) { - strcat(aInfo, ", HB-ISO Tx"); -- strcat(aInfo, " (X)"); /* no driver support */ -+ musb->hb_iso_tx = true; - } - if (reg & MUSB_CONFIGDATA_SOFTCONE) - strcat(aInfo, ", SoftConn"); -diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h -index f56a56c..0ac4faf 100644 ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -387,6 +387,9 @@ struct musb { - unsigned is_multipoint:1; - unsigned ignore_disconnect:1; /* during bus resets */ - -+ unsigned hb_iso_rx:1; /* high bandwidth iso rx? */ -+ unsigned hb_iso_tx:1; /* high bandwidth iso tx? */ -+ - #ifdef C_MP_TX - unsigned bulk_split:1; - #define can_bulk_split(musb,type) \ -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index 71e835e..ece5122 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -602,7 +602,8 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) - musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg); - musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg); - /* NOTE: bulk combining rewrites high bits of maxpacket */ -- musb_writew(ep->regs, MUSB_RXMAXP, qh->maxpacket); -+ musb_writew(ep->regs, MUSB_RXMAXP, -+ qh->maxpacket | ((qh->hb_mult - 1) << 11)); - - ep->rx_reinit = 0; - } -@@ -624,9 +625,10 @@ static bool musb_tx_dma_program(struct dma_controller *dma, - csr = musb_readw(epio, MUSB_TXCSR); - if (length > pkt_size) { - mode = 1; -- csr |= MUSB_TXCSR_AUTOSET -- | MUSB_TXCSR_DMAMODE -- | MUSB_TXCSR_DMAENAB; -+ csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB; -+ /* autoset shouldn't be set in high bandwidth */ -+ if (qh->hb_mult == 1) -+ csr |= MUSB_TXCSR_AUTOSET; - } else { - mode = 0; - csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE); -@@ -1432,6 +1434,10 @@ void musb_host_rx(struct musb *musb, u8 epnum) - /* packet error reported later */ - iso_err = true; - } -+ } else if (rx_csr & MUSB_RXCSR_INCOMPRX) { -+ DBG(3, "end %d high bandwidth incomplete ISO packet RX\n", -+ epnum); -+ status = -EPROTO; - } - - /* faults abort the transfer */ -@@ -1639,7 +1645,11 @@ void musb_host_rx(struct musb *musb, u8 epnum) - val &= ~MUSB_RXCSR_H_AUTOREQ; - else - val |= MUSB_RXCSR_H_AUTOREQ; -- val |= MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAENAB; -+ val |= MUSB_RXCSR_DMAENAB; -+ -+ /* autoclear shouldn't be set in high bandwidth */ -+ if (qh->hb_mult == 1) -+ val |= MUSB_RXCSR_AUTOCLEAR; - - musb_writew(epio, MUSB_RXCSR, - MUSB_RXCSR_H_WZC_BITS | val); -@@ -1725,9 +1735,10 @@ static int musb_schedule( - continue; - - if (is_in) -- diff = hw_ep->max_packet_sz_rx - qh->maxpacket; -+ diff = hw_ep->max_packet_sz_rx; - else -- diff = hw_ep->max_packet_sz_tx - qh->maxpacket; -+ diff = hw_ep->max_packet_sz_tx; -+ diff -= (qh->maxpacket * qh->hb_mult); - - if (diff >= 0 && best_diff > diff) { - best_diff = diff; -@@ -1830,15 +1841,27 @@ static int musb_urb_enqueue( - qh->is_ready = 1; - - qh->maxpacket = le16_to_cpu(epd->wMaxPacketSize); -+ qh->type = usb_endpoint_type(epd); - -- /* no high bandwidth support yet */ -- if (qh->maxpacket & ~0x7ff) { -- ret = -EMSGSIZE; -- goto done; -+ /* Bits 11 & 12 of wMaxPacketSize encode high bandwidth multiplier. -+ * Some musb cores don't support high bandwidth ISO transfers; and -+ * we don't (yet!) support high bandwidth interrupt transfers. -+ */ -+ qh->hb_mult = 1 + ((qh->maxpacket >> 11) & 0x03); -+ if (qh->hb_mult > 1) { -+ int ok = (qh->type == USB_ENDPOINT_XFER_ISOC); -+ -+ if (ok) -+ ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx) -+ || (usb_pipeout(urb->pipe) && musb->hb_iso_tx); -+ if (!ok) { -+ ret = -EMSGSIZE; -+ goto done; -+ } -+ qh->maxpacket &= 0x7ff; - } - - qh->epnum = usb_endpoint_num(epd); -- qh->type = usb_endpoint_type(epd); - - /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */ - qh->addr_reg = (u8) usb_pipedevice(urb->pipe); -diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h -index 0b7fbcd..14b0077 100644 ---- a/drivers/usb/musb/musb_host.h -+++ b/drivers/usb/musb/musb_host.h -@@ -67,6 +67,7 @@ struct musb_qh { - u8 is_ready; /* safe to modify hw_ep */ - u8 type; /* XFERTYPE_* */ - u8 epnum; -+ u8 hb_mult; /* high bandwidth pkts per uf */ - u16 maxpacket; - u16 frame; /* for periodic schedule */ - unsigned iso_idx; /* in urb->iso_frame_desc[] */ --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0024-USB-otg-adding-nop-usb-transceiver.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0024-USB-otg-adding-nop-usb-transceiver.patch deleted file mode 100644 index 67004d7ec6..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0024-USB-otg-adding-nop-usb-transceiver.patch +++ /dev/null @@ -1,259 +0,0 @@ -From de835357b3597af5304742cbd89771d70533292a Mon Sep 17 00:00:00 2001 -From: Ajay Kumar Gupta <ajay.gupta@ti.com> -Date: Fri, 6 Feb 2009 17:32:35 +0530 -Subject: [PATCH] USB: otg: adding nop usb transceiver - -NOP transceiver is used by all the usb transceiver which are mostly -autonomous and doesn't require any programming or which are built -into the usb ip itself.NOP transceiver only allocates the memory -for struct xceiv and calls otg_set_transceiver() so function call -to otg_get_transceiver() will return a valid transceiver. - -NOP transceiver device should be registered by calling -usb_nop_xceiv_register() from platform files. - -Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> -Cc: Felipe Balbi <felipe.balbi@nokia.com> -Cc: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> ---- - drivers/usb/otg/Kconfig | 8 ++ - drivers/usb/otg/Makefile | 1 + - drivers/usb/otg/nop-usb-xceiv.c | 180 +++++++++++++++++++++++++++++++++++++++ - include/linux/usb/otg.h | 4 + - 4 files changed, 193 insertions(+), 0 deletions(-) - create mode 100644 drivers/usb/otg/nop-usb-xceiv.c - -diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig -index 5790a5b..aa884d0 100644 ---- a/drivers/usb/otg/Kconfig -+++ b/drivers/usb/otg/Kconfig -@@ -51,4 +51,12 @@ config TWL4030_USB - This transceiver supports high and full speed devices plus, - in host mode, low speed. - -+config NOP_USB_XCEIV -+ tristate "NOP USB Transceiver Driver" -+ select USB_OTG_UTILS -+ help -+ this driver is to be used by all the usb transceiver which are either -+ built-in with usb ip or which are autonomous and doesn't require any -+ phy programming such as ISP1x04 etc. -+ - endif # USB || OTG -diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile -index d73c7cf..2081678 100644 ---- a/drivers/usb/otg/Makefile -+++ b/drivers/usb/otg/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o - obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o - obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o - obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o -+obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o - - ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG - ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG -diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c -new file mode 100644 -index 0000000..4b933f6 ---- /dev/null -+++ b/drivers/usb/otg/nop-usb-xceiv.c -@@ -0,0 +1,180 @@ -+/* -+ * drivers/usb/otg/nop-usb-xceiv.c -+ * -+ * NOP USB transceiver for all USB transceiver which are either built-in -+ * into USB IP or which are mostly autonomous. -+ * -+ * Copyright (C) 2009 Texas Instruments Inc -+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * Current status: -+ * this is to add "nop" transceiver for all those phy which is -+ * autonomous such as isp1504 etc. -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/dma-mapping.h> -+#include <linux/usb/otg.h> -+ -+struct nop_usb_xceiv { -+ struct otg_transceiver otg; -+ struct device *dev; -+}; -+ -+static u64 nop_xceiv_dmamask = DMA_32BIT_MASK; -+ -+static struct platform_device nop_xceiv_device = { -+ .name = "nop_usb_xceiv", -+ .id = -1, -+ .dev = { -+ .dma_mask = &nop_xceiv_dmamask, -+ .coherent_dma_mask = DMA_32BIT_MASK, -+ .platform_data = NULL, -+ }, -+}; -+ -+void usb_nop_xceiv_register(void) -+{ -+ if (platform_device_register(&nop_xceiv_device) < 0) { -+ printk(KERN_ERR "Unable to register usb nop transceiver\n"); -+ return; -+ } -+} -+ -+void usb_nop_xceiv_unregister(void) -+{ -+ platform_device_unregister(&nop_xceiv_device); -+} -+ -+static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x) -+{ -+ return container_of(x, struct nop_usb_xceiv, otg); -+} -+ -+static int nop_set_suspend(struct otg_transceiver *x, int suspend) -+{ -+ return 0; -+} -+ -+static int nop_set_peripheral(struct otg_transceiver *x, -+ struct usb_gadget *gadget) -+{ -+ struct nop_usb_xceiv *nop; -+ -+ if (!x) -+ return -ENODEV; -+ -+ nop = xceiv_to_nop(x); -+ -+ if (!gadget) { -+ nop->otg.gadget = NULL; -+ return -ENODEV; -+ } -+ -+ nop->otg.gadget = gadget; -+ nop->otg.state = OTG_STATE_B_IDLE; -+ return 0; -+} -+ -+static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host) -+{ -+ struct nop_usb_xceiv *nop; -+ -+ if (!x) -+ return -ENODEV; -+ -+ nop = xceiv_to_nop(x); -+ -+ if (!host) { -+ nop->otg.host = NULL; -+ return -ENODEV; -+ } -+ -+ nop->otg.host = host; -+ return 0; -+} -+ -+static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) -+{ -+ struct nop_usb_xceiv *nop; -+ int err; -+ -+ nop = kzalloc(sizeof *nop, GFP_KERNEL); -+ if (!nop) -+ return -ENOMEM; -+ -+ nop->dev = &pdev->dev; -+ nop->otg.dev = nop->dev; -+ nop->otg.label = "nop-xceiv"; -+ nop->otg.state = OTG_STATE_UNDEFINED; -+ nop->otg.set_host = nop_set_host; -+ nop->otg.set_peripheral = nop_set_peripheral; -+ nop->otg.set_suspend = nop_set_suspend; -+ -+ err = otg_set_transceiver(&nop->otg); -+ if (err) { -+ dev_err(&pdev->dev, "can't register transceiver, err: %d\n", -+ err); -+ goto exit; -+ } -+ -+ platform_set_drvdata(pdev, nop); -+ -+ return 0; -+exit: -+ kfree(nop); -+ return err; -+} -+ -+static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) -+{ -+ struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); -+ -+ otg_set_transceiver(NULL); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(nop); -+ -+ return 0; -+} -+ -+static struct platform_driver nop_usb_xceiv_driver = { -+ .probe = nop_usb_xceiv_probe, -+ .remove = __devexit_p(nop_usb_xceiv_remove), -+ .driver = { -+ .name = "nop_usb_xceiv", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init nop_usb_xceiv_init(void) -+{ -+ return platform_driver_register(&nop_usb_xceiv_driver); -+} -+subsys_initcall(nop_usb_xceiv_init); -+ -+static void __exit nop_usb_xceiv_exit(void) -+{ -+ platform_driver_unregister(&nop_usb_xceiv_driver); -+} -+module_exit(nop_usb_xceiv_exit); -+ -+MODULE_ALIAS("platform:nop_usb_xceiv"); -+MODULE_AUTHOR("Texas Instruments Inc"); -+MODULE_DESCRIPTION("NOP USB Transceiver driver"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h -index 94df4fe..54f2424 100644 ---- a/include/linux/usb/otg.h -+++ b/include/linux/usb/otg.h -@@ -80,6 +80,10 @@ struct otg_transceiver { - - /* for board-specific init logic */ - extern int otg_set_transceiver(struct otg_transceiver *); -+#ifdef CONFIG_NOP_USB_XCEIV -+extern void usb_nop_xceiv_register(void); -+extern void usb_nop_xceiv_unregister(void); -+#endif - - - /* for usb host and peripheral controller drivers */ --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0025-nop-usb-xceiv-behave-when-linked-as-a-module.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0025-nop-usb-xceiv-behave-when-linked-as-a-module.patch deleted file mode 100644 index 21fe7bea17..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0025-nop-usb-xceiv-behave-when-linked-as-a-module.patch +++ /dev/null @@ -1,90 +0,0 @@ -From ae4f027580168814f734cf3c41a662a7f10c744c Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Tue, 31 Mar 2009 12:28:31 -0700 -Subject: [PATCH] nop-usb-xceiv: behave when linked as a module - -The NOP OTG transceiver driver needs to be usable from modules. -Make sure its symbols are always accessible at both compile and -link time, and make sure the device instance is allocated from -the heap so that device lifetime rules are obeyed. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/otg/nop-usb-xceiv.c | 25 ++++++++++--------------- - include/linux/usb/otg.h | 4 ++-- - 2 files changed, 12 insertions(+), 17 deletions(-) - -diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c -index 4b933f6..9ed5ea5 100644 ---- a/drivers/usb/otg/nop-usb-xceiv.c -+++ b/drivers/usb/otg/nop-usb-xceiv.c -@@ -22,8 +22,8 @@ - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Current status: -- * this is to add "nop" transceiver for all those phy which is -- * autonomous such as isp1504 etc. -+ * This provides a "nop" transceiver for PHYs which are -+ * autonomous such as isp1504, isp1707, etc. - */ - - #include <linux/module.h> -@@ -36,30 +36,25 @@ struct nop_usb_xceiv { - struct device *dev; - }; - --static u64 nop_xceiv_dmamask = DMA_32BIT_MASK; -- --static struct platform_device nop_xceiv_device = { -- .name = "nop_usb_xceiv", -- .id = -1, -- .dev = { -- .dma_mask = &nop_xceiv_dmamask, -- .coherent_dma_mask = DMA_32BIT_MASK, -- .platform_data = NULL, -- }, --}; -+static struct platform_device *pd; - - void usb_nop_xceiv_register(void) - { -- if (platform_device_register(&nop_xceiv_device) < 0) { -+ if (pd) -+ return; -+ pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0); -+ if (!pd) { - printk(KERN_ERR "Unable to register usb nop transceiver\n"); - return; - } - } -+EXPORT_SYMBOL(usb_nop_xceiv_register); - - void usb_nop_xceiv_unregister(void) - { -- platform_device_unregister(&nop_xceiv_device); -+ platform_device_unregister(pd); - } -+EXPORT_SYMBOL(usb_nop_xceiv_unregister); - - static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x) - { -diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h -index 54f2424..7df8bae 100644 ---- a/include/linux/usb/otg.h -+++ b/include/linux/usb/otg.h -@@ -80,10 +80,10 @@ struct otg_transceiver { - - /* for board-specific init logic */ - extern int otg_set_transceiver(struct otg_transceiver *); --#ifdef CONFIG_NOP_USB_XCEIV -+ -+/* sometimes transceivers are accessed only through e.g. ULPI */ - extern void usb_nop_xceiv_register(void); - extern void usb_nop_xceiv_unregister(void); --#endif - - - /* for usb host and peripheral controller drivers */ --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch deleted file mode 100644 index 035a6c7676..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0026-musb-proper-hookup-to-transceiver-drivers.patch +++ /dev/null @@ -1,1109 +0,0 @@ -From 43ee46723ffa9dd43d611362064d235440aa04e7 Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Tue, 31 Mar 2009 12:30:04 -0700 -Subject: [PATCH] musb: proper hookup to transceiver drivers - -Let the otg_transceiver in MUSB be managed by an external driver; -don't assume it's integrated. OMAP3 chips need it to be external, -and there may be ways to interact with the transceiver which add -functionality to the system. - -Platform init code is responsible for setting up the transeciver, -probably using the NOP transceiver for integrated transceivers. -External ones will use whatever the board init code provided, -such as twl4030 or something more hands-off. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/Kconfig | 2 + - drivers/usb/musb/blackfin.c | 11 +++- - drivers/usb/musb/davinci.c | 33 +++++++++----- - drivers/usb/musb/musb_core.c | 96 +++++++++++++++++++++------------------ - drivers/usb/musb/musb_core.h | 2 +- - drivers/usb/musb/musb_gadget.c | 38 +++++++-------- - drivers/usb/musb/musb_host.c | 2 +- - drivers/usb/musb/musb_virthub.c | 20 ++++---- - drivers/usb/musb/omap2430.c | 62 +++++++++---------------- - drivers/usb/musb/tusb6010.c | 70 ++++++++++++++++++----------- - 10 files changed, 181 insertions(+), 155 deletions(-) - -diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig -index 9985db0..9eea991 100644 ---- a/drivers/usb/musb/Kconfig -+++ b/drivers/usb/musb/Kconfig -@@ -10,6 +10,7 @@ comment "Enable Host or Gadget support to see Inventra options" - config USB_MUSB_HDRC - depends on (USB || USB_GADGET) && HAVE_CLK - depends on !SUPERH -+ select NOP_USB_XCEIV if ARCH_DAVINCI - select TWL4030_USB if MACH_OMAP_3430SDP - select USB_OTG_UTILS - tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' -@@ -55,6 +56,7 @@ comment "Blackfin high speed USB Support" - config USB_TUSB6010 - boolean "TUSB 6010 support" - depends on USB_MUSB_HDRC && !USB_MUSB_SOC -+ select NOP_USB_XCEIV - default y - help - The TUSB 6010 chip, from Texas Instruments, connects a discrete -diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c -index 7861348..f2f66eb 100644 ---- a/drivers/usb/musb/blackfin.c -+++ b/drivers/usb/musb/blackfin.c -@@ -143,7 +143,7 @@ static void musb_conn_timer_handler(unsigned long _musb) - u16 val; - - spin_lock_irqsave(&musb->lock, flags); -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_IDLE: - case OTG_STATE_A_WAIT_BCON: - /* Start a new session */ -@@ -154,7 +154,7 @@ static void musb_conn_timer_handler(unsigned long _musb) - val = musb_readw(musb->mregs, MUSB_DEVCTL); - if (!(val & MUSB_DEVCTL_BDEVICE)) { - gpio_set_value(musb->config->gpio_vrsel, 1); -- musb->xceiv.state = OTG_STATE_A_WAIT_BCON; -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - } else { - gpio_set_value(musb->config->gpio_vrsel, 0); - -@@ -247,6 +247,11 @@ int __init musb_platform_init(struct musb *musb) - } - gpio_direction_output(musb->config->gpio_vrsel, 0); - -+ usb_nop_xceiv_register(); -+ musb->xceiv = otg_get_transceiver(); -+ if (!musb->xceiv) -+ return -ENODEV; -+ - if (ANOMALY_05000346) { - bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); - SSYNC(); -@@ -291,7 +296,7 @@ int __init musb_platform_init(struct musb *musb) - musb_conn_timer_handler, (unsigned long) musb); - } - if (is_peripheral_enabled(musb)) -- musb->xceiv.set_power = bfin_set_power; -+ musb->xceiv->set_power = bfin_set_power; - - musb->isr = blackfin_interrupt; - -diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c -index 9fd74bf..81de742 100644 ---- a/drivers/usb/musb/davinci.c -+++ b/drivers/usb/musb/davinci.c -@@ -200,7 +200,7 @@ static void otg_timer(unsigned long _musb) - DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); - - spin_lock_irqsave(&musb->lock, flags); -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_VFALL: - /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL - * seems to mis-handle session "start" otherwise (or in our -@@ -211,7 +211,7 @@ static void otg_timer(unsigned long _musb) - mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); - break; - } -- musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, - MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); - break; -@@ -236,7 +236,7 @@ static void otg_timer(unsigned long _musb) - if (devctl & MUSB_DEVCTL_BDEVICE) - mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); - else -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - break; - default: - break; -@@ -310,21 +310,21 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) - * to stop registering in devctl. - */ - musb->int_usb &= ~MUSB_INTR_VBUSERROR; -- musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; - mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); - WARNING("VBUS error workaround (delay coming)\n"); - } else if (is_host_enabled(musb) && drvvbus) { - musb->is_active = 1; - MUSB_HST_MODE(musb); -- musb->xceiv.default_a = 1; -- musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; -+ musb->xceiv->default_a = 1; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; - portstate(musb->port1_status |= USB_PORT_STAT_POWER); - del_timer(&otg_workaround); - } else { - musb->is_active = 0; - MUSB_DEV_MODE(musb); -- musb->xceiv.default_a = 0; -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->default_a = 0; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); - } - -@@ -346,7 +346,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) - - /* poll for ID change */ - if (is_otg_enabled(musb) -- && musb->xceiv.state == OTG_STATE_B_IDLE) -+ && musb->xceiv->state == OTG_STATE_B_IDLE) - mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); - - spin_unlock_irqrestore(&musb->lock, flags); -@@ -365,6 +365,11 @@ int __init musb_platform_init(struct musb *musb) - void __iomem *tibase = musb->ctrl_base; - u32 revision; - -+ usb_nop_xceiv_register(); -+ musb->xceiv = otg_get_transceiver(); -+ if (!musb->xceiv) -+ return -ENODEV; -+ - musb->mregs += DAVINCI_BASE_OFFSET; - - clk_enable(musb->clock); -@@ -372,7 +377,7 @@ int __init musb_platform_init(struct musb *musb) - /* returns zero if e.g. not clocked */ - revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); - if (revision == 0) -- return -ENODEV; -+ goto fail; - - if (is_host_enabled(musb)) - setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); -@@ -396,6 +401,10 @@ int __init musb_platform_init(struct musb *musb) - - musb->isr = davinci_interrupt; - return 0; -+ -+fail: -+ usb_nop_xceiv_unregister(); -+ return -ENODEV; - } - - int musb_platform_exit(struct musb *musb) -@@ -406,7 +415,7 @@ int musb_platform_exit(struct musb *musb) - davinci_source_power(musb, 0 /*off*/, 1); - - /* delay, to avoid problems with module reload */ -- if (is_host_enabled(musb) && musb->xceiv.default_a) { -+ if (is_host_enabled(musb) && musb->xceiv->default_a) { - int maxdelay = 30; - u8 devctl, warn = 0; - -@@ -435,5 +444,7 @@ int musb_platform_exit(struct musb *musb) - - clk_disable(musb->clock); - -+ usb_nop_xceiv_unregister(); -+ - return 0; - } -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index d953305..ac150af 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -267,7 +267,7 @@ void musb_load_testpacket(struct musb *musb) - - const char *otg_state_string(struct musb *musb) - { -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_IDLE: return "a_idle"; - case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise"; - case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon"; -@@ -302,11 +302,11 @@ void musb_otg_timer_func(unsigned long data) - unsigned long flags; - - spin_lock_irqsave(&musb->lock, flags); -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_B_WAIT_ACON: - DBG(1, "HNP: b_wait_acon timeout; back to b_peripheral\n"); - musb_g_disconnect(musb); -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - musb->is_active = 0; - break; - case OTG_STATE_A_WAIT_BCON: -@@ -331,20 +331,20 @@ void musb_hnp_stop(struct musb *musb) - void __iomem *mbase = musb->mregs; - u8 reg; - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_PERIPHERAL: - case OTG_STATE_A_WAIT_VFALL: - case OTG_STATE_A_WAIT_BCON: - DBG(1, "HNP: Switching back to A-host\n"); - musb_g_disconnect(musb); -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); - musb->is_active = 0; - break; - case OTG_STATE_B_HOST: - DBG(1, "HNP: Disabling HR\n"); - hcd->self.is_b_host = 0; -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - MUSB_DEV_MODE(musb); - reg = musb_readb(mbase, MUSB_POWER); - reg |= MUSB_POWER_SUSPENDM; -@@ -402,7 +402,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - - if (devctl & MUSB_DEVCTL_HM) { - #ifdef CONFIG_USB_MUSB_HDRC_HCD -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_SUSPEND: - /* remote wakeup? later, GetPortStatus - * will stop RESUME signaling -@@ -425,12 +425,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - musb->rh_timer = jiffies - + msecs_to_jiffies(20); - -- musb->xceiv.state = OTG_STATE_A_HOST; -+ musb->xceiv->state = OTG_STATE_A_HOST; - musb->is_active = 1; - usb_hcd_resume_root_hub(musb_to_hcd(musb)); - break; - case OTG_STATE_B_WAIT_ACON: -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - musb->is_active = 1; - MUSB_DEV_MODE(musb); - break; -@@ -441,11 +441,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - } - #endif - } else { -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - #ifdef CONFIG_USB_MUSB_HDRC_HCD - case OTG_STATE_A_SUSPEND: - /* possibly DISCONNECT is upcoming */ -- musb->xceiv.state = OTG_STATE_A_HOST; -+ musb->xceiv->state = OTG_STATE_A_HOST; - usb_hcd_resume_root_hub(musb_to_hcd(musb)); - break; - #endif -@@ -490,7 +490,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - */ - musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); - musb->ep0_stage = MUSB_EP0_START; -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); - musb_set_vbus(musb, 1); - -@@ -516,7 +516,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - * REVISIT: do delays from lots of DEBUG_KERNEL checks - * make trouble here, keeping VBUS < 4.4V ? - */ -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_HOST: - /* recovery is dicey once we've gotten past the - * initial stages of enumeration, but if VBUS -@@ -602,11 +602,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - MUSB_HST_MODE(musb); - - /* indicate new connection to OTG machine */ -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_B_PERIPHERAL: - if (int_usb & MUSB_INTR_SUSPEND) { - DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n"); -- musb->xceiv.state = OTG_STATE_B_HOST; -+ musb->xceiv->state = OTG_STATE_B_HOST; - hcd->self.is_b_host = 1; - int_usb &= ~MUSB_INTR_SUSPEND; - } else -@@ -614,13 +614,13 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - break; - case OTG_STATE_B_WAIT_ACON: - DBG(1, "HNP: Waiting to switch to b_host state\n"); -- musb->xceiv.state = OTG_STATE_B_HOST; -+ musb->xceiv->state = OTG_STATE_B_HOST; - hcd->self.is_b_host = 1; - break; - default: - if ((devctl & MUSB_DEVCTL_VBUS) - == (3 << MUSB_DEVCTL_VBUS_SHIFT)) { -- musb->xceiv.state = OTG_STATE_A_HOST; -+ musb->xceiv->state = OTG_STATE_A_HOST; - hcd->self.is_b_host = 0; - } - break; -@@ -650,7 +650,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - } - } else if (is_peripheral_capable()) { - DBG(1, "BUS RESET as %s\n", otg_state_string(musb)); -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - #ifdef CONFIG_USB_OTG - case OTG_STATE_A_SUSPEND: - /* We need to ignore disconnect on suspend -@@ -673,12 +673,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - case OTG_STATE_B_WAIT_ACON: - DBG(1, "HNP: RESET (%s), to b_peripheral\n", - otg_state_string(musb)); -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - musb_g_reset(musb); - break; - #endif - case OTG_STATE_B_IDLE: -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - /* FALLTHROUGH */ - case OTG_STATE_B_PERIPHERAL: - musb_g_reset(musb); -@@ -763,7 +763,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - MUSB_MODE(musb), devctl); - handled = IRQ_HANDLED; - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - #ifdef CONFIG_USB_MUSB_HDRC_HCD - case OTG_STATE_A_HOST: - case OTG_STATE_A_SUSPEND: -@@ -805,7 +805,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - otg_state_string(musb), devctl, power); - handled = IRQ_HANDLED; - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - #ifdef CONFIG_USB_MUSB_OTG - case OTG_STATE_A_PERIPHERAL: - /* -@@ -817,10 +817,10 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - case OTG_STATE_B_PERIPHERAL: - musb_g_suspend(musb); - musb->is_active = is_otg_enabled(musb) -- && musb->xceiv.gadget->b_hnp_enable; -+ && musb->xceiv->gadget->b_hnp_enable; - if (musb->is_active) { - #ifdef CONFIG_USB_MUSB_OTG -- musb->xceiv.state = OTG_STATE_B_WAIT_ACON; -+ musb->xceiv->state = OTG_STATE_B_WAIT_ACON; - DBG(1, "HNP: Setting timer for b_ase0_brst\n"); - musb_otg_timer.data = (unsigned long)musb; - mod_timer(&musb_otg_timer, jiffies -@@ -834,9 +834,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - + msecs_to_jiffies(musb->a_wait_bcon)); - break; - case OTG_STATE_A_HOST: -- musb->xceiv.state = OTG_STATE_A_SUSPEND; -+ musb->xceiv->state = OTG_STATE_A_SUSPEND; - musb->is_active = is_otg_enabled(musb) -- && musb->xceiv.host->b_hnp_enable; -+ && musb->xceiv->host->b_hnp_enable; - break; - case OTG_STATE_B_HOST: - /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ -@@ -1681,7 +1681,7 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, - - spin_lock_irqsave(&musb->lock, flags); - musb->a_wait_bcon = val; -- if (musb->xceiv.state == OTG_STATE_A_WAIT_BCON) -+ if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) - musb->is_active = 0; - musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); - spin_unlock_irqrestore(&musb->lock, flags); -@@ -1742,8 +1742,8 @@ static void musb_irq_work(struct work_struct *data) - struct musb *musb = container_of(data, struct musb, irq_work); - static int old_state; - -- if (musb->xceiv.state != old_state) { -- old_state = musb->xceiv.state; -+ if (musb->xceiv->state != old_state) { -+ old_state = musb->xceiv->state; - sysfs_notify(&musb->controller->kobj, NULL, "mode"); - } - } -@@ -1840,7 +1840,7 @@ static void musb_free(struct musb *musb) - } - - #ifdef CONFIG_USB_MUSB_OTG -- put_device(musb->xceiv.dev); -+ put_device(musb->xceiv->dev); - #endif - - #ifdef CONFIG_USB_MUSB_HDRC_HCD -@@ -1921,10 +1921,18 @@ bad_config: - } - } - -- /* assume vbus is off */ -- -- /* platform adjusts musb->mregs and musb->isr if needed, -- * and activates clocks -+ /* The musb_platform_init() call: -+ * - adjusts musb->mregs and musb->isr if needed, -+ * - may initialize an integrated tranceiver -+ * - initializes musb->xceiv, usually by otg_get_transceiver() -+ * - activates clocks. -+ * - stops powering VBUS -+ * - assigns musb->board_set_vbus if host mode is enabled -+ * -+ * There are various transciever configurations. Blackfin, -+ * DaVinci, TUSB60x0, and others integrate them. OMAP3 uses -+ * external/discrete ones in various flavors (twl4030 family, -+ * isp1504, non-OTG, etc) mostly hooking up through ULPI. - */ - musb->isr = generic_interrupt; - status = musb_platform_init(musb); -@@ -1992,17 +2000,17 @@ bad_config: - ? "DMA" : "PIO", - musb->nIrq); - --#ifdef CONFIG_USB_MUSB_HDRC_HCD -- /* host side needs more setup, except for no-host modes */ -- if (musb->board_mode != MUSB_PERIPHERAL) { -+ /* host side needs more setup */ -+ if (is_host_enabled(musb)) { - struct usb_hcd *hcd = musb_to_hcd(musb); - -- if (musb->board_mode == MUSB_OTG) -+ otg_set_host(musb->xceiv, &hcd->self); -+ -+ if (is_otg_enabled(musb)) - hcd->self.otg_port = 1; -- musb->xceiv.host = &hcd->self; -+ musb->xceiv->host = &hcd->self; - hcd->power_budget = 2 * (plat->power ? : 250); - } --#endif /* CONFIG_USB_MUSB_HDRC_HCD */ - - /* For the host-only role, we can activate right away. - * (We expect the ID pin to be forcibly grounded!!) -@@ -2010,8 +2018,8 @@ bad_config: - */ - if (!is_otg_enabled(musb) && is_host_enabled(musb)) { - MUSB_HST_MODE(musb); -- musb->xceiv.default_a = 1; -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->default_a = 1; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - - status = usb_add_hcd(musb_to_hcd(musb), -1, 0); - if (status) -@@ -2026,8 +2034,8 @@ bad_config: - - } else /* peripheral is enabled */ { - MUSB_DEV_MODE(musb); -- musb->xceiv.default_a = 0; -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->default_a = 0; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - - status = musb_gadget_setup(musb); - if (status) -diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h -index 0ac4faf..c3ee348 100644 ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -356,7 +356,7 @@ struct musb { - u16 int_rx; - u16 int_tx; - -- struct otg_transceiver xceiv; -+ struct otg_transceiver *xceiv; - - int nIrq; - unsigned irq_wake:1; -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index e8f920c..2fbfba5 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -1406,7 +1406,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) - - spin_lock_irqsave(&musb->lock, flags); - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_B_PERIPHERAL: - /* NOTE: OTG state machine doesn't include B_SUSPENDED; - * that's part of the standard usb 1.1 state machine, and -@@ -1508,9 +1508,9 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) - { - struct musb *musb = gadget_to_musb(gadget); - -- if (!musb->xceiv.set_power) -+ if (!musb->xceiv->set_power) - return -EOPNOTSUPP; -- return otg_set_power(&musb->xceiv, mA); -+ return otg_set_power(musb->xceiv, mA); - } - - static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) -@@ -1733,11 +1733,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) - - spin_lock_irqsave(&musb->lock, flags); - -- /* REVISIT always use otg_set_peripheral(), handling -- * issues including the root hub one below ... -- */ -- musb->xceiv.gadget = &musb->g; -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ otg_set_peripheral(musb->xceiv, &musb->g); - musb->is_active = 1; - - /* FIXME this ignores the softconnect flag. Drivers are -@@ -1749,6 +1745,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) - if (!is_otg_enabled(musb)) - musb_start(musb); - -+ otg_set_peripheral(musb->xceiv, &musb->g); -+ - spin_unlock_irqrestore(&musb->lock, flags); - - if (is_otg_enabled(musb)) { -@@ -1762,8 +1760,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) - if (retval < 0) { - DBG(1, "add_hcd failed, %d\n", retval); - spin_lock_irqsave(&musb->lock, flags); -- musb->xceiv.gadget = NULL; -- musb->xceiv.state = OTG_STATE_UNDEFINED; -+ otg_set_peripheral(musb->xceiv, NULL); - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - spin_unlock_irqrestore(&musb->lock, flags); -@@ -1846,8 +1843,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) - - (void) musb_gadget_vbus_draw(&musb->g, 0); - -- musb->xceiv.state = OTG_STATE_UNDEFINED; -+ musb->xceiv->state = OTG_STATE_UNDEFINED; - stop_activity(musb, driver); -+ otg_set_peripheral(musb->xceiv, NULL); - - DBG(3, "unregistering driver %s\n", driver->function); - spin_unlock_irqrestore(&musb->lock, flags); -@@ -1883,7 +1881,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver); - void musb_g_resume(struct musb *musb) - { - musb->is_suspended = 0; -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_B_IDLE: - break; - case OTG_STATE_B_WAIT_ACON: -@@ -1909,10 +1907,10 @@ void musb_g_suspend(struct musb *musb) - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - DBG(3, "devctl %02x\n", devctl); - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_B_IDLE: - if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - break; - case OTG_STATE_B_PERIPHERAL: - musb->is_suspended = 1; -@@ -1958,22 +1956,22 @@ void musb_g_disconnect(struct musb *musb) - spin_lock(&musb->lock); - } - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - default: - #ifdef CONFIG_USB_MUSB_OTG - DBG(2, "Unhandled disconnect %s, setting a_idle\n", - otg_state_string(musb)); -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - break; - case OTG_STATE_A_PERIPHERAL: -- musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; - break; - case OTG_STATE_B_WAIT_ACON: - case OTG_STATE_B_HOST: - #endif - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_IDLE: -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - break; - case OTG_STATE_B_SRP_INIT: - break; -@@ -2029,10 +2027,10 @@ __acquires(musb->lock) - * or else after HNP, as A-Device - */ - if (devctl & MUSB_DEVCTL_BDEVICE) { -- musb->xceiv.state = OTG_STATE_B_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - musb->g.is_a_peripheral = 0; - } else if (is_otg_enabled(musb)) { -- musb->xceiv.state = OTG_STATE_A_PERIPHERAL; -+ musb->xceiv->state = OTG_STATE_A_PERIPHERAL; - musb->g.is_a_peripheral = 1; - } else - WARN_ON(1); -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index ece5122..795dabe 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -2169,7 +2169,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) - { - struct musb *musb = hcd_to_musb(hcd); - -- if (musb->xceiv.state == OTG_STATE_A_SUSPEND) -+ if (musb->xceiv->state == OTG_STATE_A_SUSPEND) - return 0; - - if (is_host_active(musb) && musb->is_active) { -diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c -index e0e9ce5..7e7900f 100644 ---- a/drivers/usb/musb/musb_virthub.c -+++ b/drivers/usb/musb/musb_virthub.c -@@ -78,18 +78,18 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) - DBG(3, "Root port suspended, power %02x\n", power); - - musb->port1_status |= USB_PORT_STAT_SUSPEND; -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_HOST: -- musb->xceiv.state = OTG_STATE_A_SUSPEND; -+ musb->xceiv->state = OTG_STATE_A_SUSPEND; - musb->is_active = is_otg_enabled(musb) -- && musb->xceiv.host->b_hnp_enable; -+ && musb->xceiv->host->b_hnp_enable; - musb_platform_try_idle(musb, 0); - break; - #ifdef CONFIG_USB_MUSB_OTG - case OTG_STATE_B_HOST: -- musb->xceiv.state = OTG_STATE_B_WAIT_ACON; -+ musb->xceiv->state = OTG_STATE_B_WAIT_ACON; - musb->is_active = is_otg_enabled(musb) -- && musb->xceiv.host->b_hnp_enable; -+ && musb->xceiv->host->b_hnp_enable; - musb_platform_try_idle(musb, 0); - break; - #endif -@@ -116,7 +116,7 @@ static void musb_port_reset(struct musb *musb, bool do_reset) - void __iomem *mbase = musb->mregs; - - #ifdef CONFIG_USB_MUSB_OTG -- if (musb->xceiv.state == OTG_STATE_B_IDLE) { -+ if (musb->xceiv->state == OTG_STATE_B_IDLE) { - DBG(2, "HNP: Returning from HNP; no hub reset from b_idle\n"); - musb->port1_status &= ~USB_PORT_STAT_RESET; - return; -@@ -186,14 +186,14 @@ void musb_root_disconnect(struct musb *musb) - usb_hcd_poll_rh_status(musb_to_hcd(musb)); - musb->is_active = 0; - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_HOST: - case OTG_STATE_A_SUSPEND: -- musb->xceiv.state = OTG_STATE_A_WAIT_BCON; -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - musb->is_active = 0; - break; - case OTG_STATE_A_WAIT_VFALL: -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - break; - default: - DBG(1, "host disconnect (%s)\n", otg_state_string(musb)); -@@ -332,7 +332,7 @@ int musb_hub_control( - musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; - usb_hcd_poll_rh_status(musb_to_hcd(musb)); - /* NOTE: it might really be A_WAIT_BCON ... */ -- musb->xceiv.state = OTG_STATE_A_HOST; -+ musb->xceiv->state = OTG_STATE_A_HOST; - } - - put_unaligned(cpu_to_le32(musb->port1_status -diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c -index 901dffd..5f67b03 100644 ---- a/drivers/usb/musb/omap2430.c -+++ b/drivers/usb/musb/omap2430.c -@@ -62,17 +62,17 @@ static void musb_do_idle(unsigned long _musb) - - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_BCON: - devctl &= ~MUSB_DEVCTL_SESSION; - musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) { -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); - } else { -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); - } - break; -@@ -90,7 +90,7 @@ static void musb_do_idle(unsigned long _musb) - musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; - usb_hcd_poll_rh_status(musb_to_hcd(musb)); - /* NOTE: it might really be A_WAIT_BCON ... */ -- musb->xceiv.state = OTG_STATE_A_HOST; -+ musb->xceiv->state = OTG_STATE_A_HOST; - } - break; - #endif -@@ -98,9 +98,9 @@ static void musb_do_idle(unsigned long _musb) - case OTG_STATE_A_HOST: - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - else -- musb->xceiv.state = OTG_STATE_A_WAIT_BCON; -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - #endif - default: - break; -@@ -119,7 +119,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) - - /* Never idle if active, or when VBUS timeout is not set as host */ - if (musb->is_active || ((musb->a_wait_bcon == 0) -- && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) { -+ && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); - del_timer(&musb_idle_timer); - last_timer = jiffies; -@@ -164,8 +164,8 @@ static void omap_set_vbus(struct musb *musb, int is_on) - - if (is_on) { - musb->is_active = 1; -- musb->xceiv.default_a = 1; -- musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; -+ musb->xceiv->default_a = 1; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; - devctl |= MUSB_DEVCTL_SESSION; - - MUSB_HST_MODE(musb); -@@ -176,8 +176,8 @@ static void omap_set_vbus(struct musb *musb, int is_on) - * jumping right to B_IDLE... - */ - -- musb->xceiv.default_a = 0; -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->default_a = 0; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - devctl &= ~MUSB_DEVCTL_SESSION; - - MUSB_DEV_MODE(musb); -@@ -189,10 +189,6 @@ static void omap_set_vbus(struct musb *musb, int is_on) - otg_state_string(musb), - musb_readb(musb->mregs, MUSB_DEVCTL)); - } --static int omap_set_power(struct otg_transceiver *x, unsigned mA) --{ -- return 0; --} - - static int musb_platform_resume(struct musb *musb); - -@@ -203,24 +199,6 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) - devctl |= MUSB_DEVCTL_SESSION; - musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - -- switch (musb_mode) { --#ifdef CONFIG_USB_MUSB_HDRC_HCD -- case MUSB_HOST: -- otg_set_host(&musb->xceiv, musb->xceiv.host); -- break; --#endif --#ifdef CONFIG_USB_GADGET_MUSB_HDRC -- case MUSB_PERIPHERAL: -- otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); -- break; --#endif --#ifdef CONFIG_USB_MUSB_OTG -- case MUSB_OTG: -- break; --#endif -- default: -- return -EINVAL; -- } - return 0; - } - -@@ -232,6 +210,16 @@ int __init musb_platform_init(struct musb *musb) - omap_cfg_reg(AE5_2430_USB0HS_STP); - #endif - -+ /* We require some kind of external transceiver, hooked -+ * up through ULPI. TWL4030-family PMICs include one, -+ * which needs a driver, drivers aren't always needed. -+ */ -+ musb->xceiv = otg_get_transceiver(); -+ if (!musb->xceiv) { -+ pr_err("HS USB OTG: no transceiver configured\n"); -+ return -ENODEV; -+ } -+ - musb_platform_resume(musb); - - l = omap_readl(OTG_SYSCONFIG); -@@ -258,8 +246,6 @@ int __init musb_platform_init(struct musb *musb) - - if (is_host_enabled(musb)) - musb->board_set_vbus = omap_set_vbus; -- if (is_peripheral_enabled(musb)) -- musb->xceiv.set_power = omap_set_power; - musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON; - - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); -@@ -283,8 +269,7 @@ int musb_platform_suspend(struct musb *musb) - l |= ENABLEWAKEUP; /* enable wakeup */ - omap_writel(l, OTG_SYSCONFIG); - -- if (musb->xceiv.set_suspend) -- musb->xceiv.set_suspend(&musb->xceiv, 1); -+ otg_set_suspend(musb->xceiv, 1); - - if (musb->set_clock) - musb->set_clock(musb->clock, 0); -@@ -301,8 +286,7 @@ static int musb_platform_resume(struct musb *musb) - if (!musb->clock) - return 0; - -- if (musb->xceiv.set_suspend) -- musb->xceiv.set_suspend(&musb->xceiv, 0); -+ otg_set_suspend(musb->xceiv, 0); - - if (musb->set_clock) - musb->set_clock(musb->clock, 1); -diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c -index 9e20fd0..c473dec 100644 ---- a/drivers/usb/musb/tusb6010.c -+++ b/drivers/usb/musb/tusb6010.c -@@ -260,6 +260,8 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) - tusb_fifo_read_unaligned(fifo, buf, len); - } - -+static struct musb *the_musb; -+ - #ifdef CONFIG_USB_GADGET_MUSB_HDRC - - /* This is used by gadget drivers, and OTG transceiver logic, allowing -@@ -270,7 +272,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) - */ - static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) - { -- struct musb *musb = container_of(x, struct musb, xceiv); -+ struct musb *musb = the_musb; - void __iomem *tbase = musb->ctrl_base; - u32 reg; - -@@ -420,7 +422,7 @@ static void musb_do_idle(unsigned long _musb) - - spin_lock_irqsave(&musb->lock, flags); - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_BCON: - if ((musb->a_wait_bcon != 0) - && (musb->idle_timeout == 0 -@@ -484,7 +486,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) - - /* Never idle if active, or when VBUS timeout is not set as host */ - if (musb->is_active || ((musb->a_wait_bcon == 0) -- && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) { -+ && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); - del_timer(&musb_idle_timer); - last_timer = jiffies; -@@ -533,8 +535,8 @@ static void tusb_source_power(struct musb *musb, int is_on) - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); -- musb->xceiv.default_a = 1; -- musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; -+ musb->xceiv->default_a = 1; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; - devctl |= MUSB_DEVCTL_SESSION; - - conf |= TUSB_DEV_CONF_USB_HOST_MODE; -@@ -547,24 +549,24 @@ static void tusb_source_power(struct musb *musb, int is_on) - /* If ID pin is grounded, we want to be a_idle */ - otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); - if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_VRISE: - case OTG_STATE_A_WAIT_BCON: -- musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; -+ musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; - break; - case OTG_STATE_A_WAIT_VFALL: -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - break; - default: -- musb->xceiv.state = OTG_STATE_A_IDLE; -+ musb->xceiv->state = OTG_STATE_A_IDLE; - } - musb->is_active = 0; -- musb->xceiv.default_a = 1; -+ musb->xceiv->default_a = 1; - MUSB_HST_MODE(musb); - } else { - musb->is_active = 0; -- musb->xceiv.default_a = 0; -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->default_a = 0; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); - } - -@@ -675,7 +677,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) - else - default_a = is_host_enabled(musb); - DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); -- musb->xceiv.default_a = default_a; -+ musb->xceiv->default_a = default_a; - tusb_source_power(musb, default_a); - - /* Don't allow idling immediately */ -@@ -687,7 +689,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) - if (int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) { - - /* B-dev state machine: no vbus ~= disconnect */ -- if ((is_otg_enabled(musb) && !musb->xceiv.default_a) -+ if ((is_otg_enabled(musb) && !musb->xceiv->default_a) - || !is_host_enabled(musb)) { - #ifdef CONFIG_USB_MUSB_HDRC_HCD - /* ? musb_root_disconnect(musb); */ -@@ -702,9 +704,9 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) - - if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { - DBG(1, "Forcing disconnect (no interrupt)\n"); -- if (musb->xceiv.state != OTG_STATE_B_IDLE) { -+ if (musb->xceiv->state != OTG_STATE_B_IDLE) { - /* INTR_DISCONNECT can hide... */ -- musb->xceiv.state = OTG_STATE_B_IDLE; -+ musb->xceiv->state = OTG_STATE_B_IDLE; - musb->int_usb |= MUSB_INTR_DISCONNECT; - } - musb->is_active = 0; -@@ -718,7 +720,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) - DBG(2, "vbus change, %s, otg %03x\n", - otg_state_string(musb), otg_stat); - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_IDLE: - DBG(2, "Got SRP, turning on VBUS\n"); - musb_set_vbus(musb, 1); -@@ -766,7 +768,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) - - DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat); - -- switch (musb->xceiv.state) { -+ switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_VRISE: - /* VBUS has probably been valid for a while now, - * but may well have bounced out of range a bit -@@ -778,7 +780,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) - DBG(2, "devctl %02x\n", devctl); - break; - } -- musb->xceiv.state = OTG_STATE_A_WAIT_BCON; -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - musb->is_active = 0; - idle_timeout = jiffies - + msecs_to_jiffies(musb->a_wait_bcon); -@@ -1094,9 +1096,14 @@ int __init musb_platform_init(struct musb *musb) - { - struct platform_device *pdev; - struct resource *mem; -- void __iomem *sync; -+ void __iomem *sync = NULL; - int ret; - -+ usb_nop_xceiv_register(); -+ musb->xceiv = otg_get_transceiver(); -+ if (!musb->xceiv) -+ return -ENODEV; -+ - pdev = to_platform_device(musb->controller); - - /* dma address for async dma */ -@@ -1107,14 +1114,16 @@ int __init musb_platform_init(struct musb *musb) - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!mem) { - pr_debug("no sync dma resource?\n"); -- return -ENODEV; -+ ret = -ENODEV; -+ goto done; - } - musb->sync = mem->start; - - sync = ioremap(mem->start, mem->end - mem->start + 1); - if (!sync) { - pr_debug("ioremap for sync failed\n"); -- return -ENOMEM; -+ ret = -ENOMEM; -+ goto done; - } - musb->sync_va = sync; - -@@ -1127,28 +1136,37 @@ int __init musb_platform_init(struct musb *musb) - if (ret) { - printk(KERN_ERR "Could not start tusb6010 (%d)\n", - ret); -- return -ENODEV; -+ goto done; - } - musb->isr = tusb_interrupt; - - if (is_host_enabled(musb)) - musb->board_set_vbus = tusb_source_power; -- if (is_peripheral_enabled(musb)) -- musb->xceiv.set_power = tusb_draw_power; -+ if (is_peripheral_enabled(musb)) { -+ musb->xceiv->set_power = tusb_draw_power; -+ the_musb = musb; -+ } - - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - -+done: -+ if (ret < 0) { -+ if (sync) -+ iounmap(sync); -+ usb_nop_xceiv_unregister(); -+ } - return ret; - } - - int musb_platform_exit(struct musb *musb) - { - del_timer_sync(&musb_idle_timer); -+ the_musb = NULL; - - if (musb->board_set_power) - musb->board_set_power(0); - - iounmap(musb->sync_va); -- -+ usb_nop_xceiv_unregister(); - return 0; - } --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch deleted file mode 100644 index f41b766cfe..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch +++ /dev/null @@ -1,198 +0,0 @@ -From b4b8c1e7604784b9877f07400ff2a718118ef05c Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Tue, 31 Mar 2009 12:32:12 -0700 -Subject: [PATCH] musb: otg timer cleanup - -Minor cleanup of OTG timer handling: - * unify decls for OTG time constants, in the core header - * set up and use that timer in a more normal way - * move to the driver struct, so it's usable outside core - -And tighten use and setup of T(a_wait_bcon) so that if it's used, -it's always valid. (If that timer expires, the A-device will -stop powering VBUS. For non-OTG systems, that will be a surprise.) -No behavioral changes, other than more consistency when applying -that core HNP timeout. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_core.c | 41 ++++++++++++++++++++++------------------- - drivers/usb/musb/musb_core.h | 14 +++++++++++--- - drivers/usb/musb/omap2430.c | 2 -- - 3 files changed, 33 insertions(+), 24 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index ac150af..05c5dd3 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -112,6 +112,7 @@ - #include "davinci.h" - #endif - -+#define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) - - - unsigned musb_debug; -@@ -288,12 +289,6 @@ const char *otg_state_string(struct musb *musb) - #ifdef CONFIG_USB_MUSB_OTG - - /* -- * See also USB_OTG_1-3.pdf 6.6.5 Timers -- * REVISIT: Are the other timers done in the hardware? -- */ --#define TB_ASE0_BRST 100 /* Min 3.125 ms */ -- --/* - * Handles OTG hnp timeouts, such as b_ase0_brst - */ - void musb_otg_timer_func(unsigned long data) -@@ -320,10 +315,8 @@ void musb_otg_timer_func(unsigned long data) - spin_unlock_irqrestore(&musb->lock, flags); - } - --static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0); -- - /* -- * Stops the B-device HNP state. Caller must take care of locking. -+ * Stops the HNP transition. Caller must take care of locking. - */ - void musb_hnp_stop(struct musb *musb) - { -@@ -661,11 +654,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - musb_g_reset(musb); - /* FALLTHROUGH */ - case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ -- DBG(1, "HNP: Setting timer as %s\n", -- otg_state_string(musb)); -- musb_otg_timer.data = (unsigned long)musb; -- mod_timer(&musb_otg_timer, jiffies -- + msecs_to_jiffies(100)); -+ /* never use invalid T(a_wait_bcon) */ -+ DBG(1, "HNP: in %s, %d msec timeout\n", -+ otg_state_string(musb), -+ TA_WAIT_BCON(musb)); -+ mod_timer(&musb->otg_timer, jiffies -+ + msecs_to_jiffies(TA_WAIT_BCON(musb))); - break; - case OTG_STATE_A_PERIPHERAL: - musb_hnp_stop(musb); -@@ -822,9 +816,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - #ifdef CONFIG_USB_MUSB_OTG - musb->xceiv->state = OTG_STATE_B_WAIT_ACON; - DBG(1, "HNP: Setting timer for b_ase0_brst\n"); -- musb_otg_timer.data = (unsigned long)musb; -- mod_timer(&musb_otg_timer, jiffies -- + msecs_to_jiffies(TB_ASE0_BRST)); -+ mod_timer(&musb->otg_timer, jiffies -+ + msecs_to_jiffies( -+ OTG_TIME_B_ASE0_BRST)); - #endif - } - break; -@@ -1680,7 +1674,8 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, - } - - spin_lock_irqsave(&musb->lock, flags); -- musb->a_wait_bcon = val; -+ /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ -+ musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ; - if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) - musb->is_active = 0; - musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); -@@ -1699,10 +1694,13 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) - - spin_lock_irqsave(&musb->lock, flags); - val = musb->a_wait_bcon; -+ /* FIXME get_vbus_status() is normally #defined as false... -+ * and is effectively TUSB-specific. -+ */ - vbus = musb_platform_get_vbus_status(musb); - spin_unlock_irqrestore(&musb->lock, flags); - -- return sprintf(buf, "Vbus %s, timeout %lu\n", -+ return sprintf(buf, "Vbus %s, timeout %lu msec\n", - vbus ? "on" : "off", val); - } - static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store); -@@ -1775,6 +1773,7 @@ allocate_instance(struct device *dev, - hcd->uses_new_polling = 1; - - musb->vbuserr_retry = VBUSERR_RETRY_COUNT; -+ musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON; - #else - musb = kzalloc(sizeof *musb, GFP_KERNEL); - if (!musb) -@@ -1969,6 +1968,10 @@ bad_config: - if (status < 0) - goto fail2; - -+#ifdef CONFIG_USB_OTG -+ setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); -+#endif -+ - /* Init IRQ workqueue before request_irq */ - INIT_WORK(&musb->irq_work, musb_irq_work); - -diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h -index c3ee348..cf3ccb0 100644 ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -40,6 +40,7 @@ - #include <linux/interrupt.h> - #include <linux/smp_lock.h> - #include <linux/errno.h> -+#include <linux/timer.h> - #include <linux/clk.h> - #include <linux/device.h> - #include <linux/usb/ch9.h> -@@ -180,10 +181,15 @@ enum musb_g_ep0_state { - MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */ - } __attribute__ ((packed)); - --/* OTG protocol constants */ -+/* -+ * OTG protocol constants. See USB OTG 1.3 spec, -+ * sections 5.5 "Device Timings" and 6.6.5 "Timers". -+ */ - #define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */ --#define OTG_TIME_A_WAIT_BCON 0 /* 0=infinite; min 1000 msec */ --#define OTG_TIME_A_IDLE_BDIS 200 /* msec (min) */ -+#define OTG_TIME_A_WAIT_BCON 1100 /* min 1 second */ -+#define OTG_TIME_A_AIDL_BDIS 200 /* min 200 msec */ -+#define OTG_TIME_B_ASE0_BRST 100 /* min 3.125 ms */ -+ - - /*************************** REGISTER ACCESS ********************************/ - -@@ -332,6 +338,8 @@ struct musb { - struct list_head control; /* of musb_qh */ - struct list_head in_bulk; /* of musb_qh */ - struct list_head out_bulk; /* of musb_qh */ -+ -+ struct timer_list otg_timer; - #endif - - /* called with IRQs blocked; ON/nonzero implies starting a session, -diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c -index 5f67b03..3fbc807 100644 ---- a/drivers/usb/musb/omap2430.c -+++ b/drivers/usb/musb/omap2430.c -@@ -45,7 +45,6 @@ - #define get_cpu_rev() 2 - #endif - --#define MUSB_TIMEOUT_A_WAIT_BCON 1100 - - static struct timer_list musb_idle_timer; - -@@ -246,7 +245,6 @@ int __init musb_platform_init(struct musb *musb) - - if (is_host_enabled(musb)) - musb->board_set_vbus = omap_set_vbus; -- musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON; - - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch deleted file mode 100644 index 6269016223..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch +++ /dev/null @@ -1,133 +0,0 @@ -From a637c5056ef52fbb7c41eb7537a9ec3d150231ad Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Thu, 2 Apr 2009 10:16:11 -0700 -Subject: [PATCH] musb: make initial HNP roleswitch work (v2) - -Minor HNP bugfixes, so the initial role switch works: - - - A-Device: - * disconnect-during-suspend enters A_PERIPHERAL state - * kill OTG timer after reset as A_PERIPHERAL ... - * ... and also pass that reset to the gadget - * once HNP succeeds, clear the "ignore_disconnect" flag - * from A_PERIPHERAL, disconnect transitions to A_WAIT_BCON - - - B-Device: - * kill OTG timer on entry to B_HOST state (HNP succeeded) - * once HNP succeeds, clear "ignore_disconnect" flag - * kick the root hub only _after_ the state is adjusted - -Other state transitions are left alone. Notably, exit paths from -the "roles have switched" state ... A_PERIPHERAL handling of that -stays seriously broken. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_core.c | 27 ++++++++++++++++----------- - drivers/usb/musb/musb_gadget.c | 2 +- - drivers/usb/musb/musb_virthub.c | 11 ++++++++++- - 3 files changed, 27 insertions(+), 13 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index 05c5dd3..9dc995a 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -587,28 +587,23 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - if (devctl & MUSB_DEVCTL_LSDEV) - musb->port1_status |= USB_PORT_STAT_LOW_SPEED; - -- if (hcd->status_urb) -- usb_hcd_poll_rh_status(hcd); -- else -- usb_hcd_resume_root_hub(hcd); -- -- MUSB_HST_MODE(musb); -- - /* indicate new connection to OTG machine */ - switch (musb->xceiv->state) { - case OTG_STATE_B_PERIPHERAL: - if (int_usb & MUSB_INTR_SUSPEND) { - DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n"); -- musb->xceiv->state = OTG_STATE_B_HOST; -- hcd->self.is_b_host = 1; - int_usb &= ~MUSB_INTR_SUSPEND; -+ goto b_host; - } else - DBG(1, "CONNECT as b_peripheral???\n"); - break; - case OTG_STATE_B_WAIT_ACON: -- DBG(1, "HNP: Waiting to switch to b_host state\n"); -+ DBG(1, "HNP: CONNECT, now b_host\n"); -+b_host: - musb->xceiv->state = OTG_STATE_B_HOST; - hcd->self.is_b_host = 1; -+ musb->ignore_disconnect = 0; -+ del_timer(&musb->otg_timer); - break; - default: - if ((devctl & MUSB_DEVCTL_VBUS) -@@ -618,6 +613,14 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - } - break; - } -+ -+ /* poke the root hub */ -+ MUSB_HST_MODE(musb); -+ if (hcd->status_urb) -+ usb_hcd_poll_rh_status(hcd); -+ else -+ usb_hcd_resume_root_hub(hcd); -+ - DBG(1, "CONNECT (%s) devctl %02x\n", - otg_state_string(musb), devctl); - } -@@ -662,7 +665,9 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - + msecs_to_jiffies(TA_WAIT_BCON(musb))); - break; - case OTG_STATE_A_PERIPHERAL: -- musb_hnp_stop(musb); -+ musb->ignore_disconnect = 0; -+ del_timer(&musb->otg_timer); -+ musb_g_reset(musb); - break; - case OTG_STATE_B_WAIT_ACON: - DBG(1, "HNP: RESET (%s), to b_peripheral\n", -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index 2fbfba5..7dd3d59 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -1964,7 +1964,7 @@ void musb_g_disconnect(struct musb *musb) - musb->xceiv->state = OTG_STATE_A_IDLE; - break; - case OTG_STATE_A_PERIPHERAL: -- musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; -+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - break; - case OTG_STATE_B_WAIT_ACON: - case OTG_STATE_B_HOST: -diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c -index 7e7900f..14f7cf3 100644 ---- a/drivers/usb/musb/musb_virthub.c -+++ b/drivers/usb/musb/musb_virthub.c -@@ -187,8 +187,17 @@ void musb_root_disconnect(struct musb *musb) - musb->is_active = 0; - - switch (musb->xceiv->state) { -- case OTG_STATE_A_HOST: - case OTG_STATE_A_SUSPEND: -+#ifdef CONFIG_USB_MUSB_OTG -+ if (is_otg_enabled(musb) -+ && musb->xceiv->host->b_hnp_enable) { -+ musb->xceiv->state = OTG_STATE_A_PERIPHERAL; -+ musb->g.is_a_peripheral = 1; -+ break; -+ } -+#endif -+ /* FALLTHROUGH */ -+ case OTG_STATE_A_HOST: - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; - musb->is_active = 0; - break; --- -1.6.0.4 - diff --git a/meta/packages/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch b/meta/packages/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch deleted file mode 100644 index fc34fb983e..0000000000 --- a/meta/packages/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 4288b7df4ae6629a4fb14aca2c489da01d4d19c3 Mon Sep 17 00:00:00 2001 -From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> -Date: Tue, 31 Mar 2009 12:35:09 -0700 -Subject: [PATCH] musb: support disconnect after HNP roleswitch - -Adjust HNP state machines in MUSB driver so that they handle the -case where the cable is disconnected. The A-side machine was -very wrong (unrecoverable); the B-Side was much less so. - - - A_PERIPHERAL ... as usual, the non-observability of the ID - pin through Mentor's registers makes trouble. We can't go - directly to A_WAIT_VFALL to end the session and start the - disconnect processing. We can however sense link suspending, - go to A_WAIT_BCON, and from there use OTG timeouts to finally - trigger that A_WAIT_VFALL transition. (Hoping that nobody - reconnects quickly to that port and notices the wrong state.) - - - B_HOST ... actually clear the Host Request (HR) bit as the - messages say, disconnect the peripheral from the root hub, - and don't detour through a suspend state. (In some cases - this would eventually have cleaned up.) - -Also adjust the A_SUSPEND transition to respect the A_AIDL_BDIS -timeout, so if HNP doesn't trigger quickly enough the A_WAIT_VFALL -transition happens as it should. - -Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> ---- - drivers/usb/musb/musb_core.c | 41 +++++++++++++++++++++++++++----------- - drivers/usb/musb/musb_gadget.c | 2 + - drivers/usb/musb/musb_virthub.c | 4 +++ - 3 files changed, 35 insertions(+), 12 deletions(-) - -diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c -index 9dc995a..5770ccb 100644 ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -304,9 +304,11 @@ void musb_otg_timer_func(unsigned long data) - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; - musb->is_active = 0; - break; -+ case OTG_STATE_A_SUSPEND: - case OTG_STATE_A_WAIT_BCON: -- DBG(1, "HNP: a_wait_bcon timeout; back to a_host\n"); -- musb_hnp_stop(musb); -+ DBG(1, "HNP: %s timeout\n", otg_state_string(musb)); -+ musb_set_vbus(musb, 0); -+ musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; - break; - default: - DBG(1, "HNP: Unhandled mode %s\n", otg_state_string(musb)); -@@ -324,15 +326,12 @@ void musb_hnp_stop(struct musb *musb) - void __iomem *mbase = musb->mregs; - u8 reg; - -+ DBG(1, "HNP: stop from %s\n", otg_state_string(musb)); -+ - switch (musb->xceiv->state) { - case OTG_STATE_A_PERIPHERAL: -- case OTG_STATE_A_WAIT_VFALL: -- case OTG_STATE_A_WAIT_BCON: -- DBG(1, "HNP: Switching back to A-host\n"); - musb_g_disconnect(musb); -- musb->xceiv->state = OTG_STATE_A_IDLE; -- MUSB_HST_MODE(musb); -- musb->is_active = 0; -+ DBG(1, "HNP: back to %s\n", otg_state_string(musb)); - break; - case OTG_STATE_B_HOST: - DBG(1, "HNP: Disabling HR\n"); -@@ -775,7 +774,16 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - #endif /* HOST */ - #ifdef CONFIG_USB_MUSB_OTG - case OTG_STATE_B_HOST: -- musb_hnp_stop(musb); -+ /* REVISIT this behaves for "real disconnect" -+ * cases; make sure the other transitions from -+ * from B_HOST act right too. The B_HOST code -+ * in hnp_stop() is currently not used... -+ */ -+ musb_root_disconnect(musb); -+ musb_to_hcd(musb)->self.is_b_host = 0; -+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL; -+ MUSB_DEV_MODE(musb); -+ musb_g_disconnect(musb); - break; - case OTG_STATE_A_PERIPHERAL: - musb_hnp_stop(musb); -@@ -807,10 +815,19 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, - switch (musb->xceiv->state) { - #ifdef CONFIG_USB_MUSB_OTG - case OTG_STATE_A_PERIPHERAL: -- /* -- * We cannot stop HNP here, devctl BDEVICE might be -- * still set. -+ /* We also come here if the cable is removed, since -+ * this silicon doesn't report ID-no-longer-grounded. -+ * -+ * We depend on T(a_wait_bcon) to shut us down, and -+ * hope users don't do anything dicey during this -+ * undesired detour through A_WAIT_BCON. - */ -+ musb_hnp_stop(musb); -+ usb_hcd_resume_root_hub(musb_to_hcd(musb)); -+ musb_root_disconnect(musb); -+ musb_platform_try_idle(musb, jiffies -+ + msecs_to_jiffies(musb->a_wait_bcon -+ ? : OTG_TIME_A_WAIT_BCON)); - break; - #endif - case OTG_STATE_B_PERIPHERAL: -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index 7dd3d59..8b3c4e2 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -1962,9 +1962,11 @@ void musb_g_disconnect(struct musb *musb) - DBG(2, "Unhandled disconnect %s, setting a_idle\n", - otg_state_string(musb)); - musb->xceiv->state = OTG_STATE_A_IDLE; -+ MUSB_HST_MODE(musb); - break; - case OTG_STATE_A_PERIPHERAL: - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; -+ MUSB_HST_MODE(musb); - break; - case OTG_STATE_B_WAIT_ACON: - case OTG_STATE_B_HOST: -diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c -index 14f7cf3..e8ef925 100644 ---- a/drivers/usb/musb/musb_virthub.c -+++ b/drivers/usb/musb/musb_virthub.c -@@ -83,6 +83,10 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) - musb->xceiv->state = OTG_STATE_A_SUSPEND; - musb->is_active = is_otg_enabled(musb) - && musb->xceiv->host->b_hnp_enable; -+ if (musb->is_active) -+ mod_timer(&musb->otg_timer, jiffies -+ + msecs_to_jiffies( -+ OTG_TIME_A_AIDL_BDIS)); - musb_platform_try_idle(musb, 0); - break; - #ifdef CONFIG_USB_MUSB_OTG --- -1.6.0.4 - |
