/* Used the DMA wrapper */
bool wrapper;
void __iomem *inst_wrapper;
+ int usage_count;
/* Populated by the PL330 core driver during pl330_add */
struct pl330_config pcfg;
spin_lock_irqsave(&pl330->lock, flags);
+ if (!pl330->usage_count) {
+ pr_info("[%s] Channel is already free!\n",__func__);
+ spin_unlock_irqrestore(&pl330->lock, flags);
+ return;
+ }
+
/* The DMAC itself gone nuts */
if (pl330->dmac_tbd.reset_dmac) {
pl330->state = DYING;
spin_lock_irqsave(&pl330->lock, flags);
+ if (!pl330->usage_count) {
+ dev_err(pl330->ddma.dev, "%s:%d event is not exist!\n", __func__, __LINE__);
+ spin_unlock_irqrestore(&pl330->lock, flags);
+ return 0;
+ }
+
val = readl(regs + FSM) & 0x1;
if (val)
pl330->dmac_tbd.reset_mngr = true;
thrd->req[0].desc = NULL;
thrd->req[1].desc = NULL;
thrd->req_running = -1;
+ pl330->usage_count++;
break;
}
}
/* If the event is valid and was held by the thread */
if (ev >= 0 && ev < pl330->pcfg.num_events
- && pl330->events[ev] == thrd->id)
+ && pl330->events[ev] == thrd->id) {
pl330->events[ev] = -1;
+ pl330->usage_count--;
+ }
}
static void pl330_release_channel(struct pl330_thread *thrd)
tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330);
pl330->state = INIT;
+ pl330->usage_count = 0;
return 0;
}