Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : #include <linux/string.h>
3 : : #include <linux/kernel.h>
4 : : #include <linux/of.h>
5 : : #include <linux/of_device.h>
6 : : #include <linux/of_address.h>
7 : : #include <linux/of_iommu.h>
8 : : #include <linux/dma-mapping.h>
9 : : #include <linux/init.h>
10 : : #include <linux/module.h>
11 : : #include <linux/mod_devicetable.h>
12 : : #include <linux/slab.h>
13 : : #include <linux/platform_device.h>
14 : :
15 : : #include <asm/errno.h>
16 : : #include "of_private.h"
17 : :
18 : : /**
19 : : * of_match_device - Tell if a struct device matches an of_device_id list
20 : : * @matches: array of of device match structures to search in
21 : : * @dev: the of device structure to match against
22 : : *
23 : : * Used by a driver to check whether an platform_device present in the
24 : : * system is in its list of supported devices.
25 : : */
26 : 665792 : const struct of_device_id *of_match_device(const struct of_device_id *matches,
27 : : const struct device *dev)
28 : : {
29 [ + - + - : 667408 : if ((!matches) || (!dev->of_node))
+ + + + ]
30 : : return NULL;
31 : 405212 : return of_match_node(matches, dev->of_node);
32 : : }
33 : : EXPORT_SYMBOL(of_match_device);
34 : :
35 : 0 : struct platform_device *of_dev_get(struct platform_device *dev)
36 : : {
37 : : struct device *tmp;
38 : :
39 [ # # ]: 0 : if (!dev)
40 : : return NULL;
41 : 0 : tmp = get_device(&dev->dev);
42 [ # # ]: 0 : if (tmp)
43 : 0 : return to_platform_device(tmp);
44 : : else
45 : : return NULL;
46 : : }
47 : : EXPORT_SYMBOL(of_dev_get);
48 : :
49 : 0 : void of_dev_put(struct platform_device *dev)
50 : : {
51 [ # # ]: 0 : if (dev)
52 : 0 : put_device(&dev->dev);
53 : 0 : }
54 : : EXPORT_SYMBOL(of_dev_put);
55 : :
56 : 9696 : int of_device_add(struct platform_device *ofdev)
57 : : {
58 [ - + ]: 9696 : BUG_ON(ofdev->dev.of_node == NULL);
59 : :
60 : : /* name and id have to be set so that the platform bus doesn't get
61 : : * confused on matching */
62 : 9696 : ofdev->name = dev_name(&ofdev->dev);
63 : 9696 : ofdev->id = PLATFORM_DEVID_NONE;
64 : :
65 : : /*
66 : : * If this device has not binding numa node in devicetree, that is
67 : : * of_node_to_nid returns NUMA_NO_NODE. device_add will assume that this
68 : : * device is on the same node as the parent.
69 : : */
70 : : set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node));
71 : :
72 : 9696 : return device_add(&ofdev->dev);
73 : : }
74 : :
75 : : /**
76 : : * of_dma_configure - Setup DMA configuration
77 : : * @dev: Device to apply DMA configuration
78 : : * @np: Pointer to OF node having DMA configuration
79 : : * @force_dma: Whether device is to be set up by of_dma_configure() even if
80 : : * DMA capability is not explicitly described by firmware.
81 : : *
82 : : * Try to get devices's DMA configuration from DT and update it
83 : : * accordingly.
84 : : *
85 : : * If platform code needs to use its own special DMA configuration, it
86 : : * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
87 : : * to fix up DMA configuration.
88 : : */
89 : 10908 : int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
90 : : {
91 : 10908 : u64 dma_addr, paddr, size = 0;
92 : : int ret;
93 : : bool coherent;
94 : : unsigned long offset;
95 : : const struct iommu_ops *iommu;
96 : : u64 mask, end;
97 : :
98 : 10908 : ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
99 [ + + ]: 10908 : if (ret < 0) {
100 : : /*
101 : : * For legacy reasons, we have to assume some devices need
102 : : * DMA configuration regardless of whether "dma-ranges" is
103 : : * correctly specified or not.
104 : : */
105 [ - + ]: 1616 : if (!force_dma)
106 [ # # ]: 0 : return ret == -ENODEV ? 0 : ret;
107 : :
108 : 1616 : dma_addr = offset = 0;
109 : : } else {
110 : 9292 : offset = PFN_DOWN(paddr - dma_addr);
111 : :
112 : : /*
113 : : * Add a work around to treat the size as mask + 1 in case
114 : : * it is defined in DT as a mask.
115 : : */
116 [ - + ]: 9292 : if (size & 1) {
117 : 0 : dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
118 : : size);
119 : 0 : size = size + 1;
120 : : }
121 : :
122 [ - + ]: 9292 : if (!size) {
123 : 0 : dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
124 : 0 : return -EINVAL;
125 : : }
126 : : dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
127 : : }
128 : :
129 : : /*
130 : : * If @dev is expected to be DMA-capable then the bus code that created
131 : : * it should have initialised its dma_mask pointer by this point. For
132 : : * now, we'll continue the legacy behaviour of coercing it to the
133 : : * coherent mask if not, but we'll no longer do so quietly.
134 : : */
135 [ - + ]: 10908 : if (!dev->dma_mask) {
136 : 0 : dev_warn(dev, "DMA mask not set\n");
137 : 0 : dev->dma_mask = &dev->coherent_dma_mask;
138 : : }
139 : :
140 [ + + + - ]: 10908 : if (!size && dev->coherent_dma_mask)
141 : 1616 : size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
142 [ - + ]: 9292 : else if (!size)
143 : 0 : size = 1ULL << 32;
144 : :
145 : 10908 : dev->dma_pfn_offset = offset;
146 : :
147 : : /*
148 : : * Limit coherent and dma mask based on size and default mask
149 : : * set by the driver.
150 : : */
151 : 10908 : end = dma_addr + size - 1;
152 [ - + # # : 32724 : mask = DMA_BIT_MASK(ilog2(end) + 1);
# # + - -
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
153 : 10908 : dev->coherent_dma_mask &= mask;
154 : 10908 : *dev->dma_mask &= mask;
155 : : /* ...but only set bus limit if we found valid dma-ranges earlier */
156 [ + + ]: 10908 : if (!ret)
157 : 9292 : dev->bus_dma_limit = end;
158 : :
159 : 10908 : coherent = of_dma_is_coherent(np);
160 : : dev_dbg(dev, "device is%sdma coherent\n",
161 : : coherent ? " " : " not ");
162 : :
163 : : iommu = of_iommu_configure(dev, np);
164 : : if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
165 : : return -EPROBE_DEFER;
166 : :
167 : : dev_dbg(dev, "device is%sbehind an iommu\n",
168 : : iommu ? " " : " not ");
169 : :
170 : 10908 : arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
171 : :
172 : 10908 : return 0;
173 : : }
174 : : EXPORT_SYMBOL_GPL(of_dma_configure);
175 : :
176 : 0 : int of_device_register(struct platform_device *pdev)
177 : : {
178 : 0 : device_initialize(&pdev->dev);
179 : 0 : return of_device_add(pdev);
180 : : }
181 : : EXPORT_SYMBOL(of_device_register);
182 : :
183 : 0 : void of_device_unregister(struct platform_device *ofdev)
184 : : {
185 : 0 : device_unregister(&ofdev->dev);
186 : 0 : }
187 : : EXPORT_SYMBOL(of_device_unregister);
188 : :
189 : 1616 : const void *of_device_get_match_data(const struct device *dev)
190 : : {
191 : : const struct of_device_id *match;
192 : :
193 : 1616 : match = of_match_device(dev->driver->of_match_table, dev);
194 [ + - ]: 1616 : if (!match)
195 : : return NULL;
196 : :
197 : 1616 : return match->data;
198 : : }
199 : : EXPORT_SYMBOL(of_device_get_match_data);
200 : :
201 : 79636 : static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
202 : : {
203 : : const char *compat;
204 : : char *c;
205 : : struct property *p;
206 : : ssize_t csize;
207 : : ssize_t tsize;
208 : :
209 [ + - + + ]: 79636 : if ((!dev) || (!dev->of_node))
210 : : return -ENODEV;
211 : :
212 : : /* Name & Type */
213 : : /* %p eats all alphanum characters, so %c must be used here */
214 : 159264 : csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
215 : : of_node_get_device_type(dev->of_node));
216 : : tsize = csize;
217 : 79636 : len -= csize;
218 [ + + ]: 79636 : if (str)
219 : 79634 : str += csize;
220 : :
221 [ + + ]: 168568 : of_property_for_each_string(dev->of_node, "compatible", p, compat) {
222 : 88932 : csize = strlen(compat) + 1;
223 : 88932 : tsize += csize;
224 [ + + ]: 88932 : if (csize > len)
225 : 6 : continue;
226 : :
227 : 88928 : csize = snprintf(str, len, "C%s", compat);
228 [ + + ]: 266790 : for (c = str; c; ) {
229 : 88934 : c = strchr(c, ' ');
230 [ + + ]: 88934 : if (c)
231 : 4 : *c++ = '_';
232 : : }
233 : 88928 : len -= csize;
234 : 88928 : str += csize;
235 : : }
236 : :
237 : 79624 : return tsize;
238 : : }
239 : :
240 : 0 : int of_device_request_module(struct device *dev)
241 : : {
242 : : char *str;
243 : : ssize_t size;
244 : : int ret;
245 : :
246 : 0 : size = of_device_get_modalias(dev, NULL, 0);
247 [ # # ]: 0 : if (size < 0)
248 : : return size;
249 : :
250 : 0 : str = kmalloc(size + 1, GFP_KERNEL);
251 [ # # ]: 0 : if (!str)
252 : : return -ENOMEM;
253 : :
254 : 0 : of_device_get_modalias(dev, str, size);
255 : 0 : str[size] = '\0';
256 : 0 : ret = request_module(str);
257 : 0 : kfree(str);
258 : :
259 : 0 : return ret;
260 : : }
261 : : EXPORT_SYMBOL_GPL(of_device_request_module);
262 : :
263 : : /**
264 : : * of_device_modalias - Fill buffer with newline terminated modalias string
265 : : */
266 : 0 : ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
267 : : {
268 : 0 : ssize_t sl = of_device_get_modalias(dev, str, len - 2);
269 [ # # ]: 0 : if (sl < 0)
270 : : return sl;
271 [ # # ]: 0 : if (sl > len - 2)
272 : : return -ENOMEM;
273 : :
274 : 0 : str[sl++] = '\n';
275 : 0 : str[sl] = 0;
276 : 0 : return sl;
277 : : }
278 : : EXPORT_SYMBOL_GPL(of_device_modalias);
279 : :
280 : : /**
281 : : * of_device_uevent - Display OF related uevent information
282 : : */
283 : 700130 : void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
284 : : {
285 : : const char *compat, *type;
286 : : struct alias_prop *app;
287 : : struct property *p;
288 : : int seen = 0;
289 : :
290 [ + + + + ]: 700130 : if ((!dev) || (!dev->of_node))
291 : 700142 : return;
292 : :
293 : 139768 : add_uevent_var(env, "OF_NAME=%pOFn", dev->of_node);
294 : 139776 : add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node);
295 : 139754 : type = of_node_get_device_type(dev->of_node);
296 [ + + ]: 139780 : if (type)
297 : 6876 : add_uevent_var(env, "OF_TYPE=%s", type);
298 : :
299 : : /* Since the compatible field can contain pretty much anything
300 : : * it's not really legal to split it out with commas. We split it
301 : : * up using a number of environment variables instead. */
302 [ + + ]: 292892 : of_property_for_each_string(dev->of_node, "compatible", p, compat) {
303 : 153116 : add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
304 : 153114 : seen++;
305 : : }
306 : 139772 : add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
307 : :
308 : : seen = 0;
309 : 139774 : mutex_lock(&of_mutex);
310 [ + + ]: 2096700 : list_for_each_entry(app, &aliases_lookup, link) {
311 [ + + ]: 1956920 : if (dev->of_node == app->np) {
312 : 25870 : add_uevent_var(env, "OF_ALIAS_%d=%s", seen,
313 : : app->alias);
314 : 25870 : seen++;
315 : : }
316 : : }
317 : 139780 : mutex_unlock(&of_mutex);
318 : : }
319 : :
320 : 96620 : int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
321 : : {
322 : : int sl;
323 : :
324 [ + - + + ]: 96620 : if ((!dev) || (!dev->of_node))
325 : : return -ENODEV;
326 : :
327 : : /* Devicetree modalias is tricky, we add it in 2 steps */
328 [ + + ]: 79636 : if (add_uevent_var(env, "MODALIAS="))
329 : : return -ENOMEM;
330 : :
331 : 159256 : sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
332 : 79628 : sizeof(env->buf) - env->buflen);
333 [ + + ]: 79632 : if (sl >= (sizeof(env->buf) - env->buflen))
334 : : return -ENOMEM;
335 : 79618 : env->buflen += sl;
336 : :
337 : 79618 : return 0;
338 : : }
339 : : EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
|