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