dm: core: Require users of devres to include the header
[oweals/u-boot.git] / include / dm / device.h
index defda0aebcb66102513f4cad3ba4313e239c9376..2d8b716ef5e951fd1f5501170762526250e6f353 100644 (file)
@@ -45,6 +45,7 @@ struct driver_info;
 /* Device name is allocated and should be freed on unbind() */
 #define DM_FLAG_NAME_ALLOCED           (1 << 7)
 
+/* Device has platform data provided by of-platdata */
 #define DM_FLAG_OF_PLATDATA            (1 << 8)
 
 /*
@@ -61,6 +62,12 @@ struct driver_info;
  */
 #define DM_FLAG_OS_PREPARE             (1 << 10)
 
+/* DM does not enable/disable the power domains corresponding to this device */
+#define DM_FLAG_DEFAULT_PD_CTRL_OFF    (1 << 11)
+
+/* Driver platdata has been read. Cleared when the device is removed */
+#define DM_FLAG_PLATDATA_VALID         (1 << 12)
+
 /*
  * One or multiple of these flags are passed to device_remove() so that
  * a selective device removal as specified by the remove-stage and the
@@ -402,7 +409,8 @@ const char *dev_get_uclass_name(const struct udevice *dev);
  * @return 0 if OK, -ENODEV if no such device, other error if the device fails
  *        to probe
  */
-int device_get_child(struct udevice *parent, int index, struct udevice **devp);
+int device_get_child(const struct udevice *parent, int index,
+                    struct udevice **devp);
 
 /**
  * device_get_child_count() - Get the available child count of a device
@@ -411,7 +419,7 @@ int device_get_child(struct udevice *parent, int index, struct udevice **devp);
  *
  * @parent:    Parent device to check
  */
-int device_get_child_count(struct udevice *parent);
+int device_get_child_count(const struct udevice *parent);
 
 /**
  * device_find_child_by_seq() - Find a child device based on a sequence
@@ -432,7 +440,7 @@ int device_get_child_count(struct udevice *parent);
  * Set to NULL if none is found
  * @return 0 if OK, -ve on error
  */
-int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
+int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq,
                             bool find_req_seq, struct udevice **devp);
 
 /**
@@ -450,7 +458,7 @@ int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
  * Set to NULL if none is found
  * @return 0 if OK, -ve on error
  */
-int device_get_child_by_seq(struct udevice *parent, int seq,
+int device_get_child_by_seq(const struct udevice *parent, int seq,
                            struct udevice **devp);
 
 /**
@@ -463,7 +471,7 @@ int device_get_child_by_seq(struct udevice *parent, int seq,
  * @devp: Returns pointer to device if found, otherwise this is set to NULL
  * @return 0 if OK, -ve on error
  */
-int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
+int device_find_child_by_of_offset(const struct udevice *parent, int of_offset,
                                   struct udevice **devp);
 
 /**
@@ -478,7 +486,7 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
  * @devp: Returns pointer to device if found, otherwise this is set to NULL
  * @return 0 if OK, -ve on error
  */
-int device_get_child_by_of_offset(struct udevice *parent, int of_offset,
+int device_get_child_by_of_offset(const struct udevice *parent, int of_offset,
                                  struct udevice **devp);
 
 /**
@@ -517,7 +525,8 @@ int device_get_global_by_ofnode(ofnode node, struct udevice **devp);
  * @devp: Returns first child device, or NULL if none
  * @return 0
  */
-int device_find_first_child(struct udevice *parent, struct udevice **devp);
+int device_find_first_child(const struct udevice *parent,
+                           struct udevice **devp);
 
 /**
  * device_find_next_child() - Find the next child of a device
@@ -541,7 +550,7 @@ int device_find_next_child(struct udevice **devp);
  * @devp:      Returns device found, if any
  * @return 0 if found, else -ENODEV
  */
-int device_find_first_inactive_child(struct udevice *parent,
+int device_find_first_inactive_child(const struct udevice *parent,
                                     enum uclass_id uclass_id,
                                     struct udevice **devp);
 
@@ -553,7 +562,7 @@ int device_find_first_inactive_child(struct udevice *parent,
  * @devp: Returns first child device in that uclass, if any
  * @return 0 if found, else -ENODEV
  */
-int device_find_first_child_by_uclass(struct udevice *parent,
+int device_find_first_child_by_uclass(const struct udevice *parent,
                                      enum uclass_id uclass_id,
                                      struct udevice **devp);
 
@@ -565,9 +574,56 @@ int device_find_first_child_by_uclass(struct udevice *parent,
  * @devp:      Returns device found, if any
  * @return 0 if found, else -ENODEV
  */
-int device_find_child_by_name(struct udevice *parent, const char *name,
+int device_find_child_by_name(const struct udevice *parent, const char *name,
                              struct udevice **devp);
 
+/**
+ * device_first_child_ofdata_err() - Find the first child and reads its platdata
+ *
+ * The ofdata_to_platdata() method is called on the child before it is returned,
+ * but the child is not probed.
+ *
+ * @parent: Parent to check
+ * @devp: Returns child that was found, if any
+ * @return 0 on success, -ENODEV if no children, other -ve on error
+ */
+int device_first_child_ofdata_err(struct udevice *parent,
+                                 struct udevice **devp);
+
+/*
+ * device_next_child_ofdata_err() - Find the next child and read its platdata
+ *
+ * The ofdata_to_platdata() method is called on the child before it is returned,
+ * but the child is not probed.
+ *
+ * @devp: On entry, points to the previous child; on exit returns the child that
+ *     was found, if any
+ * @return 0 on success, -ENODEV if no children, other -ve on error
+ */
+int device_next_child_ofdata_err(struct udevice **devp);
+
+/**
+ * device_first_child_err() - Get the first child of a device
+ *
+ * The device returned is probed if necessary, and ready for use
+ *
+ * @parent:    Parent device to search
+ * @devp:      Returns device found, if any
+ * @return 0 if found, -ENODEV if not, -ve error if device failed to probe
+ */
+int device_first_child_err(struct udevice *parent, struct udevice **devp);
+
+/**
+ * device_next_child_err() - Get the next child of a parent device
+ *
+ * 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 sibling if no error occurred
+ * @return 0 if found, -ENODEV if not, -ve error if device failed to probe
+ */
+int device_next_child_err(struct udevice **devp);
+
 /**
  * device_has_children() - check if a device has any children
  *
@@ -583,7 +639,7 @@ bool device_has_children(const struct udevice *dev);
  * @return true if the device has one or more children and at least one of
  * them is active (probed).
  */
-bool device_has_active_children(struct udevice *dev);
+bool device_has_active_children(const struct udevice *dev);
 
 /**
  * device_is_last_sibling() - check if a device is the last sibling
@@ -596,7 +652,7 @@ bool device_has_active_children(struct udevice *dev);
  * @return true if there are no more siblings after this one - i.e. is it
  * last in the list.
  */
-bool device_is_last_sibling(struct udevice *dev);
+bool device_is_last_sibling(const struct udevice *dev);
 
 /**
  * device_set_name() - set the name of a device
@@ -636,7 +692,7 @@ void device_set_name_alloced(struct udevice *dev);
  *             device
  * @return true if OK, false if the compatible is not found
  */
-bool device_is_compatible(struct udevice *dev, const char *compat);
+bool device_is_compatible(const struct udevice *dev, const char *compat);
 
 /**
  * of_machine_is_compatible() - check if the machine is compatible with
@@ -671,7 +727,7 @@ int dev_enable_by_path(const char *path);
  * @dev:       device to test
  * @return:    true if it is on a PCI bus, false otherwise
  */
-static inline bool device_is_on_pci_bus(struct udevice *dev)
+static inline bool device_is_on_pci_bus(const struct udevice *dev)
 {
        return device_get_uclass_id(dev->parent) == UCLASS_PCI;
 }
@@ -698,275 +754,54 @@ static inline bool device_is_on_pci_bus(struct udevice *dev)
        list_for_each_entry(pos, &parent->child_head, sibling_node)
 
 /**
- * dm_scan_fdt_dev() - Bind child device in a the device tree
- *
- * This handles device which have sub-nodes in the device tree. It scans all
- * sub-nodes and binds drivers for each node where a driver can be found.
- *
- * If this is called prior to relocation, only pre-relocation devices will be
- * bound (those marked with u-boot,dm-pre-reloc in the device tree, or where
- * the driver has the DM_FLAG_PRE_RELOC flag set). Otherwise, all devices will
- * be bound.
- *
- * @dev:       Device to scan
- * @return 0 if OK, -ve on error
- */
-int dm_scan_fdt_dev(struct udevice *dev);
-
-/* device resource management */
-typedef void (*dr_release_t)(struct udevice *dev, void *res);
-typedef int (*dr_match_t)(struct udevice *dev, void *res, void *match_data);
-
-#ifdef CONFIG_DEVRES
-
-#ifdef CONFIG_DEBUG_DEVRES
-void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
-                    const char *name);
-#define _devres_alloc(release, size, gfp) \
-       __devres_alloc(release, size, gfp, #release)
-#else
-void *_devres_alloc(dr_release_t release, size_t size, gfp_t gfp);
-#endif
-
-/**
- * devres_alloc() - Allocate device resource data
- * @release: Release function devres will be associated with
- * @size: Allocation size
- * @gfp: Allocation flags
- *
- * Allocate devres of @size bytes.  The allocated area is associated
- * with @release.  The returned pointer can be passed to
- * other devres_*() functions.
- *
- * RETURNS:
- * Pointer to allocated devres on success, NULL on failure.
- */
-#define devres_alloc(release, size, gfp) \
-       _devres_alloc(release, size, gfp | __GFP_ZERO)
-
-/**
- * devres_free() - Free device resource data
- * @res: Pointer to devres data to free
+ * device_foreach_child_ofdata_to_platdata() - iterate through children
  *
- * Free devres created with devres_alloc().
- */
-void devres_free(void *res);
+ * This stops when it gets an error, with @pos set to the device that failed to
+ * read ofdata.
 
-/**
- * devres_add() - Register device resource
- * @dev: Device to add resource to
- * @res: Resource to register
- *
- * Register devres @res to @dev.  @res should have been allocated
- * using devres_alloc().  On driver detach, the associated release
- * function will be invoked and devres will be freed automatically.
- */
-void devres_add(struct udevice *dev, void *res);
-
-/**
- * devres_find() - Find device resource
- * @dev: Device to lookup resource from
- * @release: Look for resources associated with this release function
- * @match: Match function (optional)
- * @match_data: Data for the match function
- *
- * Find the latest devres of @dev which is associated with @release
- * and for which @match returns 1.  If @match is NULL, it's considered
- * to match all.
+ * This creates a for() loop which works through the available children of
+ * a device in order from start to end. Device ofdata is read by calling
+ * device_ofdata_to_platdata() on each one. The devices are not probed.
  *
- * @return pointer to found devres, NULL if not found.
- */
-void *devres_find(struct udevice *dev, dr_release_t release,
-                 dr_match_t match, void *match_data);
-
-/**
- * devres_get() - Find devres, if non-existent, add one atomically
- * @dev: Device to lookup or add devres for
- * @new_res: Pointer to new initialized devres to add if not found
- * @match: Match function (optional)
- * @match_data: Data for the match function
- *
- * Find the latest devres of @dev which has the same release function
- * as @new_res and for which @match return 1.  If found, @new_res is
- * freed; otherwise, @new_res is added atomically.
- *
- * @return ointer to found or added devres.
- */
-void *devres_get(struct udevice *dev, void *new_res,
-                dr_match_t match, void *match_data);
-
-/**
- * devres_remove() - Find a device resource and remove it
- * @dev: Device to find resource from
- * @release: Look for resources associated with this release function
- * @match: Match function (optional)
- * @match_data: Data for the match function
- *
- * Find the latest devres of @dev associated with @release and for
- * which @match returns 1.  If @match is NULL, it's considered to
- * match all.  If found, the resource is removed atomically and
- * returned.
- *
- * @return ointer to removed devres on success, NULL if not found.
+ * @pos: struct udevice * for the current device
+ * @parent: parent device to scan
  */
-void *devres_remove(struct udevice *dev, dr_release_t release,
-                   dr_match_t match, void *match_data);
+#define device_foreach_child_ofdata_to_platdata(pos, parent)   \
+       for (int _ret = device_first_child_ofdata_err(parent, &dev); !_ret; \
+            _ret = device_next_child_ofdata_err(&dev))
 
 /**
- * devres_destroy() - Find a device resource and destroy it
- * @dev: Device to find resource from
- * @release: Look for resources associated with this release function
- * @match: Match function (optional)
- * @match_data: Data for the match function
+ * device_foreach_child_probe() - iterate through children, probing them
  *
- * Find the latest devres of @dev associated with @release and for
- * which @match returns 1.  If @match is NULL, it's considered to
- * match all.  If found, the resource is removed atomically and freed.
+ * This creates a for() loop which works through the available children of
+ * a device in order from start to end. Devices are probed if necessary,
+ * and ready for use.
  *
- * Note that the release function for the resource will not be called,
- * only the devres-allocated data will be freed.  The caller becomes
- * responsible for freeing any other data.
+ * This stops when it gets an error, with @pos set to the device that failed to
+ * probe
  *
- * @return 0 if devres is found and freed, -ENOENT if not found.
- */
-int devres_destroy(struct udevice *dev, dr_release_t release,
-                  dr_match_t match, void *match_data);
-
-/**
- * devres_release() - Find a device resource and destroy it, calling release
- * @dev: Device to find resource from
- * @release: Look for resources associated with this release function
- * @match: Match function (optional)
- * @match_data: Data for the match function
- *
- * Find the latest devres of @dev associated with @release and for
- * which @match returns 1.  If @match is NULL, it's considered to
- * match all.  If found, the resource is removed atomically, the
- * release function called and the resource freed.
- *
- * @return 0 if devres is found and freed, -ENOENT if not found.
+ * @pos: struct udevice * for the current device
+ * @parent: parent device to scan
  */
-int devres_release(struct udevice *dev, dr_release_t release,
-                  dr_match_t match, void *match_data);
+#define device_foreach_child_probe(pos, parent)        \
+       for (int _ret = device_first_child_err(parent, &dev); !_ret; \
+            _ret = device_next_child_err(&dev))
 
-/* managed devm_k.alloc/kfree for device drivers */
 /**
- * devm_kmalloc() - Resource-managed kmalloc
- * @dev: Device to allocate memory for
- * @size: Allocation size
- * @gfp: Allocation gfp flags
+ * dm_scan_fdt_dev() - Bind child device in a the device tree
  *
- * Managed kmalloc.  Memory allocated with this function is
- * automatically freed on driver detach.  Like all other devres
- * resources, guaranteed alignment is unsigned long long.
+ * This handles device which have sub-nodes in the device tree. It scans all
+ * sub-nodes and binds drivers for each node where a driver can be found.
  *
- * @return pointer to allocated memory on success, NULL on failure.
- */
-void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp);
-static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp)
-{
-       return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
-}
-static inline void *devm_kmalloc_array(struct udevice *dev,
-                                      size_t n, size_t size, gfp_t flags)
-{
-       if (size != 0 && n > SIZE_MAX / size)
-               return NULL;
-       return devm_kmalloc(dev, n * size, flags);
-}
-static inline void *devm_kcalloc(struct udevice *dev,
-                                size_t n, size_t size, gfp_t flags)
-{
-       return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
-}
-
-/**
- * devm_kfree() - Resource-managed kfree
- * @dev: Device this memory belongs to
- * @ptr: Memory to free
+ * If this is called prior to relocation, only pre-relocation devices will be
+ * bound (those marked with u-boot,dm-pre-reloc in the device tree, or where
+ * the driver has the DM_FLAG_PRE_RELOC flag set). Otherwise, all devices will
+ * be bound.
  *
- * Free memory allocated with devm_kmalloc().
+ * @dev:       Device to scan
+ * @return 0 if OK, -ve on error
  */
-void devm_kfree(struct udevice *dev, void *ptr);
-
-#else /* ! CONFIG_DEVRES */
-
-static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
-{
-       return kzalloc(size, gfp);
-}
-
-static inline void devres_free(void *res)
-{
-       kfree(res);
-}
-
-static inline void devres_add(struct udevice *dev, void *res)
-{
-}
-
-static inline void *devres_find(struct udevice *dev, dr_release_t release,
-                               dr_match_t match, void *match_data)
-{
-       return NULL;
-}
-
-static inline void *devres_get(struct udevice *dev, void *new_res,
-                              dr_match_t match, void *match_data)
-{
-       return NULL;
-}
-
-static inline void *devres_remove(struct udevice *dev, dr_release_t release,
-                                 dr_match_t match, void *match_data)
-{
-       return NULL;
-}
-
-static inline int devres_destroy(struct udevice *dev, dr_release_t release,
-                                dr_match_t match, void *match_data)
-{
-       return 0;
-}
-
-static inline int devres_release(struct udevice *dev, dr_release_t release,
-                                dr_match_t match, void *match_data)
-{
-       return 0;
-}
-
-static inline void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp)
-{
-       return kmalloc(size, gfp);
-}
-
-static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp)
-{
-       return kzalloc(size, gfp);
-}
-
-static inline void *devm_kmaloc_array(struct udevice *dev,
-                                     size_t n, size_t size, gfp_t flags)
-{
-       /* TODO: add kmalloc_array() to linux/compat.h */
-       if (size != 0 && n > SIZE_MAX / size)
-               return NULL;
-       return kmalloc(n * size, flags);
-}
-
-static inline void *devm_kcalloc(struct udevice *dev,
-                                size_t n, size_t size, gfp_t flags)
-{
-       /* TODO: add kcalloc() to linux/compat.h */
-       return kmalloc(n * size, flags | __GFP_ZERO);
-}
-
-static inline void devm_kfree(struct udevice *dev, void *ptr)
-{
-       kfree(ptr);
-}
-
-#endif /* ! CONFIG_DEVRES */
+int dm_scan_fdt_dev(struct udevice *dev);
 
 /*
  * REVISIT: