diff options
Diffstat (limited to 'drivers/usb/gadget/omap_udc.c')
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 437 |
1 files changed, 183 insertions, 254 deletions
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index a460e8c204f4..f9132ada53b5 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -35,16 +35,18 @@ #include <linux/usb/otg.h> #include <linux/dma-mapping.h> #include <linux/clk.h> +#include <linux/err.h> #include <linux/prefetch.h> +#include <linux/io.h> #include <asm/byteorder.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/unaligned.h> #include <asm/mach-types.h> #include <plat/dma.h> -#include <plat/usb.h> + +#include <mach/usb.h> #include "omap_udc.h" @@ -59,11 +61,6 @@ #define DRIVER_DESC "OMAP UDC driver" #define DRIVER_VERSION "4 October 2004" -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - -#define OMAP2_DMA_CH(ch) (((ch) - 1) << 1) -#define OMAP24XX_DMA(name, ch) (OMAP24XX_DMA_##name + OMAP2_DMA_CH(ch)) - /* * The OMAP UDC needs _very_ early endpoint setup: before enabling the * D+ pullup to allow enumeration. That's too early for the gadget @@ -87,14 +84,14 @@ #ifdef USE_ISO static unsigned fifo_mode = 3; #else -static unsigned fifo_mode = 0; +static unsigned fifo_mode; #endif /* "modprobe omap_udc fifo_mode=42", or else as a kernel * boot parameter "omap_udc:fifo_mode=42" */ -module_param (fifo_mode, uint, 0); -MODULE_PARM_DESC (fifo_mode, "endpoint configuration"); +module_param(fifo_mode, uint, 0); +MODULE_PARM_DESC(fifo_mode, "endpoint configuration"); #ifdef USE_DMA static bool use_dma = 1; @@ -102,8 +99,8 @@ static bool use_dma = 1; /* "modprobe omap_udc use_dma=y", or else as a kernel * boot parameter "omap_udc:use_dma=y" */ -module_param (use_dma, bool, 0); -MODULE_PARM_DESC (use_dma, "enable/disable DMA"); +module_param(use_dma, bool, 0); +MODULE_PARM_DESC(use_dma, "enable/disable DMA"); #else /* !USE_DMA */ /* save a bit of code */ @@ -111,8 +108,8 @@ MODULE_PARM_DESC (use_dma, "enable/disable DMA"); #endif /* !USE_DMA */ -static const char driver_name [] = "omap_udc"; -static const char driver_desc [] = DRIVER_DESC; +static const char driver_name[] = "omap_udc"; +static const char driver_desc[] = DRIVER_DESC; /*-------------------------------------------------------------------------*/ @@ -250,7 +247,7 @@ static int omap_ep_disable(struct usb_ep *_ep) spin_lock_irqsave(&ep->udc->lock, flags); ep->ep.desc = NULL; - nuke (ep, -ESHUTDOWN); + nuke(ep, -ESHUTDOWN); ep->ep.maxpacket = ep->maxpacket; ep->has_dma = 0; omap_writew(UDC_SET_HALT, UDC_CTRL); @@ -271,10 +268,11 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) struct omap_req *req; req = kzalloc(sizeof(*req), gfp_flags); - if (req) { - req->req.dma = DMA_ADDR_INVALID; - INIT_LIST_HEAD (&req->queue); - } + if (!req) + return NULL; + + INIT_LIST_HEAD(&req->queue); + return &req->req; } @@ -283,8 +281,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) { struct omap_req *req = container_of(_req, struct omap_req, req); - if (_req) - kfree (req); + kfree(req); } /*-------------------------------------------------------------------------*/ @@ -292,6 +289,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) static void done(struct omap_ep *ep, struct omap_req *req, int status) { + struct omap_udc *udc = ep->udc; unsigned stopped = ep->stopped; list_del_init(&req->queue); @@ -301,22 +299,9 @@ done(struct omap_ep *ep, struct omap_req *req, int status) else status = req->req.status; - if (use_dma && ep->has_dma) { - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - } + if (use_dma && ep->has_dma) + usb_gadget_unmap_request(&udc->gadget, &req->req, + (ep->bEndpointAddress & USB_DIR_IN)); #ifndef USB_TRACE if (status && status != -ESHUTDOWN) @@ -364,10 +349,10 @@ write_packet(u8 *buf, struct omap_req *req, unsigned max) return len; } -// FIXME change r/w fifo calling convention +/* FIXME change r/w fifo calling convention */ -// return: 0 = still running, 1 = completed, negative = errno +/* return: 0 = still running, 1 = completed, negative = errno */ static int write_fifo(struct omap_ep *ep, struct omap_req *req) { u8 *buf; @@ -429,7 +414,7 @@ read_packet(u8 *buf, struct omap_req *req, unsigned avail) return len; } -// return: 0 = still running, 1 = queue empty, negative = errno +/* return: 0 = still running, 1 = queue empty, negative = errno */ static int read_fifo(struct omap_ep *ep, struct omap_req *req) { u8 *buf; @@ -536,12 +521,8 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) : OMAP_DMA_SYNC_ELEMENT; int dma_trigger = 0; - if (cpu_is_omap24xx()) - dma_trigger = OMAP24XX_DMA(USB_W2FC_TX0, ep->dma_channel); - /* measure length in either bytes or packets */ if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) - || (cpu_is_omap24xx() && length < ep->maxpacket) || (cpu_is_omap15xx() && length < ep->maxpacket)) { txdma_ctrl = UDC_TXN_EOT | length; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, @@ -600,28 +581,14 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) int dma_trigger = 0; u16 w; - if (cpu_is_omap24xx()) - dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); - - /* NOTE: we filtered out "short reads" before, so we know - * the buffer has only whole numbers of packets. - * except MODE SELECT(6) sent the 24 bytes data in OMAP24XX DMA mode - */ - if (cpu_is_omap24xx() && packets < ep->maxpacket) { - omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, - packets, 1, OMAP_DMA_SYNC_ELEMENT, - dma_trigger, 0); - req->dma_bytes = packets; - } else { - /* set up this DMA transfer, enable the fifo, start */ - packets /= ep->ep.maxpacket; - packets = min(packets, (unsigned)UDC_RXN_TC + 1); - req->dma_bytes = packets * ep->ep.maxpacket; - omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, - ep->ep.maxpacket >> 1, packets, - OMAP_DMA_SYNC_ELEMENT, - dma_trigger, 0); - } + /* set up this DMA transfer, enable the fifo, start */ + packets /= ep->ep.maxpacket; + packets = min(packets, (unsigned)UDC_RXN_TC + 1); + req->dma_bytes = packets * ep->ep.maxpacket; + omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, + ep->ep.maxpacket >> 1, packets, + OMAP_DMA_SYNC_ELEMENT, + dma_trigger, 0); omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, 0, 0); @@ -683,7 +650,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) } omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC); - if (!list_empty (&ep->queue)) { + if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, struct omap_req, queue); next_in_dma(ep, req); @@ -702,7 +669,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) } omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC); - if (!list_empty (&ep->queue)) { + if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, struct omap_req, queue); next_out_dma(ep, req); @@ -760,10 +727,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) ep->dma_channel = channel; if (is_in) { - if (cpu_is_omap24xx()) - dma_channel = OMAP24XX_DMA(USB_W2FC_TX0, channel); - else - dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; + dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { @@ -780,11 +744,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) 0, 0); } } else { - if (cpu_is_omap24xx()) - dma_channel = OMAP24XX_DMA(USB_W2FC_RX0, channel); - else - dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; - + dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { @@ -808,7 +768,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); /* channel type P: hw synch (fifo) */ - if (cpu_class_is_omap1() && !cpu_is_omap15xx()) + if (!cpu_is_omap15xx()) omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P); } @@ -928,13 +888,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* this isn't bogus, but OMAP DMA isn't the only hardware to * have a hard time with partial packet reads... reject it. - * Except OMAP2 can handle the small packets. */ if (use_dma && ep->has_dma && ep->bEndpointAddress != 0 && (ep->bEndpointAddress & USB_DIR_IN) == 0 - && !cpu_class_is_omap2() && (req->req.length % ep->ep.maxpacket) != 0) { DBG("%s, no partial packet OUT reads\n", __func__); return -EMSGSIZE; @@ -944,26 +902,9 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) return -ESHUTDOWN; - if (use_dma && ep->has_dma) { - if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single( - ep->udc->gadget.dev.parent, - req->req.buf, - req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 1; - } else { - dma_sync_single_for_device( - ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 0; - } - } + if (use_dma && ep->has_dma) + usb_gadget_map_request(&udc->gadget, &req->req, + (ep->bEndpointAddress & USB_DIR_IN)); VDBG("%s queue req %p, len %d buf %p\n", ep->ep.name, _req, _req->length, _req->buf); @@ -984,7 +925,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) int is_in; if (ep->bEndpointAddress == 0) { - if (!udc->ep0_pending || !list_empty (&ep->queue)) { + if (!udc->ep0_pending || !list_empty(&ep->queue)) { spin_unlock_irqrestore(&udc->lock, flags); return -EL2HLT; } @@ -1011,7 +952,8 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) * always an IN ... even for IN transfers, * a weird case which seem to stall OMAP. */ - omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); + omap_writew(UDC_EP_SEL | UDC_EP_DIR, + UDC_EP_NUM); omap_writew(UDC_CLR_EP, UDC_CTRL); omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); omap_writew(UDC_EP_DIR, UDC_EP_NUM); @@ -1023,7 +965,8 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* non-empty DATA stage */ } else if (is_in) { - omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); + omap_writew(UDC_EP_SEL | UDC_EP_DIR, + UDC_EP_NUM); } else { if (udc->ep0_setup) goto irq_wait; @@ -1071,7 +1014,7 @@ static int omap_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) spin_lock_irqsave(&ep->udc->lock, flags); /* make sure it's actually queued on this endpoint */ - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { if (&req->req == _req) break; } @@ -1178,8 +1121,8 @@ static struct usb_ep_ops omap_ep_ops = { .dequeue = omap_ep_dequeue, .set_halt = omap_ep_set_halt, - // fifo_status ... report bytes in fifo - // fifo_flush ... flush fifo + /* fifo_status ... report bytes in fifo */ + /* fifo_flush ... flush fifo */ }; /*-------------------------------------------------------------------------*/ @@ -1211,7 +1154,7 @@ static int omap_wakeup(struct usb_gadget *gadget) /* NOTE: non-OTG systems may use SRP TOO... */ } else if (!(udc->devstat & UDC_ATT)) { - if (udc->transceiver) + if (!IS_ERR_OR_NULL(udc->transceiver)) retval = otg_start_srp(udc->transceiver->otg); } spin_unlock_irqrestore(&udc->lock, flags); @@ -1343,7 +1286,7 @@ static int omap_vbus_draw(struct usb_gadget *gadget, unsigned mA) struct omap_udc *udc; udc = container_of(gadget, struct omap_udc, gadget); - if (udc->transceiver) + if (!IS_ERR_OR_NULL(udc->transceiver)) return usb_phy_set_power(udc->transceiver, mA); return -EOPNOTSUPP; } @@ -1409,7 +1352,7 @@ static void udc_quiesce(struct omap_udc *udc) udc->gadget.speed = USB_SPEED_UNKNOWN; nuke(&udc->ep[0], -ESHUTDOWN); - list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) nuke(ep, -ESHUTDOWN); } @@ -1525,7 +1468,8 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) /* read next OUT packet of request, maybe * reactiviting the fifo; stall on errors. */ - if (!req || (stat = read_fifo(ep0, req)) < 0) { + stat = read_fifo(ep0, req); + if (!req || stat < 0) { omap_writew(UDC_STALL_CMD, UDC_SYSCON2); udc->ep0_pending = 0; stat = 0; @@ -1658,7 +1602,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) /* this has rude side-effects (aborts) and * can't really work if DMA-IN is active */ - DBG("%s host set_halt, NYET \n", ep->name); + DBG("%s host set_halt, NYET\n", ep->name); goto do_stall; } use_ep(ep, 0); @@ -1749,7 +1693,7 @@ delegate: */ udc->ep0_setup = 1; spin_unlock(&udc->lock); - status = udc->driver->setup (&udc->gadget, &u.r); + status = udc->driver->setup(&udc->gadget, &u.r); spin_lock(&udc->lock); udc->ep0_setup = 0; } @@ -1792,12 +1736,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) if (devstat & UDC_ATT) { udc->gadget.speed = USB_SPEED_FULL; VDBG("connect\n"); - if (!udc->transceiver) + if (IS_ERR_OR_NULL(udc->transceiver)) pullup_enable(udc); - // if (driver->connect) call it + /* if (driver->connect) call it */ } else if (udc->gadget.speed != USB_SPEED_UNKNOWN) { udc->gadget.speed = USB_SPEED_UNKNOWN; - if (!udc->transceiver) + if (IS_ERR_OR_NULL(udc->transceiver)) pullup_disable(udc); DBG("disconnect, gadget %s\n", udc->driver->driver.name); @@ -1826,7 +1770,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) } if (change & UDC_SUS) { if (udc->gadget.speed != USB_SPEED_UNKNOWN) { - // FIXME tell isp1301 to suspend/resume (?) + /* FIXME tell isp1301 to suspend/resume (?) */ if (devstat & UDC_SUS) { VDBG("suspend\n"); update_otg(udc); @@ -1837,12 +1781,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) udc->driver->suspend(&udc->gadget); spin_lock(&udc->lock); } - if (udc->transceiver) + if (!IS_ERR_OR_NULL(udc->transceiver)) usb_phy_set_suspend( udc->transceiver, 1); } else { VDBG("resume\n"); - if (udc->transceiver) + if (!IS_ERR_OR_NULL(udc->transceiver)) usb_phy_set_suspend( udc->transceiver, 0); if (udc->gadget.speed == USB_SPEED_FULL @@ -2029,7 +1973,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) spin_lock_irqsave(&udc->lock, flags); /* handle all non-DMA ISO transfers */ - list_for_each_entry (ep, &udc->iso, iso) { + list_for_each_entry(ep, &udc->iso, iso) { u16 stat; struct omap_req *req; @@ -2088,15 +2032,11 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) static inline int machine_without_vbus_sense(void) { - return (machine_is_omap_innovator() + return machine_is_omap_innovator() || machine_is_omap_osk() - || machine_is_omap_apollon() -#ifndef CONFIG_MACH_OMAP_H4_OTG - || machine_is_omap_h4() -#endif || machine_is_sx1() - || cpu_is_omap7xx() /* No known omap7xx boards with vbus sense */ - ); + /* No known omap7xx boards with vbus sense */ + || cpu_is_omap7xx(); } static int omap_udc_start(struct usb_gadget_driver *driver, @@ -2110,7 +2050,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, if (!udc) return -ENODEV; if (!driver - // FIXME if otg, check: driver->is_otg + /* FIXME if otg, check: driver->is_otg */ || driver->max_speed < USB_SPEED_FULL || !bind || !driver->setup) return -EINVAL; @@ -2122,7 +2062,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, } /* reset state */ - list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { ep->irqs = 0; if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) continue; @@ -2154,13 +2094,13 @@ static int omap_udc_start(struct usb_gadget_driver *driver, omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); /* connect to bus through transceiver */ - if (udc->transceiver) { + if (!IS_ERR_OR_NULL(udc->transceiver)) { status = otg_set_peripheral(udc->transceiver->otg, &udc->gadget); if (status < 0) { ERR("can't bind to transceiver\n"); if (driver->unbind) { - driver->unbind (&udc->gadget); + driver->unbind(&udc->gadget); udc->gadget.dev.driver = NULL; udc->driver = NULL; } @@ -2168,9 +2108,9 @@ static int omap_udc_start(struct usb_gadget_driver *driver, } } else { if (can_pullup(udc)) - pullup_enable (udc); + pullup_enable(udc); else - pullup_disable (udc); + pullup_disable(udc); } /* boards that don't have VBUS sensing can't autogate 48MHz; @@ -2201,7 +2141,7 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) if (machine_without_vbus_sense()) omap_vbus_session(&udc->gadget, 0); - if (udc->transceiver) + if (!IS_ERR_OR_NULL(udc->transceiver)) (void) otg_set_peripheral(udc->transceiver->otg, NULL); else pullup_disable(udc); @@ -2229,7 +2169,7 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) static const char proc_filename[] = "driver/udc"; #define FOURBITS "%s%s%s%s" -#define EIGHTBITS FOURBITS FOURBITS +#define EIGHTBITS "%s%s%s%s%s%s%s%s" static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) { @@ -2251,12 +2191,21 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", ep->name, buf, ep->double_buf ? "dbuf " : "", - ({char *s; switch(ep->ackwait){ - case 0: s = ""; break; - case 1: s = "(ackw) "; break; - case 2: s = "(ackw2) "; break; - default: s = "(?) "; break; - } s;}), + ({ char *s; + switch (ep->ackwait) { + case 0: + s = ""; + break; + case 1: + s = "(ackw) "; + break; + case 2: + s = "(ackw2) "; + break; + default: + s = "(?) "; + break; + } s; }), ep->irqs, stat_flg, (stat_flg & UDC_NO_RXPACKET) ? "no_rxpacket " : "", (stat_flg & UDC_MISS_IN) ? "miss_in " : "", @@ -2272,10 +2221,10 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) (stat_flg & UDC_NON_ISO_FIFO_EMPTY) ? "fifo_empty " : "", (stat_flg & UDC_NON_ISO_FIFO_FULL) ? "fifo_full " : ""); - if (list_empty (&ep->queue)) + if (list_empty(&ep->queue)) seq_printf(s, "\t(queue empty)\n"); else - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { unsigned length = req->req.actual; if (use_dma && buf[0]) { @@ -2293,11 +2242,16 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) static char *trx_mode(unsigned m, int enabled) { switch (m) { - case 0: return enabled ? "*6wire" : "unused"; - case 1: return "4wire"; - case 2: return "3wire"; - case 3: return "6wire"; - default: return "unknown"; + case 0: + return enabled ? "*6wire" : "unused"; + case 1: + return "4wire"; + case 2: + return "3wire"; + case 3: + return "6wire"; + default: + return "unknown"; } } @@ -2307,12 +2261,9 @@ static int proc_otg_show(struct seq_file *s) u32 trans = 0; char *ctrl_name = "(UNKNOWN)"; - /* XXX This needs major revision for OMAP2+ */ tmp = omap_readl(OTG_REV); - if (cpu_class_is_omap1()) { - ctrl_name = "tranceiver_ctrl"; - trans = omap_readw(USB_TRANSCEIVER_CTRL); - } + ctrl_name = "tranceiver_ctrl"; + trans = omap_readw(USB_TRANSCEIVER_CTRL); seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", tmp >> 4, tmp & 0xf, ctrl_name, trans); tmp = omap_readw(OTG_SYSCON_1); @@ -2332,7 +2283,7 @@ static int proc_otg_show(struct seq_file *s) " b_ase_brst=%d hmc=%d\n", tmp, (tmp & OTG_EN) ? " otg_en" : "", (tmp & USBX_SYNCHRO) ? " synchro" : "", - // much more SRP stuff + /* much more SRP stuff */ (tmp & SRP_DATA) ? " srp_data" : "", (tmp & SRP_VBUS) ? " srp_vbus" : "", (tmp & OTG_PADEN) ? " otg_paden" : "", @@ -2399,14 +2350,12 @@ static int proc_udc_show(struct seq_file *s, void *_) HMC, udc->transceiver ? udc->transceiver->label - : ((cpu_is_omap1710() || cpu_is_omap24xx()) + : (cpu_is_omap1710() ? "external" : "(none)")); - if (cpu_class_is_omap1()) { - seq_printf(s, "ULPD control %04x req %04x status %04x\n", - omap_readw(ULPD_CLOCK_CTRL), - omap_readw(ULPD_SOFT_REQ), - omap_readw(ULPD_STATUS_REQ)); - } + seq_printf(s, "ULPD control %04x req %04x status %04x\n", + omap_readw(ULPD_CLOCK_CTRL), + omap_readw(ULPD_SOFT_REQ), + omap_readw(ULPD_STATUS_REQ)); /* OTG controller registers */ if (!cpu_is_omap15xx()) @@ -2422,7 +2371,7 @@ static int proc_udc_show(struct seq_file *s, void *_) (tmp & UDC_SELF_PWR) ? " self_pwr" : "", (tmp & UDC_SOFF_DIS) ? " soff_dis" : "", (tmp & UDC_PULLUP_EN) ? " PULLUP" : ""); - // syscon2 is write-only + /* syscon2 is write-only */ /* UDC controller registers */ if (!(tmp & UDC_PULLUP_EN)) { @@ -2506,7 +2455,7 @@ static int proc_udc_show(struct seq_file *s, void *_) if (tmp & UDC_ATT) { proc_ep_show(s, &udc->ep[0]); if (tmp & UDC_ADD) { - list_for_each_entry (ep, &udc->gadget.ep_list, + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { if (ep->ep.desc) proc_ep_show(s, ep); @@ -2557,7 +2506,7 @@ static inline void remove_proc_file(void) {} * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that * capability yet though. */ -static unsigned __init +static unsigned __devinit omap_ep_setup(char *name, u8 addr, u8 type, unsigned buf, unsigned maxp, int dbuf) { @@ -2575,14 +2524,29 @@ omap_ep_setup(char *name, u8 addr, u8 type, /* chip setup ... bit values are same for IN, OUT */ if (type == USB_ENDPOINT_XFER_ISOC) { switch (maxp) { - case 8: epn_rxtx = 0 << 12; break; - case 16: epn_rxtx = 1 << 12; break; - case 32: epn_rxtx = 2 << 12; break; - case 64: epn_rxtx = 3 << 12; break; - case 128: epn_rxtx = 4 << 12; break; - case 256: epn_rxtx = 5 << 12; break; - case 512: epn_rxtx = 6 << 12; break; - default: BUG(); + case 8: + epn_rxtx = 0 << 12; + break; + case 16: + epn_rxtx = 1 << 12; + break; + case 32: + epn_rxtx = 2 << 12; + break; + case 64: + epn_rxtx = 3 << 12; + break; + case 128: + epn_rxtx = 4 << 12; + break; + case 256: + epn_rxtx = 5 << 12; + break; + case 512: + epn_rxtx = 6 << 12; + break; + default: + BUG(); } epn_rxtx |= UDC_EPN_RX_ISO; dbuf = 1; @@ -2591,15 +2555,24 @@ omap_ep_setup(char *name, u8 addr, u8 type, * and ignored for PIO-IN on newer chips * (for more reliable behavior) */ - if (!use_dma || cpu_is_omap15xx() || cpu_is_omap24xx()) + if (!use_dma || cpu_is_omap15xx()) dbuf = 0; switch (maxp) { - case 8: epn_rxtx = 0 << 12; break; - case 16: epn_rxtx = 1 << 12; break; - case 32: epn_rxtx = 2 << 12; break; - case 64: epn_rxtx = 3 << 12; break; - default: BUG(); + case 8: + epn_rxtx = 0 << 12; + break; + case 16: + epn_rxtx = 1 << 12; + break; + case 32: + epn_rxtx = 2 << 12; + break; + case 64: + epn_rxtx = 3 << 12; + break; + default: + BUG(); } if (dbuf && addr) epn_rxtx |= UDC_EPN_RX_DB; @@ -2639,7 +2612,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, ep->ep.name = ep->name; ep->ep.ops = &omap_ep_ops; ep->ep.maxpacket = ep->maxpacket = maxp; - list_add_tail (&ep->ep.ep_list, &udc->gadget.ep_list); + list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); return buf; } @@ -2647,11 +2620,11 @@ omap_ep_setup(char *name, u8 addr, u8 type, static void omap_udc_release(struct device *dev) { complete(udc->done); - kfree (udc); + kfree(udc); udc = NULL; } -static int __init +static int __devinit omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) { unsigned tmp, buf; @@ -2665,13 +2638,13 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) omap_writew(0, UDC_TXDMA_CFG); /* UDC_PULLUP_EN gates the chip clock */ - // OTG_SYSCON_1 |= DEV_IDLE_EN; + /* OTG_SYSCON_1 |= DEV_IDLE_EN; */ udc = kzalloc(sizeof(*udc), GFP_KERNEL); if (!udc) return -ENOMEM; - spin_lock_init (&udc->lock); + spin_lock_init(&udc->lock); udc->gadget.ops = &omap_gadget_ops; udc->gadget.ep0 = &udc->ep[0].ep; @@ -2701,13 +2674,13 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) omap_writew(0, UDC_EP_TX(tmp)); } -#define OMAP_BULK_EP(name,addr) \ +#define OMAP_BULK_EP(name, addr) \ buf = omap_ep_setup(name "-bulk", addr, \ USB_ENDPOINT_XFER_BULK, buf, 64, 1); -#define OMAP_INT_EP(name,addr, maxp) \ +#define OMAP_INT_EP(name, addr, maxp) \ buf = omap_ep_setup(name "-int", addr, \ USB_ENDPOINT_XFER_INT, buf, maxp, 0); -#define OMAP_ISO_EP(name,addr, maxp) \ +#define OMAP_ISO_EP(name, addr, maxp) \ buf = omap_ep_setup(name "-iso", addr, \ USB_ENDPOINT_XFER_ISOC, buf, maxp, 1); @@ -2788,15 +2761,18 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) return 0; } -static int __init omap_udc_probe(struct platform_device *pdev) +static int __devinit omap_udc_probe(struct platform_device *pdev) { int status = -ENODEV; int hmc; struct usb_phy *xceiv = NULL; const char *type = NULL; struct omap_usb_config *config = pdev->dev.platform_data; - struct clk *dc_clk; - struct clk *hhc_clk; + struct clk *dc_clk = NULL; + struct clk *hhc_clk = NULL; + + if (cpu_is_omap7xx()) + use_dma = 0; /* NOTE: "knows" the order of the resources! */ if (!request_mem_region(pdev->resource[0].start, @@ -2816,16 +2792,6 @@ static int __init omap_udc_probe(struct platform_device *pdev) udelay(100); } - if (cpu_is_omap24xx()) { - dc_clk = clk_get(&pdev->dev, "usb_fck"); - hhc_clk = clk_get(&pdev->dev, "usb_l4_ick"); - BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk)); - /* can't use omap_udc_enable_clock yet */ - clk_enable(dc_clk); - clk_enable(hhc_clk); - udelay(100); - } - if (cpu_is_omap7xx()) { dc_clk = clk_get(&pdev->dev, "usb_dc_ck"); hhc_clk = clk_get(&pdev->dev, "l3_ocpi_ck"); @@ -2865,8 +2831,8 @@ static int __init omap_udc_probe(struct platform_device *pdev) * use it. Except for OTG, we don't _need_ to talk to one; * but not having one probably means no VBUS detection. */ - xceiv = usb_get_transceiver(); - if (xceiv) + xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (!IS_ERR_OR_NULL(xceiv)) type = xceiv->label; else if (config->otg) { DBG("OTG requires external transceiver!\n"); @@ -2875,14 +2841,6 @@ static int __init omap_udc_probe(struct platform_device *pdev) hmc = HMC_1610; - if (cpu_is_omap24xx()) { - /* this could be transceiverless in one of the - * "we don't need to know" modes. - */ - type = "external"; - goto known; - } - switch (hmc) { case 0: /* POWERUP DEFAULT == 0 */ case 4: @@ -2898,7 +2856,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) case 16: case 19: case 25: - if (!xceiv) { + if (IS_ERR_OR_NULL(xceiv)) { DBG("external transceiver not registered!\n"); type = "unknown"; } @@ -2921,16 +2879,16 @@ bad_on_1710: goto cleanup0; } } -known: + INFO("hmc mode %d, %s transceiver\n", hmc, type); /* a "gadget" abstracts/virtualizes the controller */ status = omap_udc_setup(pdev, xceiv); - if (status) { + if (status) goto cleanup0; - } + xceiv = NULL; - // "udc" is now valid + /* "udc" is now valid */ pullup_disable(udc); #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) udc->gadget.is_otg = (config->otg != 0); @@ -2944,7 +2902,7 @@ known: /* USB general purpose IRQ: ep0, state changes, dma, etc */ status = request_irq(pdev->resource[1].start, omap_udc_irq, - IRQF_SAMPLE_RANDOM, driver_name, udc); + 0, driver_name, udc); if (status != 0) { ERR("can't get irq %d, err %d\n", (int) pdev->resource[1].start, status); @@ -2953,7 +2911,7 @@ known: /* USB "non-iso" IRQ (PIO for all but ep0) */ status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, - IRQF_SAMPLE_RANDOM, "omap_udc pio", udc); + 0, "omap_udc pio", udc); if (status != 0) { ERR("can't get irq %d, err %d\n", (int) pdev->resource[2].start, status); @@ -2975,16 +2933,6 @@ known: clk_disable(dc_clk); } - if (cpu_is_omap24xx()) { - udc->dc_clk = dc_clk; - udc->hhc_clk = hhc_clk; - /* FIXME OMAP2 don't release hhc & dc clock */ -#if 0 - clk_disable(hhc_clk); - clk_disable(dc_clk); -#endif - } - create_proc_file(); status = device_add(&udc->gadget.dev); if (status) @@ -3006,14 +2954,14 @@ cleanup2: free_irq(pdev->resource[1].start, udc); cleanup1: - kfree (udc); + kfree(udc); udc = NULL; cleanup0: - if (xceiv) - usb_put_transceiver(xceiv); + if (!IS_ERR_OR_NULL(xceiv)) + usb_put_phy(xceiv); - if (cpu_is_omap16xx() || cpu_is_omap24xx() || cpu_is_omap7xx()) { + if (cpu_is_omap16xx() || cpu_is_omap7xx()) { clk_disable(hhc_clk); clk_disable(dc_clk); clk_put(hhc_clk); @@ -3026,7 +2974,7 @@ cleanup0: return status; } -static int __exit omap_udc_remove(struct platform_device *pdev) +static int __devexit omap_udc_remove(struct platform_device *pdev) { DECLARE_COMPLETION_ONSTACK(done); @@ -3040,8 +2988,8 @@ static int __exit omap_udc_remove(struct platform_device *pdev) udc->done = &done; pullup_disable(udc); - if (udc->transceiver) { - usb_put_transceiver(udc->transceiver); + if (!IS_ERR_OR_NULL(udc->transceiver)) { + usb_put_phy(udc->transceiver); udc->transceiver = NULL; } omap_writew(0, UDC_SYSCON1); @@ -3111,7 +3059,8 @@ static int omap_udc_resume(struct platform_device *dev) /*-------------------------------------------------------------------------*/ static struct platform_driver udc_driver = { - .remove = __exit_p(omap_udc_remove), + .probe = omap_udc_probe, + .remove = __devexit_p(omap_udc_remove), .suspend = omap_udc_suspend, .resume = omap_udc_resume, .driver = { @@ -3120,27 +3069,7 @@ static struct platform_driver udc_driver = { }, }; -static int __init udc_init(void) -{ - /* Disable DMA for omap7xx -- it doesn't work right. */ - if (cpu_is_omap7xx()) - use_dma = 0; - - INFO("%s, version: " DRIVER_VERSION -#ifdef USE_ISO - " (iso)" -#endif - "%s\n", driver_desc, - use_dma ? " (dma)" : ""); - return platform_driver_probe(&udc_driver, omap_udc_probe); -} -module_init(udc_init); - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); +module_platform_driver(udc_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); |