X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=include%2Fdm%2Fuclass.h;h=a5bf3eb831868b7f5e3efd75e2d505da4078df37;hb=e63d142f6fbab886fc2975274425a70eaedb4239;hp=8d09ecff7b4e0c0c4590792391303f0eeea7f2f6;hpb=c23154aab5825fec81d5500c53eaa686646c76b5;p=u-boot diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 8d09ecff7b..a5bf3eb831 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -10,7 +10,9 @@ #ifndef _DM_UCLASS_H #define _DM_UCLASS_H +#include #include +#include #include /** @@ -37,8 +39,12 @@ struct uclass { struct list_head sibling_node; }; +struct driver; struct udevice; +/* Members of this uclass sequence themselves with aliases */ +#define DM_UC_FLAG_SEQ_ALIAS (1 << 0) + /** * struct uclass_driver - Driver for the uclass * @@ -49,8 +55,10 @@ struct udevice; * @id: ID number of this uclass * @post_bind: Called after a new device is bound to this uclass * @pre_unbind: Called before a device is unbound from this uclass + * @pre_probe: Called before a new device is probed * @post_probe: Called after a new device is probed * @pre_remove: Called before a device is removed + * @child_post_bind: Called after a child is bound to a device in this uclass * @init: Called to set up the uclass * @destroy: Called to destroy the uclass * @priv_auto_alloc_size: If non-zero this is the size of the private data @@ -59,21 +67,39 @@ struct udevice; * @per_device_auto_alloc_size: Each device can hold private data owned * by the uclass. If required this will be automatically allocated if this * value is non-zero. + * @per_device_platdata_auto_alloc_size: Each device can hold platform data + * owned by the uclass as 'dev->uclass_platdata'. If the value is non-zero, + * then this will be automatically allocated. + * @per_child_auto_alloc_size: Each child device (of a parent in this + * uclass) can hold parent data for the device/uclass. This value is only + * used as a fallback if this member is 0 in the driver. + * @per_child_platdata_auto_alloc_size: A bus likes to store information about + * its children. If non-zero this is the size of this data, to be allocated + * in the child device's parent_platdata pointer. This value is only used as + * a fallback if this member is 0 in the driver. * @ops: Uclass operations, providing the consistent interface to devices * within the uclass. + * @flags: Flags for this uclass (DM_UC_...) */ struct uclass_driver { const char *name; enum uclass_id id; int (*post_bind)(struct udevice *dev); int (*pre_unbind)(struct udevice *dev); + int (*pre_probe)(struct udevice *dev); int (*post_probe)(struct udevice *dev); int (*pre_remove)(struct udevice *dev); + int (*child_post_bind)(struct udevice *dev); + int (*child_pre_probe)(struct udevice *dev); int (*init)(struct uclass *class); int (*destroy)(struct uclass *class); int priv_auto_alloc_size; int per_device_auto_alloc_size; + int per_device_platdata_auto_alloc_size; + int per_child_auto_alloc_size; + int per_child_platdata_auto_alloc_size; const void *ops; + uint32_t flags; }; /* Declare a new uclass_driver */ @@ -93,6 +119,22 @@ struct uclass_driver { */ int uclass_get(enum uclass_id key, struct uclass **ucp); +/** + * uclass_get_name() - Get the name of a uclass driver + * + * @id: ID to look up + * @returns the name of the uclass driver for that ID, or NULL if none + */ +const char *uclass_get_name(enum uclass_id id); + +/** + * uclass_get_by_name() - Look up a uclass by its driver name + * + * @name: Name to look up + * @returns the associated uclass ID, or UCLASS_INVALID if not found + */ +enum uclass_id uclass_get_by_name(const char *name); + /** * uclass_get_device() - Get a uclass device based on an ID and index * @@ -105,6 +147,21 @@ int uclass_get(enum uclass_id key, struct uclass **ucp); */ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp); +/** + * uclass_get_device_by_name() - Get a uclass device by its name + * + * This searches the devices in the uclass for one with the exactly given name. + * + * The device is probed to activate it ready for use. + * + * @id: ID to look up + * @name: name of a device to get + * @devp: Returns pointer to device (the first one with the name) + * @return 0 if OK, -ve on error + */ +int uclass_get_device_by_name(enum uclass_id id, const char *name, + struct udevice **devp); + /** * uclass_get_device_by_seq() - Get a uclass device based on an ID and sequence * @@ -137,24 +194,145 @@ int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp); int uclass_get_device_by_of_offset(enum uclass_id id, int node, struct udevice **devp); +/** + * uclass_get_device_by_ofnode() - Get a uclass device by device tree node + * + * This searches the devices in the uclass for one attached to the given + * device tree node. + * + * The device is probed to activate it ready for use. + * + * @id: ID to look up + * @np: Device tree node to search for (if NULL then -ENODEV is returned) + * @devp: Returns pointer to device (there is only one for each node) + * @return 0 if OK, -ve on error + */ +int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node, + struct udevice **devp); + +/** + * uclass_get_device_by_phandle_id() - Get a uclass device by phandle id + * + * This searches the devices in the uclass for one with the given phandle id. + * + * The device is probed to activate it ready for use. + * + * @id: uclass ID to look up + * @phandle_id: the phandle id to look up + * @devp: Returns pointer to device (there is only one for each node) + * @return 0 if OK, -ENODEV if there is no device match the phandle, other + * -ve on error + */ +int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id, + struct udevice **devp); + +/** + * uclass_get_device_by_phandle() - Get a uclass device by phandle + * + * This searches the devices in the uclass for one with the given phandle. + * + * The device is probed to activate it ready for use. + * + * @id: uclass ID to look up + * @parent: Parent device containing the phandle pointer + * @name: Name of property in the parent device node + * @devp: Returns pointer to device (there is only one for each node) + * @return 0 if OK, -ENOENT if there is no @name present in the node, other + * -ve on error + */ +int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, + const char *name, struct udevice **devp); + +/** + * uclass_get_device_by_driver() - Get a uclass device for a driver + * + * This searches the devices in the uclass for one that uses the given + * driver. Use DM_GET_DRIVER(name) for the @drv argument, where 'name' is + * the driver name - as used in U_BOOT_DRIVER(name). + * + * The device is probed to activate it ready for use. + * + * @id: ID to look up + * @drv: Driver to look for + * @devp: Returns pointer to the first device with that driver + * @return 0 if OK, -ve on error + */ +int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv, + struct udevice **devp); + /** * uclass_first_device() - Get the first device in a uclass * + * The device returned is probed if necessary, and ready for use + * + * This function is useful to start iterating through a list of devices which + * are functioning correctly and can be probed. + * * @id: Uclass ID to look up - * @devp: Returns pointer to the first device in that uclass, or NULL if none - * @return 0 if OK (found or not found), -1 on error + * @devp: Returns pointer to the first device in that uclass if no error + * occurred, or NULL if there is no first device, or an error occurred with + * that device. + * @return 0 if OK (found or not found), other -ve on error */ int uclass_first_device(enum uclass_id id, struct udevice **devp); +/** + * uclass_first_device_err() - Get the first device in a uclass + * + * The device returned is probed if necessary, and ready for use + * + * @id: Uclass ID to look up + * @devp: Returns pointer to the first device in that uclass, or NULL if none + * @return 0 if found, -ENODEV if not found, other -ve on error + */ +int uclass_first_device_err(enum uclass_id id, struct udevice **devp); + /** * uclass_next_device() - Get the next device in a uclass * + * The device returned is probed if necessary, and ready for use + * + * This function is useful to start iterating through a list of devices which + * are functioning correctly and can be probed. + * * @devp: On entry, pointer to device to lookup. On exit, returns pointer - * to the next device in the same uclass, or NULL if none - * @return 0 if OK (found or not found), -1 on error + * to the next device in the uclass if no error occurred, or NULL if there is + * no next device, or an error occurred with that next device. + * @return 0 if OK (found or not found), other -ve on error */ int uclass_next_device(struct udevice **devp); +/** + * uclass_first_device() - Get the first device in a uclass + * + * The device returned is probed if necessary, and ready for use + * + * This function is useful to start iterating through a list of devices which + * are functioning correctly and can be probed. + * + * @id: Uclass ID to look up + * @devp: Returns pointer to the first device in that uclass, or NULL if there + * is no first device + * @return 0 if OK (found or not found), other -ve on error. If an error occurs + * it is still possible to move to the next device. + */ +int uclass_first_device_check(enum uclass_id id, struct udevice **devp); + +/** + * uclass_next_device() - Get the next device in a uclass + * + * The device returned is probed if necessary, and ready for use + * + * This function is useful to start iterating through a list of devices which + * are functioning correctly and can be probed. + * + * @devp: On entry, pointer to device to lookup. On exit, returns pointer + * to the next device in the uclass if any + * @return 0 if OK (found or not found), other -ve on error. If an error occurs + * it is still possible to move to the next device. + */ +int uclass_next_device_check(struct udevice **devp); + /** * uclass_resolve_seq() - Resolve a device's sequence number * @@ -180,12 +358,22 @@ int uclass_resolve_seq(struct udevice *dev); * are no more devices. * @uc: uclass to scan */ -#define uclass_foreach_dev(pos, uc) \ - for (pos = list_entry((&(uc)->dev_head)->next, typeof(*pos), \ - uclass_node); \ - prefetch(pos->uclass_node.next), \ - &pos->uclass_node != (&(uc)->dev_head); \ - pos = list_entry(pos->uclass_node.next, typeof(*pos), \ - uclass_node)) +#define uclass_foreach_dev(pos, uc) \ + list_for_each_entry(pos, &uc->dev_head, uclass_node) + +/** + * uclass_foreach_dev_safe() - Helper function to safely iteration through devs + * + * This creates a for() loop which works through the available devices in + * a uclass in order from start to end. Inside the loop, it is safe to remove + * @pos if required. + * + * @pos: struct udevice * to hold the current device. Set to NULL when there + * are no more devices. + * @next: struct udevice * to hold the next next + * @uc: uclass to scan + */ +#define uclass_foreach_dev_safe(pos, next, uc) \ + list_for_each_entry_safe(pos, next, &uc->dev_head, uclass_node) #endif