1a21cad93SAndy Shevchenko /* SPDX-License-Identifier: GPL-2.0 */
2a21cad93SAndy Shevchenko #ifndef _DEVICE_DEVRES_H_
3a21cad93SAndy Shevchenko #define _DEVICE_DEVRES_H_
4a21cad93SAndy Shevchenko
5a21cad93SAndy Shevchenko #include <linux/err.h>
6a21cad93SAndy Shevchenko #include <linux/gfp_types.h>
7a21cad93SAndy Shevchenko #include <linux/numa.h>
8a21cad93SAndy Shevchenko #include <linux/overflow.h>
9a21cad93SAndy Shevchenko #include <linux/stdarg.h>
10a21cad93SAndy Shevchenko #include <linux/types.h>
11a21cad93SAndy Shevchenko
12a21cad93SAndy Shevchenko struct device;
13a21cad93SAndy Shevchenko struct device_node;
14a21cad93SAndy Shevchenko struct resource;
15a21cad93SAndy Shevchenko
16a21cad93SAndy Shevchenko /* device resource management */
17a21cad93SAndy Shevchenko typedef void (*dr_release_t)(struct device *dev, void *res);
18a21cad93SAndy Shevchenko typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
19a21cad93SAndy Shevchenko
20a21cad93SAndy Shevchenko void * __malloc
21a21cad93SAndy Shevchenko __devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, int nid, const char *name);
22a21cad93SAndy Shevchenko #define devres_alloc(release, size, gfp) \
23a21cad93SAndy Shevchenko __devres_alloc_node(release, size, gfp, NUMA_NO_NODE, #release)
24a21cad93SAndy Shevchenko #define devres_alloc_node(release, size, gfp, nid) \
25a21cad93SAndy Shevchenko __devres_alloc_node(release, size, gfp, nid, #release)
26a21cad93SAndy Shevchenko
27a21cad93SAndy Shevchenko void devres_for_each_res(struct device *dev, dr_release_t release,
28a21cad93SAndy Shevchenko dr_match_t match, void *match_data,
29a21cad93SAndy Shevchenko void (*fn)(struct device *, void *, void *),
30a21cad93SAndy Shevchenko void *data);
31a21cad93SAndy Shevchenko void devres_free(void *res);
32a21cad93SAndy Shevchenko void devres_add(struct device *dev, void *res);
33a21cad93SAndy Shevchenko void *devres_find(struct device *dev, dr_release_t release, dr_match_t match, void *match_data);
34a21cad93SAndy Shevchenko void *devres_get(struct device *dev, void *new_res, dr_match_t match, void *match_data);
35a21cad93SAndy Shevchenko void *devres_remove(struct device *dev, dr_release_t release, dr_match_t match, void *match_data);
36a21cad93SAndy Shevchenko int devres_destroy(struct device *dev, dr_release_t release, dr_match_t match, void *match_data);
37a21cad93SAndy Shevchenko int devres_release(struct device *dev, dr_release_t release, dr_match_t match, void *match_data);
38a21cad93SAndy Shevchenko
39a21cad93SAndy Shevchenko /* devres group */
40a21cad93SAndy Shevchenko void * __must_check devres_open_group(struct device *dev, void *id, gfp_t gfp);
41a21cad93SAndy Shevchenko void devres_close_group(struct device *dev, void *id);
42a21cad93SAndy Shevchenko void devres_remove_group(struct device *dev, void *id);
43a21cad93SAndy Shevchenko int devres_release_group(struct device *dev, void *id);
44a21cad93SAndy Shevchenko
45a21cad93SAndy Shevchenko /* managed devm_k.alloc/kfree for device drivers */
46a21cad93SAndy Shevchenko void * __alloc_size(2)
47a21cad93SAndy Shevchenko devm_kmalloc(struct device *dev, size_t size, gfp_t gfp);
48a21cad93SAndy Shevchenko void * __must_check __realloc_size(3)
49a21cad93SAndy Shevchenko devm_krealloc(struct device *dev, void *ptr, size_t size, gfp_t gfp);
devm_kzalloc(struct device * dev,size_t size,gfp_t gfp)50a21cad93SAndy Shevchenko static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
51a21cad93SAndy Shevchenko {
52a21cad93SAndy Shevchenko return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
53a21cad93SAndy Shevchenko }
devm_kmalloc_array(struct device * dev,size_t n,size_t size,gfp_t flags)54a21cad93SAndy Shevchenko static inline void *devm_kmalloc_array(struct device *dev, size_t n, size_t size, gfp_t flags)
55a21cad93SAndy Shevchenko {
56a21cad93SAndy Shevchenko size_t bytes;
57a21cad93SAndy Shevchenko
58a21cad93SAndy Shevchenko if (unlikely(check_mul_overflow(n, size, &bytes)))
59a21cad93SAndy Shevchenko return NULL;
60a21cad93SAndy Shevchenko
61a21cad93SAndy Shevchenko return devm_kmalloc(dev, bytes, flags);
62a21cad93SAndy Shevchenko }
devm_kcalloc(struct device * dev,size_t n,size_t size,gfp_t flags)63a21cad93SAndy Shevchenko static inline void *devm_kcalloc(struct device *dev, size_t n, size_t size, gfp_t flags)
64a21cad93SAndy Shevchenko {
65a21cad93SAndy Shevchenko return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
66a21cad93SAndy Shevchenko }
67a21cad93SAndy Shevchenko static inline __realloc_size(3, 4) void * __must_check
devm_krealloc_array(struct device * dev,void * p,size_t new_n,size_t new_size,gfp_t flags)68a21cad93SAndy Shevchenko devm_krealloc_array(struct device *dev, void *p, size_t new_n, size_t new_size, gfp_t flags)
69a21cad93SAndy Shevchenko {
70a21cad93SAndy Shevchenko size_t bytes;
71a21cad93SAndy Shevchenko
72a21cad93SAndy Shevchenko if (unlikely(check_mul_overflow(new_n, new_size, &bytes)))
73a21cad93SAndy Shevchenko return NULL;
74a21cad93SAndy Shevchenko
75a21cad93SAndy Shevchenko return devm_krealloc(dev, p, bytes, flags);
76a21cad93SAndy Shevchenko }
77a21cad93SAndy Shevchenko
78a21cad93SAndy Shevchenko void devm_kfree(struct device *dev, const void *p);
79a21cad93SAndy Shevchenko
80a21cad93SAndy Shevchenko void * __realloc_size(3)
81a21cad93SAndy Shevchenko devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp);
devm_kmemdup_array(struct device * dev,const void * src,size_t n,size_t size,gfp_t flags)82*a103b833SRaag Jadav static inline void *devm_kmemdup_array(struct device *dev, const void *src,
83*a103b833SRaag Jadav size_t n, size_t size, gfp_t flags)
84*a103b833SRaag Jadav {
85*a103b833SRaag Jadav return devm_kmemdup(dev, src, size_mul(size, n), flags);
86*a103b833SRaag Jadav }
87a21cad93SAndy Shevchenko
88a21cad93SAndy Shevchenko char * __malloc
89a21cad93SAndy Shevchenko devm_kstrdup(struct device *dev, const char *s, gfp_t gfp);
90a21cad93SAndy Shevchenko const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp);
91a21cad93SAndy Shevchenko char * __printf(3, 0) __malloc
92a21cad93SAndy Shevchenko devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, va_list ap);
93a21cad93SAndy Shevchenko char * __printf(3, 4) __malloc
94a21cad93SAndy Shevchenko devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
95a21cad93SAndy Shevchenko
96a21cad93SAndy Shevchenko unsigned long devm_get_free_pages(struct device *dev, gfp_t gfp_mask, unsigned int order);
97a21cad93SAndy Shevchenko void devm_free_pages(struct device *dev, unsigned long addr);
98a21cad93SAndy Shevchenko
99a21cad93SAndy Shevchenko #ifdef CONFIG_HAS_IOMEM
100a21cad93SAndy Shevchenko
101a21cad93SAndy Shevchenko void __iomem *devm_ioremap_resource(struct device *dev, const struct resource *res);
102a21cad93SAndy Shevchenko void __iomem *devm_ioremap_resource_wc(struct device *dev, const struct resource *res);
103a21cad93SAndy Shevchenko
104a21cad93SAndy Shevchenko void __iomem *devm_of_iomap(struct device *dev, struct device_node *node, int index,
105a21cad93SAndy Shevchenko resource_size_t *size);
106a21cad93SAndy Shevchenko #else
107a21cad93SAndy Shevchenko
108a21cad93SAndy Shevchenko static inline
devm_ioremap_resource(struct device * dev,const struct resource * res)109a21cad93SAndy Shevchenko void __iomem *devm_ioremap_resource(struct device *dev, const struct resource *res)
110a21cad93SAndy Shevchenko {
111a21cad93SAndy Shevchenko return IOMEM_ERR_PTR(-EINVAL);
112a21cad93SAndy Shevchenko }
113a21cad93SAndy Shevchenko
114a21cad93SAndy Shevchenko static inline
devm_ioremap_resource_wc(struct device * dev,const struct resource * res)115a21cad93SAndy Shevchenko void __iomem *devm_ioremap_resource_wc(struct device *dev, const struct resource *res)
116a21cad93SAndy Shevchenko {
117a21cad93SAndy Shevchenko return IOMEM_ERR_PTR(-EINVAL);
118a21cad93SAndy Shevchenko }
119a21cad93SAndy Shevchenko
120a21cad93SAndy Shevchenko static inline
devm_of_iomap(struct device * dev,struct device_node * node,int index,resource_size_t * size)121a21cad93SAndy Shevchenko void __iomem *devm_of_iomap(struct device *dev, struct device_node *node, int index,
122a21cad93SAndy Shevchenko resource_size_t *size)
123a21cad93SAndy Shevchenko {
124a21cad93SAndy Shevchenko return IOMEM_ERR_PTR(-EINVAL);
125a21cad93SAndy Shevchenko }
126a21cad93SAndy Shevchenko
127a21cad93SAndy Shevchenko #endif
128a21cad93SAndy Shevchenko
129a21cad93SAndy Shevchenko #endif /* _DEVICE_DEVRES_H_ */
130