XenevaOS
Loading...
Searching...
No Matches
devres.h
Go to the documentation of this file.
1/*
2 * DCL <linux/devres.h> -- managed-device resources without the lifetime.
3 *
4 * mainline ties every devm_* allocation and action to a struct device's
5 * probe-to-remove span and runs them all on device release. DCL devices
6 * have no release: put_device() is a documented no-op (DCL/linux_cdev_shim.c)
7 * and no driver in the tree ever unbinds, so the "managed" half reduces to
8 * what the call sites actually test. vkms_drv.c asks devres_open_group()
9 * for a non-NULL token before it builds its device and
10 * devres_release_group() for a "closed" answer on the way out; drm_drv.c:816
11 * returns devm_add_action_or_reset()'s status as the last step of
12 * devm_drm_dev_alloc(). Allocations hand back a real allocation -- the
13 * caller keeps the pointer on mainline too, and here it is never revoked.
14 *
15 * This header's include point is <linux/device.h>: mainline spreads these
16 * declarations over devres.h and reaches them from device users directly,
17 * while DCL's drm chain reaches device.h through drm_print.h, which makes
18 * that the one include that covers drm_drv.c, drm_bridge.c and the vkms
19 * side (via device/faux.h) without editing a vendored include list.
20 */
21#ifndef _LINUX_DEVRES_H
22#define _LINUX_DEVRES_H
23
24#include <linux/slab.h> /* kmalloc/kzalloc for the devm_ allocators */
25
26struct device;
27
28static inline void *devres_open_group(struct device *dev, const char *name,
29 gfp_t gfp)
30{
31 static int dcl_devres_group_marker;
32
33 (void)dev;
34 (void)name;
35 (void)gfp;
36 return &dcl_devres_group_marker;
37}
38
39static inline int devres_release_group(struct device *dev, const void *id)
40{
41 (void)dev;
42 (void)id;
43 return 1;
44}
45
46static inline int devm_add_action_or_reset(struct device *dev,
47 void (*action)(void *),
48 void *data)
49{
50 (void)dev;
51 (void)action;
52 (void)data;
53 return 0;
54}
55
56static inline void devm_release_action(struct device *dev,
57 void (*action)(void *), void *data)
58{
59 (void)dev;
60 (void)action;
61 (void)data;
62}
63
64static inline void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
65{
66 (void)dev;
67 return kmalloc(size, gfp);
68}
69
70static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
71{
72 (void)dev;
73 return kzalloc(size, gfp);
74}
75
76/*
77 * devres_alloc() / devres_add() / devres_free() -- the three that back
78 * devres_open_group()'s siblings above, asked for by drm_drv.c:823-834.
79 *
80 * The sequence there is the one mainline documents for a private devres
81 * entry: allocate a block that carries a release function, either free it
82 * again on the failure path or hand it to the device on the success one.
83 * `devm_kfree_strarray` is the release; it is never run here, for the reason
84 * the header's opening comment gives -- no device in this tree ever releases,
85 * so the release half has nowhere to be called from.
86 *
87 * The block is a real allocation and devres_free() really frees it, because
88 * unlike the group tokens above this one is a caller's pointer: drm_drv.c
89 * stores it and drm_drv.c drops it, and an "allocation" that leaked or that
90 * outlived its free would be a defect rather than a harmless stub. devres_add()
91 * is the only empty one of the three, since it exists in mainline to link the
92 * block to a device's list and there is no list.
93 *
94 * dr_release_t is mainline's typedef, kept so a later real devres could be
95 * dropped in without the caller's declaration changing.
96 */
97typedef void (*dr_release_t)(struct device* dev, void* res);
98typedef int (*dr_match_t)(struct device* dev, void* res, void* match_data);
99
100/*
101 * devres_destroy() -- remove a managed resource without running its release.
102 * The input core asks for this only from input_free_device()'s devres-managed
103 * arm, which no device in this tree takes: no device is ever released, so
104 * there is nothing on a list to find and the honest result is "not found".
105 */
106static inline int devres_destroy(struct device* dev, dr_release_t release,
107 dr_match_t match, void* match_data)
108{
109 (void)dev;
110 (void)release;
111 (void)match;
112 (void)match_data;
113 return -2; /* -ENOENT */
114}
115
116static inline void* devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
117{
118 (void)release;
119 return kmalloc(size, gfp);
120}
121
122static inline void devres_add(struct device* dev, void* res)
123{
124 (void)dev;
125 (void)res;
126}
127
128static inline void devres_free(void* res)
129{
130 kfree(res);
131}
132
133/*
134 * The four "managed" calls bochs.c makes around its BARs. "Managed" for the
135 * region pair means the claim would be released when the device goes away;
136 * no device in this tree ever releases (see the header comment), so the plain
137 * claim is the whole behavior -- and requesting it again here instead of
138 * calling request_mem_region() directly is what keeps the driver's
139 * error handling meaningful: a NULL still means "someone else owns this
140 * window", which is the one answer bochs_pci_probe tests before proceeding.
141 *
142 * devm_ioremap()/devm_ioremap_wc() cannot be inlines here: their bodies need
143 * AuMapMMIO() and the page size, which live under <Mm/vmmngr.h> -- a kernel
144 * header the BaseHdr tree does not include. Bodies in DCL/pci_shim.c. They
145 * are exactly what the native drivers do with a BAR (virtgpu.cpp maps its
146 * registers the same way): the linear physical->virtual map is for RAM, PCI
147 * BARs are device memory, and a PCI window is not promised to land inside
148 * the direct map's range -- so the mapping is made explicitly, for the
149 * window, with device attributes.
150 */
154 const char* name);
158 const char* name);
163
164#endif /* _LINUX_DEVRES_H */
void * devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size)
void * devm_ioremap_wc(struct device *dev, resource_size_t offset, resource_size_t size)
int(* dr_match_t)(struct device *dev, void *res, void *match_data)
Definition devres.h:98
struct resource * devm_request_mem_region(struct device *dev, resource_size_t start, resource_size_t n, const char *name)
struct resource * devm_request_region(struct device *dev, resource_size_t start, resource_size_t n, const char *name)
void(* dr_release_t)(struct device *dev, void *res)
Definition devres.h:97
size_t size
Definition drm_bridge.h:1299
size_t size_t offset
Definition drm_bridge.h:1299
struct drm_crtc struct drm_plane struct drm_plane const struct drm_crtc_funcs const char * name
Definition drm_crtc.h:1242
const struct device * dev
Definition drm_print.h:519
void kfree(void)
void * data
Definition kthread.h:30
uintptr_t resource_size_t
Definition kernel.h:41
unsigned int gfp_t
Definition kernel.h:56
#define kmalloc(size, flags)
Definition slab.h:123
#define kzalloc(size, flags)
Definition slab.h:257
Definition fs.h:255
void(* release)(struct device *)
Definition fs.h:264
Definition ioport.h:44
resource_size_t start
Definition ioport.h:45