xref: /openbmc/linux/Documentation/driver-api/driver-model/devres.rst (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1fe34c89dSMauro Carvalho Chehab================================
2fe34c89dSMauro Carvalho ChehabDevres - Managed Device Resource
3fe34c89dSMauro Carvalho Chehab================================
4fe34c89dSMauro Carvalho Chehab
5fe34c89dSMauro Carvalho ChehabTejun Heo	<teheo@suse.de>
6fe34c89dSMauro Carvalho Chehab
7fe34c89dSMauro Carvalho ChehabFirst draft	10 January 2007
8fe34c89dSMauro Carvalho Chehab
9fe34c89dSMauro Carvalho Chehab.. contents
10fe34c89dSMauro Carvalho Chehab
11fe34c89dSMauro Carvalho Chehab   1. Intro			: Huh? Devres?
12fe34c89dSMauro Carvalho Chehab   2. Devres			: Devres in a nutshell
13fe34c89dSMauro Carvalho Chehab   3. Devres Group		: Group devres'es and release them together
14fe34c89dSMauro Carvalho Chehab   4. Details			: Life time rules, calling context, ...
15fe34c89dSMauro Carvalho Chehab   5. Overhead			: How much do we have to pay for this?
16fe34c89dSMauro Carvalho Chehab   6. List of managed interfaces: Currently implemented managed interfaces
17fe34c89dSMauro Carvalho Chehab
18fe34c89dSMauro Carvalho Chehab
19fe34c89dSMauro Carvalho Chehab1. Intro
20fe34c89dSMauro Carvalho Chehab--------
21fe34c89dSMauro Carvalho Chehab
22fe34c89dSMauro Carvalho Chehabdevres came up while trying to convert libata to use iomap.  Each
23fe34c89dSMauro Carvalho Chehabiomapped address should be kept and unmapped on driver detach.  For
24fe34c89dSMauro Carvalho Chehabexample, a plain SFF ATA controller (that is, good old PCI IDE) in
25fe34c89dSMauro Carvalho Chehabnative mode makes use of 5 PCI BARs and all of them should be
26fe34c89dSMauro Carvalho Chehabmaintained.
27fe34c89dSMauro Carvalho Chehab
28fe34c89dSMauro Carvalho ChehabAs with many other device drivers, libata low level drivers have
29fe34c89dSMauro Carvalho Chehabsufficient bugs in ->remove and ->probe failure path.  Well, yes,
30fe34c89dSMauro Carvalho Chehabthat's probably because libata low level driver developers are lazy
31fe34c89dSMauro Carvalho Chehabbunch, but aren't all low level driver developers?  After spending a
32fe34c89dSMauro Carvalho Chehabday fiddling with braindamaged hardware with no document or
33fe34c89dSMauro Carvalho Chehabbraindamaged document, if it's finally working, well, it's working.
34fe34c89dSMauro Carvalho Chehab
35fe34c89dSMauro Carvalho ChehabFor one reason or another, low level drivers don't receive as much
36fe34c89dSMauro Carvalho Chehabattention or testing as core code, and bugs on driver detach or
37fe34c89dSMauro Carvalho Chehabinitialization failure don't happen often enough to be noticeable.
38fe34c89dSMauro Carvalho ChehabInit failure path is worse because it's much less travelled while
39fe34c89dSMauro Carvalho Chehabneeds to handle multiple entry points.
40fe34c89dSMauro Carvalho Chehab
41fe34c89dSMauro Carvalho ChehabSo, many low level drivers end up leaking resources on driver detach
42fe34c89dSMauro Carvalho Chehaband having half broken failure path implementation in ->probe() which
43fe34c89dSMauro Carvalho Chehabwould leak resources or even cause oops when failure occurs.  iomap
44fe34c89dSMauro Carvalho Chehabadds more to this mix.  So do msi and msix.
45fe34c89dSMauro Carvalho Chehab
46fe34c89dSMauro Carvalho Chehab
47fe34c89dSMauro Carvalho Chehab2. Devres
48fe34c89dSMauro Carvalho Chehab---------
49fe34c89dSMauro Carvalho Chehab
50fe34c89dSMauro Carvalho Chehabdevres is basically linked list of arbitrarily sized memory areas
51fe34c89dSMauro Carvalho Chehabassociated with a struct device.  Each devres entry is associated with
52fe34c89dSMauro Carvalho Chehaba release function.  A devres can be released in several ways.  No
53fe34c89dSMauro Carvalho Chehabmatter what, all devres entries are released on driver detach.  On
54fe34c89dSMauro Carvalho Chehabrelease, the associated release function is invoked and then the
55fe34c89dSMauro Carvalho Chehabdevres entry is freed.
56fe34c89dSMauro Carvalho Chehab
57fe34c89dSMauro Carvalho ChehabManaged interface is created for resources commonly used by device
58fe34c89dSMauro Carvalho Chehabdrivers using devres.  For example, coherent DMA memory is acquired
59fe34c89dSMauro Carvalho Chehabusing dma_alloc_coherent().  The managed version is called
60fe34c89dSMauro Carvalho Chehabdmam_alloc_coherent().  It is identical to dma_alloc_coherent() except
61fe34c89dSMauro Carvalho Chehabfor the DMA memory allocated using it is managed and will be
62fe34c89dSMauro Carvalho Chehabautomatically released on driver detach.  Implementation looks like
63fe34c89dSMauro Carvalho Chehabthe following::
64fe34c89dSMauro Carvalho Chehab
65fe34c89dSMauro Carvalho Chehab  struct dma_devres {
66fe34c89dSMauro Carvalho Chehab	size_t		size;
67fe34c89dSMauro Carvalho Chehab	void		*vaddr;
68fe34c89dSMauro Carvalho Chehab	dma_addr_t	dma_handle;
69fe34c89dSMauro Carvalho Chehab  };
70fe34c89dSMauro Carvalho Chehab
71fe34c89dSMauro Carvalho Chehab  static void dmam_coherent_release(struct device *dev, void *res)
72fe34c89dSMauro Carvalho Chehab  {
73fe34c89dSMauro Carvalho Chehab	struct dma_devres *this = res;
74fe34c89dSMauro Carvalho Chehab
75fe34c89dSMauro Carvalho Chehab	dma_free_coherent(dev, this->size, this->vaddr, this->dma_handle);
76fe34c89dSMauro Carvalho Chehab  }
77fe34c89dSMauro Carvalho Chehab
78fe34c89dSMauro Carvalho Chehab  dmam_alloc_coherent(dev, size, dma_handle, gfp)
79fe34c89dSMauro Carvalho Chehab  {
80fe34c89dSMauro Carvalho Chehab	struct dma_devres *dr;
81fe34c89dSMauro Carvalho Chehab	void *vaddr;
82fe34c89dSMauro Carvalho Chehab
83fe34c89dSMauro Carvalho Chehab	dr = devres_alloc(dmam_coherent_release, sizeof(*dr), gfp);
84fe34c89dSMauro Carvalho Chehab	...
85fe34c89dSMauro Carvalho Chehab
86fe34c89dSMauro Carvalho Chehab	/* alloc DMA memory as usual */
87fe34c89dSMauro Carvalho Chehab	vaddr = dma_alloc_coherent(...);
88fe34c89dSMauro Carvalho Chehab	...
89fe34c89dSMauro Carvalho Chehab
90fe34c89dSMauro Carvalho Chehab	/* record size, vaddr, dma_handle in dr */
91fe34c89dSMauro Carvalho Chehab	dr->vaddr = vaddr;
92fe34c89dSMauro Carvalho Chehab	...
93fe34c89dSMauro Carvalho Chehab
94fe34c89dSMauro Carvalho Chehab	devres_add(dev, dr);
95fe34c89dSMauro Carvalho Chehab
96fe34c89dSMauro Carvalho Chehab	return vaddr;
97fe34c89dSMauro Carvalho Chehab  }
98fe34c89dSMauro Carvalho Chehab
99fe34c89dSMauro Carvalho ChehabIf a driver uses dmam_alloc_coherent(), the area is guaranteed to be
100fe34c89dSMauro Carvalho Chehabfreed whether initialization fails half-way or the device gets
101fe34c89dSMauro Carvalho Chehabdetached.  If most resources are acquired using managed interface, a
102fe34c89dSMauro Carvalho Chehabdriver can have much simpler init and exit code.  Init path basically
103fe34c89dSMauro Carvalho Chehablooks like the following::
104fe34c89dSMauro Carvalho Chehab
105fe34c89dSMauro Carvalho Chehab  my_init_one()
106fe34c89dSMauro Carvalho Chehab  {
107fe34c89dSMauro Carvalho Chehab	struct mydev *d;
108fe34c89dSMauro Carvalho Chehab
109fe34c89dSMauro Carvalho Chehab	d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
110fe34c89dSMauro Carvalho Chehab	if (!d)
111fe34c89dSMauro Carvalho Chehab		return -ENOMEM;
112fe34c89dSMauro Carvalho Chehab
113fe34c89dSMauro Carvalho Chehab	d->ring = dmam_alloc_coherent(...);
114fe34c89dSMauro Carvalho Chehab	if (!d->ring)
115fe34c89dSMauro Carvalho Chehab		return -ENOMEM;
116fe34c89dSMauro Carvalho Chehab
117fe34c89dSMauro Carvalho Chehab	if (check something)
118fe34c89dSMauro Carvalho Chehab		return -EINVAL;
119fe34c89dSMauro Carvalho Chehab	...
120fe34c89dSMauro Carvalho Chehab
121fe34c89dSMauro Carvalho Chehab	return register_to_upper_layer(d);
122fe34c89dSMauro Carvalho Chehab  }
123fe34c89dSMauro Carvalho Chehab
124fe34c89dSMauro Carvalho ChehabAnd exit path::
125fe34c89dSMauro Carvalho Chehab
126fe34c89dSMauro Carvalho Chehab  my_remove_one()
127fe34c89dSMauro Carvalho Chehab  {
128fe34c89dSMauro Carvalho Chehab	unregister_from_upper_layer(d);
129fe34c89dSMauro Carvalho Chehab	shutdown_my_hardware();
130fe34c89dSMauro Carvalho Chehab  }
131fe34c89dSMauro Carvalho Chehab
132fe34c89dSMauro Carvalho ChehabAs shown above, low level drivers can be simplified a lot by using
133fe34c89dSMauro Carvalho Chehabdevres.  Complexity is shifted from less maintained low level drivers
134fe34c89dSMauro Carvalho Chehabto better maintained higher layer.  Also, as init failure path is
135fe34c89dSMauro Carvalho Chehabshared with exit path, both can get more testing.
136fe34c89dSMauro Carvalho Chehab
137fe34c89dSMauro Carvalho ChehabNote though that when converting current calls or assignments to
138fe34c89dSMauro Carvalho Chehabmanaged devm_* versions it is up to you to check if internal operations
139fe34c89dSMauro Carvalho Chehablike allocating memory, have failed. Managed resources pertains to the
140fe34c89dSMauro Carvalho Chehabfreeing of these resources *only* - all other checks needed are still
141fe34c89dSMauro Carvalho Chehabon you. In some cases this may mean introducing checks that were not
142fe34c89dSMauro Carvalho Chehabnecessary before moving to the managed devm_* calls.
143fe34c89dSMauro Carvalho Chehab
144fe34c89dSMauro Carvalho Chehab
145fe34c89dSMauro Carvalho Chehab3. Devres group
146fe34c89dSMauro Carvalho Chehab---------------
147fe34c89dSMauro Carvalho Chehab
148fe34c89dSMauro Carvalho ChehabDevres entries can be grouped using devres group.  When a group is
149fe34c89dSMauro Carvalho Chehabreleased, all contained normal devres entries and properly nested
150fe34c89dSMauro Carvalho Chehabgroups are released.  One usage is to rollback series of acquired
151fe34c89dSMauro Carvalho Chehabresources on failure.  For example::
152fe34c89dSMauro Carvalho Chehab
153fe34c89dSMauro Carvalho Chehab  if (!devres_open_group(dev, NULL, GFP_KERNEL))
154fe34c89dSMauro Carvalho Chehab	return -ENOMEM;
155fe34c89dSMauro Carvalho Chehab
156fe34c89dSMauro Carvalho Chehab  acquire A;
157fe34c89dSMauro Carvalho Chehab  if (failed)
158fe34c89dSMauro Carvalho Chehab	goto err;
159fe34c89dSMauro Carvalho Chehab
160fe34c89dSMauro Carvalho Chehab  acquire B;
161fe34c89dSMauro Carvalho Chehab  if (failed)
162fe34c89dSMauro Carvalho Chehab	goto err;
163fe34c89dSMauro Carvalho Chehab  ...
164fe34c89dSMauro Carvalho Chehab
165fe34c89dSMauro Carvalho Chehab  devres_remove_group(dev, NULL);
166fe34c89dSMauro Carvalho Chehab  return 0;
167fe34c89dSMauro Carvalho Chehab
168fe34c89dSMauro Carvalho Chehab err:
169fe34c89dSMauro Carvalho Chehab  devres_release_group(dev, NULL);
170fe34c89dSMauro Carvalho Chehab  return err_code;
171fe34c89dSMauro Carvalho Chehab
172fe34c89dSMauro Carvalho ChehabAs resource acquisition failure usually means probe failure, constructs
173fe34c89dSMauro Carvalho Chehablike above are usually useful in midlayer driver (e.g. libata core
174fe34c89dSMauro Carvalho Chehablayer) where interface function shouldn't have side effect on failure.
175fe34c89dSMauro Carvalho ChehabFor LLDs, just returning error code suffices in most cases.
176fe34c89dSMauro Carvalho Chehab
177fe34c89dSMauro Carvalho ChehabEach group is identified by `void *id`.  It can either be explicitly
178fe34c89dSMauro Carvalho Chehabspecified by @id argument to devres_open_group() or automatically
179fe34c89dSMauro Carvalho Chehabcreated by passing NULL as @id as in the above example.  In both
180fe34c89dSMauro Carvalho Chehabcases, devres_open_group() returns the group's id.  The returned id
181fe34c89dSMauro Carvalho Chehabcan be passed to other devres functions to select the target group.
182fe34c89dSMauro Carvalho ChehabIf NULL is given to those functions, the latest open group is
183fe34c89dSMauro Carvalho Chehabselected.
184fe34c89dSMauro Carvalho Chehab
185fe34c89dSMauro Carvalho ChehabFor example, you can do something like the following::
186fe34c89dSMauro Carvalho Chehab
187fe34c89dSMauro Carvalho Chehab  int my_midlayer_create_something()
188fe34c89dSMauro Carvalho Chehab  {
189fe34c89dSMauro Carvalho Chehab	if (!devres_open_group(dev, my_midlayer_create_something, GFP_KERNEL))
190fe34c89dSMauro Carvalho Chehab		return -ENOMEM;
191fe34c89dSMauro Carvalho Chehab
192fe34c89dSMauro Carvalho Chehab	...
193fe34c89dSMauro Carvalho Chehab
194fe34c89dSMauro Carvalho Chehab	devres_close_group(dev, my_midlayer_create_something);
195fe34c89dSMauro Carvalho Chehab	return 0;
196fe34c89dSMauro Carvalho Chehab  }
197fe34c89dSMauro Carvalho Chehab
198fe34c89dSMauro Carvalho Chehab  void my_midlayer_destroy_something()
199fe34c89dSMauro Carvalho Chehab  {
200fe34c89dSMauro Carvalho Chehab	devres_release_group(dev, my_midlayer_create_something);
201fe34c89dSMauro Carvalho Chehab  }
202fe34c89dSMauro Carvalho Chehab
203fe34c89dSMauro Carvalho Chehab
204fe34c89dSMauro Carvalho Chehab4. Details
205fe34c89dSMauro Carvalho Chehab----------
206fe34c89dSMauro Carvalho Chehab
207fe34c89dSMauro Carvalho ChehabLifetime of a devres entry begins on devres allocation and finishes
208fe34c89dSMauro Carvalho Chehabwhen it is released or destroyed (removed and freed) - no reference
209fe34c89dSMauro Carvalho Chehabcounting.
210fe34c89dSMauro Carvalho Chehab
211fe34c89dSMauro Carvalho Chehabdevres core guarantees atomicity to all basic devres operations and
212fe34c89dSMauro Carvalho Chehabhas support for single-instance devres types (atomic
213fe34c89dSMauro Carvalho Chehablookup-and-add-if-not-found).  Other than that, synchronizing
214fe34c89dSMauro Carvalho Chehabconcurrent accesses to allocated devres data is caller's
215fe34c89dSMauro Carvalho Chehabresponsibility.  This is usually non-issue because bus ops and
216fe34c89dSMauro Carvalho Chehabresource allocations already do the job.
217fe34c89dSMauro Carvalho Chehab
218fe34c89dSMauro Carvalho ChehabFor an example of single-instance devres type, read pcim_iomap_table()
219fe34c89dSMauro Carvalho Chehabin lib/devres.c.
220fe34c89dSMauro Carvalho Chehab
221fe34c89dSMauro Carvalho ChehabAll devres interface functions can be called without context if the
222fe34c89dSMauro Carvalho Chehabright gfp mask is given.
223fe34c89dSMauro Carvalho Chehab
224fe34c89dSMauro Carvalho Chehab
225fe34c89dSMauro Carvalho Chehab5. Overhead
226fe34c89dSMauro Carvalho Chehab-----------
227fe34c89dSMauro Carvalho Chehab
228fe34c89dSMauro Carvalho ChehabEach devres bookkeeping info is allocated together with requested data
229fe34c89dSMauro Carvalho Chehabarea.  With debug option turned off, bookkeeping info occupies 16
230fe34c89dSMauro Carvalho Chehabbytes on 32bit machines and 24 bytes on 64bit (three pointers rounded
231fe34c89dSMauro Carvalho Chehabup to ull alignment).  If singly linked list is used, it can be
232fe34c89dSMauro Carvalho Chehabreduced to two pointers (8 bytes on 32bit, 16 bytes on 64bit).
233fe34c89dSMauro Carvalho Chehab
234fe34c89dSMauro Carvalho ChehabEach devres group occupies 8 pointers.  It can be reduced to 6 if
235fe34c89dSMauro Carvalho Chehabsingly linked list is used.
236fe34c89dSMauro Carvalho Chehab
237fe34c89dSMauro Carvalho ChehabMemory space overhead on ahci controller with two ports is between 300
238fe34c89dSMauro Carvalho Chehaband 400 bytes on 32bit machine after naive conversion (we can
239fe34c89dSMauro Carvalho Chehabcertainly invest a bit more effort into libata core layer).
240fe34c89dSMauro Carvalho Chehab
241fe34c89dSMauro Carvalho Chehab
242fe34c89dSMauro Carvalho Chehab6. List of managed interfaces
243fe34c89dSMauro Carvalho Chehab-----------------------------
244fe34c89dSMauro Carvalho Chehab
245fe34c89dSMauro Carvalho ChehabCLOCK
246fe34c89dSMauro Carvalho Chehab  devm_clk_get()
247fe34c89dSMauro Carvalho Chehab  devm_clk_get_optional()
248fe34c89dSMauro Carvalho Chehab  devm_clk_put()
249916f562fSLinus Torvalds  devm_clk_bulk_get()
250916f562fSLinus Torvalds  devm_clk_bulk_get_all()
251916f562fSLinus Torvalds  devm_clk_bulk_get_optional()
25210434640SJohan Hovold  devm_get_clk_from_child()
253fe34c89dSMauro Carvalho Chehab  devm_clk_hw_register()
254fe34c89dSMauro Carvalho Chehab  devm_of_clk_add_hw_provider()
255fe34c89dSMauro Carvalho Chehab  devm_clk_hw_register_clkdev()
256fe34c89dSMauro Carvalho Chehab
257fe34c89dSMauro Carvalho ChehabDMA
258fe34c89dSMauro Carvalho Chehab  dmaenginem_async_device_register()
259fe34c89dSMauro Carvalho Chehab  dmam_alloc_coherent()
260fe34c89dSMauro Carvalho Chehab  dmam_alloc_attrs()
261fe34c89dSMauro Carvalho Chehab  dmam_free_coherent()
262fe34c89dSMauro Carvalho Chehab  dmam_pool_create()
263fe34c89dSMauro Carvalho Chehab  dmam_pool_destroy()
264fe34c89dSMauro Carvalho Chehab
265fe34c89dSMauro Carvalho ChehabDRM
2664c8e84b8SDaniel Vetter  devm_drm_dev_alloc()
267fe34c89dSMauro Carvalho Chehab
268fe34c89dSMauro Carvalho ChehabGPIO
269fe34c89dSMauro Carvalho Chehab  devm_gpiod_get()
2706cc1d456SMatti Vaittinen  devm_gpiod_get_array()
2716cc1d456SMatti Vaittinen  devm_gpiod_get_array_optional()
272fe34c89dSMauro Carvalho Chehab  devm_gpiod_get_index()
273fe34c89dSMauro Carvalho Chehab  devm_gpiod_get_index_optional()
274fe34c89dSMauro Carvalho Chehab  devm_gpiod_get_optional()
275fe34c89dSMauro Carvalho Chehab  devm_gpiod_put()
276fe34c89dSMauro Carvalho Chehab  devm_gpiod_unhinge()
277fe34c89dSMauro Carvalho Chehab  devm_gpiochip_add_data()
278fe34c89dSMauro Carvalho Chehab  devm_gpio_request()
279fe34c89dSMauro Carvalho Chehab  devm_gpio_request_one()
280fe34c89dSMauro Carvalho Chehab
281fe34c89dSMauro Carvalho ChehabI2C
2828e987f1fSYang Yingliang  devm_i2c_add_adapter()
283fe34c89dSMauro Carvalho Chehab  devm_i2c_new_dummy_device()
284fe34c89dSMauro Carvalho Chehab
285fe34c89dSMauro Carvalho ChehabIIO
286fe34c89dSMauro Carvalho Chehab  devm_iio_device_alloc()
287fe34c89dSMauro Carvalho Chehab  devm_iio_device_register()
288a02c09e4SAlexandru Ardelean  devm_iio_dmaengine_buffer_setup()
289e36db6a0SAlexandru Ardelean  devm_iio_kfifo_buffer_setup()
29038124788SYang Yingliang  devm_iio_kfifo_buffer_setup_ext()
29125c02edfSAlexandru Ardelean  devm_iio_map_array_register()
292fe34c89dSMauro Carvalho Chehab  devm_iio_triggered_buffer_setup()
29338124788SYang Yingliang  devm_iio_triggered_buffer_setup_ext()
294fe34c89dSMauro Carvalho Chehab  devm_iio_trigger_alloc()
295fe34c89dSMauro Carvalho Chehab  devm_iio_trigger_register()
296fe34c89dSMauro Carvalho Chehab  devm_iio_channel_get()
297fe34c89dSMauro Carvalho Chehab  devm_iio_channel_get_all()
29838124788SYang Yingliang  devm_iio_hw_consumer_alloc()
29938124788SYang Yingliang  devm_fwnode_iio_channel_get_by_name()
300fe34c89dSMauro Carvalho Chehab
301fe34c89dSMauro Carvalho ChehabINPUT
302fe34c89dSMauro Carvalho Chehab  devm_input_allocate_device()
303fe34c89dSMauro Carvalho Chehab
304fe34c89dSMauro Carvalho ChehabIO region
305fe34c89dSMauro Carvalho Chehab  devm_release_mem_region()
306fe34c89dSMauro Carvalho Chehab  devm_release_region()
307fe34c89dSMauro Carvalho Chehab  devm_release_resource()
308fe34c89dSMauro Carvalho Chehab  devm_request_mem_region()
309657ed9c9SYang Yingliang  devm_request_free_mem_region()
310fe34c89dSMauro Carvalho Chehab  devm_request_region()
311fe34c89dSMauro Carvalho Chehab  devm_request_resource()
312fe34c89dSMauro Carvalho Chehab
313fe34c89dSMauro Carvalho ChehabIOMAP
314fe34c89dSMauro Carvalho Chehab  devm_ioport_map()
315fe34c89dSMauro Carvalho Chehab  devm_ioport_unmap()
316fe34c89dSMauro Carvalho Chehab  devm_ioremap()
3177b8c4d73STuowen Zhao  devm_ioremap_uc()
318fe34c89dSMauro Carvalho Chehab  devm_ioremap_wc()
319fe34c89dSMauro Carvalho Chehab  devm_ioremap_resource() : checks resource, requests memory region, ioremaps
320b873af62SBartosz Golaszewski  devm_ioremap_resource_wc()
3214154abcaSBartosz Golaszewski  devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device
322c9c8641dSBartosz Golaszewski  devm_platform_ioremap_resource_byname()
3233699158dSDejin Zheng  devm_platform_get_and_ioremap_resource()
324fe34c89dSMauro Carvalho Chehab  devm_iounmap()
325fe34c89dSMauro Carvalho Chehab  pcim_iomap()
326fe34c89dSMauro Carvalho Chehab  pcim_iomap_regions()	: do request_region() and iomap() on multiple BARs
327fe34c89dSMauro Carvalho Chehab  pcim_iomap_table()	: array of mapped addresses indexed by BAR
328fe34c89dSMauro Carvalho Chehab  pcim_iounmap()
329fe34c89dSMauro Carvalho Chehab
330fe34c89dSMauro Carvalho ChehabIRQ
331fe34c89dSMauro Carvalho Chehab  devm_free_irq()
332fe34c89dSMauro Carvalho Chehab  devm_request_any_context_irq()
333fe34c89dSMauro Carvalho Chehab  devm_request_irq()
334fe34c89dSMauro Carvalho Chehab  devm_request_threaded_irq()
335fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_descs()
336fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_desc()
337fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_desc_at()
338fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_desc_from()
339fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_descs_from()
340fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_generic_chip()
341fe34c89dSMauro Carvalho Chehab  devm_irq_setup_generic_chip()
34206699e69SYang Yingliang  devm_irq_domain_create_sim()
343fe34c89dSMauro Carvalho Chehab
344fe34c89dSMauro Carvalho ChehabLED
345fe34c89dSMauro Carvalho Chehab  devm_led_classdev_register()
3465478cf6aSYang Yingliang  devm_led_classdev_register_ext()
347fe34c89dSMauro Carvalho Chehab  devm_led_classdev_unregister()
3485478cf6aSYang Yingliang  devm_led_trigger_register()
3495478cf6aSYang Yingliang  devm_of_led_get()
350fe34c89dSMauro Carvalho Chehab
351fe34c89dSMauro Carvalho ChehabMDIO
352fe34c89dSMauro Carvalho Chehab  devm_mdiobus_alloc()
353fe34c89dSMauro Carvalho Chehab  devm_mdiobus_alloc_size()
354bd8ff6deSBartosz Golaszewski  devm_mdiobus_register()
35514eeb6e0SBartosz Golaszewski  devm_of_mdiobus_register()
356fe34c89dSMauro Carvalho Chehab
357fe34c89dSMauro Carvalho ChehabMEM
358fe34c89dSMauro Carvalho Chehab  devm_free_pages()
359fe34c89dSMauro Carvalho Chehab  devm_get_free_pages()
360fe34c89dSMauro Carvalho Chehab  devm_kasprintf()
361fe34c89dSMauro Carvalho Chehab  devm_kcalloc()
362fe34c89dSMauro Carvalho Chehab  devm_kfree()
363fe34c89dSMauro Carvalho Chehab  devm_kmalloc()
364fe34c89dSMauro Carvalho Chehab  devm_kmalloc_array()
365fe34c89dSMauro Carvalho Chehab  devm_kmemdup()
366f8248572SBartosz Golaszewski  devm_krealloc()
367*d388f06aSJames Clark  devm_krealloc_array()
368fe34c89dSMauro Carvalho Chehab  devm_kstrdup()
3699e6002adSYang Yingliang  devm_kstrdup_const()
370fe34c89dSMauro Carvalho Chehab  devm_kvasprintf()
371fe34c89dSMauro Carvalho Chehab  devm_kzalloc()
372fe34c89dSMauro Carvalho Chehab
373fe34c89dSMauro Carvalho ChehabMFD
374fe34c89dSMauro Carvalho Chehab  devm_mfd_add_devices()
375fe34c89dSMauro Carvalho Chehab
376fe34c89dSMauro Carvalho ChehabMUX
377fe34c89dSMauro Carvalho Chehab  devm_mux_chip_alloc()
378fe34c89dSMauro Carvalho Chehab  devm_mux_chip_register()
379fe34c89dSMauro Carvalho Chehab  devm_mux_control_get()
38084564481SAswath Govindraju  devm_mux_state_get()
381fe34c89dSMauro Carvalho Chehab
3827eef3d09SBartosz GolaszewskiNET
3837eef3d09SBartosz Golaszewski  devm_alloc_etherdev()
3847eef3d09SBartosz Golaszewski  devm_alloc_etherdev_mqs()
385cd16627fSBartosz Golaszewski  devm_register_netdev()
3867eef3d09SBartosz Golaszewski
387fe34c89dSMauro Carvalho ChehabPER-CPU MEM
388fe34c89dSMauro Carvalho Chehab  devm_alloc_percpu()
389fe34c89dSMauro Carvalho Chehab  devm_free_percpu()
390fe34c89dSMauro Carvalho Chehab
391fe34c89dSMauro Carvalho ChehabPCI
392fe34c89dSMauro Carvalho Chehab  devm_pci_alloc_host_bridge()  : managed PCI host bridge allocation
393fe34c89dSMauro Carvalho Chehab  devm_pci_remap_cfgspace()	: ioremap PCI configuration space
394fe34c89dSMauro Carvalho Chehab  devm_pci_remap_cfg_resource()	: ioremap PCI configuration space resource
395fe34c89dSMauro Carvalho Chehab  pcim_enable_device()		: after success, all PCI ops become managed
396fe34c89dSMauro Carvalho Chehab  pcim_pin_device()		: keep PCI device enabled after release
397fe34c89dSMauro Carvalho Chehab
398fe34c89dSMauro Carvalho ChehabPHY
399fe34c89dSMauro Carvalho Chehab  devm_usb_get_phy()
40077ece812SYang Yingliang  devm_usb_get_phy_by_node()
40177ece812SYang Yingliang  devm_usb_get_phy_by_phandle()
402fe34c89dSMauro Carvalho Chehab  devm_usb_put_phy()
403fe34c89dSMauro Carvalho Chehab
404fe34c89dSMauro Carvalho ChehabPINCTRL
405fe34c89dSMauro Carvalho Chehab  devm_pinctrl_get()
406fe34c89dSMauro Carvalho Chehab  devm_pinctrl_put()
407a9a7da03SYang Yingliang  devm_pinctrl_get_select()
408fe34c89dSMauro Carvalho Chehab  devm_pinctrl_register()
409a9a7da03SYang Yingliang  devm_pinctrl_register_and_init()
410fe34c89dSMauro Carvalho Chehab  devm_pinctrl_unregister()
411fe34c89dSMauro Carvalho Chehab
412fe34c89dSMauro Carvalho ChehabPOWER
413fe34c89dSMauro Carvalho Chehab  devm_reboot_mode_register()
414fe34c89dSMauro Carvalho Chehab  devm_reboot_mode_unregister()
415fe34c89dSMauro Carvalho Chehab
416fe34c89dSMauro Carvalho ChehabPWM
41784de206fSYang Yingliang  devm_pwmchip_add()
418fe34c89dSMauro Carvalho Chehab  devm_pwm_get()
419c333b936SAndy Shevchenko  devm_fwnode_pwm_get()
420fe34c89dSMauro Carvalho Chehab
421fe34c89dSMauro Carvalho ChehabREGULATOR
4229b6744f6SMatti Vaittinen  devm_regulator_bulk_register_supply_alias()
423fe34c89dSMauro Carvalho Chehab  devm_regulator_bulk_get()
424692fab08SYang Yingliang  devm_regulator_bulk_get_const()
4259048b991SMatti Vaittinen  devm_regulator_bulk_get_enable()
4269048b991SMatti Vaittinen  devm_regulator_bulk_put()
427fe34c89dSMauro Carvalho Chehab  devm_regulator_get()
4289048b991SMatti Vaittinen  devm_regulator_get_enable()
4299048b991SMatti Vaittinen  devm_regulator_get_enable_optional()
4309b6744f6SMatti Vaittinen  devm_regulator_get_exclusive()
4319b6744f6SMatti Vaittinen  devm_regulator_get_optional()
4329b6744f6SMatti Vaittinen  devm_regulator_irq_helper()
433fe34c89dSMauro Carvalho Chehab  devm_regulator_put()
434fe34c89dSMauro Carvalho Chehab  devm_regulator_register()
4359b6744f6SMatti Vaittinen  devm_regulator_register_notifier()
4369b6744f6SMatti Vaittinen  devm_regulator_register_supply_alias()
4379b6744f6SMatti Vaittinen  devm_regulator_unregister_notifier()
438fe34c89dSMauro Carvalho Chehab
439fe34c89dSMauro Carvalho ChehabRESET
440fe34c89dSMauro Carvalho Chehab  devm_reset_control_get()
441fe34c89dSMauro Carvalho Chehab  devm_reset_controller_register()
442fe34c89dSMauro Carvalho Chehab
4434d49ffc7SBartosz GolaszewskiRTC
4444d49ffc7SBartosz Golaszewski  devm_rtc_device_register()
4454d49ffc7SBartosz Golaszewski  devm_rtc_allocate_device()
446fdcfd854SBartosz Golaszewski  devm_rtc_register_device()
4473a905c2dSBartosz Golaszewski  devm_rtc_nvmem_register()
4484d49ffc7SBartosz Golaszewski
449fe34c89dSMauro Carvalho ChehabSERDEV
450fe34c89dSMauro Carvalho Chehab  devm_serdev_device_open()
451fe34c89dSMauro Carvalho Chehab
452fe34c89dSMauro Carvalho ChehabSLAVE DMA ENGINE
453fe34c89dSMauro Carvalho Chehab  devm_acpi_dma_controller_register()
454739153a6SYang Yingliang  devm_acpi_dma_controller_free()
455fe34c89dSMauro Carvalho Chehab
456fe34c89dSMauro Carvalho ChehabSPI
45749beeea7SYang Yingliang  devm_spi_alloc_master()
45849beeea7SYang Yingliang  devm_spi_alloc_slave()
459fe34c89dSMauro Carvalho Chehab  devm_spi_register_master()
460fe34c89dSMauro Carvalho Chehab
461fe34c89dSMauro Carvalho ChehabWATCHDOG
462fe34c89dSMauro Carvalho Chehab  devm_watchdog_register_device()
463