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>
This commit is contained in:
		
					parent
					
						
							
								cbbaa603a0
							
						
					
				
			
			
				commit
				
					
						a4e9a38b40
					
				
			
		
					 3 changed files with 97 additions and 81 deletions
				
			
		|  | @ -478,10 +478,9 @@ static void hdmi_print_sad_info(int i, struct cea_sad *a, | ||||||
| 		snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); | 		snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void hdmi_print_eld_info(struct snd_info_entry *entry, | void snd_hdmi_print_eld_info(struct hdmi_eld *eld, | ||||||
| 				struct snd_info_buffer *buffer) | 			     struct snd_info_buffer *buffer) | ||||||
| { | { | ||||||
| 	struct hdmi_eld *eld = entry->private_data; |  | ||||||
| 	struct parsed_hdmi_eld *e = &eld->info; | 	struct parsed_hdmi_eld *e = &eld->info; | ||||||
| 	char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; | 	char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; | ||||||
| 	int i; | 	int i; | ||||||
|  | @ -500,13 +499,10 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry, | ||||||
| 		[4 ... 7] = "reserved" | 		[4 ... 7] = "reserved" | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&eld->lock); |  | ||||||
| 	snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); | 	snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); | ||||||
| 	snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); | 	snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); | ||||||
| 	if (!eld->eld_valid) { | 	if (!eld->eld_valid) | ||||||
| 		mutex_unlock(&eld->lock); |  | ||||||
| 		return; | 		return; | ||||||
| 	} |  | ||||||
| 	snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); | 	snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); | ||||||
| 	snd_iprintf(buffer, "connection_type\t\t%s\n", | 	snd_iprintf(buffer, "connection_type\t\t%s\n", | ||||||
| 				eld_connection_type_names[e->conn_type]); | 				eld_connection_type_names[e->conn_type]); | ||||||
|  | @ -528,13 +524,11 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry, | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < e->sad_count; i++) | 	for (i = 0; i < e->sad_count; i++) | ||||||
| 		hdmi_print_sad_info(i, e->sad + i, buffer); | 		hdmi_print_sad_info(i, e->sad + i, buffer); | ||||||
| 	mutex_unlock(&eld->lock); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void hdmi_write_eld_info(struct snd_info_entry *entry, | void snd_hdmi_write_eld_info(struct hdmi_eld *eld, | ||||||
| 				struct snd_info_buffer *buffer) | 			     struct snd_info_buffer *buffer) | ||||||
| { | { | ||||||
| 	struct hdmi_eld *eld = entry->private_data; |  | ||||||
| 	struct parsed_hdmi_eld *e = &eld->info; | 	struct parsed_hdmi_eld *e = &eld->info; | ||||||
| 	char line[64]; | 	char line[64]; | ||||||
| 	char name[64]; | 	char name[64]; | ||||||
|  | @ -542,7 +536,6 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry, | ||||||
| 	long long val; | 	long long val; | ||||||
| 	unsigned int n; | 	unsigned int n; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&eld->lock); |  | ||||||
| 	while (!snd_info_get_line(buffer, line, sizeof(line))) { | 	while (!snd_info_get_line(buffer, line, sizeof(line))) { | ||||||
| 		if (sscanf(line, "%s %llx", name, &val) != 2) | 		if (sscanf(line, "%s %llx", name, &val) != 2) | ||||||
| 			continue; | 			continue; | ||||||
|  | @ -594,38 +587,7 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry, | ||||||
| 				e->sad_count = n + 1; | 				e->sad_count = n + 1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	mutex_unlock(&eld->lock); |  | ||||||
| } | } | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, |  | ||||||
| 			 int index) |  | ||||||
| { |  | ||||||
| 	char name[32]; |  | ||||||
| 	struct snd_info_entry *entry; |  | ||||||
| 	int err; |  | ||||||
| 
 |  | ||||||
| 	snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index); |  | ||||||
| 	err = snd_card_proc_new(codec->bus->card, name, &entry); |  | ||||||
| 	if (err < 0) |  | ||||||
| 		return err; |  | ||||||
| 
 |  | ||||||
| 	snd_info_set_text_ops(entry, eld, hdmi_print_eld_info); |  | ||||||
| 	entry->c.text.write = hdmi_write_eld_info; |  | ||||||
| 	entry->mode |= S_IWUSR; |  | ||||||
| 	eld->proc_entry = entry; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) |  | ||||||
| { |  | ||||||
| 	if (!codec->bus->shutdown && eld->proc_entry) { |  | ||||||
| 		snd_device_free(codec->bus->card, eld->proc_entry); |  | ||||||
| 		eld->proc_entry = NULL; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #endif /* CONFIG_PROC_FS */ | #endif /* CONFIG_PROC_FS */ | ||||||
| 
 | 
 | ||||||
| /* update PCM info based on ELD */ | /* update PCM info based on ELD */ | ||||||
|  |  | ||||||
|  | @ -752,10 +752,6 @@ struct hdmi_eld { | ||||||
| 	int	eld_size; | 	int	eld_size; | ||||||
| 	char    eld_buffer[ELD_MAX_SIZE]; | 	char    eld_buffer[ELD_MAX_SIZE]; | ||||||
| 	struct parsed_hdmi_eld info; | 	struct parsed_hdmi_eld info; | ||||||
| 	struct mutex lock; |  | ||||||
| #ifdef CONFIG_PROC_FS |  | ||||||
| 	struct snd_info_entry *proc_entry; |  | ||||||
| #endif |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); | int 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, | ||||||
| 			      struct hda_pcm_stream *hinfo); | 			      struct hda_pcm_stream *hinfo); | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_PROC_FS | #ifdef CONFIG_PROC_FS | ||||||
| int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, | void snd_hdmi_print_eld_info(struct hdmi_eld *eld, | ||||||
| 			 int index); | 			     struct snd_info_buffer *buffer); | ||||||
| void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld); | void snd_hdmi_write_eld_info(struct hdmi_eld *eld, | ||||||
| #else | 			     struct snd_info_buffer *buffer); | ||||||
| static inline int snd_hda_eld_proc_new(struct hda_codec *codec, |  | ||||||
| 				       struct hdmi_eld *eld, |  | ||||||
| 				       int index) |  | ||||||
| { |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| static inline void snd_hda_eld_proc_free(struct hda_codec *codec, |  | ||||||
| 					 struct hdmi_eld *eld) |  | ||||||
| { |  | ||||||
| } |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 | #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 | ||||||
|  |  | ||||||
|  | @ -67,6 +67,7 @@ struct hdmi_spec_per_pin { | ||||||
| 
 | 
 | ||||||
| 	struct hda_codec *codec; | 	struct hda_codec *codec; | ||||||
| 	struct hdmi_eld sink_eld; | 	struct hdmi_eld sink_eld; | ||||||
|  | 	struct mutex lock; | ||||||
| 	struct delayed_work work; | 	struct delayed_work work; | ||||||
| 	struct snd_kcontrol *eld_ctl; | 	struct snd_kcontrol *eld_ctl; | ||||||
| 	int repoll_count; | 	int repoll_count; | ||||||
|  | @ -76,6 +77,9 @@ struct hdmi_spec_per_pin { | ||||||
| 	bool chmap_set;		/* channel-map override by ALSA API? */ | 	bool chmap_set;		/* channel-map override by ALSA API? */ | ||||||
| 	unsigned char chmap[8]; /* ALSA API channel-map */ | 	unsigned char chmap[8]; /* ALSA API channel-map */ | ||||||
| 	char pcm_name[8];	/* filled in build_pcm callbacks */ | 	char pcm_name[8];	/* filled in build_pcm callbacks */ | ||||||
|  | #ifdef CONFIG_PROC_FS | ||||||
|  | 	struct snd_info_entry *proc_entry; | ||||||
|  | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct hdmi_spec { | struct hdmi_spec { | ||||||
|  | @ -349,17 +353,19 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, | ||||||
| { | { | ||||||
| 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||||||
| 	struct hdmi_spec *spec = codec->spec; | 	struct hdmi_spec *spec = codec->spec; | ||||||
|  | 	struct hdmi_spec_per_pin *per_pin; | ||||||
| 	struct hdmi_eld *eld; | 	struct hdmi_eld *eld; | ||||||
| 	int pin_idx; | 	int pin_idx; | ||||||
| 
 | 
 | ||||||
| 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||||||
| 
 | 
 | ||||||
| 	pin_idx = kcontrol->private_value; | 	pin_idx = kcontrol->private_value; | ||||||
| 	eld = &get_pin(spec, pin_idx)->sink_eld; | 	per_pin = get_pin(spec, pin_idx); | ||||||
|  | 	eld = &per_pin->sink_eld; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&eld->lock); | 	mutex_lock(&per_pin->lock); | ||||||
| 	uinfo->count = eld->eld_valid ? eld->eld_size : 0; | 	uinfo->count = eld->eld_valid ? eld->eld_size : 0; | ||||||
| 	mutex_unlock(&eld->lock); | 	mutex_unlock(&per_pin->lock); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -369,15 +375,17 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, | ||||||
| { | { | ||||||
| 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||||||
| 	struct hdmi_spec *spec = codec->spec; | 	struct hdmi_spec *spec = codec->spec; | ||||||
|  | 	struct hdmi_spec_per_pin *per_pin; | ||||||
| 	struct hdmi_eld *eld; | 	struct hdmi_eld *eld; | ||||||
| 	int pin_idx; | 	int pin_idx; | ||||||
| 
 | 
 | ||||||
| 	pin_idx = kcontrol->private_value; | 	pin_idx = kcontrol->private_value; | ||||||
| 	eld = &get_pin(spec, pin_idx)->sink_eld; | 	per_pin = get_pin(spec, pin_idx); | ||||||
|  | 	eld = &per_pin->sink_eld; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&eld->lock); | 	mutex_lock(&per_pin->lock); | ||||||
| 	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) { | 	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) { | ||||||
| 		mutex_unlock(&eld->lock); | 		mutex_unlock(&per_pin->lock); | ||||||
| 		snd_BUG(); | 		snd_BUG(); | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	} | 	} | ||||||
|  | @ -387,7 +395,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, | ||||||
| 	if (eld->eld_valid) | 	if (eld->eld_valid) | ||||||
| 		memcpy(ucontrol->value.bytes.data, eld->eld_buffer, | 		memcpy(ucontrol->value.bytes.data, eld->eld_buffer, | ||||||
| 		       eld->eld_size); | 		       eld->eld_size); | ||||||
| 	mutex_unlock(&eld->lock); | 	mutex_unlock(&per_pin->lock); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -478,6 +486,68 @@ static void hdmi_set_channel_count(struct hda_codec *codec, | ||||||
| 				    AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); | 				    AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * ELD proc files | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_PROC_FS | ||||||
|  | static void print_eld_info(struct snd_info_entry *entry, | ||||||
|  | 			   struct snd_info_buffer *buffer) | ||||||
|  | { | ||||||
|  | 	struct hdmi_spec_per_pin *per_pin = entry->private_data; | ||||||
|  | 
 | ||||||
|  | 	mutex_lock(&per_pin->lock); | ||||||
|  | 	snd_hdmi_print_eld_info(&per_pin->sink_eld, buffer); | ||||||
|  | 	mutex_unlock(&per_pin->lock); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void write_eld_info(struct snd_info_entry *entry, | ||||||
|  | 			   struct snd_info_buffer *buffer) | ||||||
|  | { | ||||||
|  | 	struct hdmi_spec_per_pin *per_pin = entry->private_data; | ||||||
|  | 
 | ||||||
|  | 	mutex_lock(&per_pin->lock); | ||||||
|  | 	snd_hdmi_write_eld_info(&per_pin->sink_eld, buffer); | ||||||
|  | 	mutex_unlock(&per_pin->lock); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index) | ||||||
|  | { | ||||||
|  | 	char name[32]; | ||||||
|  | 	struct hda_codec *codec = per_pin->codec; | ||||||
|  | 	struct snd_info_entry *entry; | ||||||
|  | 	int err; | ||||||
|  | 
 | ||||||
|  | 	snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index); | ||||||
|  | 	err = snd_card_proc_new(codec->bus->card, name, &entry); | ||||||
|  | 	if (err < 0) | ||||||
|  | 		return err; | ||||||
|  | 
 | ||||||
|  | 	snd_info_set_text_ops(entry, per_pin, print_eld_info); | ||||||
|  | 	entry->c.text.write = write_eld_info; | ||||||
|  | 	entry->mode |= S_IWUSR; | ||||||
|  | 	per_pin->proc_entry = entry; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void eld_proc_free(struct hdmi_spec_per_pin *per_pin) | ||||||
|  | { | ||||||
|  | 	if (!per_pin->codec->bus->shutdown && per_pin->proc_entry) { | ||||||
|  | 		snd_device_free(per_pin->codec->bus->card, per_pin->proc_entry); | ||||||
|  | 		per_pin->proc_entry = NULL; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | #else | ||||||
|  | static inline int snd_hda_eld_proc_new(struct hdmi_spec_per_pin *per_pin, | ||||||
|  | 				       int index) | ||||||
|  | { | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | static inline void snd_hda_eld_proc_free(struct hdmi_spec_per_pin *per_pin) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Channel mapping routines |  * Channel mapping routines | ||||||
|  | @ -1342,7 +1412,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | ||||||
| 	bool update_eld = false; | 	bool update_eld = false; | ||||||
| 	bool eld_changed = false; | 	bool eld_changed = false; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&pin_eld->lock); | 	mutex_lock(&per_pin->lock); | ||||||
| 	pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 	pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | ||||||
| 	if (pin_eld->monitor_present) | 	if (pin_eld->monitor_present) | ||||||
| 		eld->eld_valid  = !!(present & AC_PINSENSE_ELDV); | 		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) | ||||||
| 			       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, | 			       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, | ||||||
| 			       &per_pin->eld_ctl->id); | 			       &per_pin->eld_ctl->id); | ||||||
|  unlock: |  unlock: | ||||||
| 	mutex_unlock(&pin_eld->lock); | 	mutex_unlock(&per_pin->lock); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void hdmi_repoll_eld(struct work_struct *work) | static void hdmi_repoll_eld(struct work_struct *work) | ||||||
|  | @ -1577,12 +1647,12 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||||||
| 	bool non_pcm; | 	bool non_pcm; | ||||||
| 
 | 
 | ||||||
| 	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | 	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | ||||||
| 	mutex_lock(&per_pin->sink_eld.lock); | 	mutex_lock(&per_pin->lock); | ||||||
| 	per_pin->channels = substream->runtime->channels; | 	per_pin->channels = substream->runtime->channels; | ||||||
| 	per_pin->setup = true; | 	per_pin->setup = true; | ||||||
| 
 | 
 | ||||||
| 	hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); | 	hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); | ||||||
| 	mutex_unlock(&per_pin->sink_eld.lock); | 	mutex_unlock(&per_pin->lock); | ||||||
| 
 | 
 | ||||||
| 	return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); | 	return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); | ||||||
| } | } | ||||||
|  | @ -1621,13 +1691,13 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | ||||||
| 
 | 
 | ||||||
| 		snd_hda_spdif_ctls_unassign(codec, pin_idx); | 		snd_hda_spdif_ctls_unassign(codec, pin_idx); | ||||||
| 
 | 
 | ||||||
| 		mutex_lock(&per_pin->sink_eld.lock); | 		mutex_lock(&per_pin->lock); | ||||||
| 		per_pin->chmap_set = false; | 		per_pin->chmap_set = false; | ||||||
| 		memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); | 		memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); | ||||||
| 
 | 
 | ||||||
| 		per_pin->setup = false; | 		per_pin->setup = false; | ||||||
| 		per_pin->channels = 0; | 		per_pin->channels = 0; | ||||||
| 		mutex_unlock(&per_pin->sink_eld.lock); | 		mutex_unlock(&per_pin->lock); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -1756,12 +1826,12 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol, | ||||||
| 	ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap); | 	ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap); | ||||||
| 	if (ca < 0) | 	if (ca < 0) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	mutex_lock(&per_pin->sink_eld.lock); | 	mutex_lock(&per_pin->lock); | ||||||
| 	per_pin->chmap_set = true; | 	per_pin->chmap_set = true; | ||||||
| 	memcpy(per_pin->chmap, chmap, sizeof(chmap)); | 	memcpy(per_pin->chmap, chmap, sizeof(chmap)); | ||||||
| 	if (prepared) | 	if (prepared) | ||||||
| 		hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); | 		hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); | ||||||
| 	mutex_unlock(&per_pin->sink_eld.lock); | 	mutex_unlock(&per_pin->lock); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -1878,12 +1948,11 @@ static int generic_hdmi_init_per_pins(struct hda_codec *codec) | ||||||
| 
 | 
 | ||||||
| 	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | ||||||
| 		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | 		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | ||||||
| 		struct hdmi_eld *eld = &per_pin->sink_eld; |  | ||||||
| 
 | 
 | ||||||
| 		per_pin->codec = codec; | 		per_pin->codec = codec; | ||||||
| 		mutex_init(&eld->lock); | 		mutex_init(&per_pin->lock); | ||||||
| 		INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); | 		INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); | ||||||
| 		snd_hda_eld_proc_new(codec, eld, pin_idx); | 		eld_proc_new(per_pin, pin_idx); | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -1924,10 +1993,9 @@ static void generic_hdmi_free(struct hda_codec *codec) | ||||||
| 
 | 
 | ||||||
| 	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | ||||||
| 		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | 		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | ||||||
| 		struct hdmi_eld *eld = &per_pin->sink_eld; |  | ||||||
| 
 | 
 | ||||||
| 		cancel_delayed_work(&per_pin->work); | 		cancel_delayed_work(&per_pin->work); | ||||||
| 		snd_hda_eld_proc_free(codec, eld); | 		eld_proc_free(per_pin); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	flush_workqueue(codec->bus->workq); | 	flush_workqueue(codec->bus->workq); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Takashi Iwai
				Takashi Iwai