1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * Copyright (c) 2013 Google, Inc 4 * 5 * (C) Copyright 2012 6 * Pavel Herrmann <morpheus.ibis@gmail.com> 7 */ 8 9#ifndef _DM_UCLASS_INTERNAL_H 10#define _DM_UCLASS_INTERNAL_H 11 12#include <dm/ofnode.h> 13 14/* 15 * These next two macros DM_UCLASS_INST() and DM_UCLASS_REF() are only allowed 16 * in code generated by dtoc, because the ordering is important and if other 17 * instances creep in then they may mess up the ordering expected by dtoc. 18 * 19 * It is OK to use them with 'extern' though, since that does not actually 20 * add a new record to the linker_list. 21 */ 22 23/** 24 * DM_UCLASS_INST() - Declare a uclass ready for run-time use 25 * 26 * This adds an actual struct uclass to a list which is found by driver model 27 * on start-up. 28 * 29 * For example: 30 * 31 * DM_UCLASS_INST(clk) = { 32 * .uc_drv = DM_UCLASS_DRIVER_REF(clk), 33 * ... 34 * }; 35 * 36 * @_name: Name of the uclass. This must be a valid C identifier, used by the 37 * linker_list. 38 */ 39#define DM_UCLASS_INST(_name) \ 40 ll_entry_declare(struct uclass, _name, uclass) 41 42/** 43 * DM_UCLASS_REF() - Get a reference to a uclass 44 * 45 * This is useful for referencing a uclass at build time. Before this is used, 46 * an extern DM_UCLASS_INST() must have been declared. 47 * 48 * For example: 49 * 50 * extern DM_UCLASS_INST(clk); 51 * 52 * struct uclass *ucs[] = { 53 * DM_UCLASS_REF(clk), 54 * } 55 * 56 * @_name: Name of the uclass. This must be a valid C identifier, used by the 57 * linker_list 58 * @returns struct uclass * for the device 59 */ 60#define DM_UCLASS_REF(_name) \ 61 ll_entry_ref(struct uclass, _name, uclass) 62 63/** 64 * uclass_set_priv() - Set the private data for a uclass 65 * 66 * This is normally handled by driver model, which automatically allocates 67 * private data when an 'auto' size if provided by the uclass driver. 68 * 69 * Use this function to override normal operation for special situations, such 70 * as needing to allocate a variable amount of data. 71 * 72 * If OF_PLATDATA_RT is enabled, this function cannot be used out of core driver 73 * model code, since the pointer must be within the gd->dm_priv_base region. 74 * 75 * @uc Uclass to update 76 * @priv New private-data pointer 77 */ 78void uclass_set_priv(struct uclass *uc, void *priv); 79 80/** 81 * uclass_find_next_free_seq() - Get the next free sequence number 82 * 83 * This returns the next free sequence number. This is useful only if 84 * OF_CONTROL is not used. The next free sequence number is simply the 85 * maximum sequence number used by all devices in the uclass + 1. The value 86 * returned is always greater than the largest alias, if DM_SEQ_ALIAS is enabled 87 * and the uclass has the DM_UC_FLAG_SEQ_ALIAS flag. 88 * 89 * This allows assigning the sequence number in the binding order. 90 * 91 * @uc: uclass to check 92 * @return The next free sequence number 93 */ 94int uclass_find_next_free_seq(struct uclass *uc); 95 96/** 97 * uclass_get_device_tail() - handle the end of a get_device call 98 * 99 * This handles returning an error or probing a device as needed. 100 * 101 * @dev: Device that needs to be probed 102 * @ret: Error to return. If non-zero then the device is not probed 103 * @devp: Returns the value of 'dev' if there is no error 104 * @return ret, if non-zero, else the result of the device_probe() call 105 */ 106int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp); 107 108/** 109 * dev_get_uclass_index() - Get uclass and index of device 110 * @dev: - in - Device that we want the uclass/index of 111 * @ucp: - out - A pointer to the uclass the device belongs to 112 * 113 * The device is not prepared for use - this is an internal function. 114 * 115 * @return the index of the device in the uclass list or -ENODEV if not found. 116 */ 117int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp); 118 119/** 120 * uclass_find_device() - Return n-th child of uclass 121 * @id: Id number of the uclass 122 * @index: Position of the child in uclass's list 123 * #devp: Returns pointer to device, or NULL on error 124 * 125 * The device is not prepared for use - this is an internal function. 126 * The function uclass_get_device_tail() can be used to probe the device. 127 * 128 * @return the uclass pointer of a child at the given index or 129 * return NULL on error. 130 */ 131int uclass_find_device(enum uclass_id id, int index, struct udevice **devp); 132 133/** 134 * uclass_find_first_device() - Return the first device in a uclass 135 * @id: Id number of the uclass 136 * #devp: Returns pointer to device, or NULL on error 137 * 138 * The device is not prepared for use - this is an internal function. 139 * The function uclass_get_device_tail() can be used to probe the device. 140 * 141 * @return 0 if OK (found or not found), -ve on error 142 */ 143int uclass_find_first_device(enum uclass_id id, struct udevice **devp); 144 145/** 146 * uclass_find_next_device() - Return the next device in a uclass 147 * @devp: On entry, pointer to device to lookup. On exit, returns pointer 148 * to the next device in the same uclass, or NULL if none 149 * 150 * The device is not prepared for use - this is an internal function. 151 * The function uclass_get_device_tail() can be used to probe the device. 152 * 153 * @return 0 if OK (found or not found), -ve on error 154 */ 155int uclass_find_next_device(struct udevice **devp); 156 157/** 158 * uclass_find_device_by_name() - Find uclass device based on ID and name 159 * 160 * This searches for a device with the exactly given name. 161 * 162 * The device is NOT probed, it is merely returned. 163 * 164 * @id: ID to look up 165 * @name: name of a device to find 166 * @devp: Returns pointer to device (the first one with the name) 167 * @return 0 if OK, -ve on error 168 */ 169int uclass_find_device_by_name(enum uclass_id id, const char *name, 170 struct udevice **devp); 171 172/** 173 * uclass_find_device_by_seq() - Find uclass device based on ID and sequence 174 * 175 * This searches for a device with the given seq. 176 * 177 * The device is NOT probed, it is merely returned. 178 * 179 * @id: ID to look up 180 * @seq: Sequence number to find (0=first) 181 * @devp: Returns pointer to device (there is only one per for each seq) 182 * @return 0 if OK, -ENODEV if not found 183 */ 184int uclass_find_device_by_seq(enum uclass_id id, int seq, 185 struct udevice **devp); 186 187/** 188 * uclass_find_device_by_of_offset() - Find a uclass device by device tree node 189 * 190 * This searches the devices in the uclass for one attached to the given 191 * device tree node. 192 * 193 * The device is NOT probed, it is merely returned. 194 * 195 * @id: ID to look up 196 * @node: Device tree offset to search for (if -ve then -ENODEV is returned) 197 * @devp: Returns pointer to device (there is only one for each node) 198 * @return 0 if OK, -ve on error 199 */ 200int uclass_find_device_by_of_offset(enum uclass_id id, int node, 201 struct udevice **devp); 202 203/** 204 * uclass_find_device_by_of_node() - Find a uclass device by device tree node 205 * 206 * This searches the devices in the uclass for one attached to the given 207 * device tree node. 208 * 209 * The device is NOT probed, it is merely returned. 210 * 211 * @id: ID to look up 212 * @node: Device tree offset to search for (if NULL then -ENODEV is returned) 213 * @devp: Returns pointer to device (there is only one for each node) 214 * @return 0 if OK, -ve on error 215 */ 216int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node, 217 struct udevice **devp); 218 219/** 220 * uclass_find_device_by_phandle() - Find a uclass device by phandle 221 * 222 * This searches the devices in the uclass for one with the given phandle. 223 * 224 * The device is NOT probed, it is merely returned. 225 * 226 * @id: ID to look up 227 * @parent: Parent device containing the phandle pointer 228 * @name: Name of property in the parent device node 229 * @devp: Returns pointer to device (there is only one for each node) 230 * @return 0 if OK, -ENOENT if there is no @name present in the node, other 231 * -ve on error 232 */ 233int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent, 234 const char *name, struct udevice **devp); 235 236/** 237 * uclass_bind_device() - Associate device with a uclass 238 * 239 * Connect the device into uclass's list of devices. 240 * 241 * @dev: Pointer to the device 242 * #return 0 on success, -ve on error 243 */ 244int uclass_bind_device(struct udevice *dev); 245 246/** 247 * uclass_unbind_device() - Deassociate device with a uclass 248 * 249 * Disconnect the device from uclass's list of devices. 250 * 251 * @dev: Pointer to the device 252 * #return 0 on success, -ve on error 253 */ 254#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) 255int uclass_unbind_device(struct udevice *dev); 256#else 257static inline int uclass_unbind_device(struct udevice *dev) { return 0; } 258#endif 259 260/** 261 * uclass_pre_probe_device() - Deal with a device that is about to be probed 262 * 263 * Perform any pre-processing that is needed by the uclass before it can be 264 * probed. This includes the uclass' pre-probe() method and the parent 265 * uclass' child_pre_probe() method. 266 * 267 * @dev: Pointer to the device 268 * #return 0 on success, -ve on error 269 */ 270int uclass_pre_probe_device(struct udevice *dev); 271 272/** 273 * uclass_post_probe_device() - Deal with a device that has just been probed 274 * 275 * Perform any post-processing of a probed device that is needed by the 276 * uclass. 277 * 278 * @dev: Pointer to the device 279 * #return 0 on success, -ve on error 280 */ 281int uclass_post_probe_device(struct udevice *dev); 282 283/** 284 * uclass_pre_remove_device() - Handle a device which is about to be removed 285 * 286 * Perform any pre-processing of a device that is about to be removed. 287 * 288 * @dev: Pointer to the device 289 * #return 0 on success, -ve on error 290 */ 291#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) 292int uclass_pre_remove_device(struct udevice *dev); 293#else 294static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; } 295#endif 296 297/** 298 * uclass_find() - Find uclass by its id 299 * 300 * @id: Id to serach for 301 * @return pointer to uclass, or NULL if not found 302 */ 303struct uclass *uclass_find(enum uclass_id key); 304 305/** 306 * uclass_destroy() - Destroy a uclass 307 * 308 * Destroy a uclass and all its devices 309 * 310 * @uc: uclass to destroy 311 * @return 0 on success, -ve on error 312 */ 313int uclass_destroy(struct uclass *uc); 314 315#endif 316