of: dma: fix potential deadlock when requesting a slave channel
[firefly-linux-kernel-4.4.55.git] / drivers / of / dma.c
1 /*
2  * Device tree helpers for DMA request / controller
3  *
4  * Based on of_gpio.c
5  *
6  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/device.h>
14 #include <linux/err.h>
15 #include <linux/module.h>
16 #include <linux/rculist.h>
17 #include <linux/slab.h>
18 #include <linux/of.h>
19 #include <linux/of_dma.h>
20
21 static LIST_HEAD(of_dma_list);
22
23 /**
24  * of_dma_find_controller - Find a DMA controller in DT DMA helpers list
25  * @np:         device node of DMA controller
26  */
27 static struct of_dma *of_dma_find_controller(struct device_node *np)
28 {
29         struct of_dma *ofdma;
30
31         if (list_empty(&of_dma_list)) {
32                 pr_err("empty DMA controller list\n");
33                 return NULL;
34         }
35
36         list_for_each_entry_rcu(ofdma, &of_dma_list, of_dma_controllers)
37                 if (ofdma->of_node == np)
38                         return ofdma;
39
40         return NULL;
41 }
42
43 /**
44  * of_dma_controller_register - Register a DMA controller to DT DMA helpers
45  * @np:                 device node of DMA controller
46  * @of_dma_xlate:       translation function which converts a phandle
47  *                      arguments list into a dma_chan structure
48  * @data                pointer to controller specific data to be used by
49  *                      translation function
50  *
51  * Returns 0 on success or appropriate errno value on error.
52  *
53  * Allocated memory should be freed with appropriate of_dma_controller_free()
54  * call.
55  */
56 int of_dma_controller_register(struct device_node *np,
57                                 struct dma_chan *(*of_dma_xlate)
58                                 (struct of_phandle_args *, struct of_dma *),
59                                 void *data)
60 {
61         struct of_dma   *ofdma;
62         int             nbcells;
63
64         if (!np || !of_dma_xlate) {
65                 pr_err("%s: not enough information provided\n", __func__);
66                 return -EINVAL;
67         }
68
69         ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
70         if (!ofdma)
71                 return -ENOMEM;
72
73         nbcells = be32_to_cpup(of_get_property(np, "#dma-cells", NULL));
74         if (!nbcells) {
75                 pr_err("%s: #dma-cells property is missing or invalid\n",
76                        __func__);
77                 return -EINVAL;
78         }
79
80         ofdma->of_node = np;
81         ofdma->of_dma_nbcells = nbcells;
82         ofdma->of_dma_xlate = of_dma_xlate;
83         ofdma->of_dma_data = data;
84
85         /* Now queue of_dma controller structure in list */
86         list_add_tail_rcu(&ofdma->of_dma_controllers, &of_dma_list);
87
88         return 0;
89 }
90 EXPORT_SYMBOL_GPL(of_dma_controller_register);
91
92 /**
93  * of_dma_controller_free - Remove a DMA controller from DT DMA helpers list
94  * @np:         device node of DMA controller
95  *
96  * Memory allocated by of_dma_controller_register() is freed here.
97  */
98 void of_dma_controller_free(struct device_node *np)
99 {
100         struct of_dma *ofdma;
101
102         ofdma = of_dma_find_controller(np);
103         if (ofdma) {
104                 list_del_rcu(&ofdma->of_dma_controllers);
105                 kfree(ofdma);
106         }
107 }
108 EXPORT_SYMBOL_GPL(of_dma_controller_free);
109
110 /**
111  * of_dma_match_channel - Check if a DMA specifier matches name
112  * @np:         device node to look for DMA channels
113  * @name:       channel name to be matched
114  * @index:      index of DMA specifier in list of DMA specifiers
115  * @dma_spec:   pointer to DMA specifier as found in the device tree
116  *
117  * Check if the DMA specifier pointed to by the index in a list of DMA
118  * specifiers, matches the name provided. Returns 0 if the name matches and
119  * a valid pointer to the DMA specifier is found. Otherwise returns -ENODEV.
120  */
121 static int of_dma_match_channel(struct device_node *np, char *name, int index,
122                                 struct of_phandle_args *dma_spec)
123 {
124         const char *s;
125
126         if (of_property_read_string_index(np, "dma-names", index, &s))
127                 return -ENODEV;
128
129         if (strcmp(name, s))
130                 return -ENODEV;
131
132         if (of_parse_phandle_with_args(np, "dmas", "#dma-cells", index,
133                                        dma_spec))
134                 return -ENODEV;
135
136         return 0;
137 }
138
139 /**
140  * of_dma_request_slave_channel - Get the DMA slave channel
141  * @np:         device node to get DMA request from
142  * @name:       name of desired channel
143  *
144  * Returns pointer to appropriate dma channel on success or NULL on error.
145  */
146 struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
147                                               char *name)
148 {
149         struct of_phandle_args  dma_spec;
150         struct of_dma           *ofdma;
151         struct dma_chan         *chan;
152         int                     count, i;
153
154         if (!np || !name) {
155                 pr_err("%s: not enough information provided\n", __func__);
156                 return NULL;
157         }
158
159         count = of_property_count_strings(np, "dma-names");
160         if (count < 0) {
161                 pr_err("%s: dma-names property missing or empty\n", __func__);
162                 return NULL;
163         }
164
165         for (i = 0; i < count; i++) {
166                 if (of_dma_match_channel(np, name, i, &dma_spec))
167                         continue;
168
169                 ofdma = of_dma_find_controller(dma_spec.np);
170                 if (!ofdma) {
171                         pr_debug("%s: can't find DMA controller %s\n",
172                                  np->full_name, dma_spec.np->full_name);
173                         continue;
174                 }
175
176                 if (dma_spec.args_count != ofdma->of_dma_nbcells) {
177                         pr_debug("%s: wrong #dma-cells for %s\n", np->full_name,
178                                  dma_spec.np->full_name);
179                         continue;
180                 }
181
182                 chan = ofdma->of_dma_xlate(&dma_spec, ofdma);
183
184                 of_node_put(dma_spec.np);
185
186                 if (chan)
187                         return chan;
188         }
189
190         return NULL;
191 }
192
193 /**
194  * of_dma_simple_xlate - Simple DMA engine translation function
195  * @dma_spec:   pointer to DMA specifier as found in the device tree
196  * @of_dma:     pointer to DMA controller data
197  *
198  * A simple translation function for devices that use a 32-bit value for the
199  * filter_param when calling the DMA engine dma_request_channel() function.
200  * Note that this translation function requires that #dma-cells is equal to 1
201  * and the argument of the dma specifier is the 32-bit filter_param. Returns
202  * pointer to appropriate dma channel on success or NULL on error.
203  */
204 struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
205                                                 struct of_dma *ofdma)
206 {
207         int count = dma_spec->args_count;
208         struct of_dma_filter_info *info = ofdma->of_dma_data;
209
210         if (!info || !info->filter_fn)
211                 return NULL;
212
213         if (count != 1)
214                 return NULL;
215
216         return dma_request_channel(info->dma_cap, info->filter_fn,
217                         &dma_spec->args[0]);
218 }
219 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);