]> git.ipfire.org Git - thirdparty/u-boot.git/blame - include/bootdev.h
board: rockchip: add Theobroma-Systems RK3588 Jaguar SBC
[thirdparty/u-boot.git] / include / bootdev.h
CommitLineData
201417d7
SG
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright 2021 Google LLC
4 * Written by Simon Glass <sjg@chromium.org>
5 */
6
7#ifndef __bootdev_h
8#define __bootdev_h
9
e62714ca 10#include <dm/uclass-id.h>
201417d7
SG
11#include <linux/list.h>
12
13struct bootflow;
14struct bootflow_iter;
bd90b092 15struct bootstd_priv;
201417d7
SG
16struct udevice;
17
18/**
19 * enum bootdev_prio_t - priority of each bootdev
20 *
21 * These values are associated with each bootdev and set up by the driver.
22 *
23 * Smallest value is the highest priority. By default, bootdevs are scanned from
24 * highest to lowest priority
eacc2611
SG
25 *
26 * BOOTDEVP_0_NONE: Invalid value, do not use
27 * @BOOTDEVP_6_PRE_SCAN: Scan bootdevs with this priority always, before
28 * starting any bootflow scan
29 * @BOOTDEVP_2_INTERNAL_FAST: Internal devices which don't need scanning and
30 * generally very quick to access, e.g. less than 100ms
31 * @BOOTDEVP_3_INTERNAL_SLOW: Internal devices which don't need scanning but
32 * take a significant fraction of a second to access
33 * @BOOTDEVP_4_SCAN_FAST: Extenal devices which need scanning or bus
34 * enumeration to find, but this enumeration happens quickly, typically under
35 * 100ms
36 * @BOOTDEVP_5_SCAN_SLOW: Extenal devices which need scanning or bus
37 * enumeration to find. The enumeration takes significant fraction of a second
38 * to complete
39 * @BOOTDEVP_6_NET_BASE: Basic network devices which are quickly and easily
40 * available. Typically used for an internal Ethernet device
41 * @BOOTDEVP_7_NET_FALLBACK: Secondary network devices which require extra time
42 * to start up, or are less desirable. Typically used for secondary Ethernet
43 * devices. Note that USB ethernet devices are found during USB enumeration,
44 * so do not use this priority
201417d7
SG
45 */
46enum bootdev_prio_t {
eacc2611
SG
47 BOOTDEVP_0_NONE,
48 BOOTDEVP_1_PRE_SCAN,
49 BOOTDEVP_2_INTERNAL_FAST,
50 BOOTDEVP_3_INTERNAL_SLOW,
51 BOOTDEVP_4_SCAN_FAST,
52 BOOTDEVP_5_SCAN_SLOW,
53 BOOTDEVP_6_NET_BASE,
54 BOOTDEVP_7_NET_FALLBACK,
201417d7
SG
55
56 BOOTDEVP_COUNT,
57};
58
bd90b092
SG
59struct bootdev_hunter;
60
61/**
62 * bootdev_hunter_func - function to probe for bootdevs of a given type
63 *
64 * This should hunt around for bootdevs of the given type, binding them as it
65 * finds them. This may involve bus enumeration, etc.
66 *
67 * @info: Info structure describing this hunter
68 * @show: true to show information from the hunter
ee2ce292 69 * Returns: 0 if OK, -ENOENT on device not found, otherwise -ve on error
bd90b092
SG
70 */
71typedef int (*bootdev_hunter_func)(struct bootdev_hunter *info, bool show);
72
73/**
74 * struct bootdev_hunter - information about how to hunt for bootdevs
75 *
76 * @prio: Scanning priority of this hunter
77 * @uclass: Uclass ID for the media associated with this bootdev
78 * @drv: bootdev driver for the things found by this hunter
79 * @hunt: Function to call to hunt for bootdevs of this type (NULL if none)
80 *
81 * Some bootdevs are not visible until other devices are enumerated. For
82 * example, USB bootdevs only appear when the USB bus is enumerated.
83 *
84 * On the other hand, we don't always want to enumerate all the buses just to
85 * find the first valid bootdev. Ideally we want to work through them in
86 * priority order, so that the fastest bootdevs are discovered first.
87 *
88 * This struct holds information about the bootdev so we can determine the probe
89 * order and how to hunt for bootdevs of this type
90 */
91struct bootdev_hunter {
92 enum bootdev_prio_t prio;
93 enum uclass_id uclass;
94 struct driver *drv;
95 bootdev_hunter_func hunt;
96};
97
98/* declare a new bootdev hunter */
99#define BOOTDEV_HUNTER(__name) \
100 ll_entry_declare(struct bootdev_hunter, __name, bootdev_hunter)
101
102/* access a bootdev hunter by name */
103#define BOOTDEV_HUNTER_GET(__name) \
104 ll_entry_get(struct bootdev_hunter, __name, bootdev_hunter)
105
201417d7
SG
106/**
107 * struct bootdev_uc_plat - uclass information about a bootdev
108 *
109 * This is attached to each device in the bootdev uclass and accessible via
110 * dev_get_uclass_plat(dev)
111 *
112 * @bootflows: List of available bootflows for this bootdev
113 * @piro: Priority of this bootdev
114 */
115struct bootdev_uc_plat {
116 struct list_head bootflow_head;
117 enum bootdev_prio_t prio;
118};
119
120/** struct bootdev_ops - Operations for the bootdev uclass */
121struct bootdev_ops {
122 /**
b85fc8db
SG
123 * get_bootflow() - get a bootflow (optional)
124 *
125 * If this is NULL then the default implementaton is used, which is
126 * default_get_bootflow()
201417d7
SG
127 *
128 * @dev: Bootflow device to check
129 * @iter: Provides current dev, part, method to get. Should update
130 * max_part if there is a partition table. Should update state,
131 * subdir, fname, buf, size according to progress
132 * @bflow: Updated bootflow if found
133 * Return: 0 if OK, -ESHUTDOWN if there are no more bootflows on this
134 * device, -ENOSYS if this device doesn't support bootflows,
135 * other -ve value on other error
136 */
137 int (*get_bootflow)(struct udevice *dev, struct bootflow_iter *iter,
138 struct bootflow *bflow);
139};
140
141#define bootdev_get_ops(dev) ((struct bootdev_ops *)(dev)->driver->ops)
142
143/**
144 * bootdev_get_bootflow() - get a bootflow
145 *
146 * @dev: Bootflow device to check
147 * @iter: Provides current part, method to get
148 * @bflow: Returns bootflow if found
149 * Return: 0 if OK, -ESHUTDOWN if there are no more bootflows on this device,
150 * -ENOSYS if this device doesn't support bootflows, other -ve value on
151 * other error
152 */
153int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
154 struct bootflow *bflow);
155
156/**
157 * bootdev_bind() - Bind a new named bootdev device
158 *
159 * @parent: Parent of the new device
160 * @drv_name: Driver name to use for the bootdev device
161 * @name: Name for the device (parent name is prepended)
162 * @devp: the new device (which has not been probed)
163 */
164int bootdev_bind(struct udevice *parent, const char *drv_name, const char *name,
165 struct udevice **devp);
166
167/**
168 * bootdev_find_in_blk() - Find a bootdev in a block device
169 *
170 * @dev: Bootflow device associated with this block device
171 * @blk: Block device to search
172 * @iter: Provides current dev, part, method to get. Should update
173 * max_part if there is a partition table
174 * @bflow: On entry, provides information about the partition and device to
175 * check. On exit, returns bootflow if found
176 * Return: 0 if found, -ESHUTDOWN if no more bootflows, other -ve on error
177 */
178int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
179 struct bootflow_iter *iter, struct bootflow *bflow);
180
181/**
182 * bootdev_list() - List all available bootdevs
183 *
184 * @probe: true to probe devices, false to leave them as is
185 */
186void bootdev_list(bool probe);
187
188/**
189 * bootdev_clear_bootflows() - Clear bootflows from a bootdev
190 *
191 * Each bootdev maintains a list of discovered bootflows. This provides a
192 * way to clear it. These bootflows are removed from the global list too.
193 *
194 * @dev: bootdev device to update
195 */
196void bootdev_clear_bootflows(struct udevice *dev);
197
198/**
199 * bootdev_add_bootflow() - Add a bootflow to the bootdev's list
200 *
201 * All fields in @bflow must be set up. Note that @bflow->dev is used to add the
202 * bootflow to that device.
203 *
4de979f6 204 * @dev: Bootdev device to add to
201417d7
SG
205 * @bflow: Bootflow to add. Note that fields within bflow must be allocated
206 * since this function takes over ownership of these. This functions makes
207 * a copy of @bflow itself (without allocating its fields again), so the
208 * caller must dispose of the memory used by the @bflow pointer itself
209 * Return: 0 if OK, -ENOMEM if out of memory
210 */
211int bootdev_add_bootflow(struct bootflow *bflow);
212
213/**
214 * bootdev_first_bootflow() - Get the first bootflow from a bootdev
215 *
216 * Returns the first bootflow attached to a bootdev
217 *
218 * @dev: bootdev device
219 * @bflowp: Returns a pointer to the bootflow
220 * Return: 0 if found, -ENOENT if there are no bootflows
221 */
222int bootdev_first_bootflow(struct udevice *dev, struct bootflow **bflowp);
223
224/**
225 * bootdev_next_bootflow() - Get the next bootflow from a bootdev
226 *
227 * Returns the next bootflow attached to a bootdev
228 *
229 * @bflowp: On entry, the last bootflow returned , e.g. from
230 * bootdev_first_bootflow()
231 * Return: 0 if found, -ENOENT if there are no more bootflows
232 */
233int bootdev_next_bootflow(struct bootflow **bflowp);
234
235/**
236 * bootdev_find_by_label() - Look up a bootdev by label
237 *
238 * Each bootdev has a label which contains the media-uclass name and a number,
239 * e.g. 'mmc2'. This looks up the label and returns the associated bootdev
240 *
241 * The lookup is performed based on the media device's sequence number. So for
242 * 'mmc2' this looks for a device in UCLASS_MMC with a dev_seq() of 2.
243 *
244 * @label: Label to look up (e.g. "mmc1" or "mmc0")
245 * @devp: Returns the bootdev device found, or NULL if none (note it does not
246 * return the media device, but its bootdev child)
d9f48579
SG
247 * @method_flagsp: If non-NULL, returns any flags implied by the label
248 * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
201417d7 249 * Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
d9f48579 250 * -ENOENT if there is no device with that number
201417d7 251 */
d9f48579
SG
252int bootdev_find_by_label(const char *label, struct udevice **devp,
253 int *method_flagsp);
201417d7
SG
254
255/**
256 * bootdev_find_by_any() - Find a bootdev by name, label or sequence
257 *
258 * @name: name (e.g. "mmc2.bootdev"), label ("mmc2"), or sequence ("2") to find
259 * @devp: returns the device found, on success
d9f48579
SG
260 * @method_flagsp: If non-NULL, returns any flags implied by the label
261 * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
1736b4af 262 * Return: 0 if OK, -EPFNOSUPPORT if the uclass is not supported by this board,
d9f48579 263 * -ENOENT if there is no device with that number
201417d7 264 */
d9f48579
SG
265int bootdev_find_by_any(const char *name, struct udevice **devp,
266 int *method_flagsp);
201417d7
SG
267
268/**
47aedc29 269 * bootdev_setup_iter() - Set up iteration through bootdevs
201417d7 270 *
91943ff7
SG
271 * This sets up the an interation, based on the provided device or label. If
272 * neither is provided, the iteration is based on the priority of each bootdev,
273 * the * bootdev-order property in the bootstd node (or the boot_targets env
274 * var).
201417d7
SG
275 *
276 * @iter: Iterator to update with the order
91943ff7 277 * @label: label to scan, or NULL to scan all
201417d7
SG
278 * @devp: On entry, *devp is NULL to scan all, otherwise this is the (single)
279 * device to scan. Returns the first device to use, which is the passed-in
280 * @devp if it was non-NULL
47aedc29
SG
281 * @method_flagsp: If non-NULL, returns any flags implied by the label
282 * (enum bootflow_meth_flags_t), 0 if none
201417d7
SG
283 * Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
284 * on other error
285 */
91943ff7
SG
286int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
287 struct udevice **devp, int *method_flagsp);
201417d7 288
bd90b092
SG
289/**
290 * bootdev_list_hunters() - List the available bootdev hunters
291 *
292 * These provide a way to find new bootdevs by enumerating buses, etc. This
293 * function lists the available hunters
294 *
295 * @std: Pointer to bootstd private info
296 */
297void bootdev_list_hunters(struct bootstd_priv *std);
298
c7b63d50
SG
299/**
300 * bootdev_hunt() - Hunt for bootdevs matching a particular spec
301 *
302 * This runs the selected hunter (or all if @spec is NULL) to try to find new
303 * bootdevs.
304 *
305 * @spec: Spec to match, e.g. "mmc0", or NULL for any. If provided, this must
306 * match a uclass name so that the hunter can be determined. Any trailing number
307 * is ignored
308 * @show: true to show each hunter before using it
309 * Returns: 0 if OK, -ve on error
310 */
311int bootdev_hunt(const char *spec, bool show);
312
79a7d4a6
SG
313/**
314 * bootdev_hunt_prio() - Hunt for bootdevs of a particular priority
315 *
316 * This runs all hunters which can find bootdevs of the given priority.
317 *
318 * @prio: Priority to use
319 * @show: true to show each hunter as it is used
320 * Returns: 0 if OK, -ve on error
321 */
322int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show);
323
1b1d36ec
SG
324/**
325 * bootdev_unhunt() - Mark a device as needing to be hunted again
326 *
327 * @id: uclass ID to update
328 * Return: 0 if done, -EALREADY if already in this state, -ENOENT if no hunter
329 * found for that uclass
330 */
331int bootdev_unhunt(enum uclass_id id);
332
66e3dce7
SG
333/**
334 * bootdev_hunt_and_find_by_label() - Hunt for bootdevs by label
335 *
336 * Runs the hunter for the label, then tries to find the bootdev, possible
337 * created by the hunter
338 *
339 * @label: Label to look up (e.g. "mmc1" or "mmc0")
340 * @devp: Returns the bootdev device found, or NULL if none (note it does not
341 * return the media device, but its bootdev child)
342 * @method_flagsp: If non-NULL, returns any flags implied by the label
343 * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
344 * Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
345 * -ENOENT if there is no device with that number
346 */
347int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
348 int *method_flagsp);
349
e4b69489
SG
350/**
351 * bootdev_next_label() - Move to the next bootdev in the label sequence
352 *
353 * Looks through the remaining labels until it finds one that matches a bootdev.
354 * Bootdev scanners are used as needed. For example a label "mmc1" results in
355 * running the "mmc" bootdrv.
356 *
357 * @iter: Interation info, containing iter->cur_label
358 * @devp: New bootdev found, if any was found
359 * @method_flagsp: If non-NULL, returns any flags implied by the label
360 * (enum bootflow_meth_flags_t), 0 if none
361 * Returns 0 if OK, -ENODEV if no bootdev was found
362 */
363int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
364 int *method_flagsp);
365
43e89a30
SG
366/**
367 * bootdev_next_prio() - Find the next bootdev in priority order
368 *
369 * This moves @devp to the next bootdev with the current priority. If there is
370 * none, then it moves to the next priority and scans for new bootdevs there.
371 *
372 * @iter: Interation info, containing iter->cur_prio
373 * @devp: On entry this is the previous bootdev that was considered. On exit
374 * this is the new bootdev, if any was found
375 * Returns 0 on success (*devp is updated), -ENODEV if there are no more
376 * bootdevs at any priority
377 */
378int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp);
379
201417d7
SG
380#if CONFIG_IS_ENABLED(BOOTSTD)
381/**
3a2cb96e
SG
382 * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
383 *
d7d78576 384 * Please use bootdev_setup_for_sibling_blk() instead since it supports multiple
3a2cb96e 385 * (child) block devices for each media device.
201417d7
SG
386 *
387 * Creates a bootdev device as a child of @parent. This should be called from
388 * the driver's bind() method or its uclass' post_bind() method.
389 *
390 * If a child bootdev already exists, this function does nothing
391 *
392 * @parent: Parent device (e.g. MMC or Ethernet)
393 * @drv_name: Name of bootdev driver to bind
394 * Return: 0 if OK, -ve on error
395 */
396int bootdev_setup_for_dev(struct udevice *parent, const char *drv_name);
397
398/**
d7d78576 399 * bootdev_setup_for_sibling_blk() - Bind a new bootdev device for a blk device
201417d7
SG
400 *
401 * Creates a bootdev device as a sibling of @blk. This should be called from
402 * the driver's bind() method or its uclass' post_bind() method, at the same
403 * time as the bould device is bound
404 *
405 * If a device of the same name already exists, this function does nothing
406 *
407 * @parent: Parent device (e.g. MMC or Ethernet)
408 * @drv_name: Name of bootdev driver to bind
409 * Return: 0 if OK, -ve on error
410 */
d7d78576 411int bootdev_setup_for_sibling_blk(struct udevice *blk, const char *drv_name);
201417d7
SG
412
413/**
414 * bootdev_get_sibling_blk() - Locate the block device for a bootdev
415 *
416 * @dev: bootdev to check
417 * @blkp: returns associated block device
418 * Return: 0 if OK, -EINVAL if @dev is not a bootdev device, other -ve on other
419 * error
420 */
421int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp);
422
423/**
424 * bootdev_unbind_dev() - Unbind a bootdev device
425 *
426 * Remove and unbind a bootdev device which is a child of @parent. This should
427 * be called from the driver's unbind() method or its uclass' post_bind()
428 * method.
429 *
430 * @parent: Parent device (e.g. MMC or Ethernet)
431 * Return: 0 if OK, -ve on error
432 */
433int bootdev_unbind_dev(struct udevice *parent);
434#else
435static inline int bootdev_setup_for_dev(struct udevice *parent,
436 const char *drv_name)
437{
438 return 0;
439}
440
d7d78576
SG
441static inline int bootdev_setup_for_sibling_blk(struct udevice *blk,
442 const char *drv_name)
201417d7
SG
443{
444 return 0;
445}
446
447static inline int bootdev_unbind_dev(struct udevice *parent)
448{
449 return 0;
450}
451#endif
452
453#endif