1a0b03a61SMark Brown /* 2a0b03a61SMark Brown * soc-devres.c -- ALSA SoC Audio Layer devres functions 3a0b03a61SMark Brown * 4a0b03a61SMark Brown * Copyright (C) 2013 Linaro Ltd 5a0b03a61SMark Brown * 6a0b03a61SMark Brown * This program is free software; you can redistribute it and/or modify it 7a0b03a61SMark Brown * under the terms of the GNU General Public License as published by the 8a0b03a61SMark Brown * Free Software Foundation; either version 2 of the License, or (at your 9a0b03a61SMark Brown * option) any later version. 10a0b03a61SMark Brown */ 11a0b03a61SMark Brown 12a0b03a61SMark Brown #include <linux/module.h> 13a0b03a61SMark Brown #include <linux/moduleparam.h> 14a0b03a61SMark Brown #include <sound/soc.h> 15a0b03a61SMark Brown 16a0b03a61SMark Brown static void devm_component_release(struct device *dev, void *res) 17a0b03a61SMark Brown { 18a0b03a61SMark Brown snd_soc_unregister_component(*(struct device **)res); 19a0b03a61SMark Brown } 20a0b03a61SMark Brown 21a0b03a61SMark Brown /** 22a0b03a61SMark Brown * devm_snd_soc_register_component - resource managed component registration 23a0b03a61SMark Brown * @dev: Device used to manage component 24a0b03a61SMark Brown * @cmpnt_drv: Component driver 25a0b03a61SMark Brown * @dai_drv: DAI driver 26a0b03a61SMark Brown * @num_dai: Number of DAIs to register 27a0b03a61SMark Brown * 28a0b03a61SMark Brown * Register a component with automatic unregistration when the device is 29a0b03a61SMark Brown * unregistered. 30a0b03a61SMark Brown */ 31a0b03a61SMark Brown int devm_snd_soc_register_component(struct device *dev, 32a0b03a61SMark Brown const struct snd_soc_component_driver *cmpnt_drv, 33a0b03a61SMark Brown struct snd_soc_dai_driver *dai_drv, int num_dai) 34a0b03a61SMark Brown { 35a0b03a61SMark Brown struct device **ptr; 36a0b03a61SMark Brown int ret; 37a0b03a61SMark Brown 38a0b03a61SMark Brown ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); 39a0b03a61SMark Brown if (!ptr) 40a0b03a61SMark Brown return -ENOMEM; 41a0b03a61SMark Brown 42a0b03a61SMark Brown ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); 43a0b03a61SMark Brown if (ret == 0) { 44a0b03a61SMark Brown *ptr = dev; 45a0b03a61SMark Brown devres_add(dev, ptr); 46a0b03a61SMark Brown } else { 47a0b03a61SMark Brown devres_free(ptr); 48a0b03a61SMark Brown } 49a0b03a61SMark Brown 50a0b03a61SMark Brown return ret; 51a0b03a61SMark Brown } 52a0b03a61SMark Brown EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); 53*0e4ff5c8SMark Brown 54*0e4ff5c8SMark Brown static void devm_card_release(struct device *dev, void *res) 55*0e4ff5c8SMark Brown { 56*0e4ff5c8SMark Brown snd_soc_unregister_card(*(struct snd_soc_card **)res); 57*0e4ff5c8SMark Brown } 58*0e4ff5c8SMark Brown 59*0e4ff5c8SMark Brown /** 60*0e4ff5c8SMark Brown * devm_snd_soc_register_card - resource managed card registration 61*0e4ff5c8SMark Brown * @dev: Device used to manage card 62*0e4ff5c8SMark Brown * @card: Card to register 63*0e4ff5c8SMark Brown * 64*0e4ff5c8SMark Brown * Register a card with automatic unregistration when the device is 65*0e4ff5c8SMark Brown * unregistered. 66*0e4ff5c8SMark Brown */ 67*0e4ff5c8SMark Brown int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) 68*0e4ff5c8SMark Brown { 69*0e4ff5c8SMark Brown struct device **ptr; 70*0e4ff5c8SMark Brown int ret; 71*0e4ff5c8SMark Brown 72*0e4ff5c8SMark Brown ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL); 73*0e4ff5c8SMark Brown if (!ptr) 74*0e4ff5c8SMark Brown return -ENOMEM; 75*0e4ff5c8SMark Brown 76*0e4ff5c8SMark Brown ret = snd_soc_register_card(card); 77*0e4ff5c8SMark Brown if (ret == 0) { 78*0e4ff5c8SMark Brown *ptr = dev; 79*0e4ff5c8SMark Brown devres_add(dev, ptr); 80*0e4ff5c8SMark Brown } else { 81*0e4ff5c8SMark Brown devres_free(ptr); 82*0e4ff5c8SMark Brown } 83*0e4ff5c8SMark Brown 84*0e4ff5c8SMark Brown return ret; 85*0e4ff5c8SMark Brown } 86*0e4ff5c8SMark Brown EXPORT_SYMBOL_GPL(devm_snd_soc_register_card); 87