dm: core: Allow device_bind() to used without CONFIG_OF_CONTROL
[oweals/u-boot.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 /**
28  * device_chld_unbind() - Unbind all device's children from the device
29  *
30  * On error, the function continues to unbind all children, and reports the
31  * first error.
32  *
33  * @dev:        The device that is to be stripped of its children
34  * @return 0 on success, -ve on error
35  */
36 static int device_chld_unbind(struct udevice *dev)
37 {
38         struct udevice *pos, *n;
39         int ret, saved_ret = 0;
40
41         assert(dev);
42
43         list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
44                 ret = device_unbind(pos);
45                 if (ret && !saved_ret)
46                         saved_ret = ret;
47         }
48
49         return saved_ret;
50 }
51
52 /**
53  * device_chld_remove() - Stop all device's children
54  * @dev:        The device whose children are to be removed
55  * @return 0 on success, -ve on error
56  */
57 static int device_chld_remove(struct udevice *dev)
58 {
59         struct udevice *pos, *n;
60         int ret;
61
62         assert(dev);
63
64         list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
65                 ret = device_remove(pos);
66                 if (ret)
67                         return ret;
68         }
69
70         return 0;
71 }
72
73 int device_bind(struct udevice *parent, struct driver *drv, const char *name,
74                 void *platdata, int of_offset, struct udevice **devp)
75 {
76         struct udevice *dev;
77         struct uclass *uc;
78         int ret = 0;
79
80         *devp = NULL;
81         if (!name)
82                 return -EINVAL;
83
84         ret = uclass_get(drv->id, &uc);
85         if (ret)
86                 return ret;
87
88         dev = calloc(1, sizeof(struct udevice));
89         if (!dev)
90                 return -ENOMEM;
91
92         INIT_LIST_HEAD(&dev->sibling_node);
93         INIT_LIST_HEAD(&dev->child_head);
94         INIT_LIST_HEAD(&dev->uclass_node);
95         dev->platdata = platdata;
96         dev->name = name;
97         dev->of_offset = of_offset;
98         dev->parent = parent;
99         dev->driver = drv;
100         dev->uclass = uc;
101
102         /*
103          * For some devices, such as a SPI or I2C bus, the 'reg' property
104          * is a reasonable indicator of the sequence number. But if there is
105          * an alias, we use that in preference. In any case, this is just
106          * a 'requested' sequence, and will be resolved (and ->seq updated)
107          * when the device is probed.
108          */
109         dev->seq = -1;
110 #ifdef CONFIG_OF_CONTROL
111         dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1);
112         if (uc->uc_drv->name && of_offset != -1) {
113                 fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset,
114                                      &dev->req_seq);
115         }
116 #else
117         dev->req_seq = -1;
118 #endif
119         if (!dev->platdata && drv->platdata_auto_alloc_size)
120                 dev->flags |= DM_FLAG_ALLOC_PDATA;
121
122         /* put dev into parent's successor list */
123         if (parent)
124                 list_add_tail(&dev->sibling_node, &parent->child_head);
125
126         ret = uclass_bind_device(dev);
127         if (ret)
128                 goto fail_bind;
129
130         /* if we fail to bind we remove device from successors and free it */
131         if (drv->bind) {
132                 ret = drv->bind(dev);
133                 if (ret) {
134                         if (uclass_unbind_device(dev)) {
135                                 dm_warn("Failed to unbind dev '%s' on error path\n",
136                                         dev->name);
137                         }
138                         goto fail_bind;
139                 }
140         }
141         if (parent)
142                 dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
143         *devp = dev;
144
145         return 0;
146
147 fail_bind:
148         list_del(&dev->sibling_node);
149         free(dev);
150         return ret;
151 }
152
153 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
154                         const struct driver_info *info, struct udevice **devp)
155 {
156         struct driver *drv;
157
158         drv = lists_driver_lookup_name(info->name);
159         if (!drv)
160                 return -ENOENT;
161         if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
162                 return -EPERM;
163
164         return device_bind(parent, drv, info->name, (void *)info->platdata,
165                            -1, devp);
166 }
167
168 int device_unbind(struct udevice *dev)
169 {
170         struct driver *drv;
171         int ret;
172
173         if (!dev)
174                 return -EINVAL;
175
176         if (dev->flags & DM_FLAG_ACTIVATED)
177                 return -EINVAL;
178
179         drv = dev->driver;
180         assert(drv);
181
182         if (drv->unbind) {
183                 ret = drv->unbind(dev);
184                 if (ret)
185                         return ret;
186         }
187
188         ret = device_chld_unbind(dev);
189         if (ret)
190                 return ret;
191
192         ret = uclass_unbind_device(dev);
193         if (ret)
194                 return ret;
195
196         if (dev->parent)
197                 list_del(&dev->sibling_node);
198         free(dev);
199
200         return 0;
201 }
202
203 /**
204  * device_free() - Free memory buffers allocated by a device
205  * @dev:        Device that is to be started
206  */
207 static void device_free(struct udevice *dev)
208 {
209         int size;
210
211         if (dev->driver->priv_auto_alloc_size) {
212                 free(dev->priv);
213                 dev->priv = NULL;
214         }
215         if (dev->flags & DM_FLAG_ALLOC_PDATA) {
216                 free(dev->platdata);
217                 dev->platdata = NULL;
218         }
219         size = dev->uclass->uc_drv->per_device_auto_alloc_size;
220         if (size) {
221                 free(dev->uclass_priv);
222                 dev->uclass_priv = NULL;
223         }
224         if (dev->parent) {
225                 size = dev->parent->driver->per_child_auto_alloc_size;
226                 if (size) {
227                         free(dev->parent_priv);
228                         dev->parent_priv = NULL;
229                 }
230         }
231 }
232
233 int device_probe(struct udevice *dev)
234 {
235         struct driver *drv;
236         int size = 0;
237         int ret;
238         int seq;
239
240         if (!dev)
241                 return -EINVAL;
242
243         if (dev->flags & DM_FLAG_ACTIVATED)
244                 return 0;
245
246         drv = dev->driver;
247         assert(drv);
248
249         /* Allocate private data and platdata if requested */
250         if (drv->priv_auto_alloc_size) {
251                 dev->priv = calloc(1, drv->priv_auto_alloc_size);
252                 if (!dev->priv) {
253                         ret = -ENOMEM;
254                         goto fail;
255                 }
256         }
257         /* Allocate private data if requested */
258         if (dev->flags & DM_FLAG_ALLOC_PDATA) {
259                 dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
260                 if (!dev->platdata) {
261                         ret = -ENOMEM;
262                         goto fail;
263                 }
264         }
265         size = dev->uclass->uc_drv->per_device_auto_alloc_size;
266         if (size) {
267                 dev->uclass_priv = calloc(1, size);
268                 if (!dev->uclass_priv) {
269                         ret = -ENOMEM;
270                         goto fail;
271                 }
272         }
273
274         /* Ensure all parents are probed */
275         if (dev->parent) {
276                 size = dev->parent->driver->per_child_auto_alloc_size;
277                 if (size) {
278                         dev->parent_priv = calloc(1, size);
279                         if (!dev->parent_priv) {
280                                 ret = -ENOMEM;
281                                 goto fail;
282                         }
283                 }
284
285                 ret = device_probe(dev->parent);
286                 if (ret)
287                         goto fail;
288         }
289
290         seq = uclass_resolve_seq(dev);
291         if (seq < 0) {
292                 ret = seq;
293                 goto fail;
294         }
295         dev->seq = seq;
296
297         if (dev->parent && dev->parent->driver->child_pre_probe) {
298                 ret = dev->parent->driver->child_pre_probe(dev);
299                 if (ret)
300                         goto fail;
301         }
302
303         if (drv->ofdata_to_platdata && dev->of_offset >= 0) {
304                 ret = drv->ofdata_to_platdata(dev);
305                 if (ret)
306                         goto fail;
307         }
308
309         if (drv->probe) {
310                 ret = drv->probe(dev);
311                 if (ret)
312                         goto fail;
313         }
314
315         dev->flags |= DM_FLAG_ACTIVATED;
316
317         ret = uclass_post_probe_device(dev);
318         if (ret) {
319                 dev->flags &= ~DM_FLAG_ACTIVATED;
320                 goto fail_uclass;
321         }
322
323         return 0;
324 fail_uclass:
325         if (device_remove(dev)) {
326                 dm_warn("%s: Device '%s' failed to remove on error path\n",
327                         __func__, dev->name);
328         }
329 fail:
330         dev->seq = -1;
331         device_free(dev);
332
333         return ret;
334 }
335
336 int device_remove(struct udevice *dev)
337 {
338         struct driver *drv;
339         int ret;
340
341         if (!dev)
342                 return -EINVAL;
343
344         if (!(dev->flags & DM_FLAG_ACTIVATED))
345                 return 0;
346
347         drv = dev->driver;
348         assert(drv);
349
350         ret = uclass_pre_remove_device(dev);
351         if (ret)
352                 return ret;
353
354         ret = device_chld_remove(dev);
355         if (ret)
356                 goto err;
357
358         if (drv->remove) {
359                 ret = drv->remove(dev);
360                 if (ret)
361                         goto err_remove;
362         }
363
364         if (dev->parent && dev->parent->driver->child_post_remove) {
365                 ret = dev->parent->driver->child_post_remove(dev);
366                 if (ret) {
367                         dm_warn("%s: Device '%s' failed child_post_remove()",
368                                 __func__, dev->name);
369                 }
370         }
371
372         device_free(dev);
373
374         dev->seq = -1;
375         dev->flags &= ~DM_FLAG_ACTIVATED;
376
377         return ret;
378
379 err_remove:
380         /* We can't put the children back */
381         dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
382                 __func__, dev->name);
383 err:
384         ret = uclass_post_probe_device(dev);
385         if (ret) {
386                 dm_warn("%s: Device '%s' failed to post_probe on error path\n",
387                         __func__, dev->name);
388         }
389
390         return ret;
391 }
392
393 void *dev_get_platdata(struct udevice *dev)
394 {
395         if (!dev) {
396                 dm_warn("%s: null device", __func__);
397                 return NULL;
398         }
399
400         return dev->platdata;
401 }
402
403 void *dev_get_priv(struct udevice *dev)
404 {
405         if (!dev) {
406                 dm_warn("%s: null device", __func__);
407                 return NULL;
408         }
409
410         return dev->priv;
411 }
412
413 void *dev_get_parentdata(struct udevice *dev)
414 {
415         if (!dev) {
416                 dm_warn("%s: null device", __func__);
417                 return NULL;
418         }
419
420         return dev->parent_priv;
421 }
422
423 static int device_get_device_tail(struct udevice *dev, int ret,
424                                   struct udevice **devp)
425 {
426         if (ret)
427                 return ret;
428
429         ret = device_probe(dev);
430         if (ret)
431                 return ret;
432
433         *devp = dev;
434
435         return 0;
436 }
437
438 int device_get_child(struct udevice *parent, int index, struct udevice **devp)
439 {
440         struct udevice *dev;
441
442         list_for_each_entry(dev, &parent->child_head, sibling_node) {
443                 if (!index--)
444                         return device_get_device_tail(dev, 0, devp);
445         }
446
447         return -ENODEV;
448 }
449
450 int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
451                              bool find_req_seq, struct udevice **devp)
452 {
453         struct udevice *dev;
454
455         *devp = NULL;
456         if (seq_or_req_seq == -1)
457                 return -ENODEV;
458
459         list_for_each_entry(dev, &parent->child_head, sibling_node) {
460                 if ((find_req_seq ? dev->req_seq : dev->seq) ==
461                                 seq_or_req_seq) {
462                         *devp = dev;
463                         return 0;
464                 }
465         }
466
467         return -ENODEV;
468 }
469
470 int device_get_child_by_seq(struct udevice *parent, int seq,
471                             struct udevice **devp)
472 {
473         struct udevice *dev;
474         int ret;
475
476         *devp = NULL;
477         ret = device_find_child_by_seq(parent, seq, false, &dev);
478         if (ret == -ENODEV) {
479                 /*
480                  * We didn't find it in probed devices. See if there is one
481                  * that will request this seq if probed.
482                  */
483                 ret = device_find_child_by_seq(parent, seq, true, &dev);
484         }
485         return device_get_device_tail(dev, ret, devp);
486 }
487
488 int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
489                                    struct udevice **devp)
490 {
491         struct udevice *dev;
492
493         *devp = NULL;
494
495         list_for_each_entry(dev, &parent->child_head, sibling_node) {
496                 if (dev->of_offset == of_offset) {
497                         *devp = dev;
498                         return 0;
499                 }
500         }
501
502         return -ENODEV;
503 }
504
505 int device_get_child_by_of_offset(struct udevice *parent, int seq,
506                                   struct udevice **devp)
507 {
508         struct udevice *dev;
509         int ret;
510
511         *devp = NULL;
512         ret = device_find_child_by_of_offset(parent, seq, &dev);
513         return device_get_device_tail(dev, ret, devp);
514 }