--- /dev/null
+From 4f2ab5e1d13d6aa77c55f4914659784efd776eb4 Mon Sep 17 00:00:00 2001
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+Date: Tue, 5 Feb 2019 16:29:40 +0000
+Subject: ALSA: compress: Fix stop handling on compressed capture streams
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+commit 4f2ab5e1d13d6aa77c55f4914659784efd776eb4 upstream.
+
+It is normal user behaviour to start, stop, then start a stream
+again without closing it. Currently this works for compressed
+playback streams but not capture ones.
+
+The states on a compressed capture stream go directly from OPEN to
+PREPARED, unlike a playback stream which moves to SETUP and waits
+for a write of data before moving to PREPARED. Currently however,
+when a stop is sent the state is set to SETUP for both types of
+streams. This leaves a capture stream in the situation where a new
+start can't be sent as that requires the state to be PREPARED and
+a new set_params can't be sent as that requires the state to be
+OPEN. The only option being to close the stream, and then reopen.
+
+Correct this issues by allowing snd_compr_drain_notify to set the
+state depending on the stream direction, as we already do in
+set_params.
+
+Fixes: 49bb6402f1aa ("ALSA: compress_core: Add support for capture streams")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/sound/compress_driver.h | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/sound/compress_driver.h
++++ b/include/sound/compress_driver.h
+@@ -171,7 +171,11 @@ static inline void snd_compr_drain_notif
+ if (snd_BUG_ON(!stream))
+ return;
+
+- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
++ if (stream->direction == SND_COMPRESS_PLAYBACK)
++ stream->runtime->state = SNDRV_PCM_STATE_SETUP;
++ else
++ stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
++
+ wake_up(&stream->runtime->sleep);
+ }
+
--- /dev/null
+From d561aa0a70bb2e1dd85fde98b6a5561e4175ac3e Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Fri, 1 Feb 2019 16:51:10 +0800
+Subject: ALSA: hda/realtek - Fix lose hp_pins for disable auto mute
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit d561aa0a70bb2e1dd85fde98b6a5561e4175ac3e upstream.
+
+When auto_mute = no or spec->suppress_auto_mute = 1, cfg->hp_pins will
+lose value.
+
+Add this patch to find hp_pins value.
+I add fixed for ALC282 ALC225 ALC256 ALC294 and alc_default_init()
+alc_default_shutup().
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 45 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2963,6 +2963,11 @@ static void alc282_init(struct hda_codec
+ bool hp_pin_sense;
+ int coef78;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ alc282_restore_default_value(codec);
+
+ if (!hp_pin)
+@@ -3000,6 +3005,11 @@ static void alc282_shutup(struct hda_cod
+ bool hp_pin_sense;
+ int coef78;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3159,6 +3169,11 @@ static void alc256_init(struct hda_codec
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin)
+ return;
+
+@@ -3195,6 +3210,11 @@ static void alc256_shutup(struct hda_cod
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3231,6 +3251,11 @@ static void alc225_init(struct hda_codec
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp1_pin_sense, hp2_pin_sense;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin)
+ return;
+
+@@ -3274,6 +3299,11 @@ static void alc225_shutup(struct hda_cod
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp1_pin_sense, hp2_pin_sense;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3318,6 +3348,11 @@ static void alc_default_init(struct hda_
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin)
+ return;
+
+@@ -3347,6 +3382,11 @@ static void alc_default_shutup(struct hd
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3379,6 +3419,11 @@ static void alc294_hp_init(struct hda_co
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ int i, val;
+
++ if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ hp_pin = spec->gen.autocfg.line_out_pins[0];
++ }
++
+ if (!hp_pin)
+ return;
+
--- /dev/null
+From 89e3a5682edaa4e5bb334719afb180256ac7bf78 Mon Sep 17 00:00:00 2001
+From: Jeremy Soller <jeremy@system76.com>
+Date: Wed, 30 Jan 2019 16:12:31 -0700
+Subject: ALSA: hda/realtek - Headset microphone support for System76 darp5
+
+From: Jeremy Soller <jeremy@system76.com>
+
+commit 89e3a5682edaa4e5bb334719afb180256ac7bf78 upstream.
+
+On the System76 Darter Pro (darp5), there is a headset microphone
+input attached to 0x1a that does not have a jack detect. In order to
+get it working, the pin configuration needs to be set correctly, and
+the ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC fixup needs to be applied.
+This is similar to the MIC_NO_PRESENCE fixups for some Dell laptops,
+except we have a separate microphone jack that is already configured
+correctly.
+
+Signed-off-by: Jeremy Soller <jeremy@system76.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5572,6 +5572,7 @@ enum {
+ ALC294_FIXUP_ASUS_MIC,
+ ALC294_FIXUP_ASUS_HEADSET_MIC,
+ ALC294_FIXUP_ASUS_SPK,
++ ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
+ };
+
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -6496,6 +6497,15 @@ static const struct hda_fixup alc269_fix
+ .chained = true,
+ .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
+ },
++ [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
++ },
+ };
+
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -6674,6 +6684,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
++ SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
+ SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
+ SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
--- /dev/null
+From 35a39f98567d8d3f1cea48f0f30de1a7e736b644 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 1 Feb 2019 11:19:50 +0100
+Subject: ALSA: hda/realtek - Use a common helper for hp pin reference
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 35a39f98567d8d3f1cea48f0f30de1a7e736b644 upstream.
+
+Replace the open-codes in many places with a new common helper for
+performing the same thing: referring to the primary headphone pin.
+
+This eventually fixes the potentially missing headphone pin on some
+weird devices, too.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 96 ++++++++++--------------------------------
+ 1 file changed, 24 insertions(+), 72 deletions(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -515,6 +515,15 @@ static void alc_auto_init_amp(struct hda
+ }
+ }
+
++/* get a primary headphone pin if available */
++static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
++{
++ if (spec->gen.autocfg.hp_pins[0])
++ return spec->gen.autocfg.hp_pins[0];
++ if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
++ return spec->gen.autocfg.line_out_pins[0];
++ return 0;
++}
+
+ /*
+ * Realtek SSID verification
+@@ -725,9 +734,7 @@ do_sku:
+ * 15 : 1 --> enable the function "Mute internal speaker
+ * when the external headphone out jack is plugged"
+ */
+- if (!spec->gen.autocfg.hp_pins[0] &&
+- !(spec->gen.autocfg.line_out_pins[0] &&
+- spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
++ if (!alc_get_hp_pin(spec)) {
+ hda_nid_t nid;
+ tmp = (ass >> 11) & 0x3; /* HP to chassis */
+ nid = ports[tmp];
+@@ -2959,15 +2966,10 @@ static void alc282_restore_default_value
+ static void alc282_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+ int coef78;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ alc282_restore_default_value(codec);
+
+ if (!hp_pin)
+@@ -3001,15 +3003,10 @@ static void alc282_init(struct hda_codec
+ static void alc282_shutup(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+ int coef78;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3084,14 +3081,9 @@ static void alc283_restore_default_value
+ static void alc283_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ alc283_restore_default_value(codec);
+
+ if (!hp_pin)
+@@ -3125,14 +3117,9 @@ static void alc283_init(struct hda_codec
+ static void alc283_shutup(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3166,14 +3153,9 @@ static void alc283_shutup(struct hda_cod
+ static void alc256_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin)
+ return;
+
+@@ -3207,14 +3189,9 @@ static void alc256_init(struct hda_codec
+ static void alc256_shutup(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3248,14 +3225,9 @@ static void alc256_shutup(struct hda_cod
+ static void alc225_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp1_pin_sense, hp2_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin)
+ return;
+
+@@ -3296,14 +3268,9 @@ static void alc225_init(struct hda_codec
+ static void alc225_shutup(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp1_pin_sense, hp2_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3345,14 +3312,9 @@ static void alc225_shutup(struct hda_cod
+ static void alc_default_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin)
+ return;
+
+@@ -3379,14 +3341,9 @@ static void alc_default_init(struct hda_
+ static void alc_default_shutup(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ bool hp_pin_sense;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+@@ -3416,14 +3373,9 @@ static void alc_default_shutup(struct hd
+ static void alc294_hp_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ int i, val;
+
+- if (!spec->gen.autocfg.hp_outs && spec->gen.suppress_auto_mute) {
+- if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
+- hp_pin = spec->gen.autocfg.line_out_pins[0];
+- }
+-
+ if (!hp_pin)
+ return;
+
+@@ -4825,7 +4777,7 @@ static void alc_update_headset_mode(stru
+ struct alc_spec *spec = codec->spec;
+
+ hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
+- hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
++ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+
+ int new_headset_mode;
+
+@@ -5104,7 +5056,7 @@ static void alc_fixup_tpt470_dock(struct
+ static void alc_shutup_dell_xps13(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+- int hp_pin = spec->gen.autocfg.hp_pins[0];
++ int hp_pin = alc_get_hp_pin(spec);
+
+ /* Prevent pop noises when headphones are plugged in */
+ snd_hda_codec_write(codec, hp_pin, 0,
+@@ -5197,7 +5149,7 @@ static void alc271_hp_gate_mic_jack(stru
+
+ if (action == HDA_FIXUP_ACT_PROBE) {
+ int mic_pin = find_ext_mic_pin(codec);
+- int hp_pin = spec->gen.autocfg.hp_pins[0];
++ int hp_pin = alc_get_hp_pin(spec);
+
+ if (snd_BUG_ON(!mic_pin || !hp_pin))
+ return;
--- /dev/null
+From 305a0ade180981686eec1f92aa6252a7c6ebb1cf Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 30 Jan 2019 17:46:03 +0100
+Subject: ALSA: hda - Serialize codec registrations
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 305a0ade180981686eec1f92aa6252a7c6ebb1cf upstream.
+
+In the current code, the codec registration may happen both at the
+codec bind time and the end of the controller probe time. In a rare
+occasion, they race with each other, leading to Oops due to the still
+uninitialized card device.
+
+This patch introduces a simple flag to prevent the codec registration
+at the codec bind time as long as the controller probe is going on.
+The controller probe invokes snd_card_register() that does the whole
+registration task, and we don't need to register each piece
+beforehand.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_bind.c | 3 ++-
+ sound/pci/hda/hda_codec.h | 1 +
+ sound/pci/hda/hda_intel.c | 2 ++
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_bind.c
++++ b/sound/pci/hda/hda_bind.c
+@@ -109,7 +109,8 @@ static int hda_codec_driver_probe(struct
+ err = snd_hda_codec_build_controls(codec);
+ if (err < 0)
+ goto error_module;
+- if (codec->card->registered) {
++ /* only register after the bus probe finished; otherwise it's racy */
++ if (!codec->bus->bus_probing && codec->card->registered) {
+ err = snd_card_register(codec->card);
+ if (err < 0)
+ goto error_module;
+--- a/sound/pci/hda/hda_codec.h
++++ b/sound/pci/hda/hda_codec.h
+@@ -68,6 +68,7 @@ struct hda_bus {
+ unsigned int response_reset:1; /* controller was reset */
+ unsigned int in_reset:1; /* during reset operation */
+ unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
++ unsigned int bus_probing :1; /* during probing process */
+
+ int primary_dig_out_type; /* primary digital out PCM type */
+ unsigned int mixer_assigned; /* codec addr for mixer name */
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2315,6 +2315,7 @@ static int azx_probe_continue(struct azx
+ int dev = chip->dev_index;
+ int err;
+
++ to_hda_bus(bus)->bus_probing = 1;
+ hda->probe_continued = 1;
+
+ /* bind with i915 if needed */
+@@ -2410,6 +2411,7 @@ i915_power_fail:
+ if (err < 0)
+ hda->init_failed = 1;
+ complete_all(&hda->probe_wait);
++ to_hda_bus(bus)->bus_probing = 0;
+ return err;
+ }
+
--- /dev/null
+From 3bff2407fbd28fd55ad5b5cccd98fc0c9598f23b Mon Sep 17 00:00:00 2001
+From: Udo Eberhardt <udo.eberhardt@thesycon.de>
+Date: Tue, 5 Feb 2019 17:20:47 +0100
+Subject: ALSA: usb-audio: Add support for new T+A USB DAC
+
+From: Udo Eberhardt <udo.eberhardt@thesycon.de>
+
+commit 3bff2407fbd28fd55ad5b5cccd98fc0c9598f23b upstream.
+
+This patch adds the T+A VID to the generic check in order to enable
+native DSD support for T+A devices. This works with the new T+A USB
+DAC model SD3100HV and will also work with future devices which
+support the XMOS/Thesycon style DSD format.
+
+Signed-off-by: Udo Eberhardt <udo.eberhardt@thesycon.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/quirks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1448,6 +1448,7 @@ u64 snd_usb_interface_dsd_format_quirks(
+ case 0x20b1: /* XMOS based devices */
+ case 0x152a: /* Thesycon devices */
+ case 0x25ce: /* Mytek devices */
++ case 0x2ab6: /* T+A devices */
+ if (fp->dsd_raw)
+ return SNDRV_PCM_FMTBIT_DSD_U32_BE;
+ break;
--- /dev/null
+From 9509941e9c534920ccc4771ae70bd6cbbe79df1c Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Sat, 12 Jan 2019 02:39:05 +0100
+Subject: fuse: call pipe_buf_release() under pipe lock
+
+From: Jann Horn <jannh@google.com>
+
+commit 9509941e9c534920ccc4771ae70bd6cbbe79df1c upstream.
+
+Some of the pipe_buf_release() handlers seem to assume that the pipe is
+locked - in particular, anon_pipe_buf_release() accesses pipe->tmp_page
+without taking any extra locks. From a glance through the callers of
+pipe_buf_release(), it looks like FUSE is the only one that calls
+pipe_buf_release() without having the pipe locked.
+
+This bug should only lead to a memory leak, nothing terrible.
+
+Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -2032,8 +2032,10 @@ static ssize_t fuse_dev_splice_write(str
+
+ ret = fuse_dev_do_write(fud, &cs, len);
+
++ pipe_lock(pipe);
+ for (idx = 0; idx < nbuf; idx++)
+ pipe_buf_release(pipe, &bufs[idx]);
++ pipe_unlock(pipe);
+
+ out:
+ kvfree(bufs);
--- /dev/null
+From a2ebba824106dabe79937a9f29a875f837e1b6d4 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 16 Jan 2019 10:27:59 +0100
+Subject: fuse: decrement NR_WRITEBACK_TEMP on the right page
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit a2ebba824106dabe79937a9f29a875f837e1b6d4 upstream.
+
+NR_WRITEBACK_TEMP is accounted on the temporary page in the request, not
+the page cache page.
+
+Fixes: 8b284dc47291 ("fuse: writepages: handle same page rewrites")
+Cc: <stable@vger.kernel.org> # v3.13
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1778,7 +1778,7 @@ static bool fuse_writepage_in_flight(str
+ spin_unlock(&fc->lock);
+
+ dec_wb_stat(&bdi->wb, WB_WRITEBACK);
+- dec_node_page_state(page, NR_WRITEBACK_TEMP);
++ dec_node_page_state(new_req->pages[0], NR_WRITEBACK_TEMP);
+ wb_writeout_inc(&bdi->wb);
+ fuse_writepage_free(fc, new_req);
+ fuse_request_free(new_req);
--- /dev/null
+From 97e1532ef81acb31c30f9e75bf00306c33a77812 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 16 Jan 2019 10:27:59 +0100
+Subject: fuse: handle zero sized retrieve correctly
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 97e1532ef81acb31c30f9e75bf00306c33a77812 upstream.
+
+Dereferencing req->page_descs[0] will Oops if req->max_pages is zero.
+
+Reported-by: syzbot+c1e36d30ee3416289cc0@syzkaller.appspotmail.com
+Tested-by: syzbot+c1e36d30ee3416289cc0@syzkaller.appspotmail.com
+Fixes: b2430d7567a3 ("fuse: add per-page descriptor <offset, length> to fuse_req")
+Cc: <stable@vger.kernel.org> # v3.9
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -1698,7 +1698,6 @@ static int fuse_retrieve(struct fuse_con
+ req->in.h.nodeid = outarg->nodeid;
+ req->in.numargs = 2;
+ req->in.argpages = 1;
+- req->page_descs[0].offset = offset;
+ req->end = fuse_retrieve_end;
+
+ index = outarg->offset >> PAGE_SHIFT;
+@@ -1713,6 +1712,7 @@ static int fuse_retrieve(struct fuse_con
+
+ this_num = min_t(unsigned, num, PAGE_SIZE - offset);
+ req->pages[req->num_pages] = page;
++ req->page_descs[req->num_pages].offset = offset;
+ req->page_descs[req->num_pages].length = this_num;
+ req->num_pages++;
+
--- /dev/null
+From 13054abbaa4f1fd4e6f3b4b63439ec033b4c8035 Mon Sep 17 00:00:00 2001
+From: Vladis Dronov <vdronov@redhat.com>
+Date: Tue, 29 Jan 2019 11:58:35 +0100
+Subject: HID: debug: fix the ring buffer implementation
+
+From: Vladis Dronov <vdronov@redhat.com>
+
+commit 13054abbaa4f1fd4e6f3b4b63439ec033b4c8035 upstream.
+
+Ring buffer implementation in hid_debug_event() and hid_debug_events_read()
+is strange allowing lost or corrupted data. After commit 717adfdaf147
+("HID: debug: check length before copy_to_user()") it is possible to enter
+an infinite loop in hid_debug_events_read() by providing 0 as count, this
+locks up a system. Fix this by rewriting the ring buffer implementation
+with kfifo and simplify the code.
+
+This fixes CVE-2019-3819.
+
+v2: fix an execution logic and add a comment
+v3: use __set_current_state() instead of set_current_state()
+
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=1669187
+Cc: stable@vger.kernel.org # v4.18+
+Fixes: cd667ce24796 ("HID: use debugfs for events/reports dumping")
+Fixes: 717adfdaf147 ("HID: debug: check length before copy_to_user()")
+Signed-off-by: Vladis Dronov <vdronov@redhat.com>
+Reviewed-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-debug.c | 120 ++++++++++++++++++----------------------------
+ include/linux/hid-debug.h | 9 +--
+ 2 files changed, 51 insertions(+), 78 deletions(-)
+
+--- a/drivers/hid/hid-debug.c
++++ b/drivers/hid/hid-debug.c
+@@ -30,6 +30,7 @@
+
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
++#include <linux/kfifo.h>
+ #include <linux/sched/signal.h>
+ #include <linux/export.h>
+ #include <linux/slab.h>
+@@ -661,17 +662,12 @@ EXPORT_SYMBOL_GPL(hid_dump_device);
+ /* enqueue string to 'events' ring buffer */
+ void hid_debug_event(struct hid_device *hdev, char *buf)
+ {
+- unsigned i;
+ struct hid_debug_list *list;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdev->debug_list_lock, flags);
+- list_for_each_entry(list, &hdev->debug_list, node) {
+- for (i = 0; buf[i]; i++)
+- list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] =
+- buf[i];
+- list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
+- }
++ list_for_each_entry(list, &hdev->debug_list, node)
++ kfifo_in(&list->hid_debug_fifo, buf, strlen(buf));
+ spin_unlock_irqrestore(&hdev->debug_list_lock, flags);
+
+ wake_up_interruptible(&hdev->debug_wait);
+@@ -722,8 +718,7 @@ void hid_dump_input(struct hid_device *h
+ hid_debug_event(hdev, buf);
+
+ kfree(buf);
+- wake_up_interruptible(&hdev->debug_wait);
+-
++ wake_up_interruptible(&hdev->debug_wait);
+ }
+ EXPORT_SYMBOL_GPL(hid_dump_input);
+
+@@ -1088,8 +1083,8 @@ static int hid_debug_events_open(struct
+ goto out;
+ }
+
+- if (!(list->hid_debug_buf = kzalloc(HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
+- err = -ENOMEM;
++ err = kfifo_alloc(&list->hid_debug_fifo, HID_DEBUG_FIFOSIZE, GFP_KERNEL);
++ if (err) {
+ kfree(list);
+ goto out;
+ }
+@@ -1109,77 +1104,57 @@ static ssize_t hid_debug_events_read(str
+ size_t count, loff_t *ppos)
+ {
+ struct hid_debug_list *list = file->private_data;
+- int ret = 0, len;
++ int ret = 0, copied;
+ DECLARE_WAITQUEUE(wait, current);
+
+ mutex_lock(&list->read_mutex);
+- while (ret == 0) {
+- if (list->head == list->tail) {
+- add_wait_queue(&list->hdev->debug_wait, &wait);
+- set_current_state(TASK_INTERRUPTIBLE);
+-
+- while (list->head == list->tail) {
+- if (file->f_flags & O_NONBLOCK) {
+- ret = -EAGAIN;
+- break;
+- }
+- if (signal_pending(current)) {
+- ret = -ERESTARTSYS;
+- break;
+- }
+-
+- if (!list->hdev || !list->hdev->debug) {
+- ret = -EIO;
+- set_current_state(TASK_RUNNING);
+- goto out;
+- }
+-
+- /* allow O_NONBLOCK from other threads */
+- mutex_unlock(&list->read_mutex);
+- schedule();
+- mutex_lock(&list->read_mutex);
+- set_current_state(TASK_INTERRUPTIBLE);
++ if (kfifo_is_empty(&list->hid_debug_fifo)) {
++ add_wait_queue(&list->hdev->debug_wait, &wait);
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ while (kfifo_is_empty(&list->hid_debug_fifo)) {
++ if (file->f_flags & O_NONBLOCK) {
++ ret = -EAGAIN;
++ break;
+ }
+
+- set_current_state(TASK_RUNNING);
+- remove_wait_queue(&list->hdev->debug_wait, &wait);
+- }
+-
+- if (ret)
+- goto out;
+-
+- /* pass the ringbuffer contents to userspace */
+-copy_rest:
+- if (list->tail == list->head)
+- goto out;
+- if (list->tail > list->head) {
+- len = list->tail - list->head;
+- if (len > count)
+- len = count;
+-
+- if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
+- ret = -EFAULT;
+- goto out;
++ if (signal_pending(current)) {
++ ret = -ERESTARTSYS;
++ break;
+ }
+- ret += len;
+- list->head += len;
+- } else {
+- len = HID_DEBUG_BUFSIZE - list->head;
+- if (len > count)
+- len = count;
+
+- if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
+- ret = -EFAULT;
++ /* if list->hdev is NULL we cannot remove_wait_queue().
++ * if list->hdev->debug is 0 then hid_debug_unregister()
++ * was already called and list->hdev is being destroyed.
++ * if we add remove_wait_queue() here we can hit a race.
++ */
++ if (!list->hdev || !list->hdev->debug) {
++ ret = -EIO;
++ set_current_state(TASK_RUNNING);
+ goto out;
+ }
+- list->head = 0;
+- ret += len;
+- count -= len;
+- if (count > 0)
+- goto copy_rest;
++
++ /* allow O_NONBLOCK from other threads */
++ mutex_unlock(&list->read_mutex);
++ schedule();
++ mutex_lock(&list->read_mutex);
++ set_current_state(TASK_INTERRUPTIBLE);
+ }
+
++ __set_current_state(TASK_RUNNING);
++ remove_wait_queue(&list->hdev->debug_wait, &wait);
++
++ if (ret)
++ goto out;
+ }
++
++ /* pass the fifo content to userspace, locking is not needed with only
++ * one concurrent reader and one concurrent writer
++ */
++ ret = kfifo_to_user(&list->hid_debug_fifo, buffer, count, &copied);
++ if (ret)
++ goto out;
++ ret = copied;
+ out:
+ mutex_unlock(&list->read_mutex);
+ return ret;
+@@ -1190,7 +1165,7 @@ static __poll_t hid_debug_events_poll(st
+ struct hid_debug_list *list = file->private_data;
+
+ poll_wait(file, &list->hdev->debug_wait, wait);
+- if (list->head != list->tail)
++ if (!kfifo_is_empty(&list->hid_debug_fifo))
+ return EPOLLIN | EPOLLRDNORM;
+ if (!list->hdev->debug)
+ return EPOLLERR | EPOLLHUP;
+@@ -1205,7 +1180,7 @@ static int hid_debug_events_release(stru
+ spin_lock_irqsave(&list->hdev->debug_list_lock, flags);
+ list_del(&list->node);
+ spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);
+- kfree(list->hid_debug_buf);
++ kfifo_free(&list->hid_debug_fifo);
+ kfree(list);
+
+ return 0;
+@@ -1256,4 +1231,3 @@ void hid_debug_exit(void)
+ {
+ debugfs_remove_recursive(hid_debug_root);
+ }
+-
+--- a/include/linux/hid-debug.h
++++ b/include/linux/hid-debug.h
+@@ -24,7 +24,10 @@
+
+ #ifdef CONFIG_DEBUG_FS
+
++#include <linux/kfifo.h>
++
+ #define HID_DEBUG_BUFSIZE 512
++#define HID_DEBUG_FIFOSIZE 512
+
+ void hid_dump_input(struct hid_device *, struct hid_usage *, __s32);
+ void hid_dump_report(struct hid_device *, int , u8 *, int);
+@@ -37,11 +40,8 @@ void hid_debug_init(void);
+ void hid_debug_exit(void);
+ void hid_debug_event(struct hid_device *, char *);
+
+-
+ struct hid_debug_list {
+- char *hid_debug_buf;
+- int head;
+- int tail;
++ DECLARE_KFIFO_PTR(hid_debug_fifo, char);
+ struct fasync_struct *fasync;
+ struct hid_device *hdev;
+ struct list_head node;
+@@ -64,4 +64,3 @@ struct hid_debug_list {
+ #endif
+
+ #endif
+-
skge-potential-memory-corruption-in-skge_get_regs.patch
virtio_net-account-for-tx-bytes-and-packets-on-sending-xdp_frames.patch
net-mlx5e-fpga-fix-innova-ipsec-tx-offload-data-path-performance.patch
+xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cached.patch
+alsa-compress-fix-stop-handling-on-compressed-capture-streams.patch
+alsa-usb-audio-add-support-for-new-t-a-usb-dac.patch
+alsa-hda-serialize-codec-registrations.patch
+alsa-hda-realtek-fix-lose-hp_pins-for-disable-auto-mute.patch
+alsa-hda-realtek-use-a-common-helper-for-hp-pin-reference.patch
+alsa-hda-realtek-headset-microphone-support-for-system76-darp5.patch
+fuse-call-pipe_buf_release-under-pipe-lock.patch
+fuse-decrement-nr_writeback_temp-on-the-right-page.patch
+fuse-handle-zero-sized-retrieve-correctly.patch
+hid-debug-fix-the-ring-buffer-implementation.patch
--- /dev/null
+From aa6ee4ab69293969867ab09b57546d226ace3d7a Mon Sep 17 00:00:00 2001
+From: Brian Foster <bfoster@redhat.com>
+Date: Fri, 1 Feb 2019 09:36:36 -0800
+Subject: xfs: eof trim writeback mapping as soon as it is cached
+
+From: Brian Foster <bfoster@redhat.com>
+
+commit aa6ee4ab69293969867ab09b57546d226ace3d7a upstream.
+
+The cached writeback mapping is EOF trimmed to try and avoid races
+between post-eof block management and writeback that result in
+sending cached data to a stale location. The cached mapping is
+currently trimmed on the validation check, which leaves a race
+window between the time the mapping is cached and when it is trimmed
+against the current inode size.
+
+For example, if a new mapping is cached by delalloc conversion on a
+blocksize == page size fs, we could cycle various locks, perform
+memory allocations, etc. in the writeback codepath before the
+associated mapping is eventually trimmed to i_size. This leaves
+enough time for a post-eof truncate and file append before the
+cached mapping is trimmed. The former event essentially invalidates
+a range of the cached mapping and the latter bumps the inode size
+such the trim on the next writepage event won't trim all of the
+invalid blocks. fstest generic/464 reproduces this scenario
+occasionally and causes a lost writeback and stale delalloc blocks
+warning on inode inactivation.
+
+To work around this problem, trim the cached writeback mapping as
+soon as it is cached in addition to on subsequent validation checks.
+This is a minor tweak to tighten the race window as much as possible
+until a proper invalidation mechanism is available.
+
+Fixes: 40214d128e07 ("xfs: trim writepage mapping to within eof")
+Cc: <stable@vger.kernel.org> # v4.14+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_aops.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -449,6 +449,7 @@ xfs_map_blocks(
+ }
+
+ wpc->imap = imap;
++ xfs_trim_extent_eof(&wpc->imap, ip);
+ trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap);
+ return 0;
+ allocate_blocks:
+@@ -459,6 +460,7 @@ allocate_blocks:
+ ASSERT(whichfork == XFS_COW_FORK || cow_fsb == NULLFILEOFF ||
+ imap.br_startoff + imap.br_blockcount <= cow_fsb);
+ wpc->imap = imap;
++ xfs_trim_extent_eof(&wpc->imap, ip);
+ trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap);
+ return 0;
+ }