Commit f056f2fe authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'tags/ctl-lock-fixes-6.6' into for-next

ALSA: Make control API taking controls_rwsem consistently

A few ALSA control API helpers like snd_ctl_rename(), snd_ctl_remove()
and snd_ctl_find_*() suppose the callers taking card->controls_rwsem.
But it's error-prone and fragile.  This patch set tries to change
those API functions to take the card->controls>rwsem internally by
themselves, so that the drivers don't need to take care of lockings.

After applying this patch set, only a couple of places still touch
card->controls_rwsem (which are OK-ish as they need for traversing the
control linked list).

Link: https://lore.kernel.org/r/20230718141304.1032-1-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 21634f0f 3315cf95
...@@ -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 {
......
...@@ -149,7 +149,6 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev, ...@@ -149,7 +149,6 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev,
for (i = 0; i < num_controls; i++) { for (i = 0; i < num_controls; i++) {
const struct snd_kcontrol_new *control = &controls[i]; const struct snd_kcontrol_new *control = &controls[i];
struct snd_ctl_elem_id id; struct snd_ctl_elem_id id;
struct snd_kcontrol *kctl;
if (prefix) if (prefix)
snprintf(id.name, sizeof(id.name), "%s %s", prefix, snprintf(id.name, sizeof(id.name), "%s %s", prefix,
...@@ -161,17 +160,10 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev, ...@@ -161,17 +160,10 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev,
id.device = control->device; id.device = control->device;
id.subdevice = control->subdevice; id.subdevice = control->subdevice;
id.index = control->index; id.index = control->index;
kctl = snd_ctl_find_id(card, &id); err = snd_ctl_remove_id(card, &id);
if (!kctl) { if (err < 0)
dev_err(dev, "Failed to find %s\n", control->name);
continue;
}
err = snd_ctl_remove(card, kctl);
if (err < 0) {
dev_err(dev, "%d: Failed to remove %s\n", err, dev_err(dev, "%d: Failed to remove %s\n", err,
control->name); control->name);
continue;
}
} }
return 0; return 0;
} }
...@@ -181,11 +173,7 @@ int gbaudio_remove_component_controls(struct snd_soc_component *component, ...@@ -181,11 +173,7 @@ int gbaudio_remove_component_controls(struct snd_soc_component *component,
unsigned int num_controls) unsigned int num_controls)
{ {
struct snd_card *card = component->card->snd_card; struct snd_card *card = component->card->snd_card;
int err;
down_write(&card->controls_rwsem); return gbaudio_remove_controls(card, component->dev, controls,
err = gbaudio_remove_controls(card, component->dev, controls, num_controls, component->name_prefix);
num_controls, component->name_prefix);
up_write(&card->controls_rwsem);
return err;
} }
...@@ -140,8 +140,10 @@ int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); ...@@ -140,8 +140,10 @@ int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name); void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);
int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active); int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid); struct snd_kcontrol *snd_ctl_find_numid_locked(struct snd_card *card, unsigned int numid);
struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id); struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid);
struct snd_kcontrol *snd_ctl_find_id_locked(struct snd_card *card, const struct snd_ctl_elem_id *id);
struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, const struct snd_ctl_elem_id *id);
int snd_ctl_create(struct snd_card *card); int snd_ctl_create(struct snd_card *card);
......
This diff is collapsed.
...@@ -173,7 +173,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, ...@@ -173,7 +173,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
int err; int err;
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_ctl_find_id(card, id); kctl = snd_ctl_find_id_locked(card, id);
if (! kctl) { if (! kctl) {
up_read(&card->controls_rwsem); up_read(&card->controls_rwsem);
return -ENOENT; return -ENOENT;
......
...@@ -251,7 +251,7 @@ static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id, ...@@ -251,7 +251,7 @@ static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
card = snd_card_ref(card_number); card = snd_card_ref(card_number);
if (card) { if (card) {
down_write(&card->controls_rwsem); down_write(&card->controls_rwsem);
kctl = snd_ctl_find_id(card, id); kctl = snd_ctl_find_id_locked(card, id);
if (kctl) { if (kctl) {
ioff = snd_ctl_get_ioff(kctl, id); ioff = snd_ctl_get_ioff(kctl, id);
vd = &kctl->vd[ioff]; vd = &kctl->vd[ioff];
......
...@@ -66,12 +66,10 @@ static int snd_jack_dev_free(struct snd_device *device) ...@@ -66,12 +66,10 @@ static int snd_jack_dev_free(struct snd_device *device)
struct snd_card *card = device->card; struct snd_card *card = device->card;
struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl; struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;
down_write(&card->controls_rwsem);
list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) { list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {
list_del_init(&jack_kctl->list); list_del_init(&jack_kctl->list);
snd_ctl_remove(card, jack_kctl->kctl); snd_ctl_remove(card, jack_kctl->kctl);
} }
up_write(&card->controls_rwsem);
if (jack->private_free) if (jack->private_free)
jack->private_free(jack); jack->private_free(jack);
......
...@@ -524,7 +524,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c ...@@ -524,7 +524,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
strscpy(id.name, name, sizeof(id.name)); strscpy(id.name, name, sizeof(id.name));
id.index = index; id.index = index;
return snd_ctl_find_id(card, &id); return snd_ctl_find_id_locked(card, &id);
} }
static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer, static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
...@@ -540,7 +540,7 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer, ...@@ -540,7 +540,7 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN) if (numid == ID_UNKNOWN)
return; return;
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_ctl_find_numid(card, numid); kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) { if (!kctl) {
up_read(&card->controls_rwsem); up_read(&card->controls_rwsem);
return; return;
...@@ -579,7 +579,7 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer, ...@@ -579,7 +579,7 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN) if (numid == ID_UNKNOWN)
return; return;
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_ctl_find_numid(card, numid); kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) { if (!kctl) {
up_read(&card->controls_rwsem); up_read(&card->controls_rwsem);
return; return;
...@@ -645,7 +645,7 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer, ...@@ -645,7 +645,7 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN) if (numid == ID_UNKNOWN)
return; return;
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_ctl_find_numid(card, numid); kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) { if (!kctl) {
up_read(&card->controls_rwsem); up_read(&card->controls_rwsem);
return; return;
...@@ -688,7 +688,7 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer, ...@@ -688,7 +688,7 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN) if (numid == ID_UNKNOWN)
return; return;
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_ctl_find_numid(card, numid); kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) { if (!kctl) {
up_read(&card->controls_rwsem); up_read(&card->controls_rwsem);
return; return;
......
...@@ -814,9 +814,7 @@ static void free_chmap(struct snd_pcm_str *pstr) ...@@ -814,9 +814,7 @@ static void free_chmap(struct snd_pcm_str *pstr)
if (pstr->chmap_kctl) { if (pstr->chmap_kctl) {
struct snd_card *card = pstr->pcm->card; struct snd_card *card = pstr->pcm->card;
down_write(&card->controls_rwsem);
snd_ctl_remove(card, pstr->chmap_kctl); snd_ctl_remove(card, pstr->chmap_kctl);
up_write(&card->controls_rwsem);
pstr->chmap_kctl = NULL; pstr->chmap_kctl = NULL;
} }
} }
......
...@@ -1040,10 +1040,8 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) ...@@ -1040,10 +1040,8 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
__error: __error:
for (i = 0; i < EMU8000_NUM_CONTROLS; i++) { for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
down_write(&card->controls_rwsem);
if (emu->controls[i]) if (emu->controls[i])
snd_ctl_remove(card, emu->controls[i]); snd_ctl_remove(card, emu->controls[i]);
up_write(&card->controls_rwsem);
} }
return err; return err;
} }
......
...@@ -1080,7 +1080,6 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p) ...@@ -1080,7 +1080,6 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
card = p->chip->card; card = p->chip->card;
down_write(&card->controls_rwsem);
if (p->qsound_switch) { if (p->qsound_switch) {
snd_ctl_remove(card, p->qsound_switch); snd_ctl_remove(card, p->qsound_switch);
p->qsound_switch = NULL; p->qsound_switch = NULL;
...@@ -1089,7 +1088,6 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p) ...@@ -1089,7 +1088,6 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
snd_ctl_remove(card, p->qsound_space); snd_ctl_remove(card, p->qsound_space);
p->qsound_space = NULL; p->qsound_space = NULL;
} }
up_write(&card->controls_rwsem);
/* cancel pending transfer of QSound parameters */ /* cancel pending transfer of QSound parameters */
spin_lock_irqsave (&p->q_lock, flags); spin_lock_irqsave (&p->q_lock, flags);
......
...@@ -793,13 +793,10 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, ...@@ -793,13 +793,10 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
if (snd_emu10k1_look_for_ctl(emu, &gctl->id)) if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
continue; continue;
gctl_id = (struct snd_ctl_elem_id *)&gctl->id; gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
down_read(&emu->card->controls_rwsem);
if (snd_ctl_find_id(emu->card, gctl_id)) { if (snd_ctl_find_id(emu->card, gctl_id)) {
up_read(&emu->card->controls_rwsem);
err = -EEXIST; err = -EEXIST;
goto __error; goto __error;
} }
up_read(&emu->card->controls_rwsem);
if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER && if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) { gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
err = -EINVAL; err = -EINVAL;
...@@ -971,11 +968,9 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, ...@@ -971,11 +968,9 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
in_kernel); in_kernel);
if (err < 0) if (err < 0)
return err; return err;
down_write(&card->controls_rwsem);
ctl = snd_emu10k1_look_for_ctl(emu, &id); ctl = snd_emu10k1_look_for_ctl(emu, &id);
if (ctl) if (ctl)
snd_ctl_remove(card, ctl->kcontrol); snd_ctl_remove(card, ctl->kcontrol);
up_write(&card->controls_rwsem);
} }
return 0; return 0;
} }
......
...@@ -1769,10 +1769,8 @@ void snd_hda_ctls_clear(struct hda_codec *codec) ...@@ -1769,10 +1769,8 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
int i; int i;
struct hda_nid_item *items = codec->mixers.list; struct hda_nid_item *items = codec->mixers.list;
down_write(&codec->card->controls_rwsem);
for (i = 0; i < codec->mixers.used; i++) for (i = 0; i < codec->mixers.used; i++)
snd_ctl_remove(codec->card, items[i].kctl); snd_ctl_remove(codec->card, items[i].kctl);
up_write(&codec->card->controls_rwsem);
snd_array_free(&codec->mixers); snd_array_free(&codec->mixers);
snd_array_free(&codec->nids); snd_array_free(&codec->nids);
} }
......
...@@ -386,7 +386,6 @@ static int mchp_pdmc_open(struct snd_soc_component *component, ...@@ -386,7 +386,6 @@ static int mchp_pdmc_open(struct snd_soc_component *component,
for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) { for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {
const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i]; const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];
struct snd_ctl_elem_id id; struct snd_ctl_elem_id id;
struct snd_kcontrol *kctl;
int err; int err;
if (component->name_prefix) if (component->name_prefix)
...@@ -400,17 +399,10 @@ static int mchp_pdmc_open(struct snd_soc_component *component, ...@@ -400,17 +399,10 @@ static int mchp_pdmc_open(struct snd_soc_component *component,
id.device = control->device; id.device = control->device;
id.subdevice = control->subdevice; id.subdevice = control->subdevice;
id.index = control->index; id.index = control->index;
kctl = snd_ctl_find_id(component->card->snd_card, &id); err = snd_ctl_remove_id(component->card->snd_card, &id);
if (!kctl) { if (err < 0)
dev_err(component->dev, "Failed to find %s\n", control->name);
continue;
}
err = snd_ctl_remove(component->card->snd_card, kctl);
if (err < 0) {
dev_err(component->dev, "%d: Failed to remove %s\n", err, dev_err(component->dev, "%d: Failed to remove %s\n", err,
control->name); control->name);
continue;
}
} }
return 0; return 0;
......
...@@ -669,36 +669,19 @@ static void sigmadsp_activate_ctrl(struct sigmadsp *sigmadsp, ...@@ -669,36 +669,19 @@ static void sigmadsp_activate_ctrl(struct sigmadsp *sigmadsp,
struct sigmadsp_control *ctrl, unsigned int samplerate_mask) struct sigmadsp_control *ctrl, unsigned int samplerate_mask)
{ {
struct snd_card *card = sigmadsp->component->card->snd_card; struct snd_card *card = sigmadsp->component->card->snd_card;
struct snd_kcontrol_volatile *vd;
struct snd_ctl_elem_id id;
bool active; bool active;
bool changed = false; int changed;
active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask); active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask);
if (!ctrl->kcontrol)
down_write(&card->controls_rwsem);
if (!ctrl->kcontrol) {
up_write(&card->controls_rwsem);
return; return;
} changed = snd_ctl_activate_id(card, &ctrl->kcontrol->id, active);
if (active && changed > 0) {
id = ctrl->kcontrol->id;
vd = &ctrl->kcontrol->vd[0];
if (active == (bool)(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) {
vd->access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
changed = true;
}
up_write(&card->controls_rwsem);
if (active && changed) {
mutex_lock(&sigmadsp->lock); mutex_lock(&sigmadsp->lock);
if (ctrl->cached) if (ctrl->cached)
sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache); sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache);
mutex_unlock(&sigmadsp->lock); mutex_unlock(&sigmadsp->lock);
} }
if (changed)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &id);
} }
/** /**
......
...@@ -2564,7 +2564,6 @@ EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load); ...@@ -2564,7 +2564,6 @@ EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load);
/* remove dynamic controls from the component driver */ /* remove dynamic controls from the component driver */
int snd_soc_tplg_component_remove(struct snd_soc_component *comp) int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
{ {
struct snd_card *card = comp->card->snd_card;
struct snd_soc_dobj *dobj, *next_dobj; struct snd_soc_dobj *dobj, *next_dobj;
int pass; int pass;
...@@ -2572,7 +2571,6 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp) ...@@ -2572,7 +2571,6 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
for (pass = SOC_TPLG_PASS_END; pass >= SOC_TPLG_PASS_START; pass--) { for (pass = SOC_TPLG_PASS_END; pass >= SOC_TPLG_PASS_START; pass--) {
/* remove mixer controls */ /* remove mixer controls */
down_write(&card->controls_rwsem);
list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list, list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list,
list) { list) {
...@@ -2607,7 +2605,6 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp) ...@@ -2607,7 +2605,6 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
break; break;
} }
} }
up_write(&card->controls_rwsem);
} }
/* let caller know if FW can be freed when no objects are left */ /* let caller know if FW can be freed when no objects are left */
......
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