dm: devres: Create a new devres header file
At present these functions are lumped in with the core device functions. They have their own #ifdef to control their availability, so it seems better to split them out. Move them into their own header file. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
153851ddfa
commit
42a8db5c5b
@ -720,260 +720,7 @@ static inline bool device_is_on_pci_bus(struct udevice *dev)
|
||||
*/
|
||||
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
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* Free memory allocated with devm_kmalloc().
|
||||
*/
|
||||
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_kmalloc_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 */
|
||||
#include <dm/devres.h>
|
||||
|
||||
/*
|
||||
* REVISIT:
|
||||
|
269
include/dm/devres.h
Normal file
269
include/dm/devres.h
Normal file
@ -0,0 +1,269 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
*
|
||||
* Based on the original work in Linux by
|
||||
* Copyright (c) 2006 SUSE Linux Products GmbH
|
||||
* Copyright (c) 2006 Tejun Heo <teheo@suse.de>
|
||||
* Copyright 2019 Google LLC
|
||||
*/
|
||||
|
||||
#ifndef _DM_DEVRES_H
|
||||
#define _DM_DEVRES_H
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* Free memory allocated with devm_kmalloc().
|
||||
*/
|
||||
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_kmalloc_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 /* DEVRES */
|
||||
#endif /* _DM_DEVRES_H */
|
Loading…
Reference in New Issue
Block a user