Merge tag 'usb-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman: "Here's the big USB patch set for the 3.6-rc1 merge window. Lots of little changes in here, primarily for gadget controllers and drivers. There's some scsi changes that I think also went in through the scsi tree, but they merge just fine. All of these patches have been in the linux-next tree for a while now. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" Fix up trivial conflicts in include/scsi/scsi_device.h (same libata conflict that Jeff had already encountered) * tag 'usb-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (207 commits) usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams usb: Add quirk detection based on interface information usb: s3c-hsotg: Add header file protection macros in s3c-hsotg.h USB: ehci-s5p: Add vbus setup function to the s5p ehci glue layer USB: add USB_VENDOR_AND_INTERFACE_INFO() macro USB: notify phy when root hub port connect change USB: remove 8 bytes of padding from usb_host_interface on 64 bit builds USB: option: add ZTE MF821D USB: sierra: QMI mode MC7710 moved to qcserial USB: qcserial: adding Sierra Wireless devices USB: qcserial: support generic Qualcomm serial ports USB: qcserial: make probe more flexible USB: qcserial: centralize probe exit path USB: qcserial: consolidate usb_set_interface calls USB: ehci-s5p: Add support for device tree USB: ohci-exynos: Add support for device tree USB: ehci-omap: fix compile failure(v1) usb: host: tegra: pass correct pointer in ehci_setup() USB: ehci-fsl: Update ifdef check to work on 64-bit ppc USB: serial: keyspan: Removed unrequired parentheses. ...
This commit is contained in:
@@ -35,10 +35,11 @@
|
||||
#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>
|
||||
@@ -60,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
|
||||
@@ -88,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;
|
||||
@@ -103,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 */
|
||||
@@ -112,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;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@@ -251,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);
|
||||
@@ -272,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;
|
||||
}
|
||||
|
||||
@@ -284,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);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -293,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);
|
||||
@@ -302,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)
|
||||
@@ -365,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;
|
||||
@@ -430,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;
|
||||
@@ -537,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,
|
||||
@@ -601,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);
|
||||
@@ -684,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);
|
||||
@@ -703,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);
|
||||
@@ -761,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) {
|
||||
@@ -781,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) {
|
||||
@@ -809,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);
|
||||
}
|
||||
|
||||
@@ -929,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;
|
||||
@@ -945,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);
|
||||
@@ -985,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;
|
||||
}
|
||||
@@ -1012,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);
|
||||
@@ -1024,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;
|
||||
@@ -1072,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;
|
||||
}
|
||||
@@ -1179,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 */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -1212,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);
|
||||
@@ -1344,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;
|
||||
}
|
||||
@@ -1410,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);
|
||||
}
|
||||
|
||||
@@ -1526,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;
|
||||
@@ -1659,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);
|
||||
@@ -1750,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;
|
||||
}
|
||||
@@ -1793,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);
|
||||
@@ -1827,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);
|
||||
@@ -1838,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
|
||||
@@ -2030,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;
|
||||
|
||||
@@ -2089,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,
|
||||
@@ -2111,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;
|
||||
@@ -2123,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;
|
||||
@@ -2155,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;
|
||||
}
|
||||
@@ -2169,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;
|
||||
@@ -2202,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);
|
||||
@@ -2230,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)
|
||||
{
|
||||
@@ -2252,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 " : "",
|
||||
@@ -2273,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]) {
|
||||
@@ -2294,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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2308,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);
|
||||
@@ -2333,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" : "",
|
||||
@@ -2400,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())
|
||||
@@ -2423,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)) {
|
||||
@@ -2507,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);
|
||||
@@ -2558,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)
|
||||
{
|
||||
@@ -2576,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;
|
||||
@@ -2592,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;
|
||||
@@ -2640,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;
|
||||
}
|
||||
@@ -2648,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;
|
||||
@@ -2666,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;
|
||||
@@ -2702,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);
|
||||
|
||||
@@ -2789,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,
|
||||
@@ -2817,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");
|
||||
@@ -2866,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");
|
||||
@@ -2876,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:
|
||||
@@ -2899,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";
|
||||
}
|
||||
@@ -2922,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);
|
||||
@@ -2945,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);
|
||||
@@ -2954,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);
|
||||
@@ -2976,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)
|
||||
@@ -3007,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);
|
||||
@@ -3027,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);
|
||||
|
||||
@@ -3041,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);
|
||||
@@ -3112,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 = {
|
||||
@@ -3121,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");
|
||||
|
Reference in New Issue
Block a user