mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 07:50:04 +00:00
usb: fixes for v3.4-rc cycle
Here are the fixes I have queued for v3.4-rc cycle so far. It includes fixes on many of the gadget drivers and a few of the UDC controller drivers. For musb we have a fix for a kernel oops when unloading omap2430.ko glue layer, proper error checking for pm_runtime_*, fix for the ULPI transfer block, and a bug fix in musb_cleanup_urb routine. For s3c-hsotg we have mostly FIFO-related fixes (proper TX FIFO allocation, TX FIFO corruption fix in DMA mode) but also a couple of minor fixes (fixing maximum packet size for ep0 and fix for big transfers with DMA). For the dwc3 driver we have a memory leak fix, a very important fix for USB30CV with SetFeature tests and the hability to handle ep0 requests bigger than wMaxPacketSize. On top of that there's a bunch of gadget driver minor fixes adding proper section annotations, and fixing up the sysfs interface for doing device-initiated connect/disconnect and so on. All patches have been pending on the mailing list for quite a while and look good for your for-linus branch. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJPhUWkAAoJEIaOsuA1yqRE8h0P/R5jNluFEzpLA5SLgNFAn4F1 +LkIvB9T/F+UmO5EW4cfQbJ7DgKh92KISIgwSS0+LJEsC05ODWVs1PB1KYj/IgrX D4GxrAz7DhwGlln2ejiSp/Mx3ATRCrUqhd7S4kt+tsCi7As9rBW4eduUTsp8ip5Z kxvivYqKfjjJ8MHHRwo3AkkqCZOIc+JW9lhL7itkYMlmpBLPg8NMusJ32O2+0BfD SK1WOWCladpVjVjoux7QM1y2kZN5XPgwRxLzB/XDK8QbkBukGORPbwiwRnnhHNf5 W/ceKYlCJzj6WdcEUHeDA8b4Sfhu6pbBVjhD3fybMkY0IqcgR3sGDp1eKnXjAbuS 01ALiTKiWlboMhTD4RqnBs17C70kfzRTHfPLZBHi9w04u3jbb5oCmTOgD2gNbb0m 0iHDizMdNVxt25Tcj+mtKNhTYguJ8HoFpQ/bWEHOa/Ra723WPaTd1RFhPLOAgj1K 0V6Rwsi/eb/7CdkCfzOlZe7zixeyLthzG5YbXRMj84XLoD9mBhpMBA21DFpcxizr 1OpZfcgz2LH4WqGZky35Q+BKPma2DA7tLv3VwIRXVkfv9p1ISzIS+Vre/TCHDZWs oXpsZXHBNyCU+saomJnQ/mRJQ4+uSKsqc+WJPe6D3KpwlMi6DtK3OAAnmullMPjx ptHgrZzXZuS/10gc1F7g =Wqlb -----END PGP SIGNATURE----- Merge tag 'fixes-for-v3.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus usb: fixes for v3.4-rc cycle Here are the fixes I have queued for v3.4-rc cycle so far. It includes fixes on many of the gadget drivers and a few of the UDC controller drivers. For musb we have a fix for a kernel oops when unloading omap2430.ko glue layer, proper error checking for pm_runtime_*, fix for the ULPI transfer block, and a bug fix in musb_cleanup_urb routine. For s3c-hsotg we have mostly FIFO-related fixes (proper TX FIFO allocation, TX FIFO corruption fix in DMA mode) but also a couple of minor fixes (fixing maximum packet size for ep0 and fix for big transfers with DMA). For the dwc3 driver we have a memory leak fix, a very important fix for USB30CV with SetFeature tests and the hability to handle ep0 requests bigger than wMaxPacketSize. On top of that there's a bunch of gadget driver minor fixes adding proper section annotations, and fixing up the sysfs interface for doing device-initiated connect/disconnect and so on. All patches have been pending on the mailing list for quite a while and look good for your for-linus branch.
This commit is contained in:
commit
edffaa031e
@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
|
||||
|
||||
for (i = 0; i < dwc->num_event_buffers; i++) {
|
||||
evt = dwc->ev_buffs[i];
|
||||
if (evt) {
|
||||
if (evt)
|
||||
dwc3_free_one_event_buffer(dwc, evt);
|
||||
dwc->ev_buffs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(dwc->ev_buffs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
|
||||
|
||||
dwc->test_mode_nr = wIndex >> 8;
|
||||
dwc->test_mode = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
|
||||
length = trb->size & DWC3_TRB_SIZE_MASK;
|
||||
|
||||
if (dwc->ep0_bounced) {
|
||||
unsigned transfer_size = ur->length;
|
||||
unsigned maxp = ep0->endpoint.maxpacket;
|
||||
|
||||
transfer_size += (maxp - (transfer_size % maxp));
|
||||
transferred = min_t(u32, ur->length,
|
||||
ep0->endpoint.maxpacket - length);
|
||||
transfer_size - length);
|
||||
memcpy(ur->buf, dwc->ep0_bounce, transferred);
|
||||
dwc->ep0_bounced = false;
|
||||
} else {
|
||||
transferred = ur->length - length;
|
||||
ur->actual += transferred;
|
||||
}
|
||||
|
||||
ur->actual += transferred;
|
||||
|
||||
if ((epnum & 1) && ur->actual < ur->length) {
|
||||
/* for some reason we did not get everything out */
|
||||
|
||||
|
@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
|
||||
if (code == FUNCTIONFS_INTERFACE_REVMAP) {
|
||||
struct ffs_function *func = ffs->func;
|
||||
ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
|
||||
} else if (gadget->ops->ioctl) {
|
||||
} else if (gadget && gadget->ops->ioctl) {
|
||||
ret = gadget->ops->ioctl(gadget, code, value);
|
||||
} else {
|
||||
ret = -ENOTTY;
|
||||
@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)
|
||||
ffs->ep0req = NULL;
|
||||
ffs->gadget = NULL;
|
||||
ffs_data_put(ffs);
|
||||
clear_bit(FFS_FL_BOUND, &ffs->flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
|
||||
if (buf) {
|
||||
memcpy(req->buf, buf, n);
|
||||
req->complete = rndis_response_complete;
|
||||
req->context = rndis;
|
||||
rndis_free_response(rndis->config, buf);
|
||||
value = n;
|
||||
}
|
||||
|
@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
|
||||
: (1 << (ep_index(ep)));
|
||||
|
||||
/* check if the pipe is empty */
|
||||
if (!(list_empty(&ep->queue))) {
|
||||
if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
|
||||
/* Add td to the end */
|
||||
struct fsl_req *lastreq;
|
||||
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
|
||||
@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Update ep0 state */
|
||||
if ((ep_index(ep) == 0))
|
||||
udc->ep0_state = DATA_STATE_XMIT;
|
||||
|
||||
/* irq handler advances the queue */
|
||||
if (req != NULL)
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
|
||||
udc->ep0_dir = USB_DIR_OUT;
|
||||
|
||||
ep = &udc->eps[0];
|
||||
udc->ep0_state = WAIT_FOR_OUT_STATUS;
|
||||
if (udc->ep0_state != DATA_STATE_XMIT)
|
||||
udc->ep0_state = WAIT_FOR_OUT_STATUS;
|
||||
|
||||
req->ep = ep;
|
||||
req->req.length = 0;
|
||||
@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
|
||||
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
udc->ep0_state = DATA_STATE_XMIT;
|
||||
if (ep0_prime_status(udc, EP_DIR_OUT))
|
||||
ep0stall(udc);
|
||||
|
||||
return;
|
||||
stall:
|
||||
ep0stall(udc);
|
||||
@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,
|
||||
spin_lock(&udc->lock);
|
||||
udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
|
||||
? DATA_STATE_XMIT : DATA_STATE_RECV;
|
||||
/*
|
||||
* If the data stage is IN, send status prime immediately.
|
||||
* See 2.0 Spec chapter 8.5.3.3 for detail.
|
||||
*/
|
||||
if (udc->ep0_state == DATA_STATE_XMIT)
|
||||
if (ep0_prime_status(udc, EP_DIR_OUT))
|
||||
ep0stall(udc);
|
||||
|
||||
} else {
|
||||
/* No data phase, IN status from gadget */
|
||||
udc->ep0_dir = USB_DIR_IN;
|
||||
@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
|
||||
|
||||
switch (udc->ep0_state) {
|
||||
case DATA_STATE_XMIT:
|
||||
/* receive status phase */
|
||||
if (ep0_prime_status(udc, EP_DIR_OUT))
|
||||
ep0stall(udc);
|
||||
/* already primed at setup_received_irq */
|
||||
udc->ep0_state = WAIT_FOR_OUT_STATUS;
|
||||
break;
|
||||
case DATA_STATE_RECV:
|
||||
/* send status phase */
|
||||
|
@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {
|
||||
static struct ffs_data *gfs_ffs_data;
|
||||
static unsigned long gfs_registered;
|
||||
|
||||
static int gfs_init(void)
|
||||
static int __init gfs_init(void)
|
||||
{
|
||||
ENTER();
|
||||
|
||||
@ -169,7 +169,7 @@ static int gfs_init(void)
|
||||
}
|
||||
module_init(gfs_init);
|
||||
|
||||
static void gfs_exit(void)
|
||||
static void __exit gfs_exit(void)
|
||||
{
|
||||
ENTER();
|
||||
|
||||
|
@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
|
||||
/* currently we allocate TX FIFOs for all possible endpoints,
|
||||
* and assume that they are all the same size. */
|
||||
|
||||
for (ep = 0; ep <= 15; ep++) {
|
||||
for (ep = 1; ep <= 15; ep++) {
|
||||
val = addr;
|
||||
val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
|
||||
addr += size;
|
||||
@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
|
||||
/* write size / packets */
|
||||
writel(epsize, hsotg->regs + epsize_reg);
|
||||
|
||||
if (using_dma(hsotg)) {
|
||||
if (using_dma(hsotg) && !continuing) {
|
||||
unsigned int dma_reg;
|
||||
|
||||
/* write DMA address to control register, buffer already
|
||||
@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
|
||||
reg |= mpsval;
|
||||
writel(reg, regs + S3C_DIEPCTL(ep));
|
||||
|
||||
reg = readl(regs + S3C_DOEPCTL(ep));
|
||||
reg &= ~S3C_DxEPCTL_MPS_MASK;
|
||||
reg |= mpsval;
|
||||
writel(reg, regs + S3C_DOEPCTL(ep));
|
||||
if (ep) {
|
||||
reg = readl(regs + S3C_DOEPCTL(ep));
|
||||
reg &= ~S3C_DxEPCTL_MPS_MASK;
|
||||
reg |= mpsval;
|
||||
writel(reg, regs + S3C_DOEPCTL(ep));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
|
||||
ints & S3C_DIEPMSK_TxFIFOEmpty) {
|
||||
dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
|
||||
__func__, idx);
|
||||
s3c_hsotg_trytx(hsotg, hs_ep);
|
||||
if (!using_dma(hsotg))
|
||||
s3c_hsotg_trytx(hsotg, hs_ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
|
||||
if (udc_is_newstyle(udc)) {
|
||||
udc->driver->disconnect(udc->gadget);
|
||||
udc->driver->unbind(udc->gadget);
|
||||
usb_gadget_udc_stop(udc->gadget, udc->driver);
|
||||
usb_gadget_disconnect(udc->gadget);
|
||||
usb_gadget_udc_stop(udc->gadget, udc->driver);
|
||||
} else {
|
||||
usb_gadget_stop(udc->gadget, udc->driver);
|
||||
}
|
||||
@ -411,8 +411,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
|
||||
struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
|
||||
|
||||
if (sysfs_streq(buf, "connect")) {
|
||||
if (udc_is_newstyle(udc))
|
||||
usb_gadget_udc_start(udc->gadget, udc->driver);
|
||||
usb_gadget_connect(udc->gadget);
|
||||
} else if (sysfs_streq(buf, "disconnect")) {
|
||||
if (udc_is_newstyle(udc))
|
||||
usb_gadget_udc_stop(udc->gadget, udc->driver);
|
||||
usb_gadget_disconnect(udc->gadget);
|
||||
} else {
|
||||
dev_err(dev, "unsupported command '%s'\n", buf);
|
||||
|
@ -543,11 +543,11 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* called with queue->irqlock held.. */
|
||||
static struct uvc_buffer *
|
||||
uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
|
||||
{
|
||||
struct uvc_buffer *nextbuf;
|
||||
unsigned long flags;
|
||||
|
||||
if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
|
||||
buf->buf.length != buf->buf.bytesused) {
|
||||
@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
|
||||
return buf;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&queue->irqlock, flags);
|
||||
list_del(&buf->queue);
|
||||
if (!list_empty(&queue->irqqueue))
|
||||
nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
|
||||
queue);
|
||||
else
|
||||
nextbuf = NULL;
|
||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
||||
|
||||
buf->buf.sequence = queue->sequence++;
|
||||
do_gettimeofday(&buf->buf.timestamp);
|
||||
|
@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
|
||||
int i = 0;
|
||||
u8 r;
|
||||
u8 power;
|
||||
int ret;
|
||||
|
||||
pm_runtime_get_sync(phy->io_dev);
|
||||
|
||||
/* Make sure the transceiver is not in low power mode */
|
||||
power = musb_readb(addr, MUSB_POWER);
|
||||
@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
|
||||
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
|
||||
& MUSB_ULPI_REG_CMPLT)) {
|
||||
i++;
|
||||
if (i == 10000)
|
||||
return -ETIMEDOUT;
|
||||
if (i == 10000) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
}
|
||||
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
|
||||
r &= ~MUSB_ULPI_REG_CMPLT;
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
|
||||
|
||||
return musb_readb(addr, MUSB_ULPI_REG_DATA);
|
||||
ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
|
||||
|
||||
out:
|
||||
pm_runtime_put(phy->io_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
|
||||
@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
|
||||
int i = 0;
|
||||
u8 r = 0;
|
||||
u8 power;
|
||||
int ret = 0;
|
||||
|
||||
pm_runtime_get_sync(phy->io_dev);
|
||||
|
||||
/* Make sure the transceiver is not in low power mode */
|
||||
power = musb_readb(addr, MUSB_POWER);
|
||||
@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
|
||||
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
|
||||
& MUSB_ULPI_REG_CMPLT)) {
|
||||
i++;
|
||||
if (i == 10000)
|
||||
return -ETIMEDOUT;
|
||||
if (i == 10000) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
|
||||
r &= ~MUSB_ULPI_REG_CMPLT;
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
pm_runtime_put(phy->io_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define musb_ulpi_read NULL
|
||||
@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||
|
||||
if (!musb->isr) {
|
||||
status = -ENODEV;
|
||||
goto fail3;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
if (!musb->xceiv->io_ops) {
|
||||
musb->xceiv->io_dev = musb->controller;
|
||||
musb->xceiv->io_priv = musb->mregs;
|
||||
musb->xceiv->io_ops = &musb_ulpi_access;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(musb->controller);
|
||||
|
||||
#ifndef CONFIG_MUSB_PIO_ONLY
|
||||
if (use_dma && dev->dma_mask) {
|
||||
struct dma_controller *c;
|
||||
@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||
goto fail5;
|
||||
#endif
|
||||
|
||||
pm_runtime_put(musb->controller);
|
||||
|
||||
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
|
||||
({char *s;
|
||||
switch (musb->board_mode) {
|
||||
@ -2047,6 +2070,9 @@ fail4:
|
||||
musb_gadget_cleanup(musb);
|
||||
|
||||
fail3:
|
||||
pm_runtime_put_sync(musb->controller);
|
||||
|
||||
fail2:
|
||||
if (musb->irq_wake)
|
||||
device_init_wakeup(dev, 0);
|
||||
musb_platform_exit(musb);
|
||||
|
@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
|
||||
}
|
||||
|
||||
/* turn off DMA requests, discard state, stop polling ... */
|
||||
if (is_in) {
|
||||
if (ep->epnum && is_in) {
|
||||
/* giveback saves bulk toggle */
|
||||
csr = musb_h_flush_rxfifo(ep, 0);
|
||||
|
||||
|
@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
|
||||
|
||||
static int omap2430_musb_init(struct musb *musb)
|
||||
{
|
||||
u32 l, status = 0;
|
||||
u32 l;
|
||||
int status = 0;
|
||||
struct device *dev = musb->controller;
|
||||
struct musb_hdrc_platform_data *plat = dev->platform_data;
|
||||
struct omap_musb_board_data *data = plat->board_data;
|
||||
@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)
|
||||
|
||||
status = pm_runtime_get_sync(dev);
|
||||
if (status < 0) {
|
||||
dev_err(dev, "pm_runtime_get_sync FAILED");
|
||||
dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)
|
||||
|
||||
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
|
||||
|
||||
pm_runtime_put_noidle(musb->controller);
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
|
||||
goto err2;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = platform_device_add(musb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register musb device\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
|
||||
|
||||
platform_device_del(glue->musb);
|
||||
platform_device_put(glue->musb);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
kfree(glue);
|
||||
|
||||
return 0;
|
||||
@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)
|
||||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
struct musb *musb = glue_to_musb(glue);
|
||||
|
||||
musb->context.otg_interfsel = musb_readl(musb->mregs,
|
||||
OTG_INTERFSEL);
|
||||
if (musb) {
|
||||
musb->context.otg_interfsel = musb_readl(musb->mregs,
|
||||
OTG_INTERFSEL);
|
||||
|
||||
omap2430_low_level_exit(musb);
|
||||
usb_phy_set_suspend(musb->xceiv, 1);
|
||||
omap2430_low_level_exit(musb);
|
||||
usb_phy_set_suspend(musb->xceiv, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)
|
||||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
struct musb *musb = glue_to_musb(glue);
|
||||
|
||||
omap2430_low_level_init(musb);
|
||||
musb_writel(musb->mregs, OTG_INTERFSEL,
|
||||
musb->context.otg_interfsel);
|
||||
if (musb) {
|
||||
omap2430_low_level_init(musb);
|
||||
musb_writel(musb->mregs, OTG_INTERFSEL,
|
||||
musb->context.otg_interfsel);
|
||||
|
||||
usb_phy_set_suspend(musb->xceiv, 0);
|
||||
usb_phy_set_suspend(musb->xceiv, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ struct usb_phy {
|
||||
|
||||
struct usb_otg *otg;
|
||||
|
||||
struct device *io_dev;
|
||||
struct usb_phy_io_ops *io_ops;
|
||||
void __iomem *io_priv;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user