aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/host/imx21-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/imx21-hcd.c')
-rw-r--r--drivers/usb/host/imx21-hcd.c52
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,