Commit eefae89e authored by Daniel Mack's avatar Daniel Mack Committed by Felipe Balbi

Revert "usb: musb: musb_cppi41: Handle ISOCH differently and not use the hrtimer."

This reverts commit 1af54b7a.

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: default avatarDaniel Mack <zonque@gmail.com>
Reported-by: default avatarSebastian Reimers <sebastian.reimers@googlemail.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 49a9e885
...@@ -39,7 +39,6 @@ struct cppi41_dma_channel { ...@@ -39,7 +39,6 @@ struct cppi41_dma_channel {
u32 transferred; u32 transferred;
u32 packet_sz; u32 packet_sz;
struct list_head tx_check; struct list_head tx_check;
struct work_struct dma_completion;
}; };
#define MUSB_DMA_NUM_CHANNELS 15 #define MUSB_DMA_NUM_CHANNELS 15
...@@ -117,18 +116,6 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) ...@@ -117,18 +116,6 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
return true; 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_dma_callback(void *private_data);
static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) 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) ...@@ -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) static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer)
{ {
struct cppi41_dma_controller *controller; struct cppi41_dma_controller *controller;
...@@ -274,14 +235,6 @@ static void cppi41_dma_callback(void *private_data) ...@@ -274,14 +235,6 @@ static void cppi41_dma_callback(void *private_data)
transferred < cppi41_channel->packet_sz) transferred < cppi41_channel->packet_sz)
cppi41_channel->prog_len = 0; 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); empty = musb_is_tx_fifo_empty(hw_ep);
if (empty) { if (empty) {
cppi41_trans_done(cppi41_channel); cppi41_trans_done(cppi41_channel);
...@@ -318,10 +271,6 @@ static void cppi41_dma_callback(void *private_data) ...@@ -318,10 +271,6 @@ static void cppi41_dma_callback(void *private_data)
goto out; goto out;
} }
} }
if (is_isoc(hw_ep, 0)) {
schedule_work(&cppi41_channel->dma_completion);
goto out;
}
list_add_tail(&cppi41_channel->tx_check, list_add_tail(&cppi41_channel->tx_check,
&controller->early_tx_list); &controller->early_tx_list);
if (!hrtimer_active(&controller->early_tx)) { if (!hrtimer_active(&controller->early_tx)) {
...@@ -679,8 +628,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) ...@@ -679,8 +628,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
cppi41_channel->port_num = port; cppi41_channel->port_num = port;
cppi41_channel->is_tx = is_tx; cppi41_channel->is_tx = is_tx;
INIT_LIST_HEAD(&cppi41_channel->tx_check); INIT_LIST_HEAD(&cppi41_channel->tx_check);
INIT_WORK(&cppi41_channel->dma_completion,
cppi_trans_done_work);
musb_dma = &cppi41_channel->channel; musb_dma = &cppi41_channel->channel;
musb_dma->private_data = cppi41_channel; musb_dma->private_data = cppi41_channel;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment