Revert "usb: musb: musb_cppi41: Handle ISOCH differently and not use the hrtimer."
authorDaniel Mack <zonque@gmail.com>
Thu, 19 Jun 2014 22:20:43 +0000 (00:20 +0200)
committerFelipe Balbi <balbi@ti.com>
Mon, 30 Jun 2014 19:26:28 +0000 (14:26 -0500)
This reverts commit 1af54b7a4.

The commit tried to address cases in which isochronous transfers are 'not
reliable', most probably in the tests conducted, polling for the
MUSB_TXCSR_TXPKTRDY bit in MUSB_TXCSR is done too late.

Hence, it installs a work struct which basically busy-polls for the bit in a
rather agressive way by rescheduling the work if the FIFO is not empty. With
USB audio devices, tests have shown that it takes approximately 100
iterations of the asynchronous worker until the FIFO signals completion,
which leads to 100% CPU loads when streaming audio.

The issue the patch tried to address can be handled differently, which is
what the next patch does.

Signed-off-by: Daniel Mack <zonque@gmail.com>
Reported-by: Sebastian Reimers <sebastian.reimers@googlemail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/musb/musb_cppi41.c

index 932464ffb10c5e1d7f5277794fe454abee4f621f..a2c445608e75770d50c6d615fd551ea2e8af6f55 100644 (file)
@@ -39,7 +39,6 @@ struct cppi41_dma_channel {
        u32 transferred;
        u32 packet_sz;
        struct list_head tx_check;
-       struct work_struct dma_completion;
 };
 
 #define MUSB_DMA_NUM_CHANNELS 15
@@ -117,18 +116,6 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
        return true;
 }
 
-static bool is_isoc(struct musb_hw_ep *hw_ep, bool in)
-{
-       if (in && hw_ep->in_qh) {
-               if (hw_ep->in_qh->type == USB_ENDPOINT_XFER_ISOC)
-                       return true;
-       } else if (hw_ep->out_qh) {
-               if (hw_ep->out_qh->type == USB_ENDPOINT_XFER_ISOC)
-                       return true;
-       }
-       return false;
-}
-
 static void cppi41_dma_callback(void *private_data);
 
 static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
@@ -185,32 +172,6 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
        }
 }
 
-static void cppi_trans_done_work(struct work_struct *work)
-{
-       unsigned long flags;
-       struct cppi41_dma_channel *cppi41_channel =
-               container_of(work, struct cppi41_dma_channel, dma_completion);
-       struct cppi41_dma_controller *controller = cppi41_channel->controller;
-       struct musb *musb = controller->musb;
-       struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
-       bool empty;
-
-       if (!cppi41_channel->is_tx && is_isoc(hw_ep, 1)) {
-               spin_lock_irqsave(&musb->lock, flags);
-               cppi41_trans_done(cppi41_channel);
-               spin_unlock_irqrestore(&musb->lock, flags);
-       } else {
-               empty = musb_is_tx_fifo_empty(hw_ep);
-               if (empty) {
-                       spin_lock_irqsave(&musb->lock, flags);
-                       cppi41_trans_done(cppi41_channel);
-                       spin_unlock_irqrestore(&musb->lock, flags);
-               } else {
-                       schedule_work(&cppi41_channel->dma_completion);
-               }
-       }
-}
-
 static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer)
 {
        struct cppi41_dma_controller *controller;
@@ -274,14 +235,6 @@ static void cppi41_dma_callback(void *private_data)
                        transferred < cppi41_channel->packet_sz)
                cppi41_channel->prog_len = 0;
 
-       if (!cppi41_channel->is_tx) {
-               if (is_isoc(hw_ep, 1))
-                       schedule_work(&cppi41_channel->dma_completion);
-               else
-                       cppi41_trans_done(cppi41_channel);
-               goto out;
-       }
-
        empty = musb_is_tx_fifo_empty(hw_ep);
        if (empty) {
                cppi41_trans_done(cppi41_channel);
@@ -318,10 +271,6 @@ static void cppi41_dma_callback(void *private_data)
                                goto out;
                        }
                }
-               if (is_isoc(hw_ep, 0)) {
-                       schedule_work(&cppi41_channel->dma_completion);
-                       goto out;
-               }
                list_add_tail(&cppi41_channel->tx_check,
                                &controller->early_tx_list);
                if (!hrtimer_active(&controller->early_tx)) {
@@ -679,8 +628,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
                cppi41_channel->port_num = port;
                cppi41_channel->is_tx = is_tx;
                INIT_LIST_HEAD(&cppi41_channel->tx_check);
-               INIT_WORK(&cppi41_channel->dma_completion,
-                         cppi_trans_done_work);
 
                musb_dma = &cppi41_channel->channel;
                musb_dma->private_data = cppi41_channel;