Patch "ALSA: hda/hdmi: Preserve the previous PCM device upon re-enablement" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ALSA: hda/hdmi: Preserve the previous PCM device upon re-enablement

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     alsa-hda-hdmi-preserve-the-previous-pcm-device-upon-.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c92d80279c6411d649e8ebd5d3110441c2f9ef2c
Author: Takashi Iwai <tiwai@xxxxxxx>
Date:   Fri Mar 31 16:22:17 2023 +0200

    ALSA: hda/hdmi: Preserve the previous PCM device upon re-enablement
    
    [ Upstream commit f785f5ee968f7045268b8be6b0abc850c4a4277c ]
    
    When a DRM driver turns on or off the screen with the audio
    capability, it notifies the ELD to HD-audio HDMI codec driver via
    component ops.  HDMI codec driver, in turn, attaches or detaches the
    PCM stream for the given port on the fly.
    
    The problem is that, since the recent code change, the HDMI driver
    always treats the PCM stream assignment dynamically; this ended up the
    confusion of the PCM device appearance.  e.g. when a screen goes once
    off and on again, it may appear on a different PCM device before the
    screen-off.  Although the application should treat such a change, it
    doesn't seem working gracefully with the current pipewire (maybe
    PulseAudio, too).
    
    As a workaround, this patch changes the HDMI codec driver behavior
    slightly to be more consistent.  Now it remembers the previous PCM
    slot for the given port and try to assign to it.  That is, if a port
    is re-enabled, the driver tries to use the same PCM slot that was
    assigned to that port previously.  If it conflicts, a new slot is
    searched and used like before, instead.
    
    Note that multiple monitor connections are the only typical case where
    the PCM slot preservation is effective.  As long as only a single
    monitor is connected, the behavior isn't changed, and the first PCM
    slot is still assigned always.
    
    Fixes: ef6f5494faf6 ("ALSA: hda/hdmi: Use only dynamic PCM device allocation")
    Reviewed-by: Jaroslav Kysela <perex@xxxxxxxx>
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=217259
    Link: https://lore.kernel.org/r/20230331142217.19791-1-tiwai@xxxxxxx
    Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 9ea633fe93393..4ffa3a59f419f 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -81,6 +81,7 @@ struct hdmi_spec_per_pin {
 	struct delayed_work work;
 	struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
 	int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
+	int prev_pcm_idx; /* previously assigned pcm index */
 	int repoll_count;
 	bool setup; /* the stream has been set up by prepare callback */
 	bool silent_stream;
@@ -1380,9 +1381,17 @@ static void hdmi_attach_hda_pcm(struct hdmi_spec *spec,
 	/* pcm already be attached to the pin */
 	if (per_pin->pcm)
 		return;
+	/* try the previously used slot at first */
+	idx = per_pin->prev_pcm_idx;
+	if (idx >= 0) {
+		if (!test_bit(idx, &spec->pcm_bitmap))
+			goto found;
+		per_pin->prev_pcm_idx = -1; /* no longer valid, clear it */
+	}
 	idx = hdmi_find_pcm_slot(spec, per_pin);
 	if (idx == -EBUSY)
 		return;
+ found:
 	per_pin->pcm_idx = idx;
 	per_pin->pcm = get_hdmi_pcm(spec, idx);
 	set_bit(idx, &spec->pcm_bitmap);
@@ -1398,6 +1407,7 @@ static void hdmi_detach_hda_pcm(struct hdmi_spec *spec,
 		return;
 	idx = per_pin->pcm_idx;
 	per_pin->pcm_idx = -1;
+	per_pin->prev_pcm_idx = idx; /* remember the previous index */
 	per_pin->pcm = NULL;
 	if (idx >= 0 && idx < spec->pcm_used)
 		clear_bit(idx, &spec->pcm_bitmap);
@@ -1924,6 +1934,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 
 		per_pin->pcm = NULL;
 		per_pin->pcm_idx = -1;
+		per_pin->prev_pcm_idx = -1;
 		per_pin->pin_nid = pin_nid;
 		per_pin->pin_nid_idx = spec->num_nids;
 		per_pin->dev_id = i;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux