1 /*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2021-2026 The FreeBSD Foundation
5 *
6 * Portions of this software were developed by Björn Zeeb
7 * under sponsorship from the FreeBSD Foundation.
8 *
9 */
10 #ifndef _LINUXKPI_LINUX_DEVICE_DEVRES_H_
11 #define _LINUXKPI_LINUX_DEVICE_DEVRES_H_
12
13 #include <linux/types.h>
14
15 /* Public and LinuxKPI internal devres functions. */
16 void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t);
17 void lkpi_devres_add(struct device *, void *);
18 void lkpi_devres_free(void *);
19 void *lkpi_devres_find(struct device *, void(*release)(struct device *, void *),
20 int (*match)(struct device *, void *, void *), void *);
21 int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *),
22 int (*match)(struct device *, void *, void *), void *);
23 #define devres_alloc(_r, _s, _g) lkpi_devres_alloc(_r, _s, _g)
24 #define devres_add(_d, _p) lkpi_devres_add(_d, _p)
25 #define devres_free(_p) lkpi_devres_free(_p)
26 #define devres_find(_d, _rfn, _mfn, _mp) \
27 lkpi_devres_find(_d, _rfn, _mfn, _mp)
28 #define devres_destroy(_d, _rfn, _mfn, _mp) \
29 lkpi_devres_destroy(_d, _rfn, _mfn, _mp)
30
31 void lkpi_devm_kfree(struct device *, const void *);
32 #define devm_kfree(_d, _p) lkpi_devm_kfree(_d, _p)
33
34 void lkpi_devm_kmalloc_release(struct device *, void *);
35
36 static inline void *
devm_kmalloc(struct device * dev,size_t size,gfp_t gfp)37 devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
38 {
39 void *p;
40
41 p = lkpi_devres_alloc(lkpi_devm_kmalloc_release, size, gfp);
42 if (p != NULL)
43 lkpi_devres_add(dev, p);
44
45 return (p);
46 }
47
48 static inline void *
devm_kmemdup(struct device * dev,const void * src,size_t len,gfp_t gfp)49 devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp)
50 {
51 void *dst;
52
53 if (len == 0)
54 return (NULL);
55
56 dst = devm_kmalloc(dev, len, gfp);
57 if (dst != NULL)
58 memcpy(dst, src, len);
59
60 return (dst);
61 }
62
63 static inline void *
devm_kmemdup_array(struct device * dev,const void * src,size_t n,size_t len,gfp_t gfp)64 devm_kmemdup_array(struct device *dev, const void *src, size_t n, size_t len,
65 gfp_t gfp)
66 {
67 return (devm_kmemdup(dev, src, size_mul(n, len), gfp));
68 }
69
70 #endif /* _LINUXKPI_LINUX_DEVICE_DEVRES_H_ */
71