Commit dc438bac authored by Takashi Iwai's avatar Takashi Iwai

staging: greybus: Avoid abusing controls_rwsem

The controls_rwsem of snd_card object is rather an internal lock, and
not really meant to be used by others for its data protection.

This patch addresses it by replacing the controls_rwsem usages with
the own (new) mutex.

Note that the up_write() and down_write() calls around
gbaudio_remove_component_controls() are simply dropped without
replacement.  These temporary up/down were a workaround since
gbaudio_remove_component_controls() itself took the rwsem.  Now it was
also gone, we can clean up the workaround, too.
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Vaibhav Agarwal <vaibhav.sr@gmail.com>
Cc: Mark Greer <mgreer@animalcreek.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alex Elder <elder@kernel.org>
Cc: greybus-dev@lists.linaro.org
Link: https://lore.kernel.org/r/20230718141304.1032-8-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a3bee62e
...@@ -807,7 +807,6 @@ int gbaudio_register_module(struct gbaudio_module_info *module) ...@@ -807,7 +807,6 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
{ {
int ret; int ret;
struct snd_soc_component *comp; struct snd_soc_component *comp;
struct snd_card *card;
struct gbaudio_jack *jack = NULL; struct gbaudio_jack *jack = NULL;
if (!gbcodec) { if (!gbcodec) {
...@@ -816,21 +815,20 @@ int gbaudio_register_module(struct gbaudio_module_info *module) ...@@ -816,21 +815,20 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
} }
comp = gbcodec->component; comp = gbcodec->component;
card = comp->card->snd_card;
down_write(&card->controls_rwsem); mutex_lock(&gbcodec->register_mutex);
if (module->num_dais) { if (module->num_dais) {
dev_err(gbcodec->dev, dev_err(gbcodec->dev,
"%d:DAIs not supported via gbcodec driver\n", "%d:DAIs not supported via gbcodec driver\n",
module->num_dais); module->num_dais);
up_write(&card->controls_rwsem); mutex_unlock(&gbcodec->register_mutex);
return -EINVAL; return -EINVAL;
} }
ret = gbaudio_init_jack(module, comp->card); ret = gbaudio_init_jack(module, comp->card);
if (ret) { if (ret) {
up_write(&card->controls_rwsem); mutex_unlock(&gbcodec->register_mutex);
return ret; return ret;
} }
...@@ -867,7 +865,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module) ...@@ -867,7 +865,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
ret = snd_soc_dapm_new_widgets(comp->card); ret = snd_soc_dapm_new_widgets(comp->card);
dev_dbg(comp->dev, "Registered %s module\n", module->name); dev_dbg(comp->dev, "Registered %s module\n", module->name);
up_write(&card->controls_rwsem); mutex_unlock(&gbcodec->register_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL(gbaudio_register_module); EXPORT_SYMBOL(gbaudio_register_module);
...@@ -935,13 +933,12 @@ static void gbaudio_codec_cleanup(struct gbaudio_module_info *module) ...@@ -935,13 +933,12 @@ static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
void gbaudio_unregister_module(struct gbaudio_module_info *module) void gbaudio_unregister_module(struct gbaudio_module_info *module)
{ {
struct snd_soc_component *comp = gbcodec->component; struct snd_soc_component *comp = gbcodec->component;
struct snd_card *card = comp->card->snd_card;
struct gbaudio_jack *jack, *n; struct gbaudio_jack *jack, *n;
int mask; int mask;
dev_dbg(comp->dev, "Unregister %s module\n", module->name); dev_dbg(comp->dev, "Unregister %s module\n", module->name);
down_write(&card->controls_rwsem); mutex_lock(&gbcodec->register_mutex);
mutex_lock(&gbcodec->lock); mutex_lock(&gbcodec->lock);
gbaudio_codec_cleanup(module); gbaudio_codec_cleanup(module);
list_del(&module->list); list_del(&module->list);
...@@ -978,10 +975,8 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) ...@@ -978,10 +975,8 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
dev_dbg(comp->dev, "Removing %d controls\n", dev_dbg(comp->dev, "Removing %d controls\n",
module->num_controls); module->num_controls);
/* release control semaphore */ /* release control semaphore */
up_write(&card->controls_rwsem);
gbaudio_remove_component_controls(comp, module->controls, gbaudio_remove_component_controls(comp, module->controls,
module->num_controls); module->num_controls);
down_write(&card->controls_rwsem);
} }
if (module->dapm_widgets) { if (module->dapm_widgets) {
dev_dbg(comp->dev, "Removing %d widgets\n", dev_dbg(comp->dev, "Removing %d widgets\n",
...@@ -992,7 +987,7 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) ...@@ -992,7 +987,7 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
dev_dbg(comp->dev, "Unregistered %s module\n", module->name); dev_dbg(comp->dev, "Unregistered %s module\n", module->name);
up_write(&card->controls_rwsem); mutex_unlock(&gbcodec->register_mutex);
} }
EXPORT_SYMBOL(gbaudio_unregister_module); EXPORT_SYMBOL(gbaudio_unregister_module);
...@@ -1012,6 +1007,7 @@ static int gbcodec_probe(struct snd_soc_component *comp) ...@@ -1012,6 +1007,7 @@ static int gbcodec_probe(struct snd_soc_component *comp)
info->dev = comp->dev; info->dev = comp->dev;
INIT_LIST_HEAD(&info->module_list); INIT_LIST_HEAD(&info->module_list);
mutex_init(&info->lock); mutex_init(&info->lock);
mutex_init(&info->register_mutex);
INIT_LIST_HEAD(&info->dai_list); INIT_LIST_HEAD(&info->dai_list);
/* init dai_list used to maintain runtime stream info */ /* init dai_list used to maintain runtime stream info */
......
...@@ -71,6 +71,7 @@ struct gbaudio_codec_info { ...@@ -71,6 +71,7 @@ struct gbaudio_codec_info {
/* to maintain runtime stream params for each DAI */ /* to maintain runtime stream params for each DAI */
struct list_head dai_list; struct list_head dai_list;
struct mutex lock; struct mutex lock;
struct mutex register_mutex;
}; };
struct gbaudio_widget { struct gbaudio_widget {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment