1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // soc-devres.c -- ALSA SoC Audio Layer devres functions 4 // 5 // Copyright (C) 2013 Linaro Ltd 6 7 #include <linux/module.h> 8 #include <linux/moduleparam.h> 9 #include <sound/soc.h> 10 #include <sound/dmaengine_pcm.h> 11 12 static void devm_component_release(struct device *dev, void *res) 13 { 14 snd_soc_unregister_component(*(struct device **)res); 15 } 16 17 /** 18 * devm_snd_soc_register_component - resource managed component registration 19 * @dev: Device used to manage component 20 * @cmpnt_drv: Component driver 21 * @dai_drv: DAI driver 22 * @num_dai: Number of DAIs to register 23 * 24 * Register a component with automatic unregistration when the device is 25 * unregistered. 26 */ 27 int devm_snd_soc_register_component(struct device *dev, 28 const struct snd_soc_component_driver *cmpnt_drv, 29 struct snd_soc_dai_driver *dai_drv, int num_dai) 30 { 31 struct device **ptr; 32 int ret; 33 34 ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); 35 if (!ptr) 36 return -ENOMEM; 37 38 ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); 39 if (ret == 0) { 40 *ptr = dev; 41 devres_add(dev, ptr); 42 } else { 43 devres_free(ptr); 44 } 45 46 return ret; 47 } 48 EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); 49 50 static void devm_card_release(struct device *dev, void *res) 51 { 52 snd_soc_unregister_card(*(struct snd_soc_card **)res); 53 } 54 55 /** 56 * devm_snd_soc_register_card - resource managed card registration 57 * @dev: Device used to manage card 58 * @card: Card to register 59 * 60 * Register a card with automatic unregistration when the device is 61 * unregistered. 62 */ 63 int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) 64 { 65 struct snd_soc_card **ptr; 66 int ret; 67 68 ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL); 69 if (!ptr) 70 return -ENOMEM; 71 72 ret = snd_soc_register_card(card); 73 if (ret == 0) { 74 *ptr = card; 75 devres_add(dev, ptr); 76 } else { 77 devres_free(ptr); 78 } 79 80 return ret; 81 } 82 EXPORT_SYMBOL_GPL(devm_snd_soc_register_card); 83 84 #ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM 85 86 static void devm_dmaengine_pcm_release(struct device *dev, void *res) 87 { 88 snd_dmaengine_pcm_unregister(*(struct device **)res); 89 } 90 91 /** 92 * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration 93 * @dev: The parent device for the PCM device 94 * @config: Platform specific PCM configuration 95 * @flags: Platform specific quirks 96 * 97 * Register a dmaengine based PCM device with automatic unregistration when the 98 * device is unregistered. 99 */ 100 int devm_snd_dmaengine_pcm_register(struct device *dev, 101 const struct snd_dmaengine_pcm_config *config, unsigned int flags) 102 { 103 struct device **ptr; 104 int ret; 105 106 ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL); 107 if (!ptr) 108 return -ENOMEM; 109 110 ret = snd_dmaengine_pcm_register(dev, config, flags); 111 if (ret == 0) { 112 *ptr = dev; 113 devres_add(dev, ptr); 114 } else { 115 devres_free(ptr); 116 } 117 118 return ret; 119 } 120 EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register); 121 122 #endif 123