1 /* 2 * soc-devres.c -- ALSA SoC Audio Layer devres functions 3 * 4 * Copyright (C) 2013 Linaro Ltd 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/moduleparam.h> 14 #include <sound/soc.h> 15 #include <sound/dmaengine_pcm.h> 16 17 static void devm_component_release(struct device *dev, void *res) 18 { 19 snd_soc_unregister_component(*(struct device **)res); 20 } 21 22 /** 23 * devm_snd_soc_register_component - resource managed component registration 24 * @dev: Device used to manage component 25 * @cmpnt_drv: Component driver 26 * @dai_drv: DAI driver 27 * @num_dai: Number of DAIs to register 28 * 29 * Register a component with automatic unregistration when the device is 30 * unregistered. 31 */ 32 int devm_snd_soc_register_component(struct device *dev, 33 const struct snd_soc_component_driver *cmpnt_drv, 34 struct snd_soc_dai_driver *dai_drv, int num_dai) 35 { 36 struct device **ptr; 37 int ret; 38 39 ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); 40 if (!ptr) 41 return -ENOMEM; 42 43 ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); 44 if (ret == 0) { 45 *ptr = dev; 46 devres_add(dev, ptr); 47 } else { 48 devres_free(ptr); 49 } 50 51 return ret; 52 } 53 EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); 54 55 static void devm_platform_release(struct device *dev, void *res) 56 { 57 snd_soc_unregister_platform(*(struct device **)res); 58 } 59 60 /** 61 * devm_snd_soc_register_platform - resource managed platform registration 62 * @dev: Device used to manage platform 63 * @platform_drv: platform to register 64 * 65 * Register a platform driver with automatic unregistration when the device is 66 * unregistered. 67 */ 68 int devm_snd_soc_register_platform(struct device *dev, 69 const struct snd_soc_platform_driver *platform_drv) 70 { 71 struct device **ptr; 72 int ret; 73 74 ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL); 75 if (!ptr) 76 return -ENOMEM; 77 78 ret = snd_soc_register_platform(dev, platform_drv); 79 if (ret == 0) { 80 *ptr = dev; 81 devres_add(dev, ptr); 82 } else { 83 devres_free(ptr); 84 } 85 86 return ret; 87 } 88 EXPORT_SYMBOL_GPL(devm_snd_soc_register_platform); 89 90 static void devm_card_release(struct device *dev, void *res) 91 { 92 snd_soc_unregister_card(*(struct snd_soc_card **)res); 93 } 94 95 /** 96 * devm_snd_soc_register_card - resource managed card registration 97 * @dev: Device used to manage card 98 * @card: Card to register 99 * 100 * Register a card with automatic unregistration when the device is 101 * unregistered. 102 */ 103 int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) 104 { 105 struct snd_soc_card **ptr; 106 int ret; 107 108 ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL); 109 if (!ptr) 110 return -ENOMEM; 111 112 ret = snd_soc_register_card(card); 113 if (ret == 0) { 114 *ptr = card; 115 devres_add(dev, ptr); 116 } else { 117 devres_free(ptr); 118 } 119 120 return ret; 121 } 122 EXPORT_SYMBOL_GPL(devm_snd_soc_register_card); 123 124 #ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM 125 126 static void devm_dmaengine_pcm_release(struct device *dev, void *res) 127 { 128 snd_dmaengine_pcm_unregister(*(struct device **)res); 129 } 130 131 /** 132 * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration 133 * @dev: The parent device for the PCM device 134 * @config: Platform specific PCM configuration 135 * @flags: Platform specific quirks 136 * 137 * Register a dmaengine based PCM device with automatic unregistration when the 138 * device is unregistered. 139 */ 140 int devm_snd_dmaengine_pcm_register(struct device *dev, 141 const struct snd_dmaengine_pcm_config *config, unsigned int flags) 142 { 143 struct device **ptr; 144 int ret; 145 146 ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL); 147 if (!ptr) 148 return -ENOMEM; 149 150 ret = snd_dmaengine_pcm_register(dev, config, flags); 151 if (ret == 0) { 152 *ptr = dev; 153 devres_add(dev, ptr); 154 } else { 155 devres_free(ptr); 156 } 157 158 return ret; 159 } 160 EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register); 161 162 #endif 163