162 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// soc-devres.c -- ALSA SoC Audio Layer devres functions4//5// Copyright (C) 2013 Linaro Ltd6 7#include <linux/module.h>8#include <linux/moduleparam.h>9#include <sound/soc.h>10#include <sound/dmaengine_pcm.h>11 12static void devm_dai_release(struct device *dev, void *res)13{14 snd_soc_unregister_dai(*(struct snd_soc_dai **)res);15}16 17/**18 * devm_snd_soc_register_dai - resource-managed dai registration19 * @dev: Device used to manage component20 * @component: The component the DAIs are registered for21 * @dai_drv: DAI driver to use for the DAI22 * @legacy_dai_naming: if %true, use legacy single-name format;23 * if %false, use multiple-name format;24 */25struct snd_soc_dai *devm_snd_soc_register_dai(struct device *dev,26 struct snd_soc_component *component,27 struct snd_soc_dai_driver *dai_drv,28 bool legacy_dai_naming)29{30 struct snd_soc_dai **ptr;31 struct snd_soc_dai *dai;32 33 ptr = devres_alloc(devm_dai_release, sizeof(*ptr), GFP_KERNEL);34 if (!ptr)35 return NULL;36 37 dai = snd_soc_register_dai(component, dai_drv, legacy_dai_naming);38 if (dai) {39 *ptr = dai;40 devres_add(dev, ptr);41 } else {42 devres_free(ptr);43 }44 45 return dai;46}47EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai);48 49static void devm_component_release(struct device *dev, void *res)50{51 const struct snd_soc_component_driver **cmpnt_drv = res;52 53 snd_soc_unregister_component_by_driver(dev, *cmpnt_drv);54}55 56/**57 * devm_snd_soc_register_component - resource managed component registration58 * @dev: Device used to manage component59 * @cmpnt_drv: Component driver60 * @dai_drv: DAI driver61 * @num_dai: Number of DAIs to register62 *63 * Register a component with automatic unregistration when the device is64 * unregistered.65 */66int devm_snd_soc_register_component(struct device *dev,67 const struct snd_soc_component_driver *cmpnt_drv,68 struct snd_soc_dai_driver *dai_drv, int num_dai)69{70 const struct snd_soc_component_driver **ptr;71 int ret;72 73 ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL);74 if (!ptr)75 return -ENOMEM;76 77 ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai);78 if (ret == 0) {79 *ptr = cmpnt_drv;80 devres_add(dev, ptr);81 } else {82 devres_free(ptr);83 }84 85 return ret;86}87EXPORT_SYMBOL_GPL(devm_snd_soc_register_component);88 89static void devm_card_release(struct device *dev, void *res)90{91 snd_soc_unregister_card(*(struct snd_soc_card **)res);92}93 94/**95 * devm_snd_soc_register_card - resource managed card registration96 * @dev: Device used to manage card97 * @card: Card to register98 *99 * Register a card with automatic unregistration when the device is100 * unregistered.101 */102int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)103{104 struct snd_soc_card **ptr;105 int ret;106 107 ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);108 if (!ptr)109 return -ENOMEM;110 111 ret = snd_soc_register_card(card);112 if (ret == 0) {113 *ptr = card;114 devres_add(dev, ptr);115 } else {116 devres_free(ptr);117 }118 119 return ret;120}121EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);122 123#ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM124 125static void devm_dmaengine_pcm_release(struct device *dev, void *res)126{127 snd_dmaengine_pcm_unregister(*(struct device **)res);128}129 130/**131 * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration132 * @dev: The parent device for the PCM device133 * @config: Platform specific PCM configuration134 * @flags: Platform specific quirks135 *136 * Register a dmaengine based PCM device with automatic unregistration when the137 * device is unregistered.138 */139int devm_snd_dmaengine_pcm_register(struct device *dev,140 const struct snd_dmaengine_pcm_config *config, unsigned int flags)141{142 struct device **ptr;143 int ret;144 145 ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL);146 if (!ptr)147 return -ENOMEM;148 149 ret = snd_dmaengine_pcm_register(dev, config, flags);150 if (ret == 0) {151 *ptr = dev;152 devres_add(dev, ptr);153 } else {154 devres_free(ptr);155 }156 157 return ret;158}159EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register);160 161#endif162