xref: /rk3399_rockchip-uboot/drivers/core/device.c (revision f8a85449ef3e0963add728815771ccc09aa99875)
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, struct driver *drv, const char *name,
28 		void *platdata, int of_offset, struct udevice **devp)
29 {
30 	struct udevice *dev;
31 	struct uclass *uc;
32 	int ret = 0;
33 
34 	*devp = NULL;
35 	if (!name)
36 		return -EINVAL;
37 
38 	ret = uclass_get(drv->id, &uc);
39 	if (ret)
40 		return ret;
41 
42 	dev = calloc(1, sizeof(struct udevice));
43 	if (!dev)
44 		return -ENOMEM;
45 
46 	INIT_LIST_HEAD(&dev->sibling_node);
47 	INIT_LIST_HEAD(&dev->child_head);
48 	INIT_LIST_HEAD(&dev->uclass_node);
49 	dev->platdata = platdata;
50 	dev->name = name;
51 	dev->of_offset = of_offset;
52 	dev->parent = parent;
53 	dev->driver = drv;
54 	dev->uclass = uc;
55 
56 	/*
57 	 * For some devices, such as a SPI or I2C bus, the 'reg' property
58 	 * is a reasonable indicator of the sequence number. But if there is
59 	 * an alias, we use that in preference. In any case, this is just
60 	 * a 'requested' sequence, and will be resolved (and ->seq updated)
61 	 * when the device is probed.
62 	 */
63 	dev->seq = -1;
64 #ifdef CONFIG_OF_CONTROL
65 	dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1);
66 	if (!IS_ERR_VALUE(dev->req_seq))
67 		dev->req_seq &= INT_MAX;
68 	if (uc->uc_drv->name && of_offset != -1) {
69 		fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset,
70 				     &dev->req_seq);
71 	}
72 #else
73 	dev->req_seq = -1;
74 #endif
75 	if (!dev->platdata && drv->platdata_auto_alloc_size) {
76 		dev->flags |= DM_FLAG_ALLOC_PDATA;
77 		dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
78 		if (!dev->platdata) {
79 			ret = -ENOMEM;
80 			goto fail_alloc1;
81 		}
82 	}
83 
84 	/* put dev into parent's successor list */
85 	if (parent)
86 		list_add_tail(&dev->sibling_node, &parent->child_head);
87 
88 	ret = uclass_bind_device(dev);
89 	if (ret)
90 		goto fail_uclass_bind;
91 
92 	/* if we fail to bind we remove device from successors and free it */
93 	if (drv->bind) {
94 		ret = drv->bind(dev);
95 		if (ret)
96 			goto fail_bind;
97 	}
98 	if (parent)
99 		dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
100 	*devp = dev;
101 
102 	return 0;
103 
104 fail_bind:
105 	if (uclass_unbind_device(dev)) {
106 		dm_warn("Failed to unbind dev '%s' on error path\n",
107 			dev->name);
108 	}
109 fail_uclass_bind:
110 	if (parent)
111 		list_del(&dev->sibling_node);
112 	if (dev->flags & DM_FLAG_ALLOC_PDATA) {
113 		free(dev->platdata);
114 		dev->platdata = NULL;
115 	}
116 fail_alloc1:
117 	free(dev);
118 
119 	return ret;
120 }
121 
122 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
123 			const struct driver_info *info, struct udevice **devp)
124 {
125 	struct driver *drv;
126 
127 	drv = lists_driver_lookup_name(info->name);
128 	if (!drv)
129 		return -ENOENT;
130 	if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
131 		return -EPERM;
132 
133 	return device_bind(parent, drv, info->name, (void *)info->platdata,
134 			   -1, devp);
135 }
136 
137 int device_probe_child(struct udevice *dev, void *parent_priv)
138 {
139 	struct driver *drv;
140 	int size = 0;
141 	int ret;
142 	int seq;
143 
144 	if (!dev)
145 		return -EINVAL;
146 
147 	if (dev->flags & DM_FLAG_ACTIVATED)
148 		return 0;
149 
150 	drv = dev->driver;
151 	assert(drv);
152 
153 	/* Allocate private data if requested */
154 	if (drv->priv_auto_alloc_size) {
155 		dev->priv = calloc(1, drv->priv_auto_alloc_size);
156 		if (!dev->priv) {
157 			ret = -ENOMEM;
158 			goto fail;
159 		}
160 	}
161 	/* Allocate private data if requested */
162 	size = dev->uclass->uc_drv->per_device_auto_alloc_size;
163 	if (size) {
164 		dev->uclass_priv = calloc(1, size);
165 		if (!dev->uclass_priv) {
166 			ret = -ENOMEM;
167 			goto fail;
168 		}
169 	}
170 
171 	/* Ensure all parents are probed */
172 	if (dev->parent) {
173 		size = dev->parent->driver->per_child_auto_alloc_size;
174 		if (size) {
175 			dev->parent_priv = calloc(1, size);
176 			if (!dev->parent_priv) {
177 				ret = -ENOMEM;
178 				goto fail;
179 			}
180 			if (parent_priv)
181 				memcpy(dev->parent_priv, parent_priv, size);
182 		}
183 
184 		ret = device_probe(dev->parent);
185 		if (ret)
186 			goto fail;
187 	}
188 
189 	seq = uclass_resolve_seq(dev);
190 	if (seq < 0) {
191 		ret = seq;
192 		goto fail;
193 	}
194 	dev->seq = seq;
195 
196 	if (dev->parent && dev->parent->driver->child_pre_probe) {
197 		ret = dev->parent->driver->child_pre_probe(dev);
198 		if (ret)
199 			goto fail;
200 	}
201 
202 	if (drv->ofdata_to_platdata && dev->of_offset >= 0) {
203 		ret = drv->ofdata_to_platdata(dev);
204 		if (ret)
205 			goto fail;
206 	}
207 
208 	if (drv->probe) {
209 		ret = drv->probe(dev);
210 		if (ret)
211 			goto fail;
212 	}
213 
214 	dev->flags |= DM_FLAG_ACTIVATED;
215 
216 	ret = uclass_post_probe_device(dev);
217 	if (ret) {
218 		dev->flags &= ~DM_FLAG_ACTIVATED;
219 		goto fail_uclass;
220 	}
221 
222 	return 0;
223 fail_uclass:
224 	if (device_remove(dev)) {
225 		dm_warn("%s: Device '%s' failed to remove on error path\n",
226 			__func__, dev->name);
227 	}
228 fail:
229 	dev->seq = -1;
230 	device_free(dev);
231 
232 	return ret;
233 }
234 
235 int device_probe(struct udevice *dev)
236 {
237 	return device_probe_child(dev, NULL);
238 }
239 
240 void *dev_get_platdata(struct udevice *dev)
241 {
242 	if (!dev) {
243 		dm_warn("%s: null device\n", __func__);
244 		return NULL;
245 	}
246 
247 	return dev->platdata;
248 }
249 
250 void *dev_get_priv(struct udevice *dev)
251 {
252 	if (!dev) {
253 		dm_warn("%s: null device\n", __func__);
254 		return NULL;
255 	}
256 
257 	return dev->priv;
258 }
259 
260 void *dev_get_parentdata(struct udevice *dev)
261 {
262 	if (!dev) {
263 		dm_warn("%s: null device\n", __func__);
264 		return NULL;
265 	}
266 
267 	return dev->parent_priv;
268 }
269 
270 static int device_get_device_tail(struct udevice *dev, int ret,
271 				  struct udevice **devp)
272 {
273 	if (ret)
274 		return ret;
275 
276 	ret = device_probe(dev);
277 	if (ret)
278 		return ret;
279 
280 	*devp = dev;
281 
282 	return 0;
283 }
284 
285 int device_get_child(struct udevice *parent, int index, struct udevice **devp)
286 {
287 	struct udevice *dev;
288 
289 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
290 		if (!index--)
291 			return device_get_device_tail(dev, 0, devp);
292 	}
293 
294 	return -ENODEV;
295 }
296 
297 int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
298 			     bool find_req_seq, struct udevice **devp)
299 {
300 	struct udevice *dev;
301 
302 	*devp = NULL;
303 	if (seq_or_req_seq == -1)
304 		return -ENODEV;
305 
306 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
307 		if ((find_req_seq ? dev->req_seq : dev->seq) ==
308 				seq_or_req_seq) {
309 			*devp = dev;
310 			return 0;
311 		}
312 	}
313 
314 	return -ENODEV;
315 }
316 
317 int device_get_child_by_seq(struct udevice *parent, int seq,
318 			    struct udevice **devp)
319 {
320 	struct udevice *dev;
321 	int ret;
322 
323 	*devp = NULL;
324 	ret = device_find_child_by_seq(parent, seq, false, &dev);
325 	if (ret == -ENODEV) {
326 		/*
327 		 * We didn't find it in probed devices. See if there is one
328 		 * that will request this seq if probed.
329 		 */
330 		ret = device_find_child_by_seq(parent, seq, true, &dev);
331 	}
332 	return device_get_device_tail(dev, ret, devp);
333 }
334 
335 int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
336 				   struct udevice **devp)
337 {
338 	struct udevice *dev;
339 
340 	*devp = NULL;
341 
342 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
343 		if (dev->of_offset == of_offset) {
344 			*devp = dev;
345 			return 0;
346 		}
347 	}
348 
349 	return -ENODEV;
350 }
351 
352 int device_get_child_by_of_offset(struct udevice *parent, int seq,
353 				  struct udevice **devp)
354 {
355 	struct udevice *dev;
356 	int ret;
357 
358 	*devp = NULL;
359 	ret = device_find_child_by_of_offset(parent, seq, &dev);
360 	return device_get_device_tail(dev, ret, devp);
361 }
362 
363 int device_find_first_child(struct udevice *parent, struct udevice **devp)
364 {
365 	if (list_empty(&parent->child_head)) {
366 		*devp = NULL;
367 	} else {
368 		*devp = list_first_entry(&parent->child_head, struct udevice,
369 					 sibling_node);
370 	}
371 
372 	return 0;
373 }
374 
375 int device_find_next_child(struct udevice **devp)
376 {
377 	struct udevice *dev = *devp;
378 	struct udevice *parent = dev->parent;
379 
380 	if (list_is_last(&dev->sibling_node, &parent->child_head)) {
381 		*devp = NULL;
382 	} else {
383 		*devp = list_entry(dev->sibling_node.next, struct udevice,
384 				   sibling_node);
385 	}
386 
387 	return 0;
388 }
389 
390 struct udevice *dev_get_parent(struct udevice *child)
391 {
392 	return child->parent;
393 }
394 
395 ulong dev_get_of_data(struct udevice *dev)
396 {
397 	return dev->of_id->data;
398 }
399