aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/omap_udc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/omap_udc.c')
-rw-r--r--drivers/usb/gadget/omap_udc.c598
1 files changed, 244 insertions, 354 deletions
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index f81e4f025f2..2ae4f6d69f7 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -10,15 +10,6 @@
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#undef DEBUG
@@ -31,7 +22,6 @@
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
@@ -44,17 +34,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/system.h>
#include <asm/unaligned.h>
#include <asm/mach-types.h>
-#include <plat/dma.h>
-#include <plat/usb.h>
-#include <plat/control.h>
+#include <linux/omap-dma.h>
+
+#include <mach/usb.h>
#include "omap_udc.h"
@@ -69,10 +60,8 @@
#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))
+#define OMAP_DMA_USB_W2FC_TX0 29
+#define OMAP_DMA_USB_W2FC_RX0 26
/*
* The OMAP UDC needs _very_ early endpoint setup: before enabling the
@@ -97,23 +86,23 @@
#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 unsigned use_dma = 1;
+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 */
@@ -121,8 +110,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;
/*-------------------------------------------------------------------------*/
@@ -163,18 +152,17 @@ static int omap_ep_enable(struct usb_ep *_ep,
u16 maxp;
/* catch various bogus parameters */
- if (!_ep || !desc || ep->desc
+ if (!_ep || !desc
|| desc->bDescriptorType != USB_DT_ENDPOINT
|| ep->bEndpointAddress != desc->bEndpointAddress
- || ep->maxpacket < le16_to_cpu
- (desc->wMaxPacketSize)) {
+ || ep->maxpacket < usb_endpoint_maxp(desc)) {
DBG("%s, bad ep or descriptor\n", __func__);
return -EINVAL;
}
- maxp = le16_to_cpu (desc->wMaxPacketSize);
+ maxp = usb_endpoint_maxp(desc);
if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
&& maxp != ep->maxpacket)
- || le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket
+ || usb_endpoint_maxp(desc) > ep->maxpacket
|| !desc->wMaxPacketSize) {
DBG("%s, bad %s maxpacket\n", __func__, _ep->name);
return -ERANGE;
@@ -211,7 +199,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
spin_lock_irqsave(&udc->lock, flags);
- ep->desc = desc;
+ ep->ep.desc = desc;
ep->irqs = 0;
ep->stopped = 0;
ep->ep.maxpacket = maxp;
@@ -253,15 +241,15 @@ static int omap_ep_disable(struct usb_ep *_ep)
struct omap_ep *ep = container_of(_ep, struct omap_ep, ep);
unsigned long flags;
- if (!_ep || !ep->desc) {
+ if (!_ep || !ep->ep.desc) {
DBG("%s, %s not enabled\n", __func__,
_ep ? ep->ep.name : NULL);
return -EINVAL;
}
spin_lock_irqsave(&ep->udc->lock, flags);
- ep->desc = NULL;
- nuke (ep, -ESHUTDOWN);
+ ep->ep.desc = NULL;
+ nuke(ep, -ESHUTDOWN);
ep->ep.maxpacket = ep->maxpacket;
ep->has_dma = 0;
omap_writew(UDC_SET_HALT, UDC_CTRL);
@@ -282,10 +270,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;
}
@@ -294,8 +283,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);
}
/*-------------------------------------------------------------------------*/
@@ -303,6 +291,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);
@@ -312,22 +301,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)
@@ -375,10 +351,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;
@@ -440,7 +416,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;
@@ -547,12 +523,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,
@@ -611,28 +583,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);
@@ -694,7 +652,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);
@@ -713,7 +671,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);
@@ -771,10 +729,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) {
@@ -791,11 +746,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) {
@@ -819,7 +770,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);
}
@@ -927,7 +878,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
DBG("%s, bad params\n", __func__);
return -EINVAL;
}
- if (!_ep || (!ep->desc && ep->bEndpointAddress)) {
+ if (!_ep || (!ep->ep.desc && ep->bEndpointAddress)) {
DBG("%s, bad ep\n", __func__);
return -EINVAL;
}
@@ -939,13 +890,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;
@@ -955,26 +904,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);
@@ -995,7 +927,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;
}
@@ -1022,7 +954,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);
@@ -1034,7 +967,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;
@@ -1082,7 +1016,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;
}
@@ -1131,7 +1065,7 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value)
status = 0;
/* otherwise, all active non-ISO endpoints can halt */
- } else if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && ep->desc) {
+ } else if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && ep->ep.desc) {
/* IN endpoints must already be idle */
if ((ep->bEndpointAddress & USB_DIR_IN)
@@ -1189,8 +1123,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 */
};
/*-------------------------------------------------------------------------*/
@@ -1222,8 +1156,8 @@ 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)
- retval = otg_start_srp(udc->transceiver);
+ if (!IS_ERR_OR_NULL(udc->transceiver))
+ retval = otg_start_srp(udc->transceiver->otg);
}
spin_unlock_irqrestore(&udc->lock, flags);
@@ -1354,8 +1288,8 @@ 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)
- return otg_set_power(udc->transceiver, mA);
+ if (!IS_ERR_OR_NULL(udc->transceiver))
+ return usb_phy_set_power(udc->transceiver, mA);
return -EOPNOTSUPP;
}
@@ -1375,13 +1309,20 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on)
return 0;
}
-static struct usb_gadget_ops omap_gadget_ops = {
+static int omap_udc_start(struct usb_gadget *g,
+ struct usb_gadget_driver *driver);
+static int omap_udc_stop(struct usb_gadget *g,
+ struct usb_gadget_driver *driver);
+
+static const struct usb_gadget_ops omap_gadget_ops = {
.get_frame = omap_get_frame,
.wakeup = omap_wakeup,
.set_selfpowered = omap_set_selfpowered,
.vbus_session = omap_vbus_session,
.vbus_draw = omap_vbus_draw,
.pullup = omap_pullup,
+ .udc_start = omap_udc_start,
+ .udc_stop = omap_udc_stop,
};
/*-------------------------------------------------------------------------*/
@@ -1414,7 +1355,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);
}
@@ -1530,7 +1471,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;
@@ -1629,7 +1571,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
if (w_index & USB_DIR_IN)
ep += 16;
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
- || !ep->desc)
+ || !ep->ep.desc)
goto do_stall;
use_ep(ep, 0);
omap_writew(udc->clr_halt, UDC_CTRL);
@@ -1657,13 +1599,13 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
if (w_index & USB_DIR_IN)
ep += 16;
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
- || ep == ep0 || !ep->desc)
+ || ep == ep0 || !ep->ep.desc)
goto do_stall;
if (use_dma && ep->has_dma) {
/* 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);
@@ -1692,7 +1634,7 @@ ep0out_status_stage:
ep = &udc->ep[w_index & 0xf];
if (w_index & USB_DIR_IN)
ep += 16;
- if (!ep->desc)
+ if (!ep->ep.desc)
goto do_stall;
/* iso never stalls */
@@ -1754,7 +1696,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;
}
@@ -1797,12 +1739,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);
@@ -1831,7 +1773,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);
@@ -1842,12 +1784,14 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
udc->driver->suspend(&udc->gadget);
spin_lock(&udc->lock);
}
- if (udc->transceiver)
- otg_set_suspend(udc->transceiver, 1);
+ if (!IS_ERR_OR_NULL(udc->transceiver))
+ usb_phy_set_suspend(
+ udc->transceiver, 1);
} else {
VDBG("resume\n");
- if (udc->transceiver)
- otg_set_suspend(udc->transceiver, 0);
+ if (!IS_ERR_OR_NULL(udc->transceiver))
+ usb_phy_set_suspend(
+ udc->transceiver, 0);
if (udc->gadget.speed == USB_SPEED_FULL
&& udc->driver->resume) {
spin_unlock(&udc->lock);
@@ -2032,7 +1976,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;
@@ -2091,41 +2035,24 @@ 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();
}
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+static int omap_udc_start(struct usb_gadget *g,
+ struct usb_gadget_driver *driver)
{
int status = -ENODEV;
struct omap_ep *ep;
unsigned long flags;
- /* basic sanity tests */
- if (!udc)
- return -ENODEV;
- if (!driver
- // FIXME if otg, check: driver->is_otg
- || driver->speed < USB_SPEED_FULL
- || !driver->bind
- || !driver->setup)
- return -EINVAL;
spin_lock_irqsave(&udc->lock, flags);
- if (udc->driver) {
- spin_unlock_irqrestore(&udc->lock, flags);
- return -EBUSY;
- }
-
/* 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;
@@ -2139,40 +2066,30 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
/* hook up the driver */
driver->driver.bus = NULL;
udc->driver = driver;
- udc->gadget.dev.driver = &driver->driver;
spin_unlock_irqrestore(&udc->lock, flags);
if (udc->dc_clk != NULL)
omap_udc_enable_clock(1);
- status = driver->bind (&udc->gadget);
- if (status) {
- DBG("bind to %s --> %d\n", driver->driver.name, status);
- udc->gadget.dev.driver = NULL;
- udc->driver = NULL;
- goto done;
- }
- DBG("bound to driver %s\n", driver->driver.name);
-
omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC);
/* connect to bus through transceiver */
- if (udc->transceiver) {
- status = otg_set_peripheral(udc->transceiver, &udc->gadget);
+ 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);
- udc->gadget.dev.driver = NULL;
+ driver->unbind(&udc->gadget);
udc->driver = NULL;
}
goto done;
}
} 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;
@@ -2184,28 +2101,24 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
done:
if (udc->dc_clk != NULL)
omap_udc_enable_clock(0);
+
return status;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
-int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+static int omap_udc_stop(struct usb_gadget *g,
+ struct usb_gadget_driver *driver)
{
unsigned long flags;
int status = -ENODEV;
- if (!udc)
- return -ENODEV;
- if (!driver || driver != udc->driver || !driver->unbind)
- return -EINVAL;
-
if (udc->dc_clk != NULL)
omap_udc_enable_clock(1);
if (machine_without_vbus_sense())
omap_vbus_session(&udc->gadget, 0);
- if (udc->transceiver)
- (void) otg_set_peripheral(udc->transceiver, NULL);
+ if (!IS_ERR_OR_NULL(udc->transceiver))
+ (void) otg_set_peripheral(udc->transceiver->otg, NULL);
else
pullup_disable(udc);
@@ -2213,17 +2126,13 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
udc_quiesce(udc);
spin_unlock_irqrestore(&udc->lock, flags);
- driver->unbind(&udc->gadget);
- udc->gadget.dev.driver = NULL;
udc->driver = NULL;
if (udc->dc_clk != NULL)
omap_udc_enable_clock(0);
- DBG("unregistered driver '%s'\n", driver->driver.name);
+
return status;
}
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
/*-------------------------------------------------------------------------*/
@@ -2234,7 +2143,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_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)
{
@@ -2256,12 +2165,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 " : "",
@@ -2277,10 +2195,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]) {
@@ -2298,35 +2216,28 @@ 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";
}
}
static int proc_otg_show(struct seq_file *s)
{
u32 tmp;
- u32 trans;
- char *ctrl_name;
+ u32 trans = 0;
+ char *ctrl_name = "(UNKNOWN)";
tmp = omap_readl(OTG_REV);
- if (cpu_is_omap24xx()) {
- /*
- * REVISIT: Not clear how this works on OMAP2. trans
- * is ANDed to produce bits 7 and 8, which might make
- * sense for USB_TRANSCEIVER_CTRL on OMAP1,
- * but with CONTROL_DEVCONF, these bits have something to
- * do with the frame adjustment counter and McBSP2.
- */
- ctrl_name = "control_devconf";
- trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- } else {
- 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);
@@ -2346,7 +2257,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" : "",
@@ -2413,14 +2324,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())
@@ -2436,7 +2345,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)) {
@@ -2520,9 +2429,9 @@ 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->desc)
+ if (ep->ep.desc)
proc_ep_show(s, ep);
}
}
@@ -2571,7 +2480,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
omap_ep_setup(char *name, u8 addr, u8 type,
unsigned buf, unsigned maxp, int dbuf)
{
@@ -2589,14 +2498,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;
@@ -2605,15 +2529,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;
@@ -2652,8 +2585,9 @@ 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);
+ ep->maxpacket = maxp;
+ usb_ep_set_maxpacket_limit(&ep->ep, ep->maxpacket);
+ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
return buf;
}
@@ -2661,12 +2595,12 @@ 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
-omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
+static int
+omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv)
{
unsigned tmp, buf;
@@ -2679,28 +2613,21 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *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;
INIT_LIST_HEAD(&udc->gadget.ep_list);
INIT_LIST_HEAD(&udc->iso);
udc->gadget.speed = USB_SPEED_UNKNOWN;
+ udc->gadget.max_speed = USB_SPEED_FULL;
udc->gadget.name = driver_name;
-
- device_initialize(&udc->gadget.dev);
- dev_set_name(&udc->gadget.dev, "gadget");
- udc->gadget.dev.release = omap_udc_release;
- udc->gadget.dev.parent = &odev->dev;
- if (use_dma)
- udc->gadget.dev.dma_mask = odev->dev.dma_mask;
-
udc->transceiver = xceiv;
/* ep0 is special; put it right after the SETUP buffer */
@@ -2714,13 +2641,13 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *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);
@@ -2801,15 +2728,18 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
return 0;
}
-static int __init omap_udc_probe(struct platform_device *pdev)
+static int omap_udc_probe(struct platform_device *pdev)
{
int status = -ENODEV;
int hmc;
- struct otg_transceiver *xceiv = NULL;
+ 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 omap_usb_config *config = dev_get_platdata(&pdev->dev);
+ 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,
@@ -2829,16 +2759,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");
@@ -2878,8 +2798,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 = otg_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");
@@ -2888,14 +2808,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:
@@ -2911,7 +2823,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";
}
@@ -2934,16 +2846,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);
@@ -2957,7 +2869,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);
@@ -2966,7 +2878,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);
@@ -2974,7 +2886,7 @@ known:
}
#ifdef USE_ISO
status = request_irq(pdev->resource[3].start, omap_udc_iso_irq,
- IRQF_DISABLED, "omap_udc iso", udc);
+ 0, "omap_udc iso", udc);
if (status != 0) {
ERR("can't get irq %d, err %d\n",
(int) pdev->resource[3].start, status);
@@ -2988,21 +2900,17 @@ 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)
- return status;
- /* If fail, fall through */
+ status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
+ omap_udc_release);
+ if (status)
+ goto cleanup4;
+
+ return 0;
+
+cleanup4:
+ remove_proc_file();
+
#ifdef USE_ISO
cleanup3:
free_irq(pdev->resource[2].start, udc);
@@ -3012,14 +2920,14 @@ cleanup2:
free_irq(pdev->resource[1].start, udc);
cleanup1:
- kfree (udc);
+ kfree(udc);
udc = NULL;
cleanup0:
- if (xceiv)
- otg_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);
@@ -3032,20 +2940,22 @@ cleanup0:
return status;
}
-static int __exit omap_udc_remove(struct platform_device *pdev)
+static int omap_udc_remove(struct platform_device *pdev)
{
DECLARE_COMPLETION_ONSTACK(done);
if (!udc)
return -ENODEV;
+
+ usb_del_gadget_udc(&udc->gadget);
if (udc->driver)
return -EBUSY;
udc->done = &done;
pullup_disable(udc);
- if (udc->transceiver) {
- otg_put_transceiver(udc->transceiver);
+ if (!IS_ERR_OR_NULL(udc->transceiver)) {
+ usb_put_phy(udc->transceiver);
udc->transceiver = NULL;
}
omap_writew(0, UDC_SYSCON1);
@@ -3068,7 +2978,6 @@ static int __exit omap_udc_remove(struct platform_device *pdev)
release_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1);
- device_unregister(&udc->gadget.dev);
wait_for_completion(&done);
return 0;
@@ -3115,7 +3024,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 = omap_udc_remove,
.suspend = omap_udc_suspend,
.resume = omap_udc_resume,
.driver = {
@@ -3124,27 +3034,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");