Revert "dma: k3-udma: fix deferred work in udma_ring_irq_handler()"
This reverts commit fe05209529.
This commit is contained in:
+27
-41
@@ -241,8 +241,7 @@ enum udma_chan_state {
|
||||
};
|
||||
|
||||
struct udma_tx_drain {
|
||||
struct tasklet_struct tasklet;
|
||||
struct timer_list timer;
|
||||
struct delayed_work work;
|
||||
ktime_t tstamp;
|
||||
u32 residue;
|
||||
};
|
||||
@@ -1084,9 +1083,11 @@ static bool udma_is_desc_really_done(struct udma_chan *uc, struct udma_desc *d)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void udma_check_tx_completion(struct tasklet_struct *t)
|
||||
static void udma_check_tx_completion(struct work_struct *work)
|
||||
{
|
||||
struct udma_chan *uc = container_of(t, typeof(*uc), tx_drain.tasklet);
|
||||
struct udma_chan *uc = container_of(work, typeof(*uc),
|
||||
tx_drain.work.work);
|
||||
bool desc_done = true;
|
||||
u32 residue_diff;
|
||||
ktime_t time_diff;
|
||||
unsigned long delay;
|
||||
@@ -1100,14 +1101,10 @@ static void udma_check_tx_completion(struct tasklet_struct *t)
|
||||
* Get current residue and time stamp or see if
|
||||
* transfer is complete
|
||||
*/
|
||||
if (udma_is_desc_really_done(uc, uc->desc)) {
|
||||
struct udma_desc *d = uc->desc;
|
||||
desc_done = udma_is_desc_really_done(uc, uc->desc);
|
||||
}
|
||||
|
||||
udma_decrement_byte_counters(uc, d->residue);
|
||||
udma_start(uc);
|
||||
vchan_cookie_complete(&d->vd);
|
||||
break;
|
||||
}
|
||||
if (!desc_done) {
|
||||
/*
|
||||
* Find the time delta and residue delta w.r.t
|
||||
* previous poll
|
||||
@@ -1124,36 +1121,27 @@ static void udma_check_tx_completion(struct tasklet_struct *t)
|
||||
*/
|
||||
delay = (time_diff / residue_diff) *
|
||||
uc->tx_drain.residue;
|
||||
udelay(ktime_to_us(delay));
|
||||
} else {
|
||||
/* No progress, check again in 1 second */
|
||||
mod_timer(&uc->tx_drain.timer, jiffies + 1*HZ);
|
||||
schedule_delayed_work(&uc->tx_drain.work, HZ);
|
||||
break;
|
||||
}
|
||||
|
||||
usleep_range(ktime_to_us(delay),
|
||||
ktime_to_us(delay) + 10);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void udma_delayed_check(struct timer_list *t)
|
||||
{
|
||||
struct udma_chan *uc = container_of(t, typeof(*uc), tx_drain.timer);
|
||||
|
||||
if (uc->desc) {
|
||||
/*
|
||||
* Get current residue and time stamp or see if
|
||||
* transfer is complete
|
||||
*/
|
||||
if (udma_is_desc_really_done(uc, uc->desc)) {
|
||||
if (uc->desc) {
|
||||
struct udma_desc *d = uc->desc;
|
||||
|
||||
udma_decrement_byte_counters(uc, d->residue);
|
||||
udma_start(uc);
|
||||
vchan_cookie_complete(&d->vd);
|
||||
} else {
|
||||
/* Still no progress after 1 second */
|
||||
WARN_ON_ONCE(1);
|
||||
mod_timer(&uc->tx_drain.timer, jiffies + 1*HZ);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1204,7 +1192,8 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
|
||||
udma_start(uc);
|
||||
vchan_cookie_complete(&d->vd);
|
||||
} else {
|
||||
tasklet_schedule(&uc->tx_drain.tasklet);
|
||||
schedule_delayed_work(&uc->tx_drain.work,
|
||||
0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2556,9 +2545,8 @@ static int bcdma_alloc_chan_resources(struct dma_chan *chan)
|
||||
|
||||
udma_reset_rings(uc);
|
||||
|
||||
timer_setup(&uc->tx_drain.timer, udma_delayed_check, 0);
|
||||
tasklet_setup(&uc->tx_drain.tasklet, udma_check_tx_completion);
|
||||
|
||||
INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work,
|
||||
udma_check_tx_completion);
|
||||
return 0;
|
||||
|
||||
err_irq_free:
|
||||
@@ -2721,8 +2709,8 @@ static int pktdma_alloc_chan_resources(struct dma_chan *chan)
|
||||
|
||||
udma_reset_rings(uc);
|
||||
|
||||
timer_setup(&uc->tx_drain.timer, udma_delayed_check, 0);
|
||||
tasklet_setup(&uc->tx_drain.tasklet, udma_check_tx_completion);
|
||||
INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work,
|
||||
udma_check_tx_completion);
|
||||
|
||||
if (uc->tchan)
|
||||
dev_dbg(ud->dev,
|
||||
@@ -3936,8 +3924,7 @@ static int udma_terminate_all(struct dma_chan *chan)
|
||||
uc->terminated_desc = uc->desc;
|
||||
uc->desc = NULL;
|
||||
uc->terminated_desc->terminated = true;
|
||||
del_timer(&uc->tx_drain.timer);
|
||||
tasklet_kill(&uc->tx_drain.tasklet);
|
||||
cancel_delayed_work(&uc->tx_drain.work);
|
||||
}
|
||||
|
||||
uc->paused = false;
|
||||
@@ -3971,8 +3958,7 @@ static void udma_synchronize(struct dma_chan *chan)
|
||||
if (udma_is_chan_running(uc))
|
||||
dev_warn(uc->ud->dev, "chan%d refused to stop!\n", uc->id);
|
||||
|
||||
del_timer_sync(&uc->tx_drain.timer);
|
||||
tasklet_kill(&uc->tx_drain.tasklet);
|
||||
cancel_delayed_work_sync(&uc->tx_drain.work);
|
||||
udma_reset_rings(uc);
|
||||
}
|
||||
|
||||
@@ -4066,8 +4052,7 @@ static void udma_free_chan_resources(struct dma_chan *chan)
|
||||
udma_reset_rings(uc);
|
||||
}
|
||||
|
||||
del_timer_sync(&uc->tx_drain.timer);
|
||||
tasklet_kill(&uc->tx_drain.tasklet);
|
||||
cancel_delayed_work_sync(&uc->tx_drain.work);
|
||||
|
||||
if (uc->irq_num_ring > 0) {
|
||||
free_irq(uc->irq_num_ring, uc);
|
||||
@@ -5551,6 +5536,7 @@ static int udma_probe(struct platform_device *pdev)
|
||||
/* Use custom vchan completion handling */
|
||||
tasklet_setup(&uc->vc.task, udma_vchan_complete);
|
||||
init_completion(&uc->teardown_completed);
|
||||
INIT_DELAYED_WORK(&uc->tx_drain.work, udma_check_tx_completion);
|
||||
}
|
||||
|
||||
/* Configure the copy_align to the maximum burst size the device supports */
|
||||
|
||||
Reference in New Issue
Block a user