]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'topic/defer_probe' into for-linus
authorVinod Koul <vinod.koul@intel.com>
Tue, 7 Jan 2014 16:02:28 +0000 (21:32 +0530)
committerVinod Koul <vinod.koul@intel.com>
Tue, 7 Jan 2014 16:02:28 +0000 (21:32 +0530)
drivers/dma/dmaengine.c
drivers/dma/of-dma.c
include/linux/dmaengine.h

index ea806bdc12ef92418c528be0b950758de59c3ee7..e17e9b22d85ed3407f009e3d7ce8cd68c3298dc5 100644 (file)
@@ -540,6 +540,8 @@ EXPORT_SYMBOL_GPL(dma_get_slave_channel);
  * @mask: capabilities that the channel must satisfy
  * @fn: optional callback to disposition available channels
  * @fn_param: opaque parameter to pass to dma_filter_fn
+ *
+ * Returns pointer to appropriate DMA channel on success or NULL.
  */
 struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
                                       dma_filter_fn fn, void *fn_param)
@@ -591,18 +593,43 @@ 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
+ *
+ * Returns pointer to appropriate DMA channel on success or an error pointer.
  */
-struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name)
+struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
+                                                 const char *name)
 {
+       struct dma_chan *chan;
+
        /* If device-tree is present get slave info from here */
        if (dev->of_node)
                return of_dma_request_slave_channel(dev->of_node, name);
 
        /* If device was enumerated by ACPI get slave info from here */
-       if (ACPI_HANDLE(dev))
-               return acpi_dma_request_slave_chan_by_name(dev, name);
+       if (ACPI_HANDLE(dev)) {
+               chan = acpi_dma_request_slave_chan_by_name(dev, name);
+               if (chan)
+                       return chan;
+       }
 
-       return NULL;
+       return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason);
+
+/**
+ * dma_request_slave_channel - try to allocate an exclusive slave channel
+ * @dev:       pointer to client device structure
+ * @name:      slave channel name
+ *
+ * Returns pointer to appropriate DMA channel on success or NULL.
+ */
+struct dma_chan *dma_request_slave_channel(struct device *dev,
+                                          const char *name)
+{
+       struct dma_chan *ch = dma_request_slave_channel_reason(dev, name);
+       if (IS_ERR(ch))
+               return NULL;
+       return ch;
 }
 EXPORT_SYMBOL_GPL(dma_request_slave_channel);
 
index 0b88dd3d05f4880f41561f455f79c5eb9ca0a885..e8fe9dc455f4d8989e6d75618fecdd7ce351647f 100644 (file)
@@ -143,7 +143,7 @@ static int of_dma_match_channel(struct device_node *np, const char *name,
  * @np:                device node to get DMA request from
  * @name:      name of desired channel
  *
- * Returns pointer to appropriate dma channel on success or NULL on error.
+ * Returns pointer to appropriate DMA channel on success or an error pointer.
  */
 struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
                                              const char *name)
@@ -152,17 +152,18 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
        struct of_dma           *ofdma;
        struct dma_chan         *chan;
        int                     count, i;
+       int                     ret_no_channel = -ENODEV;
 
        if (!np || !name) {
                pr_err("%s: not enough information provided\n", __func__);
-               return NULL;
+               return ERR_PTR(-ENODEV);
        }
 
        count = of_property_count_strings(np, "dma-names");
        if (count < 0) {
                pr_err("%s: dma-names property of node '%s' missing or empty\n",
                        __func__, np->full_name);
-               return NULL;
+               return ERR_PTR(-ENODEV);
        }
 
        for (i = 0; i < count; i++) {
@@ -172,10 +173,12 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
                mutex_lock(&of_dma_lock);
                ofdma = of_dma_find_controller(&dma_spec);
 
-               if (ofdma)
+               if (ofdma) {
                        chan = ofdma->of_dma_xlate(&dma_spec, ofdma);
-               else
+               } else {
+                       ret_no_channel = -EPROBE_DEFER;
                        chan = NULL;
+               }
 
                mutex_unlock(&of_dma_lock);
 
@@ -185,7 +188,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
                        return chan;
        }
 
-       return NULL;
+       return ERR_PTR(ret_no_channel);
 }
 
 /**
index bd6b88222ced26161ac030ec233285d82f9fe37b..de550c61ba434fc0330dd4c6acd8a197b67ca6c1 100644 (file)
@@ -22,6 +22,7 @@
 #define LINUX_DMAENGINE_H
 
 #include <linux/device.h>
+#include <linux/err.h>
 #include <linux/uio.h>
 #include <linux/bug.h>
 #include <linux/scatterlist.h>
@@ -1039,6 +1040,8 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
 void dma_issue_pending_all(void);
 struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
                                        dma_filter_fn fn, void *fn_param);
+struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
+                                                 const char *name);
 struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
 void dma_release_channel(struct dma_chan *chan);
 #else
@@ -1062,6 +1065,11 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
 {
        return NULL;
 }
+static inline struct dma_chan *dma_request_slave_channel_reason(
+                                       struct device *dev, const char *name)
+{
+       return ERR_PTR(-ENODEV);
+}
 static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
                                                         const char *name)
 {