aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2013-05-02 12:22:26 -0400
committerVinod Koul <vinod.koul@intel.com>2013-05-02 12:22:26 -0400
commitb2396f7984ea09e83d489cfca6d5da62cc22945a (patch)
tree43e42015e6279af397ec1358a99afcc280b0cfab
parent42361f20f29021bfee8d9b5f651362dca83fd705 (diff)
parentde61608acf89779c8831aaa1428b6975d49d98c0 (diff)
Merge branch 'topic/of' into for-linus
Conflicts: include/linux/dmaengine.h Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/dmaengine.c2
-rw-r--r--drivers/dma/of-dma.c96
-rw-r--r--include/linux/dmaengine.h4
-rw-r--r--include/linux/of_dma.h10
4 files changed, 37 insertions, 75 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 1b2df59d1d65..93f7992bee5c 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -560,7 +560,7 @@ EXPORT_SYMBOL_GPL(__dma_request_channel);
560 * @dev: pointer to client device structure 560 * @dev: pointer to client device structure
561 * @name: slave channel name 561 * @name: slave channel name
562 */ 562 */
563struct dma_chan *dma_request_slave_channel(struct device *dev, char *name) 563struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name)
564{ 564{
565 /* If device-tree is present get slave info from here */ 565 /* If device-tree is present get slave info from here */
566 if (dev->of_node) 566 if (dev->of_node)
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index 69d04d28b1ef..7aa0864cd487 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -13,43 +13,31 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/rculist.h> 16#include <linux/mutex.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/of_dma.h> 19#include <linux/of_dma.h>
20 20
21static LIST_HEAD(of_dma_list); 21static LIST_HEAD(of_dma_list);
22static DEFINE_SPINLOCK(of_dma_lock); 22static DEFINE_MUTEX(of_dma_lock);
23 23
24/** 24/**
25 * of_dma_get_controller - Get a DMA controller in DT DMA helpers list 25 * of_dma_find_controller - Get a DMA controller in DT DMA helpers list
26 * @dma_spec: pointer to DMA specifier as found in the device tree 26 * @dma_spec: pointer to DMA specifier as found in the device tree
27 * 27 *
28 * Finds a DMA controller with matching device node and number for dma cells 28 * Finds a DMA controller with matching device node and number for dma cells
29 * in a list of registered DMA controllers. If a match is found the use_count 29 * in a list of registered DMA controllers. If a match is found a valid pointer
30 * variable is increased and a valid pointer to the DMA data stored is retuned. 30 * to the DMA data stored is retuned. A NULL pointer is returned if no match is
31 * A NULL pointer is returned if no match is found. 31 * found.
32 */ 32 */
33static struct of_dma *of_dma_get_controller(struct of_phandle_args *dma_spec) 33static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
34{ 34{
35 struct of_dma *ofdma; 35 struct of_dma *ofdma;
36 36
37 spin_lock(&of_dma_lock);
38
39 if (list_empty(&of_dma_list)) {
40 spin_unlock(&of_dma_lock);
41 return NULL;
42 }
43
44 list_for_each_entry(ofdma, &of_dma_list, of_dma_controllers) 37 list_for_each_entry(ofdma, &of_dma_list, of_dma_controllers)
45 if ((ofdma->of_node == dma_spec->np) && 38 if ((ofdma->of_node == dma_spec->np) &&
46 (ofdma->of_dma_nbcells == dma_spec->args_count)) { 39 (ofdma->of_dma_nbcells == dma_spec->args_count))
47 ofdma->use_count++;
48 spin_unlock(&of_dma_lock);
49 return ofdma; 40 return ofdma;
50 }
51
52 spin_unlock(&of_dma_lock);
53 41
54 pr_debug("%s: can't find DMA controller %s\n", __func__, 42 pr_debug("%s: can't find DMA controller %s\n", __func__,
55 dma_spec->np->full_name); 43 dma_spec->np->full_name);
@@ -58,22 +46,6 @@ static struct of_dma *of_dma_get_controller(struct of_phandle_args *dma_spec)
58} 46}
59 47
60/** 48/**
61 * of_dma_put_controller - Decrement use count for a registered DMA controller
62 * @of_dma: pointer to DMA controller data
63 *
64 * Decrements the use_count variable in the DMA data structure. This function
65 * should be called only when a valid pointer is returned from
66 * of_dma_get_controller() and no further accesses to data referenced by that
67 * pointer are needed.
68 */
69static void of_dma_put_controller(struct of_dma *ofdma)
70{
71 spin_lock(&of_dma_lock);
72 ofdma->use_count--;
73 spin_unlock(&of_dma_lock);
74}
75
76/**
77 * of_dma_controller_register - Register a DMA controller to DT DMA helpers 49 * of_dma_controller_register - Register a DMA controller to DT DMA helpers
78 * @np: device node of DMA controller 50 * @np: device node of DMA controller
79 * @of_dma_xlate: translation function which converts a phandle 51 * @of_dma_xlate: translation function which converts a phandle
@@ -93,6 +65,7 @@ int of_dma_controller_register(struct device_node *np,
93{ 65{
94 struct of_dma *ofdma; 66 struct of_dma *ofdma;
95 int nbcells; 67 int nbcells;
68 const __be32 *prop;
96 69
97 if (!np || !of_dma_xlate) { 70 if (!np || !of_dma_xlate) {
98 pr_err("%s: not enough information provided\n", __func__); 71 pr_err("%s: not enough information provided\n", __func__);
@@ -103,8 +76,11 @@ int of_dma_controller_register(struct device_node *np,
103 if (!ofdma) 76 if (!ofdma)
104 return -ENOMEM; 77 return -ENOMEM;
105 78
106 nbcells = be32_to_cpup(of_get_property(np, "#dma-cells", NULL)); 79 prop = of_get_property(np, "#dma-cells", NULL);
107 if (!nbcells) { 80 if (prop)
81 nbcells = be32_to_cpup(prop);
82
83 if (!prop || !nbcells) {
108 pr_err("%s: #dma-cells property is missing or invalid\n", 84 pr_err("%s: #dma-cells property is missing or invalid\n",
109 __func__); 85 __func__);
110 kfree(ofdma); 86 kfree(ofdma);
@@ -115,12 +91,11 @@ int of_dma_controller_register(struct device_node *np,
115 ofdma->of_dma_nbcells = nbcells; 91 ofdma->of_dma_nbcells = nbcells;
116 ofdma->of_dma_xlate = of_dma_xlate; 92 ofdma->of_dma_xlate = of_dma_xlate;
117 ofdma->of_dma_data = data; 93 ofdma->of_dma_data = data;
118 ofdma->use_count = 0;
119 94
120 /* Now queue of_dma controller structure in list */ 95 /* Now queue of_dma controller structure in list */
121 spin_lock(&of_dma_lock); 96 mutex_lock(&of_dma_lock);
122 list_add_tail(&ofdma->of_dma_controllers, &of_dma_list); 97 list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
123 spin_unlock(&of_dma_lock); 98 mutex_unlock(&of_dma_lock);
124 99
125 return 0; 100 return 0;
126} 101}
@@ -132,32 +107,20 @@ EXPORT_SYMBOL_GPL(of_dma_controller_register);
132 * 107 *
133 * Memory allocated by of_dma_controller_register() is freed here. 108 * Memory allocated by of_dma_controller_register() is freed here.
134 */ 109 */
135int of_dma_controller_free(struct device_node *np) 110void of_dma_controller_free(struct device_node *np)
136{ 111{
137 struct of_dma *ofdma; 112 struct of_dma *ofdma;
138 113
139 spin_lock(&of_dma_lock); 114 mutex_lock(&of_dma_lock);
140
141 if (list_empty(&of_dma_list)) {
142 spin_unlock(&of_dma_lock);
143 return -ENODEV;
144 }
145 115
146 list_for_each_entry(ofdma, &of_dma_list, of_dma_controllers) 116 list_for_each_entry(ofdma, &of_dma_list, of_dma_controllers)
147 if (ofdma->of_node == np) { 117 if (ofdma->of_node == np) {
148 if (ofdma->use_count) {
149 spin_unlock(&of_dma_lock);
150 return -EBUSY;
151 }
152
153 list_del(&ofdma->of_dma_controllers); 118 list_del(&ofdma->of_dma_controllers);
154 spin_unlock(&of_dma_lock);
155 kfree(ofdma); 119 kfree(ofdma);
156 return 0; 120 break;
157 } 121 }
158 122
159 spin_unlock(&of_dma_lock); 123 mutex_unlock(&of_dma_lock);
160 return -ENODEV;
161} 124}
162EXPORT_SYMBOL_GPL(of_dma_controller_free); 125EXPORT_SYMBOL_GPL(of_dma_controller_free);
163 126
@@ -172,8 +135,8 @@ EXPORT_SYMBOL_GPL(of_dma_controller_free);
172 * specifiers, matches the name provided. Returns 0 if the name matches and 135 * specifiers, matches the name provided. Returns 0 if the name matches and
173 * a valid pointer to the DMA specifier is found. Otherwise returns -ENODEV. 136 * a valid pointer to the DMA specifier is found. Otherwise returns -ENODEV.
174 */ 137 */
175static int of_dma_match_channel(struct device_node *np, char *name, int index, 138static int of_dma_match_channel(struct device_node *np, const char *name,
176 struct of_phandle_args *dma_spec) 139 int index, struct of_phandle_args *dma_spec)
177{ 140{
178 const char *s; 141 const char *s;
179 142
@@ -198,7 +161,7 @@ static int of_dma_match_channel(struct device_node *np, char *name, int index,
198 * Returns pointer to appropriate dma channel on success or NULL on error. 161 * Returns pointer to appropriate dma channel on success or NULL on error.
199 */ 162 */
200struct dma_chan *of_dma_request_slave_channel(struct device_node *np, 163struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
201 char *name) 164 const char *name)
202{ 165{
203 struct of_phandle_args dma_spec; 166 struct of_phandle_args dma_spec;
204 struct of_dma *ofdma; 167 struct of_dma *ofdma;
@@ -220,14 +183,15 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
220 if (of_dma_match_channel(np, name, i, &dma_spec)) 183 if (of_dma_match_channel(np, name, i, &dma_spec))
221 continue; 184 continue;
222 185
223 ofdma = of_dma_get_controller(&dma_spec); 186 mutex_lock(&of_dma_lock);
224 187 ofdma = of_dma_find_controller(&dma_spec);
225 if (!ofdma)
226 continue;
227 188
228 chan = ofdma->of_dma_xlate(&dma_spec, ofdma); 189 if (ofdma)
190 chan = ofdma->of_dma_xlate(&dma_spec, ofdma);
191 else
192 chan = NULL;
229 193
230 of_dma_put_controller(ofdma); 194 mutex_unlock(&of_dma_lock);
231 195
232 of_node_put(dma_spec.np); 196 of_node_put(dma_spec.np);
233 197
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index dd6d21b335c8..96d3e4ab11a9 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -969,7 +969,7 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
969void dma_issue_pending_all(void); 969void dma_issue_pending_all(void);
970struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, 970struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
971 dma_filter_fn fn, void *fn_param); 971 dma_filter_fn fn, void *fn_param);
972struct dma_chan *dma_request_slave_channel(struct device *dev, char *name); 972struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
973void dma_release_channel(struct dma_chan *chan); 973void dma_release_channel(struct dma_chan *chan);
974#else 974#else
975static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) 975static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
@@ -985,7 +985,7 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
985 return NULL; 985 return NULL;
986} 986}
987static inline struct dma_chan *dma_request_slave_channel(struct device *dev, 987static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
988 char *name) 988 const char *name)
989{ 989{
990 return NULL; 990 return NULL;
991} 991}
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index d15073e080dd..364dda734877 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -25,7 +25,6 @@ struct of_dma {
25 struct dma_chan *(*of_dma_xlate) 25 struct dma_chan *(*of_dma_xlate)
26 (struct of_phandle_args *, struct of_dma *); 26 (struct of_phandle_args *, struct of_dma *);
27 void *of_dma_data; 27 void *of_dma_data;
28 int use_count;
29}; 28};
30 29
31struct of_dma_filter_info { 30struct of_dma_filter_info {
@@ -38,9 +37,9 @@ extern int of_dma_controller_register(struct device_node *np,
38 struct dma_chan *(*of_dma_xlate) 37 struct dma_chan *(*of_dma_xlate)
39 (struct of_phandle_args *, struct of_dma *), 38 (struct of_phandle_args *, struct of_dma *),
40 void *data); 39 void *data);
41extern int of_dma_controller_free(struct device_node *np); 40extern void of_dma_controller_free(struct device_node *np);
42extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np, 41extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
43 char *name); 42 const char *name);
44extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec, 43extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
45 struct of_dma *ofdma); 44 struct of_dma *ofdma);
46#else 45#else
@@ -52,13 +51,12 @@ static inline int of_dma_controller_register(struct device_node *np,
52 return -ENODEV; 51 return -ENODEV;
53} 52}
54 53
55static inline int of_dma_controller_free(struct device_node *np) 54static inline void of_dma_controller_free(struct device_node *np)
56{ 55{
57 return -ENODEV;
58} 56}
59 57
60static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np, 58static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
61 char *name) 59 const char *name)
62{ 60{
63 return NULL; 61 return NULL;
64} 62}