diff options
Diffstat (limited to 'drivers/usb/host/imx21-hcd.c')
| -rw-r--r-- | drivers/usb/host/imx21-hcd.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index f0ebe8e7c58..207bad99301 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -62,6 +62,10 @@ #include "imx21-hcd.h" +#ifdef CONFIG_DYNAMIC_DEBUG +#define DEBUG +#endif + #ifdef DEBUG #define DEBUG_LOG_FRAME(imx21, etd, event) \ (etd)->event##_frame = readl((imx21)->regs + USBH_FRMNUB) @@ -809,26 +813,36 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, /* calculate frame */ cur_frame = imx21_hc_get_frame(hcd); - if (urb->transfer_flags & URB_ISO_ASAP) { - if (list_empty(&ep_priv->td_list)) - urb->start_frame = cur_frame + 5; - else - urb->start_frame = list_entry( - ep_priv->td_list.prev, - struct td, list)->frame + urb->interval; - } - urb->start_frame = wrap_frame(urb->start_frame); - if (frame_after(cur_frame, urb->start_frame)) { - dev_dbg(imx21->dev, - "enqueue: adjusting iso start %d (cur=%d) asap=%d\n", - urb->start_frame, cur_frame, - (urb->transfer_flags & URB_ISO_ASAP) != 0); - urb->start_frame = wrap_frame(cur_frame + 1); + i = 0; + if (list_empty(&ep_priv->td_list)) { + urb->start_frame = wrap_frame(cur_frame + 5); + } else { + urb->start_frame = wrap_frame(list_entry(ep_priv->td_list.prev, + struct td, list)->frame + urb->interval); + + if (frame_after(cur_frame, urb->start_frame)) { + dev_dbg(imx21->dev, + "enqueue: adjusting iso start %d (cur=%d) asap=%d\n", + urb->start_frame, cur_frame, + (urb->transfer_flags & URB_ISO_ASAP) != 0); + i = DIV_ROUND_UP(wrap_frame( + cur_frame - urb->start_frame), + urb->interval); + + /* Treat underruns as if URB_ISO_ASAP was set */ + if ((urb->transfer_flags & URB_ISO_ASAP) || + i >= urb->number_of_packets) { + urb->start_frame = wrap_frame(urb->start_frame + + i * urb->interval); + i = 0; + } + } } /* set up transfers */ + urb_priv->isoc_remaining = urb->number_of_packets - i; td = urb_priv->isoc_td; - for (i = 0; i < urb->number_of_packets; i++, td++) { + for (; i < urb->number_of_packets; i++, td++) { unsigned int offset = urb->iso_frame_desc[i].offset; td->ep = ep; td->urb = urb; @@ -840,7 +854,6 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, list_add_tail(&td->list, &ep_priv->td_list); } - urb_priv->isoc_remaining = urb->number_of_packets; dev_vdbg(imx21->dev, "setup %d packets for iso frame %d->%d\n", urb->number_of_packets, urb->start_frame, td->frame); @@ -1851,7 +1864,7 @@ static int imx21_probe(struct platform_device *pdev) imx21 = hcd_to_imx21(hcd); imx21->hcd = hcd; imx21->dev = &pdev->dev; - imx21->pdata = pdev->dev.platform_data; + imx21->pdata = dev_get_platdata(&pdev->dev); if (!imx21->pdata) imx21->pdata = &default_pdata; @@ -1897,6 +1910,7 @@ static int imx21_probe(struct platform_device *pdev) dev_err(imx21->dev, "usb_add_hcd() returned %d\n", ret); goto failed_add_hcd; } + device_wakeup_enable(hcd->self.controller); return 0; @@ -1917,7 +1931,7 @@ failed_request_mem: static struct platform_driver imx21_hcd_driver = { .driver = { - .name = (char *)hcd_name, + .name = hcd_name, }, .probe = imx21_probe, .remove = imx21_remove, |
