soc-devres.c 3.9 KB

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