diff options
| author | Tom Rini <[email protected]> | 2015-08-06 19:56:03 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2015-08-06 19:56:03 -0400 |
| commit | ae27120c31d58b8bb694d9155bcffdcfae8552a6 (patch) | |
| tree | 8fcd4823406dc3adfb82174314198e9396c24feb /include/dm | |
| parent | f05fa6781ae1122f348e66b5b26acbfe552f6602 (diff) | |
| parent | fac971b2b5efbdb6ed2d12ebdbf7e029c5ed30e8 (diff) | |
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'include/dm')
| -rw-r--r-- | include/dm/device-internal.h | 44 | ||||
| -rw-r--r-- | include/dm/device.h | 284 | ||||
| -rw-r--r-- | include/dm/uclass-id.h | 2 | ||||
| -rw-r--r-- | include/dm/uclass.h | 19 | ||||
| -rw-r--r-- | include/dm/util.h | 9 |
5 files changed, 357 insertions, 1 deletions
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index 402304f19ef..2cd2fe91d85 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -139,8 +139,52 @@ void device_free(struct udevice *dev); static inline void device_free(struct udevice *dev) {} #endif +/** + * simple_bus_translate() - translate a bus address to a system address + * + * This handles the 'ranges' property in a simple bus. It translates the + * device address @addr to a system address using this property. + * + * @dev: Simple bus device (parent of target device) + * @addr: Address to translate + * @return new address + */ +fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr); + /* Cast away any volatile pointer */ #define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root) #define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root) +/* device resource management */ +#ifdef CONFIG_DEVRES + +/** + * devres_release_probe - Release managed resources allocated after probing + * @dev: Device to release resources for + * + * Release all resources allocated for @dev when it was probed or later. + * This function is called on driver removal. + */ +void devres_release_probe(struct udevice *dev); + +/** + * devres_release_all - Release all managed resources + * @dev: Device to release resources for + * + * Release all resources associated with @dev. This function is + * called on driver unbinding. + */ +void devres_release_all(struct udevice *dev); + +#else /* ! CONFIG_DEVRES */ + +static inline void devres_release_probe(struct udevice *dev) +{ +} + +static inline void devres_release_all(struct udevice *dev) +{ +} + +#endif /* ! CONFIG_DEVRES */ #endif diff --git a/include/dm/device.h b/include/dm/device.h index 12fd02d09a7..1f78963803d 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -14,6 +14,8 @@ #include <dm/uclass-id.h> #include <fdtdec.h> #include <linker_lists.h> +#include <linux/compat.h> +#include <linux/kernel.h> #include <linux/list.h> struct driver_info; @@ -36,6 +38,9 @@ struct driver_info; /* Allocate driver private data on a DMA boundary */ #define DM_FLAG_ALLOC_PRIV_DMA (1 << 5) +/* Device is bound */ +#define DM_FLAG_BOUND (1 << 6) + /** * struct udevice - An instance of a driver * @@ -93,6 +98,9 @@ struct udevice { uint32_t flags; int req_seq; int seq; +#ifdef CONFIG_DEVRES + struct list_head devres_head; +#endif }; /* Maximum sequence number supported */ @@ -462,4 +470,280 @@ bool device_has_active_children(struct udevice *dev); */ bool device_is_last_sibling(struct udevice *dev); +/** + * device_set_name() - set the name of a device + * + * This must be called in the device's bind() method and no later. Normally + * this is unnecessary but for probed devices which don't get a useful name + * this function can be helpful. + * + * @dev: Device to update + * @name: New name (this string is allocated new memory and attached to + * the device) + * @return 0 if OK, -ENOMEM if there is not enough memory to allocate the + * string + */ +int device_set_name(struct udevice *dev, const char *name); + +/* 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 + * + * Free devres created with devres_alloc(). + */ +void devres_free(void *res); + +/** + * 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. + * + * RETURNS: + * 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. + * + * RETURNS: + * Pointer 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. + * + * RETURNS: + * Pointer to removed devres on success, NULL if not found. + */ +void *devres_remove(struct udevice *dev, dr_release_t release, + dr_match_t match, void *match_data); + +/** + * 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 + * + * 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. + * + * 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. + * + * RETURNS: + * 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. + * + * RETURNS: + * 0 if devres is found and freed, -ENOENT if not found. + */ +int devres_release(struct udevice *dev, dr_release_t release, + dr_match_t match, void *match_data); + +/* 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 + * + * Managed kmalloc. Memory allocated with this function is + * automatically freed on driver detach. Like all other devres + * resources, guaranteed alignment is unsigned long long. + * + * RETURNS: + * 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 + * @p: Memory to free + * + * Free memory allocated with devm_kmalloc(). + */ +void devm_kfree(struct udevice *dev, void *p); + +#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 *p) +{ + kfree(p); +} + +#endif /* ! CONFIG_DEVRES */ + #endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index bc057d7adf0..c744044bb8a 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -35,6 +35,7 @@ enum uclass_id { UCLASS_I2C, /* I2C bus */ UCLASS_I2C_EEPROM, /* I2C EEPROM device */ UCLASS_I2C_GENERIC, /* Generic I2C device */ + UCLASS_I2C_MUX, /* I2C multiplexer */ UCLASS_LED, /* Light-emitting diode (LED) */ UCLASS_LPC, /* x86 'low pin count' interface */ UCLASS_MASS_STORAGE, /* Mass storage device */ @@ -56,6 +57,7 @@ enum uclass_id { UCLASS_USB, /* USB bus */ UCLASS_USB_DEV_GENERIC, /* USB generic device */ UCLASS_USB_HUB, /* USB hub */ + UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 4cfc0df84c2..d56877c8982 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -130,7 +130,7 @@ 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 it's name + * 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. * @@ -177,6 +177,23 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node, 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_first_device() - Get the first device in a uclass * * The device returned is probed if necessary, and ready for use diff --git a/include/dm/util.h b/include/dm/util.h index 7dbed6793f8..15daa3d19f1 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -39,4 +39,13 @@ void dm_dump_all(void); /* Dump out a list of uclasses and their devices */ void dm_dump_uclass(void); +#ifdef CONFIG_DEBUG_DEVRES +/* Dump out a list of device resources */ +void dm_dump_devres(void); +#else +static inline void dm_dump_devres(void) +{ +} +#endif + #endif |
