powerpc: mpc85xx: Fix CONFIG_OF_SEPARATE support for NOR booting
[platform/kernel/u-boot.git] / include / bootdev.h
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
10 #include <linux/list.h>
11
12 struct bootflow;
13 struct bootflow_iter;
14 struct udevice;
15
16 /**
17  * enum bootdev_prio_t - priority of each bootdev
18  *
19  * These values are associated with each bootdev and set up by the driver.
20  *
21  * Smallest value is the highest priority. By default, bootdevs are scanned from
22  * highest to lowest priority
23  */
24 enum bootdev_prio_t {
25         BOOTDEVP_0_INTERNAL_FAST        = 10,
26         BOOTDEVP_1_INTERNAL_SLOW        = 20,
27         BOOTDEVP_2_SCAN_FAST            = 30,
28         BOOTDEVP_3_SCAN_SLOW            = 40,
29         BOOTDEVP_4_NET_BASE             = 50,
30         BOOTDEVP_5_NET_FALLBACK         = 60,
31         BOOTDEVP_6_SYSTEM               = 70,
32
33         BOOTDEVP_COUNT,
34 };
35
36 /**
37  * struct bootdev_uc_plat - uclass information about a bootdev
38  *
39  * This is attached to each device in the bootdev uclass and accessible via
40  * dev_get_uclass_plat(dev)
41  *
42  * @bootflows: List of available bootflows for this bootdev
43  * @piro: Priority of this bootdev
44  */
45 struct bootdev_uc_plat {
46         struct list_head bootflow_head;
47         enum bootdev_prio_t prio;
48 };
49
50 /** struct bootdev_ops - Operations for the bootdev uclass */
51 struct bootdev_ops {
52         /**
53          * get_bootflow() - get a bootflow
54          *
55          * @dev:        Bootflow device to check
56          * @iter:       Provides current dev, part, method to get. Should update
57          *      max_part if there is a partition table. Should update state,
58          *      subdir, fname, buf, size according to progress
59          * @bflow:      Updated bootflow if found
60          * Return: 0 if OK, -ESHUTDOWN if there are no more bootflows on this
61          *      device, -ENOSYS if this device doesn't support bootflows,
62          *      other -ve value on other error
63          */
64         int (*get_bootflow)(struct udevice *dev, struct bootflow_iter *iter,
65                             struct bootflow *bflow);
66 };
67
68 #define bootdev_get_ops(dev)  ((struct bootdev_ops *)(dev)->driver->ops)
69
70 /**
71  * bootdev_get_bootflow() - get a bootflow
72  *
73  * @dev:        Bootflow device to check
74  * @iter:       Provides current  part, method to get
75  * @bflow:      Returns bootflow if found
76  * Return: 0 if OK, -ESHUTDOWN if there are no more bootflows on this device,
77  *      -ENOSYS if this device doesn't support bootflows, other -ve value on
78  *      other error
79  */
80 int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
81                          struct bootflow *bflow);
82
83 /**
84  * bootdev_bind() - Bind a new named bootdev device
85  *
86  * @parent:     Parent of the new device
87  * @drv_name:   Driver name to use for the bootdev device
88  * @name:       Name for the device (parent name is prepended)
89  * @devp:       the new device (which has not been probed)
90  */
91 int bootdev_bind(struct udevice *parent, const char *drv_name, const char *name,
92                  struct udevice **devp);
93
94 /**
95  * bootdev_find_in_blk() - Find a bootdev in a block device
96  *
97  * @dev: Bootflow device associated with this block device
98  * @blk: Block device to search
99  * @iter:       Provides current dev, part, method to get. Should update
100  *      max_part if there is a partition table
101  * @bflow: On entry, provides information about the partition and device to
102  *      check. On exit, returns bootflow if found
103  * Return: 0 if found, -ESHUTDOWN if no more bootflows, other -ve on error
104  */
105 int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
106                         struct bootflow_iter *iter, struct bootflow *bflow);
107
108 /**
109  * bootdev_list() - List all available bootdevs
110  *
111  * @probe: true to probe devices, false to leave them as is
112  */
113 void bootdev_list(bool probe);
114
115 /**
116  * bootdev_clear_bootflows() - Clear bootflows from a bootdev
117  *
118  * Each bootdev maintains a list of discovered bootflows. This provides a
119  * way to clear it. These bootflows are removed from the global list too.
120  *
121  * @dev: bootdev device to update
122  */
123 void bootdev_clear_bootflows(struct udevice *dev);
124
125 /**
126  * bootdev_add_bootflow() - Add a bootflow to the bootdev's list
127  *
128  * All fields in @bflow must be set up. Note that @bflow->dev is used to add the
129  * bootflow to that device.
130  *
131  * @dev: Bootdevice device to add to
132  * @bflow: Bootflow to add. Note that fields within bflow must be allocated
133  *      since this function takes over ownership of these. This functions makes
134  *      a copy of @bflow itself (without allocating its fields again), so the
135  *      caller must dispose of the memory used by the @bflow pointer itself
136  * Return: 0 if OK, -ENOMEM if out of memory
137  */
138 int bootdev_add_bootflow(struct bootflow *bflow);
139
140 /**
141  * bootdev_first_bootflow() - Get the first bootflow from a bootdev
142  *
143  * Returns the first bootflow attached to a bootdev
144  *
145  * @dev: bootdev device
146  * @bflowp: Returns a pointer to the bootflow
147  * Return: 0 if found, -ENOENT if there are no bootflows
148  */
149 int bootdev_first_bootflow(struct udevice *dev, struct bootflow **bflowp);
150
151 /**
152  * bootdev_next_bootflow() - Get the next bootflow from a bootdev
153  *
154  * Returns the next bootflow attached to a bootdev
155  *
156  * @bflowp: On entry, the last bootflow returned , e.g. from
157  *      bootdev_first_bootflow()
158  * Return: 0 if found, -ENOENT if there are no more bootflows
159  */
160 int bootdev_next_bootflow(struct bootflow **bflowp);
161
162 /**
163  * bootdev_find_by_label() - Look up a bootdev by label
164  *
165  * Each bootdev has a label which contains the media-uclass name and a number,
166  * e.g. 'mmc2'. This looks up the label and returns the associated bootdev
167  *
168  * The lookup is performed based on the media device's sequence number. So for
169  * 'mmc2' this looks for a device in UCLASS_MMC with a dev_seq() of 2.
170  *
171  * @label: Label to look up (e.g. "mmc1" or "mmc0")
172  * @devp: Returns the bootdev device found, or NULL if none (note it does not
173  *      return the media device, but its bootdev child)
174  * Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
175  *      -ENOENT if there is no device with that number
176  */
177 int bootdev_find_by_label(const char *label, struct udevice **devp);
178
179 /**
180  * bootdev_find_by_any() - Find a bootdev by name, label or sequence
181  *
182  * @name: name (e.g. "mmc2.bootdev"), label ("mmc2"), or sequence ("2") to find
183  * @devp: returns the device found, on success
184  * Return: 0 if OK, -ve on error
185  */
186 int bootdev_find_by_any(const char *name, struct udevice **devp);
187
188 /**
189  * bootdev_setup_iter_order() - Set up the ordering of bootdevs to scan
190  *
191  * This sets up the ordering information in @iter, based on the priority of each
192  * bootdev and the bootdev-order property in the bootstd node
193  *
194  * If a single device is requested, no ordering is needed
195  *
196  * @iter: Iterator to update with the order
197  * @devp: On entry, *devp is NULL to scan all, otherwise this is the (single)
198  *      device to scan. Returns the first device to use, which is the passed-in
199  *      @devp if it was non-NULL
200  * Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
201  *      on other error
202  */
203 int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp);
204
205 #if CONFIG_IS_ENABLED(BOOTSTD)
206 /**
207  * bootdev_setup_for_dev() - Bind a new bootdev device
208  *
209  * Creates a bootdev device as a child of @parent. This should be called from
210  * the driver's bind() method or its uclass' post_bind() method.
211  *
212  * If a child bootdev already exists, this function does nothing
213  *
214  * @parent: Parent device (e.g. MMC or Ethernet)
215  * @drv_name: Name of bootdev driver to bind
216  * Return: 0 if OK, -ve on error
217  */
218 int bootdev_setup_for_dev(struct udevice *parent, const char *drv_name);
219
220 /**
221  * bootdev_setup_for_blk() - Bind a new bootdev device for a blk device
222  *
223  * Creates a bootdev device as a sibling of @blk. This should be called from
224  * the driver's bind() method or its uclass' post_bind() method, at the same
225  * time as the bould device is bound
226  *
227  * If a device of the same name already exists, this function does nothing
228  *
229  * @parent: Parent device (e.g. MMC or Ethernet)
230  * @drv_name: Name of bootdev driver to bind
231  * Return: 0 if OK, -ve on error
232  */
233 int bootdev_setup_sibling_blk(struct udevice *blk, const char *drv_name);
234
235 /**
236  * bootdev_get_sibling_blk() - Locate the block device for a bootdev
237  *
238  * @dev: bootdev to check
239  * @blkp: returns associated block device
240  * Return: 0 if OK, -EINVAL if @dev is not a bootdev device, other -ve on other
241  *      error
242  */
243 int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp);
244
245 /**
246  * bootdev_unbind_dev() - Unbind a bootdev device
247  *
248  * Remove and unbind a bootdev device which is a child of @parent. This should
249  * be called from the driver's unbind() method or its uclass' post_bind()
250  * method.
251  *
252  * @parent: Parent device (e.g. MMC or Ethernet)
253  * Return: 0 if OK, -ve on error
254  */
255 int bootdev_unbind_dev(struct udevice *parent);
256 #else
257 static inline int bootdev_setup_for_dev(struct udevice *parent,
258                                         const char *drv_name)
259 {
260         return 0;
261 }
262
263 static inline int bootdev_setup_sibling_blk(struct udevice *blk,
264                                             const char *drv_name)
265 {
266         return 0;
267 }
268
269 static inline int bootdev_unbind_dev(struct udevice *parent)
270 {
271         return 0;
272 }
273 #endif
274
275 #endif