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