Commit 2971216f authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

Update OMAP USB drivers

Updates OMAP USB drivers.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 4c2d1c72
...@@ -150,7 +150,7 @@ config USB_LH7A40X ...@@ -150,7 +150,7 @@ config USB_LH7A40X
config USB_GADGET_OMAP config USB_GADGET_OMAP
boolean "OMAP USB Device Controller" boolean "OMAP USB Device Controller"
depends on ARCH_OMAP depends on ARCH_OMAP1
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
help help
Many Texas Instruments OMAP processors have flexible full Many Texas Instruments OMAP processors have flexible full
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/arch/dma.h> #include <asm/arch/dma.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h> #include <asm/arch/usb.h>
#include "omap_udc.h" #include "omap_udc.h"
...@@ -167,7 +166,7 @@ static int omap_ep_enable(struct usb_ep *_ep, ...@@ -167,7 +166,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
maxp = le16_to_cpu (desc->wMaxPacketSize); maxp = le16_to_cpu (desc->wMaxPacketSize);
if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
&& maxp != ep->maxpacket) && maxp != ep->maxpacket)
|| desc->wMaxPacketSize > ep->maxpacket || le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket
|| !desc->wMaxPacketSize) { || !desc->wMaxPacketSize) {
DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
return -ERANGE; return -ERANGE;
...@@ -214,7 +213,7 @@ static int omap_ep_enable(struct usb_ep *_ep, ...@@ -214,7 +213,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
ep->has_dma = 0; ep->has_dma = 0;
ep->lch = -1; ep->lch = -1;
use_ep(ep, UDC_EP_SEL); use_ep(ep, UDC_EP_SEL);
UDC_CTRL_REG = UDC_RESET_EP; UDC_CTRL_REG = udc->clr_halt;
ep->ackwait = 0; ep->ackwait = 0;
deselect_ep(); deselect_ep();
...@@ -253,7 +252,7 @@ static int omap_ep_disable(struct usb_ep *_ep) ...@@ -253,7 +252,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
} }
spin_lock_irqsave(&ep->udc->lock, flags); spin_lock_irqsave(&ep->udc->lock, flags);
ep->desc = 0; ep->desc = NULL;
nuke (ep, -ESHUTDOWN); nuke (ep, -ESHUTDOWN);
ep->ep.maxpacket = ep->maxpacket; ep->ep.maxpacket = ep->maxpacket;
ep->has_dma = 0; ep->has_dma = 0;
...@@ -388,8 +387,8 @@ done(struct omap_ep *ep, struct omap_req *req, int status) ...@@ -388,8 +387,8 @@ done(struct omap_ep *ep, struct omap_req *req, int status)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#define FIFO_FULL (UDC_NON_ISO_FIFO_FULL | UDC_ISO_FIFO_FULL) #define UDC_FIFO_FULL (UDC_NON_ISO_FIFO_FULL | UDC_ISO_FIFO_FULL)
#define FIFO_UNWRITABLE (UDC_EP_HALTED | FIFO_FULL) #define UDC_FIFO_UNWRITABLE (UDC_EP_HALTED | UDC_FIFO_FULL)
#define FIFO_EMPTY (UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY) #define FIFO_EMPTY (UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY)
#define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY) #define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY)
...@@ -433,7 +432,7 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req) ...@@ -433,7 +432,7 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req)
/* PIO-IN isn't double buffered except for iso */ /* PIO-IN isn't double buffered except for iso */
ep_stat = UDC_STAT_FLG_REG; ep_stat = UDC_STAT_FLG_REG;
if (ep_stat & FIFO_UNWRITABLE) if (ep_stat & UDC_FIFO_UNWRITABLE)
return 0; return 0;
count = ep->ep.maxpacket; count = ep->ep.maxpacket;
...@@ -504,7 +503,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) ...@@ -504,7 +503,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req)
if (ep_stat & UDC_EP_HALTED) if (ep_stat & UDC_EP_HALTED)
break; break;
if (ep_stat & FIFO_FULL) if (ep_stat & UDC_FIFO_FULL)
avail = ep->ep.maxpacket; avail = ep->ep.maxpacket;
else { else {
avail = UDC_RXFSTAT_REG; avail = UDC_RXFSTAT_REG;
...@@ -538,6 +537,32 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) ...@@ -538,6 +537,32 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static inline dma_addr_t dma_csac(unsigned lch)
{
dma_addr_t csac;
/* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
csac = omap_readw(OMAP_DMA_CSAC(lch));
if (csac == 0)
csac = omap_readw(OMAP_DMA_CSAC(lch));
return csac;
}
static inline dma_addr_t dma_cdac(unsigned lch)
{
dma_addr_t cdac;
/* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
cdac = omap_readw(OMAP_DMA_CDAC(lch));
if (cdac == 0)
cdac = omap_readw(OMAP_DMA_CDAC(lch));
return cdac;
}
static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
{ {
dma_addr_t end; dma_addr_t end;
...@@ -548,7 +573,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) ...@@ -548,7 +573,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
if (cpu_is_omap15xx()) if (cpu_is_omap15xx())
return 0; return 0;
end = omap_readw(OMAP_DMA_CSAC(ep->lch)); end = dma_csac(ep->lch);
if (end == ep->dma_counter) if (end == ep->dma_counter)
return 0; return 0;
...@@ -559,14 +584,14 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) ...@@ -559,14 +584,14 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
} }
#define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ #define DMA_DEST_LAST(x) (cpu_is_omap15xx() \
? OMAP_DMA_CSAC(x) /* really: CPC */ \ ? omap_readw(OMAP_DMA_CSAC(x)) /* really: CPC */ \
: OMAP_DMA_CDAC(x)) : dma_cdac(x))
static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start)
{ {
dma_addr_t end; dma_addr_t end;
end = omap_readw(DMA_DEST_LAST(ep->lch)); end = DMA_DEST_LAST(ep->lch);
if (end == ep->dma_counter) if (end == ep->dma_counter)
return 0; return 0;
...@@ -593,7 +618,7 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) ...@@ -593,7 +618,7 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req)
: OMAP_DMA_SYNC_ELEMENT; : OMAP_DMA_SYNC_ELEMENT;
/* measure length in either bytes or packets */ /* measure length in either bytes or packets */
if ((cpu_is_omap16xx() && length <= (UDC_TXN_TSC + 1)) if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC)
|| (cpu_is_omap15xx() && length < ep->maxpacket)) { || (cpu_is_omap15xx() && length < ep->maxpacket)) {
txdma_ctrl = UDC_TXN_EOT | length; txdma_ctrl = UDC_TXN_EOT | length;
omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8,
...@@ -602,15 +627,15 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) ...@@ -602,15 +627,15 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req)
length = min(length / ep->maxpacket, length = min(length / ep->maxpacket,
(unsigned) UDC_TXN_TSC + 1); (unsigned) UDC_TXN_TSC + 1);
txdma_ctrl = length; txdma_ctrl = length;
omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16,
ep->ep.maxpacket, length, sync_mode); ep->ep.maxpacket >> 1, length, sync_mode);
length *= ep->maxpacket; length *= ep->maxpacket;
} }
omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF,
OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual);
omap_start_dma(ep->lch); omap_start_dma(ep->lch);
ep->dma_counter = omap_readw(OMAP_DMA_CSAC(ep->lch)); ep->dma_counter = dma_csac(ep->lch);
UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel);
UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl;
req->dma_bytes = length; req->dma_bytes = length;
...@@ -650,12 +675,12 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) ...@@ -650,12 +675,12 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req)
packets = (req->req.length - req->req.actual) / ep->ep.maxpacket; packets = (req->req.length - req->req.actual) / ep->ep.maxpacket;
packets = min(packets, (unsigned)UDC_RXN_TC + 1); packets = min(packets, (unsigned)UDC_RXN_TC + 1);
req->dma_bytes = packets * ep->ep.maxpacket; req->dma_bytes = packets * ep->ep.maxpacket;
omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16,
ep->ep.maxpacket, packets, ep->ep.maxpacket >> 1, packets,
OMAP_DMA_SYNC_ELEMENT); OMAP_DMA_SYNC_ELEMENT);
omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF,
OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual);
ep->dma_counter = omap_readw(DMA_DEST_LAST(ep->lch)); ep->dma_counter = DMA_DEST_LAST(ep->lch);
UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1);
UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel);
...@@ -763,7 +788,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) ...@@ -763,7 +788,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
reg = UDC_TXDMA_CFG_REG; reg = UDC_TXDMA_CFG_REG;
else else
reg = UDC_RXDMA_CFG_REG; reg = UDC_RXDMA_CFG_REG;
reg |= 1 << 12; /* "pulse" activated */ reg |= UDC_DMA_REQ; /* "pulse" activated */
ep->dma_channel = 0; ep->dma_channel = 0;
ep->lch = -1; ep->lch = -1;
...@@ -787,6 +812,11 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) ...@@ -787,6 +812,11 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
ep->ep.name, dma_error, ep, &ep->lch); ep->ep.name, dma_error, ep, &ep->lch);
if (status == 0) { if (status == 0) {
UDC_TXDMA_CFG_REG = reg; UDC_TXDMA_CFG_REG = reg;
/* EMIFF */
omap_set_dma_src_burst_mode(ep->lch,
OMAP_DMA_DATA_BURST_4);
omap_set_dma_src_data_pack(ep->lch, 1);
/* TIPB */
omap_set_dma_dest_params(ep->lch, omap_set_dma_dest_params(ep->lch,
OMAP_DMA_PORT_TIPB, OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT, OMAP_DMA_AMODE_CONSTANT,
...@@ -797,10 +827,15 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) ...@@ -797,10 +827,15 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
ep->ep.name, dma_error, ep, &ep->lch); ep->ep.name, dma_error, ep, &ep->lch);
if (status == 0) { if (status == 0) {
UDC_RXDMA_CFG_REG = reg; UDC_RXDMA_CFG_REG = reg;
/* TIPB */
omap_set_dma_src_params(ep->lch, omap_set_dma_src_params(ep->lch,
OMAP_DMA_PORT_TIPB, OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT, OMAP_DMA_AMODE_CONSTANT,
(unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG)); (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG));
/* EMIFF */
omap_set_dma_dest_burst_mode(ep->lch,
OMAP_DMA_DATA_BURST_4);
omap_set_dma_dest_data_pack(ep->lch, 1);
} }
} }
if (status) if (status)
...@@ -856,7 +891,7 @@ static void dma_channel_release(struct omap_ep *ep) ...@@ -856,7 +891,7 @@ static void dma_channel_release(struct omap_ep *ep)
if (!list_empty(&ep->queue)) if (!list_empty(&ep->queue))
req = container_of(ep->queue.next, struct omap_req, queue); req = container_of(ep->queue.next, struct omap_req, queue);
else else
req = 0; req = NULL;
active = ((1 << 7) & omap_readl(OMAP_DMA_CCR(ep->lch))) != 0; active = ((1 << 7) & omap_readl(OMAP_DMA_CCR(ep->lch))) != 0;
...@@ -865,9 +900,13 @@ static void dma_channel_release(struct omap_ep *ep) ...@@ -865,9 +900,13 @@ static void dma_channel_release(struct omap_ep *ep)
(ep->bEndpointAddress & USB_DIR_IN) ? 't' : 'r', (ep->bEndpointAddress & USB_DIR_IN) ? 't' : 'r',
ep->dma_channel - 1, req); ep->dma_channel - 1, req);
/* NOTE: re-setting RX_REQ/TX_REQ because of a chip bug (before
* OMAP 1710 ES2.0) where reading the DMA_CFG can clear them.
*/
/* wait till current packet DMA finishes, and fifo empties */ /* wait till current packet DMA finishes, and fifo empties */
if (ep->bEndpointAddress & USB_DIR_IN) { if (ep->bEndpointAddress & USB_DIR_IN) {
UDC_TXDMA_CFG_REG &= ~mask; UDC_TXDMA_CFG_REG = (UDC_TXDMA_CFG_REG & ~mask) | UDC_DMA_REQ;
if (req) { if (req) {
finish_in_dma(ep, req, -ECONNRESET); finish_in_dma(ep, req, -ECONNRESET);
...@@ -880,7 +919,7 @@ static void dma_channel_release(struct omap_ep *ep) ...@@ -880,7 +919,7 @@ static void dma_channel_release(struct omap_ep *ep)
while (UDC_TXDMA_CFG_REG & mask) while (UDC_TXDMA_CFG_REG & mask)
udelay(10); udelay(10);
} else { } else {
UDC_RXDMA_CFG_REG &= ~mask; UDC_RXDMA_CFG_REG = (UDC_RXDMA_CFG_REG & ~mask) | UDC_DMA_REQ;
/* dma empties the fifo */ /* dma empties the fifo */
while (UDC_RXDMA_CFG_REG & mask) while (UDC_RXDMA_CFG_REG & mask)
...@@ -997,18 +1036,19 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) ...@@ -997,18 +1036,19 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
UDC_IRQ_EN_REG = irq_en; UDC_IRQ_EN_REG = irq_en;
} }
/* STATUS is reverse direction */ /* STATUS for zero length DATA stages is
UDC_EP_NUM_REG = is_in * always an IN ... even for IN transfers,
? UDC_EP_SEL * a wierd case which seem to stall OMAP.
: (UDC_EP_SEL|UDC_EP_DIR); */
UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR);
UDC_CTRL_REG = UDC_CLR_EP; UDC_CTRL_REG = UDC_CLR_EP;
UDC_CTRL_REG = UDC_SET_FIFO_EN; UDC_CTRL_REG = UDC_SET_FIFO_EN;
UDC_EP_NUM_REG = udc->ep0_in ? 0 : UDC_EP_DIR; UDC_EP_NUM_REG = UDC_EP_DIR;
/* cleanup */ /* cleanup */
udc->ep0_pending = 0; udc->ep0_pending = 0;
done(ep, req, 0); done(ep, req, 0);
req = 0; req = NULL;
/* non-empty DATA stage */ /* non-empty DATA stage */
} else if (is_in) { } else if (is_in) {
...@@ -1029,7 +1069,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) ...@@ -1029,7 +1069,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
(is_in ? next_in_dma : next_out_dma)(ep, req); (is_in ? next_in_dma : next_out_dma)(ep, req);
else if (req) { else if (req) {
if ((is_in ? write_fifo : read_fifo)(ep, req) == 1) if ((is_in ? write_fifo : read_fifo)(ep, req) == 1)
req = 0; req = NULL;
deselect_ep(); deselect_ep();
if (!is_in) { if (!is_in) {
UDC_CTRL_REG = UDC_SET_FIFO_EN; UDC_CTRL_REG = UDC_SET_FIFO_EN;
...@@ -1041,7 +1081,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) ...@@ -1041,7 +1081,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
irq_wait: irq_wait:
/* irq handler advances the queue */ /* irq handler advances the queue */
if (req != 0) if (req != NULL)
list_add_tail(&req->queue, &ep->queue); list_add_tail(&req->queue, &ep->queue);
spin_unlock_irqrestore(&udc->lock, flags); spin_unlock_irqrestore(&udc->lock, flags);
...@@ -1140,7 +1180,7 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) ...@@ -1140,7 +1180,7 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value)
dma_channel_claim(ep, channel); dma_channel_claim(ep, channel);
} else { } else {
use_ep(ep, 0); use_ep(ep, 0);
UDC_CTRL_REG = UDC_RESET_EP; UDC_CTRL_REG = ep->udc->clr_halt;
ep->ackwait = 0; ep->ackwait = 0;
if (!(ep->bEndpointAddress & USB_DIR_IN)) { if (!(ep->bEndpointAddress & USB_DIR_IN)) {
UDC_CTRL_REG = UDC_SET_FIFO_EN; UDC_CTRL_REG = UDC_SET_FIFO_EN;
...@@ -1238,6 +1278,8 @@ static int can_pullup(struct omap_udc *udc) ...@@ -1238,6 +1278,8 @@ static int can_pullup(struct omap_udc *udc)
static void pullup_enable(struct omap_udc *udc) static void pullup_enable(struct omap_udc *udc)
{ {
udc->gadget.dev.parent->power.power_state = PMSG_ON;
udc->gadget.dev.power.power_state = PMSG_ON;
UDC_SYSCON1_REG |= UDC_PULLUP_EN; UDC_SYSCON1_REG |= UDC_PULLUP_EN;
#ifndef CONFIG_USB_OTG #ifndef CONFIG_USB_OTG
if (!cpu_is_omap15xx()) if (!cpu_is_omap15xx())
...@@ -1382,7 +1424,7 @@ static void update_otg(struct omap_udc *udc) ...@@ -1382,7 +1424,7 @@ static void update_otg(struct omap_udc *udc)
static void ep0_irq(struct omap_udc *udc, u16 irq_src) static void ep0_irq(struct omap_udc *udc, u16 irq_src)
{ {
struct omap_ep *ep0 = &udc->ep[0]; struct omap_ep *ep0 = &udc->ep[0];
struct omap_req *req = 0; struct omap_req *req = NULL;
ep0->irqs++; ep0->irqs++;
...@@ -1438,7 +1480,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) ...@@ -1438,7 +1480,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
if (req) if (req)
done(ep0, req, 0); done(ep0, req, 0);
} }
req = 0; req = NULL;
} else if (stat & UDC_STALL) { } else if (stat & UDC_STALL) {
UDC_CTRL_REG = UDC_CLR_HALT; UDC_CTRL_REG = UDC_CLR_HALT;
UDC_EP_NUM_REG = UDC_EP_DIR; UDC_EP_NUM_REG = UDC_EP_DIR;
...@@ -1511,9 +1553,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) ...@@ -1511,9 +1553,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
u.word[3] = UDC_DATA_REG; u.word[3] = UDC_DATA_REG;
UDC_EP_NUM_REG = 0; UDC_EP_NUM_REG = 0;
} while (UDC_IRQ_SRC_REG & UDC_SETUP); } while (UDC_IRQ_SRC_REG & UDC_SETUP);
le16_to_cpus (&u.r.wValue);
le16_to_cpus (&u.r.wIndex); #define w_value le16_to_cpup (&u.r.wValue)
le16_to_cpus (&u.r.wLength); #define w_index le16_to_cpup (&u.r.wIndex)
#define w_length le16_to_cpup (&u.r.wLength)
/* Delegate almost all control requests to the gadget driver, /* Delegate almost all control requests to the gadget driver,
* except for a handful of ch9 status/feature requests that * except for a handful of ch9 status/feature requests that
...@@ -1529,11 +1572,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) ...@@ -1529,11 +1572,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
/* udc needs to know when ep != 0 is valid */ /* udc needs to know when ep != 0 is valid */
if (u.r.bRequestType != USB_RECIP_DEVICE) if (u.r.bRequestType != USB_RECIP_DEVICE)
goto delegate; goto delegate;
if (u.r.wLength != 0) if (w_length != 0)
goto do_stall; goto do_stall;
udc->ep0_set_config = 1; udc->ep0_set_config = 1;
udc->ep0_reset_config = (u.r.wValue == 0); udc->ep0_reset_config = (w_value == 0);
VDBG("set config %d\n", u.r.wValue); VDBG("set config %d\n", w_value);
/* update udc NOW since gadget driver may start /* update udc NOW since gadget driver may start
* queueing requests immediately; clear config * queueing requests immediately; clear config
...@@ -1549,23 +1592,28 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) ...@@ -1549,23 +1592,28 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
/* clear endpoint halt */ /* clear endpoint halt */
if (u.r.bRequestType != USB_RECIP_ENDPOINT) if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate; goto delegate;
if (u.r.wValue != USB_ENDPOINT_HALT if (w_value != USB_ENDPOINT_HALT
|| u.r.wLength != 0) || w_length != 0)
goto do_stall; goto do_stall;
ep = &udc->ep[u.r.wIndex & 0xf]; ep = &udc->ep[w_index & 0xf];
if (ep != ep0) { if (ep != ep0) {
if (u.r.wIndex & USB_DIR_IN) if (w_index & USB_DIR_IN)
ep += 16; ep += 16;
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
|| !ep->desc) || !ep->desc)
goto do_stall; goto do_stall;
use_ep(ep, 0); use_ep(ep, 0);
UDC_CTRL_REG = UDC_RESET_EP; UDC_CTRL_REG = udc->clr_halt;
ep->ackwait = 0; ep->ackwait = 0;
if (!(ep->bEndpointAddress & USB_DIR_IN)) { if (!(ep->bEndpointAddress & USB_DIR_IN)) {
UDC_CTRL_REG = UDC_SET_FIFO_EN; UDC_CTRL_REG = UDC_SET_FIFO_EN;
ep->ackwait = 1 + ep->double_buf; ep->ackwait = 1 + ep->double_buf;
} }
/* NOTE: assumes the host behaves sanely,
* only clearing real halts. Else we may
* need to kill pending transfers and then
* restart the queue... very messy for DMA!
*/
} }
VDBG("%s halt cleared by host\n", ep->name); VDBG("%s halt cleared by host\n", ep->name);
goto ep0out_status_stage; goto ep0out_status_stage;
...@@ -1573,11 +1621,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) ...@@ -1573,11 +1621,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
/* set endpoint halt */ /* set endpoint halt */
if (u.r.bRequestType != USB_RECIP_ENDPOINT) if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate; goto delegate;
if (u.r.wValue != USB_ENDPOINT_HALT if (w_value != USB_ENDPOINT_HALT
|| u.r.wLength != 0) || w_length != 0)
goto do_stall; goto do_stall;
ep = &udc->ep[u.r.wIndex & 0xf]; ep = &udc->ep[w_index & 0xf];
if (u.r.wIndex & USB_DIR_IN) if (w_index & USB_DIR_IN)
ep += 16; ep += 16;
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
|| ep == ep0 || !ep->desc) || ep == ep0 || !ep->desc)
...@@ -1615,13 +1663,13 @@ ep0out_status_stage: ...@@ -1615,13 +1663,13 @@ ep0out_status_stage:
UDC_CTRL_REG = UDC_SET_FIFO_EN; UDC_CTRL_REG = UDC_SET_FIFO_EN;
UDC_EP_NUM_REG = UDC_EP_DIR; UDC_EP_NUM_REG = UDC_EP_DIR;
status = 0; status = 0;
VDBG("GET_STATUS, interface %d\n", u.r.wIndex); VDBG("GET_STATUS, interface %d\n", w_index);
/* next, status stage */ /* next, status stage */
break; break;
default: default:
delegate: delegate:
/* activate the ep0out fifo right away */ /* activate the ep0out fifo right away */
if (!udc->ep0_in && u.r.wLength) { if (!udc->ep0_in && w_length) {
UDC_EP_NUM_REG = 0; UDC_EP_NUM_REG = 0;
UDC_CTRL_REG = UDC_SET_FIFO_EN; UDC_CTRL_REG = UDC_SET_FIFO_EN;
} }
...@@ -1632,7 +1680,11 @@ delegate: ...@@ -1632,7 +1680,11 @@ delegate:
*/ */
VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n", VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n",
u.r.bRequestType, u.r.bRequest, u.r.bRequestType, u.r.bRequest,
u.r.wValue, u.r.wIndex, u.r.wLength); w_value, w_index, w_length);
#undef w_value
#undef w_index
#undef w_length
/* The gadget driver may return an error here, /* The gadget driver may return an error here,
* causing an immediate protocol stall. * causing an immediate protocol stall.
...@@ -2013,7 +2065,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) ...@@ -2013,7 +2065,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
udc->softconnect = 1; udc->softconnect = 1;
/* hook up the driver */ /* hook up the driver */
driver->driver.bus = 0; driver->driver.bus = NULL;
udc->driver = driver; udc->driver = driver;
udc->gadget.dev.driver = &driver->driver; udc->gadget.dev.driver = &driver->driver;
spin_unlock_irqrestore(&udc->lock, flags); spin_unlock_irqrestore(&udc->lock, flags);
...@@ -2021,8 +2073,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) ...@@ -2021,8 +2073,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
status = driver->bind (&udc->gadget); status = driver->bind (&udc->gadget);
if (status) { if (status) {
DBG("bind to %s --> %d\n", driver->driver.name, status); DBG("bind to %s --> %d\n", driver->driver.name, status);
udc->gadget.dev.driver = 0; udc->gadget.dev.driver = NULL;
udc->driver = 0; udc->driver = NULL;
goto done; goto done;
} }
DBG("bound to driver %s\n", driver->driver.name); DBG("bound to driver %s\n", driver->driver.name);
...@@ -2035,8 +2087,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) ...@@ -2035,8 +2087,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (status < 0) { if (status < 0) {
ERR("can't bind to transceiver\n"); ERR("can't bind to transceiver\n");
driver->unbind (&udc->gadget); driver->unbind (&udc->gadget);
udc->gadget.dev.driver = 0; udc->gadget.dev.driver = NULL;
udc->driver = 0; udc->driver = NULL;
goto done; goto done;
} }
} else { } else {
...@@ -2071,7 +2123,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) ...@@ -2071,7 +2123,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
omap_vbus_session(&udc->gadget, 0); omap_vbus_session(&udc->gadget, 0);
if (udc->transceiver) if (udc->transceiver)
(void) otg_set_peripheral(udc->transceiver, 0); (void) otg_set_peripheral(udc->transceiver, NULL);
else else
pullup_disable(udc); pullup_disable(udc);
...@@ -2080,9 +2132,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) ...@@ -2080,9 +2132,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&udc->lock, flags); spin_unlock_irqrestore(&udc->lock, flags);
driver->unbind(&udc->gadget); driver->unbind(&udc->gadget);
udc->gadget.dev.driver = 0; udc->gadget.dev.driver = NULL;
udc->driver = 0; udc->driver = NULL;
DBG("unregistered driver '%s'\n", driver->driver.name); DBG("unregistered driver '%s'\n", driver->driver.name);
return status; return status;
...@@ -2178,14 +2229,14 @@ static int proc_otg_show(struct seq_file *s) ...@@ -2178,14 +2229,14 @@ static int proc_otg_show(struct seq_file *s)
tmp = OTG_REV_REG; tmp = OTG_REV_REG;
trans = USB_TRANSCEIVER_CTRL_REG; trans = USB_TRANSCEIVER_CTRL_REG;
seq_printf(s, "OTG rev %d.%d, transceiver_ctrl %03x\n", seq_printf(s, "\nOTG rev %d.%d, transceiver_ctrl %05x\n",
tmp >> 4, tmp & 0xf, trans); tmp >> 4, tmp & 0xf, trans);
tmp = OTG_SYSCON_1_REG; tmp = OTG_SYSCON_1_REG;
seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s,"
FOURBITS "\n", tmp, FOURBITS "\n", tmp,
trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R), trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R),
trx_mode(USB1_TRX_MODE(tmp), trans & CONF_USB1_UNI_R), trx_mode(USB1_TRX_MODE(tmp), trans & CONF_USB1_UNI_R),
(USB0_TRX_MODE(tmp) == 0) (USB0_TRX_MODE(tmp) == 0 && !cpu_is_omap1710())
? "internal" ? "internal"
: trx_mode(USB0_TRX_MODE(tmp), 1), : trx_mode(USB0_TRX_MODE(tmp), 1),
(tmp & OTG_IDLE_EN) ? " !otg" : "", (tmp & OTG_IDLE_EN) ? " !otg" : "",
...@@ -2235,6 +2286,7 @@ static int proc_otg_show(struct seq_file *s) ...@@ -2235,6 +2286,7 @@ static int proc_otg_show(struct seq_file *s)
seq_printf(s, "otg_outctrl %04x" "\n", tmp); seq_printf(s, "otg_outctrl %04x" "\n", tmp);
tmp = OTG_TEST_REG; tmp = OTG_TEST_REG;
seq_printf(s, "otg_test %04x" "\n", tmp); seq_printf(s, "otg_test %04x" "\n", tmp);
return 0;
} }
static int proc_udc_show(struct seq_file *s, void *_) static int proc_udc_show(struct seq_file *s, void *_)
...@@ -2378,7 +2430,7 @@ static int proc_udc_show(struct seq_file *s, void *_) ...@@ -2378,7 +2430,7 @@ static int proc_udc_show(struct seq_file *s, void *_)
static int proc_udc_open(struct inode *inode, struct file *file) static int proc_udc_open(struct inode *inode, struct file *file)
{ {
return single_open(file, proc_udc_show, 0); return single_open(file, proc_udc_show, NULL);
} }
static struct file_operations proc_ops = { static struct file_operations proc_ops = {
...@@ -2399,7 +2451,7 @@ static void create_proc_file(void) ...@@ -2399,7 +2451,7 @@ static void create_proc_file(void)
static void remove_proc_file(void) static void remove_proc_file(void)
{ {
remove_proc_entry(proc_filename, 0); remove_proc_entry(proc_filename, NULL);
} }
#else #else
...@@ -2414,6 +2466,10 @@ static inline void remove_proc_file(void) {} ...@@ -2414,6 +2466,10 @@ static inline void remove_proc_file(void) {}
/* Before this controller can enumerate, we need to pick an endpoint /* Before this controller can enumerate, we need to pick an endpoint
* configuration, or "fifo_mode" That involves allocating 2KB of packet * configuration, or "fifo_mode" That involves allocating 2KB of packet
* buffer space among the endpoints we'll be operating. * buffer space among the endpoints we'll be operating.
*
* NOTE: as of OMAP 1710 ES2.0, writing a new endpoint config when
* UDC_SYSCON_1_REG.CFG_LOCK is set can now work. We won't use that
* capability yet though.
*/ */
static unsigned __init static unsigned __init
omap_ep_setup(char *name, u8 addr, u8 type, omap_ep_setup(char *name, u8 addr, u8 type,
...@@ -2505,7 +2561,7 @@ static void omap_udc_release(struct device *dev) ...@@ -2505,7 +2561,7 @@ static void omap_udc_release(struct device *dev)
{ {
complete(udc->done); complete(udc->done);
kfree (udc); kfree (udc);
udc = 0; udc = NULL;
} }
static int __init static int __init
...@@ -2577,23 +2633,33 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) ...@@ -2577,23 +2633,33 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
case 1: case 1:
OMAP_BULK_EP("ep1in", USB_DIR_IN | 1); OMAP_BULK_EP("ep1in", USB_DIR_IN | 1);
OMAP_BULK_EP("ep2out", USB_DIR_OUT | 2); OMAP_BULK_EP("ep2out", USB_DIR_OUT | 2);
OMAP_INT_EP("ep9in", USB_DIR_IN | 9, 16);
OMAP_BULK_EP("ep3in", USB_DIR_IN | 3); OMAP_BULK_EP("ep3in", USB_DIR_IN | 3);
OMAP_BULK_EP("ep4out", USB_DIR_OUT | 4); OMAP_BULK_EP("ep4out", USB_DIR_OUT | 4);
OMAP_INT_EP("ep10in", USB_DIR_IN | 10, 16);
OMAP_BULK_EP("ep5in", USB_DIR_IN | 5); OMAP_BULK_EP("ep5in", USB_DIR_IN | 5);
OMAP_BULK_EP("ep5out", USB_DIR_OUT | 5); OMAP_BULK_EP("ep5out", USB_DIR_OUT | 5);
OMAP_INT_EP("ep11in", USB_DIR_IN | 11, 16);
OMAP_BULK_EP("ep6in", USB_DIR_IN | 6); OMAP_BULK_EP("ep6in", USB_DIR_IN | 6);
OMAP_BULK_EP("ep6out", USB_DIR_OUT | 6); OMAP_BULK_EP("ep6out", USB_DIR_OUT | 6);
OMAP_INT_EP("ep12in", USB_DIR_IN | 12, 16);
OMAP_BULK_EP("ep7in", USB_DIR_IN | 7); OMAP_BULK_EP("ep7in", USB_DIR_IN | 7);
OMAP_BULK_EP("ep7out", USB_DIR_OUT | 7); OMAP_BULK_EP("ep7out", USB_DIR_OUT | 7);
OMAP_INT_EP("ep13in", USB_DIR_IN | 13, 16);
OMAP_INT_EP("ep13out", USB_DIR_OUT | 13, 16);
OMAP_BULK_EP("ep8in", USB_DIR_IN | 8); OMAP_BULK_EP("ep8in", USB_DIR_IN | 8);
OMAP_BULK_EP("ep8out", USB_DIR_OUT | 8); OMAP_BULK_EP("ep8out", USB_DIR_OUT | 8);
OMAP_INT_EP("ep14in", USB_DIR_IN | 14, 16);
OMAP_INT_EP("ep14out", USB_DIR_OUT | 14, 16);
OMAP_BULK_EP("ep15in", USB_DIR_IN | 15);
OMAP_BULK_EP("ep15out", USB_DIR_OUT | 15);
OMAP_INT_EP("ep9in", USB_DIR_IN | 9, 16);
OMAP_INT_EP("ep10out", USB_DIR_IN | 10, 16);
OMAP_INT_EP("ep11in", USB_DIR_IN | 9, 16);
OMAP_INT_EP("ep12out", USB_DIR_IN | 10, 16);
break; break;
#ifdef USE_ISO #ifdef USE_ISO
...@@ -2640,8 +2706,8 @@ static int __init omap_udc_probe(struct device *dev) ...@@ -2640,8 +2706,8 @@ static int __init omap_udc_probe(struct device *dev)
struct platform_device *odev = to_platform_device(dev); struct platform_device *odev = to_platform_device(dev);
int status = -ENODEV; int status = -ENODEV;
int hmc; int hmc;
struct otg_transceiver *xceiv = 0; struct otg_transceiver *xceiv = NULL;
const char *type = 0; const char *type = NULL;
struct omap_usb_config *config = dev->platform_data; struct omap_usb_config *config = dev->platform_data;
/* NOTE: "knows" the order of the resources! */ /* NOTE: "knows" the order of the resources! */
...@@ -2676,54 +2742,78 @@ static int __init omap_udc_probe(struct device *dev) ...@@ -2676,54 +2742,78 @@ static int __init omap_udc_probe(struct device *dev)
FUNC_MUX_CTRL_0_REG = tmp; FUNC_MUX_CTRL_0_REG = tmp;
} }
} else { } else {
/* The transceiver may package some GPIO logic or handle
* loopback and/or transceiverless setup; if we find one,
* use it. Except for OTG, we don't _need_ to talk to one;
* but not having one probably means no VBUS detection.
*/
xceiv = otg_get_transceiver();
if (xceiv)
type = xceiv->label;
else if (config->otg) {
DBG("OTG requires external transceiver!\n");
goto cleanup0;
}
hmc = HMC_1610; hmc = HMC_1610;
switch (hmc) { switch (hmc) {
case 0: /* POWERUP DEFAULT == 0 */
case 4:
case 12:
case 20:
if (!cpu_is_omap1710()) {
type = "integrated";
break;
}
/* FALL THROUGH */
case 3: case 3:
case 11: case 11:
case 16: case 16:
case 19: case 19:
case 25: case 25:
xceiv = otg_get_transceiver();
if (!xceiv) { if (!xceiv) {
DBG("external transceiver not registered!\n"); DBG("external transceiver not registered!\n");
if (config->otg) type = "unknown";
goto cleanup0; }
type = "(unknown external)";
} else
type = xceiv->label;
break;
case 0: /* POWERUP DEFAULT == 0 */
case 4:
case 12:
case 20:
type = "INTEGRATED";
break; break;
case 21: /* internal loopback */ case 21: /* internal loopback */
type = "(loopback)"; type = "loopback";
break; break;
case 14: /* transceiverless */ case 14: /* transceiverless */
type = "(none)"; if (cpu_is_omap1710())
goto bad_on_1710;
/* FALL THROUGH */
case 13:
case 15:
type = "no";
break; break;
default: default:
bad_on_1710:
ERR("unrecognized UDC HMC mode %d\n", hmc); ERR("unrecognized UDC HMC mode %d\n", hmc);
return -ENODEV; goto cleanup0;
} }
} }
INFO("hmc mode %d, transceiver %s\n", hmc, type); INFO("hmc mode %d, %s transceiver\n", hmc, type);
/* a "gadget" abstracts/virtualizes the controller */ /* a "gadget" abstracts/virtualizes the controller */
status = omap_udc_setup(odev, xceiv); status = omap_udc_setup(odev, xceiv);
if (status) { if (status) {
goto cleanup0; goto cleanup0;
} }
xceiv = 0; xceiv = NULL;
// "udc" is now valid // "udc" is now valid
pullup_disable(udc); pullup_disable(udc);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
udc->gadget.is_otg = (config->otg != 0); udc->gadget.is_otg = (config->otg != 0);
#endif #endif
/* starting with omap1710 es2.0, clear toggle is a separate bit */
if (UDC_REV_REG >= 0x61)
udc->clr_halt = UDC_RESET_EP | UDC_CLRDATA_TOGGLE;
else
udc->clr_halt = UDC_RESET_EP;
/* USB general purpose IRQ: ep0, state changes, dma, etc */ /* USB general purpose IRQ: ep0, state changes, dma, etc */
status = request_irq(odev->resource[1].start, omap_udc_irq, status = request_irq(odev->resource[1].start, omap_udc_irq,
SA_SAMPLE_RANDOM, driver_name, udc); SA_SAMPLE_RANDOM, driver_name, udc);
...@@ -2765,7 +2855,7 @@ cleanup2: ...@@ -2765,7 +2855,7 @@ cleanup2:
cleanup1: cleanup1:
kfree (udc); kfree (udc);
udc = 0; udc = NULL;
cleanup0: cleanup0:
if (xceiv) if (xceiv)
...@@ -2788,7 +2878,7 @@ static int __exit omap_udc_remove(struct device *dev) ...@@ -2788,7 +2878,7 @@ static int __exit omap_udc_remove(struct device *dev)
pullup_disable(udc); pullup_disable(udc);
if (udc->transceiver) { if (udc->transceiver) {
put_device(udc->transceiver->dev); put_device(udc->transceiver->dev);
udc->transceiver = 0; udc->transceiver = NULL;
} }
UDC_SYSCON1_REG = 0; UDC_SYSCON1_REG = 0;
...@@ -2809,13 +2899,33 @@ static int __exit omap_udc_remove(struct device *dev) ...@@ -2809,13 +2899,33 @@ static int __exit omap_udc_remove(struct device *dev)
return 0; return 0;
} }
static int omap_udc_suspend(struct device *dev, pm_message_t state, u32 level) /* suspend/resume/wakeup from sysfs (echo > power/state) or when the
* system is forced into deep sleep
*
* REVISIT we should probably reject suspend requests when there's a host
* session active, rather than disconnecting, at least on boards that can
* report VBUS irqs (UDC_DEVSTAT_REG.UDC_ATT). And in any case, we need to
* make host resumes and VBUS detection trigger OMAP wakeup events; that
* may involve talking to an external transceiver (e.g. isp1301).
*/
static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
{ {
if (level != 0) u32 devstat;
if (level != SUSPEND_POWER_DOWN)
return 0; return 0;
devstat = UDC_DEVSTAT_REG;
DBG("suspend, state %d\n", state); /* we're requesting 48 MHz clock if the pullup is enabled
* (== we're attached to the host) and we're not suspended,
* which would prevent entry to deep sleep...
*/
if ((devstat & UDC_ATT) != 0 && (devstat & UDC_SUS) == 0) {
WARN("session active; suspend requires disconnect\n");
omap_pullup(&udc->gadget, 0); omap_pullup(&udc->gadget, 0);
}
udc->gadget.dev.power.power_state = PMSG_SUSPEND; udc->gadget.dev.power.power_state = PMSG_SUSPEND;
udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND; udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND;
return 0; return 0;
...@@ -2823,12 +2933,10 @@ static int omap_udc_suspend(struct device *dev, pm_message_t state, u32 level) ...@@ -2823,12 +2933,10 @@ static int omap_udc_suspend(struct device *dev, pm_message_t state, u32 level)
static int omap_udc_resume(struct device *dev, u32 level) static int omap_udc_resume(struct device *dev, u32 level)
{ {
if (level != 0) if (level != RESUME_POWER_ON)
return 0; return 0;
DBG("resume + wakeup/SRP\n"); DBG("resume + wakeup/SRP\n");
udc->gadget.dev.parent->power.power_state = PMSG_ON;
udc->gadget.dev.power.power_state = PMSG_ON;
omap_pullup(&udc->gadget, 1); omap_pullup(&udc->gadget, 1);
/* maybe the host would enumerate us if we nudged it */ /* maybe the host would enumerate us if we nudged it */
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */ #define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */
# define UDC_CLR_HALT (1 << 7) # define UDC_CLR_HALT (1 << 7)
# define UDC_SET_HALT (1 << 6) # define UDC_SET_HALT (1 << 6)
# define UDC_CLRDATA_TOGGLE (1 << 3)
# define UDC_SET_FIFO_EN (1 << 2) # define UDC_SET_FIFO_EN (1 << 2)
# define UDC_CLR_EP (1 << 1) # define UDC_CLR_EP (1 << 1)
# define UDC_RESET_EP (1 << 0) # define UDC_RESET_EP (1 << 0)
...@@ -99,6 +100,7 @@ ...@@ -99,6 +100,7 @@
/* DMA configuration registers: up to three channels in each direction. */ /* DMA configuration registers: up to three channels in each direction. */
#define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */ #define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */
# define UDC_DMA_REQ (1 << 12)
#define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */ #define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */
#define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */ #define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */
...@@ -162,6 +164,7 @@ struct omap_udc { ...@@ -162,6 +164,7 @@ struct omap_udc {
spinlock_t lock; spinlock_t lock;
struct omap_ep ep[32]; struct omap_ep ep[32];
u16 devstat; u16 devstat;
u16 clr_halt;
struct otg_transceiver *transceiver; struct otg_transceiver *transceiver;
struct list_head iso; struct list_head iso;
unsigned softconnect:1; unsigned softconnect:1;
...@@ -171,7 +174,6 @@ struct omap_udc { ...@@ -171,7 +174,6 @@ struct omap_udc {
unsigned ep0_set_config:1; unsigned ep0_set_config:1;
unsigned ep0_reset_config:1; unsigned ep0_reset_config:1;
unsigned ep0_setup:1; unsigned ep0_setup:1;
struct completion *done; struct completion *done;
}; };
......
...@@ -67,11 +67,11 @@ static struct clk *usb_host_ck; ...@@ -67,11 +67,11 @@ static struct clk *usb_host_ck;
static void omap_ohci_clock_power(int on) static void omap_ohci_clock_power(int on)
{ {
if (on) { if (on) {
clk_enable(usb_host_ck); clk_use(usb_host_ck);
/* guesstimate for T5 == 1x 32K clock + APLL lock time */ /* guesstimate for T5 == 1x 32K clock + APLL lock time */
udelay(100); udelay(100);
} else { } else {
clk_disable(usb_host_ck); clk_unuse(usb_host_ck);
} }
} }
...@@ -100,6 +100,7 @@ static int omap_ohci_transceiver_power(int on) ...@@ -100,6 +100,7 @@ static int omap_ohci_transceiver_power(int on)
return 0; return 0;
} }
#ifdef CONFIG_ARCH_OMAP1510
/* /*
* OMAP-1510 specific Local Bus clock on/off * OMAP-1510 specific Local Bus clock on/off
*/ */
...@@ -149,6 +150,10 @@ static int omap_1510_local_bus_init(void) ...@@ -149,6 +150,10 @@ static int omap_1510_local_bus_init(void)
return 0; return 0;
} }
#else
#define omap_1510_local_bus_power(x) {}
#define omap_1510_local_bus_init() {}
#endif
#ifdef CONFIG_USB_OTG #ifdef CONFIG_USB_OTG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment