]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/core/device.c
dm: Support address translation for simple-bus
[karo-tx-uboot.git] / drivers / core / device.c
1 /*
2  * Device manager
3  *
4  * Copyright (c) 2013 Google, Inc
5  *
6  * (C) Copyright 2012
7  * Pavel Herrmann <morpheus.ibis@gmail.com>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11
12 #include <common.h>
13 #include <fdtdec.h>
14 #include <malloc.h>
15 #include <dm/device.h>
16 #include <dm/device-internal.h>
17 #include <dm/lists.h>
18 #include <dm/platdata.h>
19 #include <dm/uclass.h>
20 #include <dm/uclass-internal.h>
21 #include <dm/util.h>
22 #include <linux/err.h>
23 #include <linux/list.h>
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 int device_bind(struct udevice *parent, const struct driver *drv,
28                 const char *name, void *platdata, int of_offset,
29                 struct udevice **devp)
30 {
31         struct udevice *dev;
32         struct uclass *uc;
33         int size, ret = 0;
34
35         *devp = NULL;
36         if (!name)
37                 return -EINVAL;
38
39         ret = uclass_get(drv->id, &uc);
40         if (ret)
41                 return ret;
42
43         dev = calloc(1, sizeof(struct udevice));
44         if (!dev)
45                 return -ENOMEM;
46
47         INIT_LIST_HEAD(&dev->sibling_node);
48         INIT_LIST_HEAD(&dev->child_head);
49         INIT_LIST_HEAD(&dev->uclass_node);
50         dev->platdata = platdata;
51         dev->name = name;
52         dev->of_offset = of_offset;
53         dev->parent = parent;
54         dev->driver = drv;
55         dev->uclass = uc;
56
57         dev->seq = -1;
58         dev->req_seq = -1;
59         if (IS_ENABLED(CONFIG_OF_CONTROL) && IS_ENABLED(CONFIG_DM_SEQ_ALIAS)) {
60                 /*
61                 * Some devices, such as a SPI bus, I2C bus and serial ports
62                 * are numbered using aliases.
63                 *
64                 * This is just a 'requested' sequence, and will be
65                 * resolved (and ->seq updated) when the device is probed.
66                 */
67                 if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
68                         if (uc->uc_drv->name && of_offset != -1) {
69                                 fdtdec_get_alias_seq(gd->fdt_blob,
70                                                 uc->uc_drv->name, of_offset,
71                                                 &dev->req_seq);
72                         }
73                 }
74         }
75
76         if (!dev->platdata && drv->platdata_auto_alloc_size) {
77                 dev->flags |= DM_FLAG_ALLOC_PDATA;
78                 dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
79                 if (!dev->platdata) {
80                         ret = -ENOMEM;
81                         goto fail_alloc1;
82                 }
83         }
84
85         size = uc->uc_drv->per_device_platdata_auto_alloc_size;
86         if (size) {
87                 dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA;
88                 dev->uclass_platdata = calloc(1, size);
89                 if (!dev->uclass_platdata) {
90                         ret = -ENOMEM;
91                         goto fail_alloc2;
92                 }
93         }
94
95         if (parent) {
96                 size = parent->driver->per_child_platdata_auto_alloc_size;
97                 if (!size) {
98                         size = parent->uclass->uc_drv->
99                                         per_child_platdata_auto_alloc_size;
100                 }
101                 if (size) {
102                         dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA;
103                         dev->parent_platdata = calloc(1, size);
104                         if (!dev->parent_platdata) {
105                                 ret = -ENOMEM;
106                                 goto fail_alloc3;
107                         }
108                 }
109         }
110
111         /* put dev into parent's successor list */
112         if (parent)
113                 list_add_tail(&dev->sibling_node, &parent->child_head);
114
115         ret = uclass_bind_device(dev);
116         if (ret)
117                 goto fail_uclass_bind;
118
119         /* if we fail to bind we remove device from successors and free it */
120         if (drv->bind) {
121                 ret = drv->bind(dev);
122                 if (ret)
123                         goto fail_bind;
124         }
125         if (parent && parent->driver->child_post_bind) {
126                 ret = parent->driver->child_post_bind(dev);
127                 if (ret)
128                         goto fail_child_post_bind;
129         }
130
131         if (parent)
132                 dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
133         *devp = dev;
134
135         return 0;
136
137 fail_child_post_bind:
138         if (IS_ENABLED(CONFIG_DM_DEVICE_REMOVE)) {
139                 if (drv->unbind && drv->unbind(dev)) {
140                         dm_warn("unbind() method failed on dev '%s' on error path\n",
141                                 dev->name);
142                 }
143         }
144
145 fail_bind:
146         if (IS_ENABLED(CONFIG_DM_DEVICE_REMOVE)) {
147                 if (uclass_unbind_device(dev)) {
148                         dm_warn("Failed to unbind dev '%s' on error path\n",
149                                 dev->name);
150                 }
151         }
152 fail_uclass_bind:
153         if (IS_ENABLED(CONFIG_DM_DEVICE_REMOVE)) {
154                 list_del(&dev->sibling_node);
155                 if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
156                         free(dev->parent_platdata);
157                         dev->parent_platdata = NULL;
158                 }
159         }
160 fail_alloc3:
161         if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
162                 free(dev->uclass_platdata);
163                 dev->uclass_platdata = NULL;
164         }
165 fail_alloc2:
166         if (dev->flags & DM_FLAG_ALLOC_PDATA) {
167                 free(dev->platdata);
168                 dev->platdata = NULL;
169         }
170 fail_alloc1:
171         free(dev);
172
173         return ret;
174 }
175
176 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
177                         const struct driver_info *info, struct udevice **devp)
178 {
179         struct driver *drv;
180
181         drv = lists_driver_lookup_name(info->name);
182         if (!drv)
183                 return -ENOENT;
184         if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
185                 return -EPERM;
186
187         return device_bind(parent, drv, info->name, (void *)info->platdata,
188                            -1, devp);
189 }
190
191 static void *alloc_priv(int size, uint flags)
192 {
193         void *priv;
194
195         if (flags & DM_FLAG_ALLOC_PRIV_DMA) {
196                 priv = memalign(ARCH_DMA_MINALIGN, size);
197                 if (priv)
198                         memset(priv, '\0', size);
199         } else {
200                 priv = calloc(1, size);
201         }
202
203         return priv;
204 }
205
206 int device_probe_child(struct udevice *dev, void *parent_priv)
207 {
208         const struct driver *drv;
209         int size = 0;
210         int ret;
211         int seq;
212
213         if (!dev)
214                 return -EINVAL;
215
216         if (dev->flags & DM_FLAG_ACTIVATED)
217                 return 0;
218
219         drv = dev->driver;
220         assert(drv);
221
222         /* Allocate private data if requested */
223         if (drv->priv_auto_alloc_size) {
224                 dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags);
225                 if (!dev->priv) {
226                         ret = -ENOMEM;
227                         goto fail;
228                 }
229         }
230         /* Allocate private data if requested */
231         size = dev->uclass->uc_drv->per_device_auto_alloc_size;
232         if (size) {
233                 dev->uclass_priv = calloc(1, size);
234                 if (!dev->uclass_priv) {
235                         ret = -ENOMEM;
236                         goto fail;
237                 }
238         }
239
240         /* Ensure all parents are probed */
241         if (dev->parent) {
242                 size = dev->parent->driver->per_child_auto_alloc_size;
243                 if (!size) {
244                         size = dev->parent->uclass->uc_drv->
245                                         per_child_auto_alloc_size;
246                 }
247                 if (size) {
248                         dev->parent_priv = alloc_priv(size, drv->flags);
249                         if (!dev->parent_priv) {
250                                 ret = -ENOMEM;
251                                 goto fail;
252                         }
253                         if (parent_priv)
254                                 memcpy(dev->parent_priv, parent_priv, size);
255                 }
256
257                 ret = device_probe(dev->parent);
258                 if (ret)
259                         goto fail;
260         }
261
262         seq = uclass_resolve_seq(dev);
263         if (seq < 0) {
264                 ret = seq;
265                 goto fail;
266         }
267         dev->seq = seq;
268
269         dev->flags |= DM_FLAG_ACTIVATED;
270
271         ret = uclass_pre_probe_device(dev);
272         if (ret)
273                 goto fail;
274
275         if (dev->parent && dev->parent->driver->child_pre_probe) {
276                 ret = dev->parent->driver->child_pre_probe(dev);
277                 if (ret)
278                         goto fail;
279         }
280
281         if (drv->ofdata_to_platdata && dev->of_offset >= 0) {
282                 ret = drv->ofdata_to_platdata(dev);
283                 if (ret)
284                         goto fail;
285         }
286
287         if (drv->probe) {
288                 ret = drv->probe(dev);
289                 if (ret) {
290                         dev->flags &= ~DM_FLAG_ACTIVATED;
291                         goto fail;
292                 }
293         }
294
295         ret = uclass_post_probe_device(dev);
296         if (ret)
297                 goto fail_uclass;
298
299         return 0;
300 fail_uclass:
301         if (device_remove(dev)) {
302                 dm_warn("%s: Device '%s' failed to remove on error path\n",
303                         __func__, dev->name);
304         }
305 fail:
306         dev->flags &= ~DM_FLAG_ACTIVATED;
307
308         dev->seq = -1;
309         device_free(dev);
310
311         return ret;
312 }
313
314 int device_probe(struct udevice *dev)
315 {
316         return device_probe_child(dev, NULL);
317 }
318
319 void *dev_get_platdata(struct udevice *dev)
320 {
321         if (!dev) {
322                 dm_warn("%s: null device\n", __func__);
323                 return NULL;
324         }
325
326         return dev->platdata;
327 }
328
329 void *dev_get_parent_platdata(struct udevice *dev)
330 {
331         if (!dev) {
332                 dm_warn("%s: null device\n", __func__);
333                 return NULL;
334         }
335
336         return dev->parent_platdata;
337 }
338
339 void *dev_get_uclass_platdata(struct udevice *dev)
340 {
341         if (!dev) {
342                 dm_warn("%s: null device\n", __func__);
343                 return NULL;
344         }
345
346         return dev->uclass_platdata;
347 }
348
349 void *dev_get_priv(struct udevice *dev)
350 {
351         if (!dev) {
352                 dm_warn("%s: null device\n", __func__);
353                 return NULL;
354         }
355
356         return dev->priv;
357 }
358
359 void *dev_get_uclass_priv(struct udevice *dev)
360 {
361         if (!dev) {
362                 dm_warn("%s: null device\n", __func__);
363                 return NULL;
364         }
365
366         return dev->uclass_priv;
367 }
368
369 void *dev_get_parentdata(struct udevice *dev)
370 {
371         if (!dev) {
372                 dm_warn("%s: null device\n", __func__);
373                 return NULL;
374         }
375
376         return dev->parent_priv;
377 }
378
379 static int device_get_device_tail(struct udevice *dev, int ret,
380                                   struct udevice **devp)
381 {
382         if (ret)
383                 return ret;
384
385         ret = device_probe(dev);
386         if (ret)
387                 return ret;
388
389         *devp = dev;
390
391         return 0;
392 }
393
394 int device_get_child(struct udevice *parent, int index, struct udevice **devp)
395 {
396         struct udevice *dev;
397
398         list_for_each_entry(dev, &parent->child_head, sibling_node) {
399                 if (!index--)
400                         return device_get_device_tail(dev, 0, devp);
401         }
402
403         return -ENODEV;
404 }
405
406 int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
407                              bool find_req_seq, struct udevice **devp)
408 {
409         struct udevice *dev;
410
411         *devp = NULL;
412         if (seq_or_req_seq == -1)
413                 return -ENODEV;
414
415         list_for_each_entry(dev, &parent->child_head, sibling_node) {
416                 if ((find_req_seq ? dev->req_seq : dev->seq) ==
417                                 seq_or_req_seq) {
418                         *devp = dev;
419                         return 0;
420                 }
421         }
422
423         return -ENODEV;
424 }
425
426 int device_get_child_by_seq(struct udevice *parent, int seq,
427                             struct udevice **devp)
428 {
429         struct udevice *dev;
430         int ret;
431
432         *devp = NULL;
433         ret = device_find_child_by_seq(parent, seq, false, &dev);
434         if (ret == -ENODEV) {
435                 /*
436                  * We didn't find it in probed devices. See if there is one
437                  * that will request this seq if probed.
438                  */
439                 ret = device_find_child_by_seq(parent, seq, true, &dev);
440         }
441         return device_get_device_tail(dev, ret, devp);
442 }
443
444 int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
445                                    struct udevice **devp)
446 {
447         struct udevice *dev;
448
449         *devp = NULL;
450
451         list_for_each_entry(dev, &parent->child_head, sibling_node) {
452                 if (dev->of_offset == of_offset) {
453                         *devp = dev;
454                         return 0;
455                 }
456         }
457
458         return -ENODEV;
459 }
460
461 int device_get_child_by_of_offset(struct udevice *parent, int node,
462                                   struct udevice **devp)
463 {
464         struct udevice *dev;
465         int ret;
466
467         *devp = NULL;
468         ret = device_find_child_by_of_offset(parent, node, &dev);
469         return device_get_device_tail(dev, ret, devp);
470 }
471
472 static struct udevice *_device_find_global_by_of_offset(struct udevice *parent,
473                                                         int of_offset)
474 {
475         struct udevice *dev, *found;
476
477         if (parent->of_offset == of_offset)
478                 return parent;
479
480         list_for_each_entry(dev, &parent->child_head, sibling_node) {
481                 found = _device_find_global_by_of_offset(dev, of_offset);
482                 if (found)
483                         return found;
484         }
485
486         return NULL;
487 }
488
489 int device_get_global_by_of_offset(int of_offset, struct udevice **devp)
490 {
491         struct udevice *dev;
492
493         dev = _device_find_global_by_of_offset(gd->dm_root, of_offset);
494         return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
495 }
496
497 int device_find_first_child(struct udevice *parent, struct udevice **devp)
498 {
499         if (list_empty(&parent->child_head)) {
500                 *devp = NULL;
501         } else {
502                 *devp = list_first_entry(&parent->child_head, struct udevice,
503                                          sibling_node);
504         }
505
506         return 0;
507 }
508
509 int device_find_next_child(struct udevice **devp)
510 {
511         struct udevice *dev = *devp;
512         struct udevice *parent = dev->parent;
513
514         if (list_is_last(&dev->sibling_node, &parent->child_head)) {
515                 *devp = NULL;
516         } else {
517                 *devp = list_entry(dev->sibling_node.next, struct udevice,
518                                    sibling_node);
519         }
520
521         return 0;
522 }
523
524 struct udevice *dev_get_parent(struct udevice *child)
525 {
526         return child->parent;
527 }
528
529 ulong dev_get_driver_data(struct udevice *dev)
530 {
531         return dev->driver_data;
532 }
533
534 const void *dev_get_driver_ops(struct udevice *dev)
535 {
536         if (!dev || !dev->driver->ops)
537                 return NULL;
538
539         return dev->driver->ops;
540 }
541
542 enum uclass_id device_get_uclass_id(struct udevice *dev)
543 {
544         return dev->uclass->uc_drv->id;
545 }
546
547 const char *dev_get_uclass_name(struct udevice *dev)
548 {
549         if (!dev)
550                 return NULL;
551
552         return dev->uclass->uc_drv->name;
553 }
554
555 fdt_addr_t dev_get_addr(struct udevice *dev)
556 {
557 #ifdef CONFIG_OF_CONTROL
558         fdt_addr_t addr;
559
560         addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
561         if (addr != FDT_ADDR_T_NONE) {
562                 if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS)
563                         addr = simple_bus_translate(dev->parent, addr);
564         }
565
566         return addr;
567 #else
568         return FDT_ADDR_T_NONE;
569 #endif
570 }
571
572 bool device_has_children(struct udevice *dev)
573 {
574         return !list_empty(&dev->child_head);
575 }
576
577 bool device_has_active_children(struct udevice *dev)
578 {
579         struct udevice *child;
580
581         for (device_find_first_child(dev, &child);
582              child;
583              device_find_next_child(&child)) {
584                 if (device_active(child))
585                         return true;
586         }
587
588         return false;
589 }
590
591 bool device_is_last_sibling(struct udevice *dev)
592 {
593         struct udevice *parent = dev->parent;
594
595         if (!parent)
596                 return false;
597         return list_is_last(&dev->sibling_node, &parent->child_head);
598 }