These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / dma / dmaengine.c
index 3ddfd1f..3ecec14 100644 (file)
@@ -267,6 +267,13 @@ static void dma_chan_put(struct dma_chan *chan)
        /* This channel is not in use anymore, free it */
        if (!chan->client_count && chan->device->device_free_chan_resources)
                chan->device->device_free_chan_resources(chan);
+
+       /* If the channel is used via a DMA request router, free the mapping */
+       if (chan->router && chan->router->route_free) {
+               chan->router->route_free(chan->router->dev, chan->route_data);
+               chan->router = NULL;
+               chan->route_data = NULL;
+       }
 }
 
 enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
@@ -536,7 +543,7 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
 }
 
 /**
- * dma_request_slave_channel - try to get specific channel exclusively
+ * dma_get_slave_channel - try to get specific channel exclusively
  * @chan: target channel
  */
 struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
@@ -547,10 +554,18 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
        mutex_lock(&dma_list_mutex);
 
        if (chan->client_count == 0) {
+               struct dma_device *device = chan->device;
+
+               dma_cap_set(DMA_PRIVATE, device->cap_mask);
+               device->privatecnt++;
                err = dma_chan_get(chan);
-               if (err)
+               if (err) {
                        pr_debug("%s: failed to get %s: (%d)\n",
                                __func__, dma_chan_name(chan), err);
+                       chan = NULL;
+                       if (--device->privatecnt == 0)
+                               dma_cap_clear(DMA_PRIVATE, device->cap_mask);
+               }
        } else
                chan = NULL;
 
@@ -648,7 +663,7 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
 EXPORT_SYMBOL_GPL(__dma_request_channel);
 
 /**
- * dma_request_slave_channel - try to allocate an exclusive slave channel
+ * dma_request_slave_channel_reason - try to allocate an exclusive slave channel
  * @dev:       pointer to client device structure
  * @name:      slave channel name
  *
@@ -682,6 +697,10 @@ struct dma_chan *dma_request_slave_channel(struct device *dev,
        struct dma_chan *ch = dma_request_slave_channel_reason(dev, name);
        if (IS_ERR(ch))
                return NULL;
+
+       dma_cap_set(DMA_PRIVATE, ch->device->cap_mask);
+       ch->device->privatecnt++;
+
        return ch;
 }
 EXPORT_SYMBOL_GPL(dma_request_slave_channel);
@@ -836,6 +855,8 @@ int dma_async_device_register(struct dma_device *device)
                !device->device_prep_dma_pq);
        BUG_ON(dma_has_cap(DMA_PQ_VAL, device->cap_mask) &&
                !device->device_prep_dma_pq_val);
+       BUG_ON(dma_has_cap(DMA_MEMSET, device->cap_mask) &&
+               !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) &&
@@ -1053,11 +1074,9 @@ static void dmaengine_destroy_unmap_pool(void)
        for (i = 0; i < ARRAY_SIZE(unmap_pool); i++) {
                struct dmaengine_unmap_pool *p = &unmap_pool[i];
 
-               if (p->pool)
-                       mempool_destroy(p->pool);
+               mempool_destroy(p->pool);
                p->pool = NULL;
-               if (p->cache)
-                       kmem_cache_destroy(p->cache);
+               kmem_cache_destroy(p->cache);
                p->cache = NULL;
        }
 }