Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / drivers / dma / dmaengine.c
index a815d44c70a41b802c771dea337bf2e5348592a8..b2728d6ba2fdea97774d904bcd04f58d12187772 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/rculist.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/of_dma.h>
 
 static DEFINE_MUTEX(dma_list_mutex);
 static DEFINE_IDR(dma_idr);
@@ -266,7 +267,10 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
                        pr_err("%s: timeout!\n", __func__);
                        return DMA_ERROR;
                }
-       } while (status == DMA_IN_PROGRESS);
+               if (status != DMA_IN_PROGRESS)
+                       break;
+               cpu_relax();
+       } while (1);
 
        return status;
 }
@@ -546,6 +550,21 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
 }
 EXPORT_SYMBOL_GPL(__dma_request_channel);
 
+/**
+ * dma_request_slave_channel - try to allocate an exclusive slave channel
+ * @dev:       pointer to client device structure
+ * @name:      slave channel name
+ */
+struct dma_chan *dma_request_slave_channel(struct device *dev, char *name)
+{
+       /* If device-tree is present get slave info from here */
+       if (dev->of_node)
+               return of_dma_request_slave_channel(dev->of_node, name);
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(dma_request_slave_channel);
+
 void dma_release_channel(struct dma_chan *chan)
 {
        mutex_lock(&dma_list_mutex);
@@ -667,18 +686,14 @@ static int get_dma_id(struct dma_device *device)
 {
        int rc;
 
- idr_retry:
-       if (!idr_pre_get(&dma_idr, GFP_KERNEL))
-               return -ENOMEM;
        mutex_lock(&dma_list_mutex);
-       rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
-       mutex_unlock(&dma_list_mutex);
-       if (rc == -EAGAIN)
-               goto idr_retry;
-       else if (rc != 0)
-               return rc;
 
-       return 0;
+       rc = idr_alloc(&dma_idr, NULL, 0, 0, GFP_KERNEL);
+       if (rc >= 0)
+               device->dev_id = rc;
+
+       mutex_unlock(&dma_list_mutex);
+       return rc < 0 ? rc : 0;
 }
 
 /**