Merge tag 'u-boot-imx-20210809' of https://source.denx.de/u-boot/custodians/u-boot-imx
[platform/kernel/u-boot.git] / include / dm / uclass.h
index eebf2d5..da0c1bf 100644 (file)
@@ -24,7 +24,7 @@
  * There may be drivers for on-chip SoC GPIO banks, I2C GPIO expanders and
  * PMIC IO lines, all made available in a unified way through the uclass.
  *
- * @priv: Private data for this uclass
+ * @priv_: Private data for this uclass (do not access outside driver model)
  * @uc_drv: The driver for the uclass itself, not to be confused with a
  * 'struct driver'
  * @dev_head: List of devices in this uclass (devices are attached to their
@@ -32,7 +32,7 @@
  * @sibling_node: Next uclass in the linked list of uclasses
  */
 struct uclass {
-       void *priv;
+       void *priv_;
        struct uclass_driver *uc_drv;
        struct list_head dev_head;
        struct list_head sibling_node;
@@ -44,6 +44,9 @@ struct udevice;
 /* Members of this uclass sequence themselves with aliases */
 #define DM_UC_FLAG_SEQ_ALIAS                   (1 << 0)
 
+/* Members of this uclass without aliases don't get a sequence number */
+#define DM_UC_FLAG_NO_AUTO_SEQ                 (1 << 1)
+
 /* Same as DM_FLAG_ALLOC_PRIV_DMA */
 #define DM_UC_FLAG_ALLOC_PRIV_DMA              (1 << 5)
 
@@ -61,27 +64,26 @@ struct udevice;
  * @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
- * @child_pre_probe: Called before a child is probed in this uclass
+ * @child_pre_probe: Called before a child in this uclass is probed
+ * @child_post_probe: Called after a child in this uclass is probed
  * @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
+ * @priv_auto: If non-zero this is the size of the private data
  * to be allocated in the uclass's ->priv pointer. If zero, then the uclass
  * driver is responsible for allocating any data required.
- * @per_device_auto_alloc_size: Each device can hold private data owned
+ * @per_device_auto: 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,
+ * @per_device_plat_auto: Each device can hold platform data
+ * owned by the uclass as 'dev->uclass_plat'. 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
+ * @per_child_auto: 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
+ * @per_child_plat_auto: 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
+ * in the child device's parent_plat 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 {
@@ -94,20 +96,59 @@ struct uclass_driver {
        int (*pre_remove)(struct udevice *dev);
        int (*child_post_bind)(struct udevice *dev);
        int (*child_pre_probe)(struct udevice *dev);
+       int (*child_post_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;
+       int priv_auto;
+       int per_device_auto;
+       int per_device_plat_auto;
+       int per_child_auto;
+       int per_child_plat_auto;
        uint32_t flags;
 };
 
 /* Declare a new uclass_driver */
 #define UCLASS_DRIVER(__name)                                          \
-       ll_entry_declare(struct uclass_driver, __name, uclass)
+       ll_entry_declare(struct uclass_driver, __name, uclass_driver)
+
+/*
+ * These two macros DM_UCLASS_DRIVER_REF and DM_UCLASS_DRIVER_REF are only
+ * allowed in code generated by dtoc, because the ordering is important and if
+ * other instances creep in then they may mess up the ordering expected by dtoc.
+ *
+ * It is OK to use them with 'extern' though, since that does not actually
+ * add a new record to the linker_list.
+ */
+
+/**
+ * DM_UCLASS_DRIVER_REF() - Get a reference to a uclass driver
+ *
+ * This is useful in data structures and code for referencing a uclass_driver at
+ * build time. Before this is used, an extern UCLASS_DRIVER() must have been
+ * declared.
+ *
+ * For example:
+ *
+ * extern UCLASS_DRIVER(clk);
+ *
+ * struct uclass_driver *drvs[] = {
+ *     DM_UCLASS_DRIVER_REF(clk),
+ * };
+ *
+ * @_name: Name of the uclass_driver. This must be a valid C identifier, used by
+ *     the linker_list.
+ * @returns struct uclass_driver * for the uclass driver
+ */
+#define DM_UCLASS_DRIVER_REF(_name)                                    \
+       ll_entry_ref(struct uclass_driver, _name, uclass_driver)
+
+/**
+ * uclass_get_priv() - Get the private data for a uclass
+ *
+ * @uc         Uclass to check
+ * @return private data, or NULL if none
+ */
+void *uclass_get_priv(const struct uclass *uc);
 
 /**
  * uclass_get() - Get a uclass based on an ID, creating it if needed
@@ -118,7 +159,8 @@ struct uclass_driver {
  *
  * @key: ID to look up
  * @ucp: Returns pointer to uclass (there is only one per ID)
- * @return 0 if OK, -ve on error
+ * @return 0 if OK, -EDEADLK if driver model is not yet inited, other -ve on
+ *     other error
  */
 int uclass_get(enum uclass_id key, struct uclass **ucp);
 
@@ -222,7 +264,8 @@ int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
  *
  * @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)
+ * @devp: Returns pointer to device (there is only one for each node). NULL if
+ *     there is no such device.
  * @return 0 if OK, -ENODEV if there is no device match the phandle, other
  *     -ve on error
  */
@@ -250,7 +293,7 @@ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
  * 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
+ * driver. Use DM_DRIVER_GET(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.
@@ -295,7 +338,7 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp);
  *
  * The device returned is probed if necessary, and ready for use
  *
- * This function is useful to start iterating through a list of devices which
+ * This function is useful to iterate 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
@@ -306,6 +349,18 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp);
 int uclass_next_device(struct udevice **devp);
 
 /**
+ * uclass_next_device_err() - Get the next device in a uclass
+ *
+ * The device returned is probed if necessary, and ready for use
+ *
+ * @devp: On entry, pointer to device to lookup. On exit, returns pointer
+ * to the next device in the uclass if no error occurred, or -ENODEV if
+ * there is no next device.
+ * @return 0 if found, -ENODEV if not found, other -ve on error
+ */
+int uclass_next_device_err(struct udevice **devp);
+
+/**
  * uclass_first_device_check() - Get the first device in a uclass
  *
  * The device returned is probed if necessary, and ready for use
@@ -337,19 +392,46 @@ int uclass_first_device_check(enum uclass_id id, struct udevice **devp);
 int uclass_next_device_check(struct udevice **devp);
 
 /**
- * uclass_resolve_seq() - Resolve a device's sequence number
+ * uclass_first_device_drvdata() - Find the first device with given driver data
  *
- * On entry dev->seq is -1, and dev->req_seq may be -1 (to allocate a
- * sequence number automatically, or >= 0 to select a particular number.
- * If the requested sequence number is in use, then this device will
- * be allocated another one.
+ * This searches through the devices for a particular uclass looking for one
+ * that has the given driver data.
  *
- * Note that the device's seq value is not changed by this function.
+ * @id: Uclass ID to check
+ * @driver_data: Driver data to search for
+ * @devp: Returns pointer to the first matching device in that uclass, if found
+ * @return 0 if found, -ENODEV if not found, other -ve on error
+ */
+int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
+                               struct udevice **devp);
+
+/**
+ * uclass_probe_all() - Probe all devices based on an uclass ID
  *
- * @dev: Device for which to allocate sequence number
- * @return sequence number allocated, or -ve on error
+ * This function probes all devices associated with a uclass by
+ * looking for its ID.
+ *
+ * @id: uclass ID to look up
+ * @return 0 if OK, other -ve on error
  */
-int uclass_resolve_seq(struct udevice *dev);
+int uclass_probe_all(enum uclass_id id);
+
+/**
+ * uclass_id_foreach_dev() - Helper function to iteration through devices
+ *
+ * This creates a for() loop which works through the available devices in
+ * a uclass ID in order from start to end.
+ *
+ * If for some reason the uclass cannot be found, this does nothing.
+ *
+ * @id: enum uclass_id ID to use
+ * @pos: struct udevice * to hold the current device. Set to NULL when there
+ * are no more devices.
+ * @uc: temporary uclass variable (struct uclass *)
+ */
+#define uclass_id_foreach_dev(id, pos, uc) \
+       if (!uclass_get(id, &uc)) \
+               list_for_each_entry(pos, &uc->dev_head, uclass_node)
 
 /**
  * uclass_foreach_dev() - Helper function to iteration through devices
@@ -379,4 +461,20 @@ int uclass_resolve_seq(struct udevice *dev);
 #define uclass_foreach_dev_safe(pos, next, uc) \
        list_for_each_entry_safe(pos, next, &uc->dev_head, uclass_node)
 
+/**
+ * uclass_foreach_dev_probe() - Helper function to iteration through devices
+ * of given uclass
+ *
+ * This creates a for() loop which works through the available devices in
+ * a uclass in order from start to end. Devices are probed if necessary,
+ * and ready for use.
+ *
+ * @id: Uclass ID
+ * @dev: struct udevice * to hold the current device. Set to NULL when there
+ * are no more devices.
+ */
+#define uclass_foreach_dev_probe(id, dev)      \
+       for (int _ret = uclass_first_device_err(id, &dev); !_ret && dev; \
+            _ret = uclass_next_device_err(&dev))
+
 #endif