summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_cppi41.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 17:07:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 17:07:21 -0700
commit42e3a58b028e0e51746f596a11abfec01cd1c5c4 (patch)
treeb2dd1e8730359dc312519bcdaed9c52bae622990 /drivers/usb/musb/musb_cppi41.c
parent4fd48b45ffc4addd3c2963448b05417aa14abbf7 (diff)
parent00fe52deb45b1a5ef42b0aa82e632e2df012eddc (diff)
downloadtalos-op-linux-42e3a58b028e0e51746f596a11abfec01cd1c5c4.tar.gz
talos-op-linux-42e3a58b028e0e51746f596a11abfec01cd1c5c4.zip
Merge tag 'usb-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB driver updates from Greg KH: "Here's the big USB (and PHY) driver patchset for 4.1-rc1. Everything here has been in linux-next, and the full details are below in the shortlog. Nothing major, just the normal round of new drivers,api updates, and other changes, mostly in the USB gadget area, as usual" * tag 'usb-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (252 commits) drivers/usb/core: devio.c: Removed an uneeded space before tab usb: dwc2: host: sleep USB_RESUME_TIMEOUT during resume usb: chipidea: debug: add low power mode check before print registers usb: chipidea: udc: bypass pullup DP when gadget connect in OTG fsm mode usb: core: hub: use new USB_RESUME_TIMEOUT usb: isp1760: hcd: use new USB_RESUME_TIMEOUT usb: dwc2: hcd: use new USB_RESUME_TIMEOUT usb: host: sl811: use new USB_RESUME_TIMEOUT usb: host: r8a66597: use new USB_RESUME_TIMEOUT usb: host: oxu210hp: use new USB_RESUME_TIMEOUT usb: host: fusbh200: use new USB_RESUME_TIMEOUT usb: host: fotg210: use new USB_RESUME_TIMEOUT usb: host: isp116x: use new USB_RESUME_TIMEOUT usb: musb: use new USB_RESUME_TIMEOUT usb: host: uhci: use new USB_RESUME_TIMEOUT usb: host: ehci: use new USB_RESUME_TIMEOUT usb: host: xhci: use new USB_RESUME_TIMEOUT usb: define a generic USB_RESUME_TIMEOUT macro usb: musb: dsps: fix build on i386 when COMPILE_TEST is set ehci-hub: use USB_DT_HUB ...
Diffstat (limited to 'drivers/usb/musb/musb_cppi41.c')
-rw-r--r--drivers/usb/musb/musb_cppi41.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index be84562d021b..8bd8c5e26921 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -225,10 +225,12 @@ static void cppi41_dma_callback(void *private_data)
struct dma_channel *channel = private_data;
struct cppi41_dma_channel *cppi41_channel = channel->private_data;
struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+ struct cppi41_dma_controller *controller;
struct musb *musb = hw_ep->musb;
unsigned long flags;
struct dma_tx_state txstate;
u32 transferred;
+ int is_hs = 0;
bool empty;
spin_lock_irqsave(&musb->lock, flags);
@@ -248,61 +250,59 @@ static void cppi41_dma_callback(void *private_data)
transferred < cppi41_channel->packet_sz)
cppi41_channel->prog_len = 0;
- empty = musb_is_tx_fifo_empty(hw_ep);
- if (empty) {
+ if (cppi41_channel->is_tx)
+ empty = musb_is_tx_fifo_empty(hw_ep);
+
+ if (!cppi41_channel->is_tx || empty) {
cppi41_trans_done(cppi41_channel);
- } else {
- struct cppi41_dma_controller *controller;
- int is_hs = 0;
- /*
- * On AM335x it has been observed that the TX interrupt fires
- * too early that means the TXFIFO is not yet empty but the DMA
- * engine says that it is done with the transfer. We don't
- * receive a FIFO empty interrupt so the only thing we can do is
- * to poll for the bit. On HS it usually takes 2us, on FS around
- * 110us - 150us depending on the transfer size.
- * We spin on HS (no longer than than 25us and setup a timer on
- * FS to check for the bit and complete the transfer.
- */
- controller = cppi41_channel->controller;
+ goto out;
+ }
- if (is_host_active(musb)) {
- if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED)
- is_hs = 1;
- } else {
- if (musb->g.speed == USB_SPEED_HIGH)
- is_hs = 1;
- }
- if (is_hs) {
- unsigned wait = 25;
-
- do {
- empty = musb_is_tx_fifo_empty(hw_ep);
- if (empty)
- break;
- wait--;
- if (!wait)
- break;
- udelay(1);
- } while (1);
+ /*
+ * On AM335x it has been observed that the TX interrupt fires
+ * too early that means the TXFIFO is not yet empty but the DMA
+ * engine says that it is done with the transfer. We don't
+ * receive a FIFO empty interrupt so the only thing we can do is
+ * to poll for the bit. On HS it usually takes 2us, on FS around
+ * 110us - 150us depending on the transfer size.
+ * We spin on HS (no longer than than 25us and setup a timer on
+ * FS to check for the bit and complete the transfer.
+ */
+ controller = cppi41_channel->controller;
+
+ if (is_host_active(musb)) {
+ if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED)
+ is_hs = 1;
+ } else {
+ if (musb->g.speed == USB_SPEED_HIGH)
+ is_hs = 1;
+ }
+ if (is_hs) {
+ unsigned wait = 25;
+ do {
empty = musb_is_tx_fifo_empty(hw_ep);
if (empty) {
cppi41_trans_done(cppi41_channel);
goto out;
}
- }
- list_add_tail(&cppi41_channel->tx_check,
- &controller->early_tx_list);
- if (!hrtimer_is_queued(&controller->early_tx)) {
- unsigned long usecs = cppi41_channel->total_len / 10;
+ wait--;
+ if (!wait)
+ break;
+ cpu_relax();
+ } while (1);
+ }
+ list_add_tail(&cppi41_channel->tx_check,
+ &controller->early_tx_list);
+ if (!hrtimer_is_queued(&controller->early_tx)) {
+ unsigned long usecs = cppi41_channel->total_len / 10;
- hrtimer_start_range_ns(&controller->early_tx,
+ hrtimer_start_range_ns(&controller->early_tx,
ktime_set(0, usecs * NSEC_PER_USEC),
20 * NSEC_PER_USEC,
HRTIMER_MODE_REL);
- }
}
+
out:
spin_unlock_irqrestore(&musb->lock, flags);
}
OpenPOWER on IntegriCloud