aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-10-17 12:21:12 -0400
committerTakashi Iwai <tiwai@suse.de>2013-10-17 13:23:45 -0400
commita4e9a38b40a0e2f7dad1a0b355896d23fbdd16e0 (patch)
treeed9f473567d7e73eb3bc6a04995d8c34caea7fae
parentcbbaa603a03cc46681e24d6b2804b62fde95a2af (diff)
ALSA: hda - Move mutex from hda_eld to per_pin in HDMI codec driver
Since the lock is used primarily in patch_hdmi.c, it's better to move it in the local struct instead of exporting in hda_eld. The only functions requiring the lock in hda_eld.c are proc accessors. So in this patch, the proc entry and its creation/deletion/accessors are moved into patch_hdmi.c, together with the mutex lock to pin_spec struct. The former proc info functions are exported so that they can be called from patch_hdmi.c. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_eld.c48
-rw-r--r--sound/pci/hda/hda_local.h22
-rw-r--r--sound/pci/hda/patch_hdmi.c108
3 files changed, 97 insertions, 81 deletions
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index d0d7ac1e99d2..f62356c2f54c 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -478,10 +478,9 @@ static void hdmi_print_sad_info(int i, struct cea_sad *a,
478 snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); 478 snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile);
479} 479}
480 480
481static void hdmi_print_eld_info(struct snd_info_entry *entry, 481void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
482 struct snd_info_buffer *buffer) 482 struct snd_info_buffer *buffer)
483{ 483{
484 struct hdmi_eld *eld = entry->private_data;
485 struct parsed_hdmi_eld *e = &eld->info; 484 struct parsed_hdmi_eld *e = &eld->info;
486 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; 485 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
487 int i; 486 int i;
@@ -500,13 +499,10 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry,
500 [4 ... 7] = "reserved" 499 [4 ... 7] = "reserved"
501 }; 500 };
502 501
503 mutex_lock(&eld->lock);
504 snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); 502 snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present);
505 snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); 503 snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid);
506 if (!eld->eld_valid) { 504 if (!eld->eld_valid)
507 mutex_unlock(&eld->lock);
508 return; 505 return;
509 }
510 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); 506 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
511 snd_iprintf(buffer, "connection_type\t\t%s\n", 507 snd_iprintf(buffer, "connection_type\t\t%s\n",
512 eld_connection_type_names[e->conn_type]); 508 eld_connection_type_names[e->conn_type]);
@@ -528,13 +524,11 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry,
528 524
529 for (i = 0; i < e->sad_count; i++) 525 for (i = 0; i < e->sad_count; i++)
530 hdmi_print_sad_info(i, e->sad + i, buffer); 526 hdmi_print_sad_info(i, e->sad + i, buffer);
531 mutex_unlock(&eld->lock);
532} 527}
533 528
534static void hdmi_write_eld_info(struct snd_info_entry *entry, 529void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
535 struct snd_info_buffer *buffer) 530 struct snd_info_buffer *buffer)
536{ 531{
537 struct hdmi_eld *eld = entry->private_data;
538 struct parsed_hdmi_eld *e = &eld->info; 532 struct parsed_hdmi_eld *e = &eld->info;
539 char line[64]; 533 char line[64];
540 char name[64]; 534 char name[64];
@@ -542,7 +536,6 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry,
542 long long val; 536 long long val;
543 unsigned int n; 537 unsigned int n;
544 538
545 mutex_lock(&eld->lock);
546 while (!snd_info_get_line(buffer, line, sizeof(line))) { 539 while (!snd_info_get_line(buffer, line, sizeof(line))) {
547 if (sscanf(line, "%s %llx", name, &val) != 2) 540 if (sscanf(line, "%s %llx", name, &val) != 2)
548 continue; 541 continue;
@@ -594,38 +587,7 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry,
594 e->sad_count = n + 1; 587 e->sad_count = n + 1;
595 } 588 }
596 } 589 }
597 mutex_unlock(&eld->lock);
598}
599
600
601int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
602 int index)
603{
604 char name[32];
605 struct snd_info_entry *entry;
606 int err;
607
608 snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
609 err = snd_card_proc_new(codec->bus->card, name, &entry);
610 if (err < 0)
611 return err;
612
613 snd_info_set_text_ops(entry, eld, hdmi_print_eld_info);
614 entry->c.text.write = hdmi_write_eld_info;
615 entry->mode |= S_IWUSR;
616 eld->proc_entry = entry;
617
618 return 0;
619}
620
621void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
622{
623 if (!codec->bus->shutdown && eld->proc_entry) {
624 snd_device_free(codec->bus->card, eld->proc_entry);
625 eld->proc_entry = NULL;
626 }
627} 590}
628
629#endif /* CONFIG_PROC_FS */ 591#endif /* CONFIG_PROC_FS */
630 592
631/* update PCM info based on ELD */ 593/* update PCM info based on ELD */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index a71bf348e389..46cddd4c7b72 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -752,10 +752,6 @@ struct hdmi_eld {
752 int eld_size; 752 int eld_size;
753 char eld_buffer[ELD_MAX_SIZE]; 753 char eld_buffer[ELD_MAX_SIZE];
754 struct parsed_hdmi_eld info; 754 struct parsed_hdmi_eld info;
755 struct mutex lock;
756#ifdef CONFIG_PROC_FS
757 struct snd_info_entry *proc_entry;
758#endif
759}; 755};
760 756
761int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 757int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
@@ -768,20 +764,10 @@ void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e,
768 struct hda_pcm_stream *hinfo); 764 struct hda_pcm_stream *hinfo);
769 765
770#ifdef CONFIG_PROC_FS 766#ifdef CONFIG_PROC_FS
771int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, 767void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
772 int index); 768 struct snd_info_buffer *buffer);
773void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld); 769void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
774#else 770 struct snd_info_buffer *buffer);
775static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
776 struct hdmi_eld *eld,
777 int index)
778{
779 return 0;
780}
781static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
782 struct hdmi_eld *eld)
783{
784}
785#endif 771#endif
786 772
787#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 773#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index c2bad9587d54..804adb872e63 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -67,6 +67,7 @@ struct hdmi_spec_per_pin {
67 67
68 struct hda_codec *codec; 68 struct hda_codec *codec;
69 struct hdmi_eld sink_eld; 69 struct hdmi_eld sink_eld;
70 struct mutex lock;
70 struct delayed_work work; 71 struct delayed_work work;
71 struct snd_kcontrol *eld_ctl; 72 struct snd_kcontrol *eld_ctl;
72 int repoll_count; 73 int repoll_count;
@@ -76,6 +77,9 @@ struct hdmi_spec_per_pin {
76 bool chmap_set; /* channel-map override by ALSA API? */ 77 bool chmap_set; /* channel-map override by ALSA API? */
77 unsigned char chmap[8]; /* ALSA API channel-map */ 78 unsigned char chmap[8]; /* ALSA API channel-map */
78 char pcm_name[8]; /* filled in build_pcm callbacks */ 79 char pcm_name[8]; /* filled in build_pcm callbacks */
80#ifdef CONFIG_PROC_FS
81 struct snd_info_entry *proc_entry;
82#endif
79}; 83};
80 84
81struct hdmi_spec { 85struct hdmi_spec {
@@ -349,17 +353,19 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
349{ 353{
350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 354 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
351 struct hdmi_spec *spec = codec->spec; 355 struct hdmi_spec *spec = codec->spec;
356 struct hdmi_spec_per_pin *per_pin;
352 struct hdmi_eld *eld; 357 struct hdmi_eld *eld;
353 int pin_idx; 358 int pin_idx;
354 359
355 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 360 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
356 361
357 pin_idx = kcontrol->private_value; 362 pin_idx = kcontrol->private_value;
358 eld = &get_pin(spec, pin_idx)->sink_eld; 363 per_pin = get_pin(spec, pin_idx);
364 eld = &per_pin->sink_eld;
359 365
360 mutex_lock(&eld->lock); 366 mutex_lock(&per_pin->lock);
361 uinfo->count = eld->eld_valid ? eld->eld_size : 0; 367 uinfo->count = eld->eld_valid ? eld->eld_size : 0;
362 mutex_unlock(&eld->lock); 368 mutex_unlock(&per_pin->lock);
363 369
364 return 0; 370 return 0;
365} 371}
@@ -369,15 +375,17 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
369{ 375{
370 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 376 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
371 struct hdmi_spec *spec = codec->spec; 377 struct hdmi_spec *spec = codec->spec;
378 struct hdmi_spec_per_pin *per_pin;
372 struct hdmi_eld *eld; 379 struct hdmi_eld *eld;
373 int pin_idx; 380 int pin_idx;
374 381
375 pin_idx = kcontrol->private_value; 382 pin_idx = kcontrol->private_value;
376 eld = &get_pin(spec, pin_idx)->sink_eld; 383 per_pin = get_pin(spec, pin_idx);
384 eld = &per_pin->sink_eld;
377 385
378 mutex_lock(&eld->lock); 386 mutex_lock(&per_pin->lock);
379 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) { 387 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) {
380 mutex_unlock(&eld->lock); 388 mutex_unlock(&per_pin->lock);
381 snd_BUG(); 389 snd_BUG();
382 return -EINVAL; 390 return -EINVAL;
383 } 391 }
@@ -387,7 +395,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
387 if (eld->eld_valid) 395 if (eld->eld_valid)
388 memcpy(ucontrol->value.bytes.data, eld->eld_buffer, 396 memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
389 eld->eld_size); 397 eld->eld_size);
390 mutex_unlock(&eld->lock); 398 mutex_unlock(&per_pin->lock);
391 399
392 return 0; 400 return 0;
393} 401}
@@ -478,6 +486,68 @@ static void hdmi_set_channel_count(struct hda_codec *codec,
478 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); 486 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
479} 487}
480 488
489/*
490 * ELD proc files
491 */
492
493#ifdef CONFIG_PROC_FS
494static void print_eld_info(struct snd_info_entry *entry,
495 struct snd_info_buffer *buffer)
496{
497 struct hdmi_spec_per_pin *per_pin = entry->private_data;
498
499 mutex_lock(&per_pin->lock);
500 snd_hdmi_print_eld_info(&per_pin->sink_eld, buffer);
501 mutex_unlock(&per_pin->lock);
502}
503
504static void write_eld_info(struct snd_info_entry *entry,
505 struct snd_info_buffer *buffer)
506{
507 struct hdmi_spec_per_pin *per_pin = entry->private_data;
508
509 mutex_lock(&per_pin->lock);
510 snd_hdmi_write_eld_info(&per_pin->sink_eld, buffer);
511 mutex_unlock(&per_pin->lock);
512}
513
514static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
515{
516 char name[32];
517 struct hda_codec *codec = per_pin->codec;
518 struct snd_info_entry *entry;
519 int err;
520
521 snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
522 err = snd_card_proc_new(codec->bus->card, name, &entry);
523 if (err < 0)
524 return err;
525
526 snd_info_set_text_ops(entry, per_pin, print_eld_info);
527 entry->c.text.write = write_eld_info;
528 entry->mode |= S_IWUSR;
529 per_pin->proc_entry = entry;
530
531 return 0;
532}
533
534static void eld_proc_free(struct hdmi_spec_per_pin *per_pin)
535{
536 if (!per_pin->codec->bus->shutdown && per_pin->proc_entry) {
537 snd_device_free(per_pin->codec->bus->card, per_pin->proc_entry);
538 per_pin->proc_entry = NULL;
539 }
540}
541#else
542static inline int snd_hda_eld_proc_new(struct hdmi_spec_per_pin *per_pin,
543 int index)
544{
545 return 0;
546}
547static inline void snd_hda_eld_proc_free(struct hdmi_spec_per_pin *per_pin)
548{
549}
550#endif
481 551
482/* 552/*
483 * Channel mapping routines 553 * Channel mapping routines
@@ -1342,7 +1412,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1342 bool update_eld = false; 1412 bool update_eld = false;
1343 bool eld_changed = false; 1413 bool eld_changed = false;
1344 1414
1345 mutex_lock(&pin_eld->lock); 1415 mutex_lock(&per_pin->lock);
1346 pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); 1416 pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
1347 if (pin_eld->monitor_present) 1417 if (pin_eld->monitor_present)
1348 eld->eld_valid = !!(present & AC_PINSENSE_ELDV); 1418 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
@@ -1406,7 +1476,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1406 SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, 1476 SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
1407 &per_pin->eld_ctl->id); 1477 &per_pin->eld_ctl->id);
1408 unlock: 1478 unlock:
1409 mutex_unlock(&pin_eld->lock); 1479 mutex_unlock(&per_pin->lock);
1410} 1480}
1411 1481
1412static void hdmi_repoll_eld(struct work_struct *work) 1482static void hdmi_repoll_eld(struct work_struct *work)
@@ -1577,12 +1647,12 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1577 bool non_pcm; 1647 bool non_pcm;
1578 1648
1579 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1649 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1580 mutex_lock(&per_pin->sink_eld.lock); 1650 mutex_lock(&per_pin->lock);
1581 per_pin->channels = substream->runtime->channels; 1651 per_pin->channels = substream->runtime->channels;
1582 per_pin->setup = true; 1652 per_pin->setup = true;
1583 1653
1584 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); 1654 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
1585 mutex_unlock(&per_pin->sink_eld.lock); 1655 mutex_unlock(&per_pin->lock);
1586 1656
1587 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); 1657 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1588} 1658}
@@ -1621,13 +1691,13 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1621 1691
1622 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1692 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1623 1693
1624 mutex_lock(&per_pin->sink_eld.lock); 1694 mutex_lock(&per_pin->lock);
1625 per_pin->chmap_set = false; 1695 per_pin->chmap_set = false;
1626 memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); 1696 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
1627 1697
1628 per_pin->setup = false; 1698 per_pin->setup = false;
1629 per_pin->channels = 0; 1699 per_pin->channels = 0;
1630 mutex_unlock(&per_pin->sink_eld.lock); 1700 mutex_unlock(&per_pin->lock);
1631 } 1701 }
1632 1702
1633 return 0; 1703 return 0;
@@ -1756,12 +1826,12 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1756 ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap); 1826 ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
1757 if (ca < 0) 1827 if (ca < 0)
1758 return -EINVAL; 1828 return -EINVAL;
1759 mutex_lock(&per_pin->sink_eld.lock); 1829 mutex_lock(&per_pin->lock);
1760 per_pin->chmap_set = true; 1830 per_pin->chmap_set = true;
1761 memcpy(per_pin->chmap, chmap, sizeof(chmap)); 1831 memcpy(per_pin->chmap, chmap, sizeof(chmap));
1762 if (prepared) 1832 if (prepared)
1763 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); 1833 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1764 mutex_unlock(&per_pin->sink_eld.lock); 1834 mutex_unlock(&per_pin->lock);
1765 1835
1766 return 0; 1836 return 0;
1767} 1837}
@@ -1878,12 +1948,11 @@ static int generic_hdmi_init_per_pins(struct hda_codec *codec)
1878 1948
1879 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1949 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1880 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 1950 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1881 struct hdmi_eld *eld = &per_pin->sink_eld;
1882 1951
1883 per_pin->codec = codec; 1952 per_pin->codec = codec;
1884 mutex_init(&eld->lock); 1953 mutex_init(&per_pin->lock);
1885 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); 1954 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
1886 snd_hda_eld_proc_new(codec, eld, pin_idx); 1955 eld_proc_new(per_pin, pin_idx);
1887 } 1956 }
1888 return 0; 1957 return 0;
1889} 1958}
@@ -1924,10 +1993,9 @@ static void generic_hdmi_free(struct hda_codec *codec)
1924 1993
1925 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1994 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1926 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 1995 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1927 struct hdmi_eld *eld = &per_pin->sink_eld;
1928 1996
1929 cancel_delayed_work(&per_pin->work); 1997 cancel_delayed_work(&per_pin->work);
1930 snd_hda_eld_proc_free(codec, eld); 1998 eld_proc_free(per_pin);
1931 } 1999 }
1932 2000
1933 flush_workqueue(codec->bus->workq); 2001 flush_workqueue(codec->bus->workq);