1fe34c89dSMauro Carvalho Chehab================================
2fe34c89dSMauro Carvalho ChehabDevres - Managed Device Resource
3fe34c89dSMauro Carvalho Chehab================================
4fe34c89dSMauro Carvalho Chehab
5fe34c89dSMauro Carvalho ChehabTejun Heo	<[email protected]>
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()
3255ccba71fSAndy Shevchenko
3265ccba71fSAndy Shevchenko  Note: For the PCI devices the specific pcim_*() functions may be used, see below.
327fe34c89dSMauro Carvalho Chehab
328fe34c89dSMauro Carvalho ChehabIRQ
329fe34c89dSMauro Carvalho Chehab  devm_free_irq()
330fe34c89dSMauro Carvalho Chehab  devm_request_any_context_irq()
331fe34c89dSMauro Carvalho Chehab  devm_request_irq()
332fe34c89dSMauro Carvalho Chehab  devm_request_threaded_irq()
333fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_descs()
334fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_desc()
335fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_desc_at()
336fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_desc_from()
337fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_descs_from()
338fe34c89dSMauro Carvalho Chehab  devm_irq_alloc_generic_chip()
339fe34c89dSMauro Carvalho Chehab  devm_irq_setup_generic_chip()
34006699e69SYang Yingliang  devm_irq_domain_create_sim()
341fe34c89dSMauro Carvalho Chehab
342fe34c89dSMauro Carvalho ChehabLED
343fe34c89dSMauro Carvalho Chehab  devm_led_classdev_register()
3445478cf6aSYang Yingliang  devm_led_classdev_register_ext()
345fe34c89dSMauro Carvalho Chehab  devm_led_classdev_unregister()
3465478cf6aSYang Yingliang  devm_led_trigger_register()
3475478cf6aSYang Yingliang  devm_of_led_get()
348fe34c89dSMauro Carvalho Chehab
349fe34c89dSMauro Carvalho ChehabMDIO
350fe34c89dSMauro Carvalho Chehab  devm_mdiobus_alloc()
351fe34c89dSMauro Carvalho Chehab  devm_mdiobus_alloc_size()
352bd8ff6deSBartosz Golaszewski  devm_mdiobus_register()
35314eeb6e0SBartosz Golaszewski  devm_of_mdiobus_register()
354fe34c89dSMauro Carvalho Chehab
355fe34c89dSMauro Carvalho ChehabMEM
356fe34c89dSMauro Carvalho Chehab  devm_free_pages()
357fe34c89dSMauro Carvalho Chehab  devm_get_free_pages()
358fe34c89dSMauro Carvalho Chehab  devm_kasprintf()
359fe34c89dSMauro Carvalho Chehab  devm_kcalloc()
360fe34c89dSMauro Carvalho Chehab  devm_kfree()
361fe34c89dSMauro Carvalho Chehab  devm_kmalloc()
362fe34c89dSMauro Carvalho Chehab  devm_kmalloc_array()
363fe34c89dSMauro Carvalho Chehab  devm_kmemdup()
364f8248572SBartosz Golaszewski  devm_krealloc()
365d388f06aSJames Clark  devm_krealloc_array()
366fe34c89dSMauro Carvalho Chehab  devm_kstrdup()
3679e6002adSYang Yingliang  devm_kstrdup_const()
368fe34c89dSMauro Carvalho Chehab  devm_kvasprintf()
369fe34c89dSMauro Carvalho Chehab  devm_kzalloc()
370fe34c89dSMauro Carvalho Chehab
371fe34c89dSMauro Carvalho ChehabMFD
372fe34c89dSMauro Carvalho Chehab  devm_mfd_add_devices()
373fe34c89dSMauro Carvalho Chehab
374fe34c89dSMauro Carvalho ChehabMUX
375fe34c89dSMauro Carvalho Chehab  devm_mux_chip_alloc()
376fe34c89dSMauro Carvalho Chehab  devm_mux_chip_register()
377fe34c89dSMauro Carvalho Chehab  devm_mux_control_get()
37884564481SAswath Govindraju  devm_mux_state_get()
379fe34c89dSMauro Carvalho Chehab
3807eef3d09SBartosz GolaszewskiNET
3817eef3d09SBartosz Golaszewski  devm_alloc_etherdev()
3827eef3d09SBartosz Golaszewski  devm_alloc_etherdev_mqs()
383cd16627fSBartosz Golaszewski  devm_register_netdev()
3847eef3d09SBartosz Golaszewski
385fe34c89dSMauro Carvalho ChehabPER-CPU MEM
386fe34c89dSMauro Carvalho Chehab  devm_alloc_percpu()
387fe34c89dSMauro Carvalho Chehab  devm_free_percpu()
388fe34c89dSMauro Carvalho Chehab
389fe34c89dSMauro Carvalho ChehabPCI
390fe34c89dSMauro Carvalho Chehab  devm_pci_alloc_host_bridge()  : managed PCI host bridge allocation
391fe34c89dSMauro Carvalho Chehab  devm_pci_remap_cfgspace()	: ioremap PCI configuration space
392fe34c89dSMauro Carvalho Chehab  devm_pci_remap_cfg_resource()	: ioremap PCI configuration space resource
3935ccba71fSAndy Shevchenko
3948839adc3SPhilipp Stanner  pcim_enable_device()		: after success, some PCI ops become managed
3955ccba71fSAndy Shevchenko  pcim_iomap()			: do iomap() on a single BAR
3965ccba71fSAndy Shevchenko  pcim_iomap_regions()		: do request_region() and iomap() on multiple BARs
3975ccba71fSAndy Shevchenko  pcim_iomap_table()		: array of mapped addresses indexed by BAR
3985ccba71fSAndy Shevchenko  pcim_iounmap()		: do iounmap() on a single BAR
3995ccba71fSAndy Shevchenko  pcim_iounmap_regions()	: do iounmap() and release_region() on multiple BARs
400fe34c89dSMauro Carvalho Chehab  pcim_pin_device()		: keep PCI device enabled after release
4015ccba71fSAndy Shevchenko  pcim_set_mwi()		: enable Memory-Write-Invalidate PCI transaction
402fe34c89dSMauro Carvalho Chehab
403fe34c89dSMauro Carvalho ChehabPHY
404fe34c89dSMauro Carvalho Chehab  devm_usb_get_phy()
40577ece812SYang Yingliang  devm_usb_get_phy_by_node()
40677ece812SYang Yingliang  devm_usb_get_phy_by_phandle()
407fe34c89dSMauro Carvalho Chehab
408fe34c89dSMauro Carvalho ChehabPINCTRL
409fe34c89dSMauro Carvalho Chehab  devm_pinctrl_get()
410fe34c89dSMauro Carvalho Chehab  devm_pinctrl_put()
411a9a7da03SYang Yingliang  devm_pinctrl_get_select()
412fe34c89dSMauro Carvalho Chehab  devm_pinctrl_register()
413a9a7da03SYang Yingliang  devm_pinctrl_register_and_init()
414fe34c89dSMauro Carvalho Chehab  devm_pinctrl_unregister()
415fe34c89dSMauro Carvalho Chehab
416fe34c89dSMauro Carvalho ChehabPOWER
417fe34c89dSMauro Carvalho Chehab  devm_reboot_mode_register()
418fe34c89dSMauro Carvalho Chehab  devm_reboot_mode_unregister()
419fe34c89dSMauro Carvalho Chehab
420fe34c89dSMauro Carvalho ChehabPWM
421024913dbSUwe Kleine-König  devm_pwmchip_alloc()
42284de206fSYang Yingliang  devm_pwmchip_add()
423fe34c89dSMauro Carvalho Chehab  devm_pwm_get()
424c333b936SAndy Shevchenko  devm_fwnode_pwm_get()
425fe34c89dSMauro Carvalho Chehab
426fe34c89dSMauro Carvalho ChehabREGULATOR
4279b6744f6SMatti Vaittinen  devm_regulator_bulk_register_supply_alias()
428fe34c89dSMauro Carvalho Chehab  devm_regulator_bulk_get()
429692fab08SYang Yingliang  devm_regulator_bulk_get_const()
4309048b991SMatti Vaittinen  devm_regulator_bulk_get_enable()
4319048b991SMatti Vaittinen  devm_regulator_bulk_put()
432fe34c89dSMauro Carvalho Chehab  devm_regulator_get()
4339048b991SMatti Vaittinen  devm_regulator_get_enable()
434b250c20bSDavid Lechner  devm_regulator_get_enable_read_voltage()
4359048b991SMatti Vaittinen  devm_regulator_get_enable_optional()
4369b6744f6SMatti Vaittinen  devm_regulator_get_exclusive()
4379b6744f6SMatti Vaittinen  devm_regulator_get_optional()
4389b6744f6SMatti Vaittinen  devm_regulator_irq_helper()
439fe34c89dSMauro Carvalho Chehab  devm_regulator_put()
440fe34c89dSMauro Carvalho Chehab  devm_regulator_register()
4419b6744f6SMatti Vaittinen  devm_regulator_register_notifier()
4429b6744f6SMatti Vaittinen  devm_regulator_register_supply_alias()
4439b6744f6SMatti Vaittinen  devm_regulator_unregister_notifier()
444fe34c89dSMauro Carvalho Chehab
445fe34c89dSMauro Carvalho ChehabRESET
446fe34c89dSMauro Carvalho Chehab  devm_reset_control_get()
447fe34c89dSMauro Carvalho Chehab  devm_reset_controller_register()
448fe34c89dSMauro Carvalho Chehab
4494d49ffc7SBartosz GolaszewskiRTC
4504d49ffc7SBartosz Golaszewski  devm_rtc_device_register()
4514d49ffc7SBartosz Golaszewski  devm_rtc_allocate_device()
452fdcfd854SBartosz Golaszewski  devm_rtc_register_device()
4533a905c2dSBartosz Golaszewski  devm_rtc_nvmem_register()
4544d49ffc7SBartosz Golaszewski
455fe34c89dSMauro Carvalho ChehabSERDEV
456fe34c89dSMauro Carvalho Chehab  devm_serdev_device_open()
457fe34c89dSMauro Carvalho Chehab
458fe34c89dSMauro Carvalho ChehabSLAVE DMA ENGINE
459fe34c89dSMauro Carvalho Chehab  devm_acpi_dma_controller_register()
460fe34c89dSMauro Carvalho Chehab
461fe34c89dSMauro Carvalho ChehabSPI
462*0809a9ccSYang Yingliang  devm_spi_alloc_host()
463*0809a9ccSYang Yingliang  devm_spi_alloc_target()
464d4a0055fSDavid Lechner  devm_spi_optimize_message()
465620d269fSUwe Kleine-König  devm_spi_register_controller()
4669b894d65SDavid Lechner  devm_spi_register_host()
4679b894d65SDavid Lechner  devm_spi_register_target()
468fe34c89dSMauro Carvalho Chehab
469fe34c89dSMauro Carvalho ChehabWATCHDOG
470fe34c89dSMauro Carvalho Chehab  devm_watchdog_register_device()
471