aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu Fengguang <wfg@linux.intel.com>2009-01-09 03:45:24 -0500
committerTakashi Iwai <tiwai@suse.de>2009-01-09 03:58:47 -0500
commit5a9e02e94989323c2a7102e2fc80ee9102b19fa0 (patch)
treee6f5d2ecd8928a5b0256f4c9f8f7c7963d1f8e36
parent57d139278e6c246d78f71e4bf0e0d15bb0390646 (diff)
ALSA: hda - create hda_codec.control_mutex for kcontrol->private_value
Fix the following lockdep warning by not reusing the hda_codec.spdif_mutex. ALSA sound/pci/hda/hda_codec.c:882: hda_codec_cleanup_stream: NID=0x2 ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.28-next-20090102 #33 ------------------------------------------------------- mplayer/3151 is trying to acquire lock: (&pcm->open_mutex){--..}, at: [<ffffffffa004ced3>] snd_pcm_release+0x43/0xd0 [snd_pcm] but task is already holding lock: (&mm->mmap_sem){----}, at: [<ffffffff810c0252>] sys_munmap+0x42/0x80 which lock already depends on the new lock. Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c25
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/patch_realtek.c12
3 files changed, 20 insertions, 18 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e16cf63821ae..f80e5f3b97dc 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -735,6 +735,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
735 codec->bus = bus; 735 codec->bus = bus;
736 codec->addr = codec_addr; 736 codec->addr = codec_addr;
737 mutex_init(&codec->spdif_mutex); 737 mutex_init(&codec->spdif_mutex);
738 mutex_init(&codec->control_mutex);
738 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 739 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
739 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 740 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
740 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32); 741 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
@@ -1418,12 +1419,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1418 unsigned long pval; 1419 unsigned long pval;
1419 int err; 1420 int err;
1420 1421
1421 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1422 mutex_lock(&codec->control_mutex);
1422 pval = kcontrol->private_value; 1423 pval = kcontrol->private_value;
1423 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ 1424 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
1424 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 1425 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
1425 kcontrol->private_value = pval; 1426 kcontrol->private_value = pval;
1426 mutex_unlock(&codec->spdif_mutex); 1427 mutex_unlock(&codec->control_mutex);
1427 return err; 1428 return err;
1428} 1429}
1429EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get); 1430EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
@@ -1435,7 +1436,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1435 unsigned long pval; 1436 unsigned long pval;
1436 int i, indices, err = 0, change = 0; 1437 int i, indices, err = 0, change = 0;
1437 1438
1438 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1439 mutex_lock(&codec->control_mutex);
1439 pval = kcontrol->private_value; 1440 pval = kcontrol->private_value;
1440 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; 1441 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
1441 for (i = 0; i < indices; i++) { 1442 for (i = 0; i < indices; i++) {
@@ -1447,7 +1448,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1447 change |= err; 1448 change |= err;
1448 } 1449 }
1449 kcontrol->private_value = pval; 1450 kcontrol->private_value = pval;
1450 mutex_unlock(&codec->spdif_mutex); 1451 mutex_unlock(&codec->control_mutex);
1451 return err < 0 ? err : change; 1452 return err < 0 ? err : change;
1452} 1453}
1453EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put); 1454EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
@@ -1462,12 +1463,12 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1462 struct hda_bind_ctls *c; 1463 struct hda_bind_ctls *c;
1463 int err; 1464 int err;
1464 1465
1465 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1466 mutex_lock(&codec->control_mutex);
1466 c = (struct hda_bind_ctls *)kcontrol->private_value; 1467 c = (struct hda_bind_ctls *)kcontrol->private_value;
1467 kcontrol->private_value = *c->values; 1468 kcontrol->private_value = *c->values;
1468 err = c->ops->info(kcontrol, uinfo); 1469 err = c->ops->info(kcontrol, uinfo);
1469 kcontrol->private_value = (long)c; 1470 kcontrol->private_value = (long)c;
1470 mutex_unlock(&codec->spdif_mutex); 1471 mutex_unlock(&codec->control_mutex);
1471 return err; 1472 return err;
1472} 1473}
1473EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info); 1474EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
@@ -1479,12 +1480,12 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1479 struct hda_bind_ctls *c; 1480 struct hda_bind_ctls *c;
1480 int err; 1481 int err;
1481 1482
1482 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1483 mutex_lock(&codec->control_mutex);
1483 c = (struct hda_bind_ctls *)kcontrol->private_value; 1484 c = (struct hda_bind_ctls *)kcontrol->private_value;
1484 kcontrol->private_value = *c->values; 1485 kcontrol->private_value = *c->values;
1485 err = c->ops->get(kcontrol, ucontrol); 1486 err = c->ops->get(kcontrol, ucontrol);
1486 kcontrol->private_value = (long)c; 1487 kcontrol->private_value = (long)c;
1487 mutex_unlock(&codec->spdif_mutex); 1488 mutex_unlock(&codec->control_mutex);
1488 return err; 1489 return err;
1489} 1490}
1490EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get); 1491EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
@@ -1497,7 +1498,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1497 unsigned long *vals; 1498 unsigned long *vals;
1498 int err = 0, change = 0; 1499 int err = 0, change = 0;
1499 1500
1500 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1501 mutex_lock(&codec->control_mutex);
1501 c = (struct hda_bind_ctls *)kcontrol->private_value; 1502 c = (struct hda_bind_ctls *)kcontrol->private_value;
1502 for (vals = c->values; *vals; vals++) { 1503 for (vals = c->values; *vals; vals++) {
1503 kcontrol->private_value = *vals; 1504 kcontrol->private_value = *vals;
@@ -1507,7 +1508,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1507 change |= err; 1508 change |= err;
1508 } 1509 }
1509 kcontrol->private_value = (long)c; 1510 kcontrol->private_value = (long)c;
1510 mutex_unlock(&codec->spdif_mutex); 1511 mutex_unlock(&codec->control_mutex);
1511 return err < 0 ? err : change; 1512 return err < 0 ? err : change;
1512} 1513}
1513EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put); 1514EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
@@ -1519,12 +1520,12 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1519 struct hda_bind_ctls *c; 1520 struct hda_bind_ctls *c;
1520 int err; 1521 int err;
1521 1522
1522 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1523 mutex_lock(&codec->control_mutex);
1523 c = (struct hda_bind_ctls *)kcontrol->private_value; 1524 c = (struct hda_bind_ctls *)kcontrol->private_value;
1524 kcontrol->private_value = *c->values; 1525 kcontrol->private_value = *c->values;
1525 err = c->ops->tlv(kcontrol, op_flag, size, tlv); 1526 err = c->ops->tlv(kcontrol, op_flag, size, tlv);
1526 kcontrol->private_value = (long)c; 1527 kcontrol->private_value = (long)c;
1527 mutex_unlock(&codec->spdif_mutex); 1528 mutex_unlock(&codec->control_mutex);
1528 return err; 1529 return err;
1529} 1530}
1530EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv); 1531EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 729fc7642d7f..e9c723e13e5d 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -771,6 +771,7 @@ struct hda_codec {
771 struct hda_cache_rec cmd_cache; /* cache for other commands */ 771 struct hda_cache_rec cmd_cache; /* cache for other commands */
772 772
773 struct mutex spdif_mutex; 773 struct mutex spdif_mutex;
774 struct mutex control_mutex;
774 unsigned int spdif_status; /* IEC958 status bits */ 775 unsigned int spdif_status; /* IEC958 status bits */
775 unsigned short spdif_ctls; /* SPDIF control bits */ 776 unsigned short spdif_ctls; /* SPDIF control bits */
776 unsigned int spdif_in_enable; /* SPDIF input enable? */ 777 unsigned int spdif_in_enable; /* SPDIF input enable? */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e8ec74173525..aa86a1584506 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1502,11 +1502,11 @@ static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1502 struct alc_spec *spec = codec->spec; 1502 struct alc_spec *spec = codec->spec;
1503 int err; 1503 int err;
1504 1504
1505 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1505 mutex_lock(&codec->control_mutex);
1506 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1506 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1507 HDA_INPUT); 1507 HDA_INPUT);
1508 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1508 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1509 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1509 mutex_unlock(&codec->control_mutex);
1510 return err; 1510 return err;
1511} 1511}
1512 1512
@@ -1517,11 +1517,11 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1517 struct alc_spec *spec = codec->spec; 1517 struct alc_spec *spec = codec->spec;
1518 int err; 1518 int err;
1519 1519
1520 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1520 mutex_lock(&codec->control_mutex);
1521 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1521 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1522 HDA_INPUT); 1522 HDA_INPUT);
1523 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1523 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1524 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1524 mutex_unlock(&codec->control_mutex);
1525 return err; 1525 return err;
1526} 1526}
1527 1527
@@ -1537,11 +1537,11 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1537 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1537 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1538 int err; 1538 int err;
1539 1539
1540 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1540 mutex_lock(&codec->control_mutex);
1541 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 1541 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1542 3, 0, HDA_INPUT); 1542 3, 0, HDA_INPUT);
1543 err = func(kcontrol, ucontrol); 1543 err = func(kcontrol, ucontrol);
1544 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1544 mutex_unlock(&codec->control_mutex);
1545 return err; 1545 return err;
1546} 1546}
1547 1547