!device->device_prep_dma_memset);
BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) &&
!device->device_prep_dma_interrupt);
++ ++ BUG_ON(dma_has_cap(DMA_SG, device->cap_mask) &&
++ ++ !device->device_prep_dma_sg);
BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
!device->device_prep_slave_sg);
+++ + BUG_ON(dma_has_cap(DMA_CYCLIC, device->cap_mask) &&
+++ + !device->device_prep_dma_cyclic);
BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
!device->device_control);
d40d->lli_log.dst = NULL;
d40d->lli_phy.src = NULL;
d40d->lli_phy.dst = NULL;
---- d40d->lli_phy.src_addr = 0;
---- d40d->lli_phy.dst_addr = 0;
}
----static dma_cookie_t d40_assign_cookie(struct d40_chan *d40c,
---- struct d40_desc *desc)
++++static int d40_lcla_alloc_one(struct d40_chan *d40c,
++++ struct d40_desc *d40d)
+ {
- -- dma_cookie_t cookie = d40c->chan.cookie;
++++ unsigned long flags;
++++ int i;
++++ int ret = -EINVAL;
++++ int p;
+
- -- if (++cookie < 0)
- -- cookie = 1;
++++ spin_lock_irqsave(&d40c->base->lcla_pool.lock, flags);
++++
++++ p = d40c->phy_chan->num * D40_LCLA_LINK_PER_EVENT_GRP;
+
- -- d40c->chan.cookie = cookie;
- -- desc->txd.cookie = cookie;
++++ /*
++++ * Allocate both src and dst at the same time, therefore the half
++++ * start on 1 since 0 can't be used since zero is used as end marker.
++++ */
++++ for (i = 1 ; i < D40_LCLA_LINK_PER_EVENT_GRP / 2; i++) {
++++ if (!d40c->base->lcla_pool.alloc_map[p + i]) {
++++ d40c->base->lcla_pool.alloc_map[p + i] = d40d;
++++ d40d->lcla_alloc++;
++++ ret = i;
++++ break;
++++ }
++++ }
++++
++++ spin_unlock_irqrestore(&d40c->base->lcla_pool.lock, flags);
++++
++++ return ret;
++++}
++++
++++static int d40_lcla_free_all(struct d40_chan *d40c,
++++ struct d40_desc *d40d)
+ ++{
- dma_cookie_t cookie = d40c->chan.cookie;
++++ unsigned long flags;
++++ int i;
++++ int ret = -EINVAL;
++++
++++ if (d40c->log_num == D40_PHY_CHAN)
++++ return 0;
+ ++
- if (++cookie < 0)
- cookie = 1;
++++ spin_lock_irqsave(&d40c->base->lcla_pool.lock, flags);
++++
++++ for (i = 1 ; i < D40_LCLA_LINK_PER_EVENT_GRP / 2; i++) {
++++ if (d40c->base->lcla_pool.alloc_map[d40c->phy_chan->num *
++++ D40_LCLA_LINK_PER_EVENT_GRP + i] == d40d) {
++++ d40c->base->lcla_pool.alloc_map[d40c->phy_chan->num *
++++ D40_LCLA_LINK_PER_EVENT_GRP + i] = NULL;
++++ d40d->lcla_alloc--;
++++ if (d40d->lcla_alloc == 0) {
++++ ret = 0;
++++ break;
++++ }
++++ }
++++ }
++++
++++ spin_unlock_irqrestore(&d40c->base->lcla_pool.lock, flags);
+ ++
- d40c->chan.cookie = cookie;
- desc->txd.cookie = cookie;
++++ return ret;
---- return cookie;
}
static void d40_desc_remove(struct d40_desc *d40d)