--- /dev/null
+From dd7b836d6bc935df95c826f69ff4d051f5561604 Mon Sep 17 00:00:00 2001
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Date: Fri, 12 Mar 2021 18:34:07 +0900
+Subject: ALSA: dice: fix null pointer dereference when node is disconnected
+
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+
+commit dd7b836d6bc935df95c826f69ff4d051f5561604 upstream.
+
+When node is removed from IEEE 1394 bus, any transaction fails to the node.
+In the case, ALSA dice driver doesn't stop isochronous contexts even if
+they are running. As a result, null pointer dereference occurs in callback
+from the running context.
+
+This commit fixes the bug to release isochronous contexts always.
+
+Cc: <stable@vger.kernel.org> # v5.4 or later
+Fixes: e9f21129b8d8 ("ALSA: dice: support AMDTP domain")
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Link: https://lore.kernel.org/r/20210312093407.23437-1-o-takashi@sakamocchi.jp
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/firewire/dice/dice-stream.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/sound/firewire/dice/dice-stream.c
++++ b/sound/firewire/dice/dice-stream.c
+@@ -493,11 +493,10 @@ void snd_dice_stream_stop_duplex(struct
+ struct reg_params tx_params, rx_params;
+
+ if (dice->substreams_counter == 0) {
+- if (get_register_params(dice, &tx_params, &rx_params) >= 0) {
+- amdtp_domain_stop(&dice->domain);
++ if (get_register_params(dice, &tx_params, &rx_params) >= 0)
+ finish_session(dice, &tx_params, &rx_params);
+- }
+
++ amdtp_domain_stop(&dice->domain);
+ release_resources(dice);
+ }
+ }
--- /dev/null
+From 2bf44e0ee95f39cc54ea1b942f0a027e0181ca4e Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Fri, 12 Mar 2021 12:14:08 +0800
+Subject: ALSA: hda: generic: Fix the micmute led init state
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit 2bf44e0ee95f39cc54ea1b942f0a027e0181ca4e upstream.
+
+Recently we found the micmute led init state is not correct after
+freshly installing the ubuntu linux on a Lenovo AIO machine. The
+internal mic is not muted, but the micmute led is on and led mode is
+'follow mute'. If we mute internal mic, the led is keeping on, then
+unmute the internal mic, the led is off. And from then on, the
+micmute led will work correctly.
+
+So the micmute led init state is not correct. The led is controlled
+by codec gpio (ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), in the
+patch_realtek, the gpio data is set to 0x4 initially and the led is
+on with this data. In the hda_generic, the led_value is set to
+0 initially, suppose users set the 'capture switch' to on from
+user space and the micmute led should change to be off with this
+operation, but the check "if (val == spec->micmute_led.led_value)" in
+the call_micmute_led_update() will skip the led setting.
+
+To guarantee the led state will be set by the 1st time of changing
+"Capture Switch", set -1 to the init led_value.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Link: https://lore.kernel.org/r/20210312041408.3776-1-hui.wang@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/hda_generic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -4065,7 +4065,7 @@ static int add_micmute_led_hook(struct h
+
+ spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE;
+ spec->micmute_led.capture = 0;
+- spec->micmute_led.led_value = 0;
++ spec->micmute_led.led_value = -1;
+ spec->micmute_led.old_hook = spec->cap_sync_hook;
+ spec->cap_sync_hook = update_micmute_led;
+ if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl))
--- /dev/null
+From e1c86210fe27428399643861b81b080eccd79f87 Mon Sep 17 00:00:00 2001
+From: Xiaoliang Yu <yxl_22@outlook.com>
+Date: Sat, 13 Mar 2021 07:54:53 +0800
+Subject: ALSA: hda/realtek: Apply headset-mic quirks for Xiaomi Redmibook Air
+
+From: Xiaoliang Yu <yxl_22@outlook.com>
+
+commit e1c86210fe27428399643861b81b080eccd79f87 upstream.
+
+There is another fix for headset-mic problem on Redmibook (1d72:1602),
+it also works on Redmibook Air (1d72:1947), which has the same issue.
+
+Signed-off-by: Xiaoliang Yu <yxl_22@outlook.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/TYBP286MB02856DC016849DEA0F9B6A37EE6F9@TYBP286MB0285.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8244,6 +8244,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
++ SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
+ SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
+ SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
--- /dev/null
+From b95bc12e0412d14d5fc764f0b82631c7bcaf1959 Mon Sep 17 00:00:00 2001
+From: Xiaoliang Yu <yxl_22@outlook.com>
+Date: Tue, 16 Mar 2021 00:49:00 +0800
+Subject: ALSA: hda/realtek: apply pin quirk for XiaomiNotebook Pro
+
+From: Xiaoliang Yu <yxl_22@outlook.com>
+
+commit b95bc12e0412d14d5fc764f0b82631c7bcaf1959 upstream.
+
+Built-in microphone and combojack on Xiaomi Notebook Pro (1d72:1701) needs
+to be fixed, the existing quirk for Dell works well on that machine.
+
+Signed-off-by: Xiaoliang Yu <yxl_22@outlook.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/OS0P286MB02749B9E13920E6899902CD8EE6C9@OS0P286MB0274.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8242,6 +8242,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
+ SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
+ SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
++ SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
--- /dev/null
+From e7d66cf799390166e90f9a5715f2eede4fe06d51 Mon Sep 17 00:00:00 2001
+From: Jeremy Szu <jeremy.szu@canonical.com>
+Date: Tue, 16 Mar 2021 15:46:24 +0800
+Subject: ALSA: hda/realtek: fix mute/micmute LEDs for HP 440 G8
+
+From: Jeremy Szu <jeremy.szu@canonical.com>
+
+commit e7d66cf799390166e90f9a5715f2eede4fe06d51 upstream.
+
+The HP EliteBook 840 G8 Notebook PC is using ALC236 codec which is
+using 0x02 to control mute LED and 0x01 to control micmute LED.
+Therefore, add a quirk to make it works.
+
+Signed-off-by: Jeremy Szu <jeremy.szu@canonical.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210316074626.79895-1-jeremy.szu@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4225,6 +4225,12 @@ static void alc_fixup_hp_gpio_led(struct
+ }
+ }
+
++static void alc236_fixup_hp_gpio_led(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ alc_fixup_hp_gpio_led(codec, action, 0x02, 0x01);
++}
++
+ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+ {
+@@ -6381,6 +6387,7 @@ enum {
+ ALC294_FIXUP_ASUS_GX502_VERBS,
+ ALC285_FIXUP_HP_GPIO_LED,
+ ALC285_FIXUP_HP_MUTE_LED,
++ ALC236_FIXUP_HP_GPIO_LED,
+ ALC236_FIXUP_HP_MUTE_LED,
+ ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
+ ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
+@@ -7616,6 +7623,10 @@ static const struct hda_fixup alc269_fix
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc285_fixup_hp_mute_led,
+ },
++ [ALC236_FIXUP_HP_GPIO_LED] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc236_fixup_hp_gpio_led,
++ },
+ [ALC236_FIXUP_HP_MUTE_LED] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc236_fixup_hp_mute_led,
+@@ -8045,6 +8056,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x103c, 0x8783, "HP ZBook Fury 15 G7 Mobile Workstation",
+ ALC285_FIXUP_HP_GPIO_AMP_INIT),
+ SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
--- /dev/null
+From ca6883393f0fa7f13ec8b860dbcef423a759c4a2 Mon Sep 17 00:00:00 2001
+From: Jeremy Szu <jeremy.szu@canonical.com>
+Date: Tue, 16 Mar 2021 14:54:50 +0800
+Subject: ALSA: hda/realtek: fix mute/micmute LEDs for HP 840 G8
+
+From: Jeremy Szu <jeremy.szu@canonical.com>
+
+commit ca6883393f0fa7f13ec8b860dbcef423a759c4a2 upstream.
+
+The HP EliteBook 840 G8 Notebook PC is using ALC285 codec which is
+using 0x04 to control mute LED and 0x01 to control micmute LED.
+Therefore, add a quirk to make it works.
+
+Signed-off-by: Jeremy Szu <jeremy.szu@canonical.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210316065452.75659-1-jeremy.szu@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8048,6 +8048,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
++ SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
+ SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
--- /dev/null
+From 53b861bec737c189cc14ec3b5785d0f13445ac0f Mon Sep 17 00:00:00 2001
+From: Jeremy Szu <jeremy.szu@canonical.com>
+Date: Tue, 16 Mar 2021 17:42:35 +0800
+Subject: ALSA: hda/realtek: fix mute/micmute LEDs for HP 850 G8
+
+From: Jeremy Szu <jeremy.szu@canonical.com>
+
+commit 53b861bec737c189cc14ec3b5785d0f13445ac0f upstream.
+
+The HP EliteBook 850 G8 Notebook PC is using ALC285 codec which is
+using 0x04 to control mute LED and 0x01 to control micmute LED.
+Therefore, add a quirk to make it works.
+
+Signed-off-by: Jeremy Szu <jeremy.szu@canonical.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210316094236.89028-1-jeremy.szu@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8060,6 +8060,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
++ SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
--- /dev/null
+From 4ec5b96775a88dd9b1c3ba1d23c43c478cab95a2 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Wed, 24 Feb 2021 14:57:51 +0800
+Subject: ASoC: ak4458: Add MODULE_DEVICE_TABLE
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 4ec5b96775a88dd9b1c3ba1d23c43c478cab95a2 upstream.
+
+Add missed MODULE_DEVICE_TABLE for the driver can be loaded
+automatically at boot.
+
+Fixes: 08660086eff9 ("ASoC: ak4458: Add support for AK4458 DAC driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1614149872-25510-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/ak4458.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/soc/codecs/ak4458.c
++++ b/sound/soc/codecs/ak4458.c
+@@ -812,6 +812,7 @@ static const struct of_device_id ak4458_
+ { .compatible = "asahi-kasei,ak4497", .data = &ak4497_drvdata},
+ { },
+ };
++MODULE_DEVICE_TABLE(of, ak4458_of_match);
+
+ static struct i2c_driver ak4458_i2c_driver = {
+ .driver = {
--- /dev/null
+From 80cffd2468ddb850e678f17841fc356930b2304a Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Wed, 24 Feb 2021 14:57:52 +0800
+Subject: ASoC: ak5558: Add MODULE_DEVICE_TABLE
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 80cffd2468ddb850e678f17841fc356930b2304a upstream.
+
+Add missed MODULE_DEVICE_TABLE for the driver can be loaded
+automatically at boot.
+
+Fixes: 920884777480 ("ASoC: ak5558: Add support for AK5558 ADC driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1614149872-25510-2-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/ak5558.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/soc/codecs/ak5558.c
++++ b/sound/soc/codecs/ak5558.c
+@@ -419,6 +419,7 @@ static const struct of_device_id ak5558_
+ { .compatible = "asahi-kasei,ak5558"},
+ { }
+ };
++MODULE_DEVICE_TABLE(of, ak5558_i2c_dt_ids);
+
+ static struct i2c_driver ak5558_i2c_driver = {
+ .driver = {
--- /dev/null
+From 0cab893f409c53634d0d818fa414641cbcdb0dab Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Fri, 19 Mar 2021 15:47:25 +0100
+Subject: Revert "PM: runtime: Update device status before letting suppliers suspend"
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 0cab893f409c53634d0d818fa414641cbcdb0dab upstream.
+
+Revert commit 44cc89f76464 ("PM: runtime: Update device status
+before letting suppliers suspend") that introduced a race condition
+into __rpm_callback() which allowed a concurrent rpm_resume() to
+run and resume the device prematurely after its status had been
+changed to RPM_SUSPENDED by __rpm_callback().
+
+Fixes: 44cc89f76464 ("PM: runtime: Update device status before letting suppliers suspend")
+Link: https://lore.kernel.org/linux-pm/24dfb6fc-5d54-6ee2-9195-26428b7ecf8a@intel.com/
+Reported-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: 4.10+ <stable@vger.kernel.org> # 4.10+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/power/runtime.c | 62 +++++++++++++++++--------------------------
+ 1 file changed, 25 insertions(+), 37 deletions(-)
+
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -325,22 +325,22 @@ static void rpm_put_suppliers(struct dev
+ static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
+ __releases(&dev->power.lock) __acquires(&dev->power.lock)
+ {
+- bool use_links = dev->power.links_count > 0;
+- bool get = false;
+ int retval, idx;
+- bool put;
++ bool use_links = dev->power.links_count > 0;
+
+ if (dev->power.irq_safe) {
+ spin_unlock(&dev->power.lock);
+- } else if (!use_links) {
+- spin_unlock_irq(&dev->power.lock);
+ } else {
+- get = dev->power.runtime_status == RPM_RESUMING;
+-
+ spin_unlock_irq(&dev->power.lock);
+
+- /* Resume suppliers if necessary. */
+- if (get) {
++ /*
++ * Resume suppliers if necessary.
++ *
++ * The device's runtime PM status cannot change until this
++ * routine returns, so it is safe to read the status outside of
++ * the lock.
++ */
++ if (use_links && dev->power.runtime_status == RPM_RESUMING) {
+ idx = device_links_read_lock();
+
+ retval = rpm_get_suppliers(dev);
+@@ -355,36 +355,24 @@ static int __rpm_callback(int (*cb)(stru
+
+ if (dev->power.irq_safe) {
+ spin_lock(&dev->power.lock);
+- return retval;
+- }
+-
+- spin_lock_irq(&dev->power.lock);
+-
+- if (!use_links)
+- return retval;
+-
+- /*
+- * If the device is suspending and the callback has returned success,
+- * drop the usage counters of the suppliers that have been reference
+- * counted on its resume.
+- *
+- * Do that if the resume fails too.
+- */
+- put = dev->power.runtime_status == RPM_SUSPENDING && !retval;
+- if (put)
+- __update_runtime_status(dev, RPM_SUSPENDED);
+- else
+- put = get && retval;
+-
+- if (put) {
+- spin_unlock_irq(&dev->power.lock);
+-
+- idx = device_links_read_lock();
++ } else {
++ /*
++ * If the device is suspending and the callback has returned
++ * success, drop the usage counters of the suppliers that have
++ * been reference counted on its resume.
++ *
++ * Do that if resume fails too.
++ */
++ if (use_links
++ && ((dev->power.runtime_status == RPM_SUSPENDING && !retval)
++ || (dev->power.runtime_status == RPM_RESUMING && retval))) {
++ idx = device_links_read_lock();
+
+-fail:
+- rpm_put_suppliers(dev);
++ fail:
++ rpm_put_suppliers(dev);
+
+- device_links_read_unlock(idx);
++ device_links_read_unlock(idx);
++ }
+
+ spin_lock_irq(&dev->power.lock);
+ }
--- /dev/null
+From 0b13525c20febcfecccf6fc1db5969727401317d Mon Sep 17 00:00:00 2001
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+Date: Wed, 10 Mar 2021 13:46:26 +0100
+Subject: s390/pci: fix leak of PCI device structure
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+commit 0b13525c20febcfecccf6fc1db5969727401317d upstream.
+
+In commit 05bc1be6db4b2 ("s390/pci: create zPCI bus") we removed the
+pci_dev_put() call matching the earlier pci_get_slot() done as part of
+__zpci_event_availability(). This was based on the wrong understanding
+that the device_put() done as part of pci_destroy_device() would counter
+the pci_get_slot() when it only counters the initial reference. This
+same understanding and existing bad example also lead to not doing
+a pci_dev_put() in zpci_remove_device().
+
+Since releasing the PCI devices, unlike releasing the PCI slot, does not
+print any debug message for testing I added one in pci_release_dev().
+This revealed that we are indeed leaking the PCI device on PCI
+hotunplug. Further testing also revealed another missing pci_dev_put() in
+disable_slot().
+
+Fix this by adding the missing pci_dev_put() in disable_slot() and fix
+zpci_remove_device() with the correct pci_dev_put() calls. Also instead
+of calling pci_get_slot() in __zpci_event_availability() to determine if
+a PCI device is registered and then doing the same again in
+zpci_remove_device() do this once in zpci_remove_device() which makes
+sure that the pdev in __zpci_event_availability() is only used for the
+result of pci_scan_single_device() which does not need a reference count
+decremnt as its ownership goes to the PCI bus.
+
+Also move the check if zdev->zbus->bus is set into zpci_remove_device()
+since it may be that we're removing a device with devfn != 0 which never
+had a PCI bus. So we can still set the pdev->error_state to indicate
+that the device is not usable anymore, add a flag to set the error state.
+
+Fixes: 05bc1be6db4b2 ("s390/pci: create zPCI bus")
+Cc: <stable@vger.kernel.org> # 5.8+: e1bff843cde6 s390/pci: remove superfluous zdev->zbus check
+Cc: <stable@vger.kernel.org> # 5.8+: ba764dd703fe s390/pci: refactor zpci_create_device()
+Cc: <stable@vger.kernel.org> # 5.8+
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/pci.h | 2 +-
+ arch/s390/pci/pci.c | 28 ++++++++++++++++++++++++----
+ arch/s390/pci/pci_event.c | 18 ++++++------------
+ drivers/pci/hotplug/s390_pci_hpc.c | 3 ++-
+ 4 files changed, 33 insertions(+), 18 deletions(-)
+
+--- a/arch/s390/include/asm/pci.h
++++ b/arch/s390/include/asm/pci.h
+@@ -202,7 +202,7 @@ extern unsigned int s390_pci_no_rid;
+ ----------------------------------------------------------------------------- */
+ /* Base stuff */
+ int zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
+-void zpci_remove_device(struct zpci_dev *zdev);
++void zpci_remove_device(struct zpci_dev *zdev, bool set_error);
+ int zpci_enable_device(struct zpci_dev *);
+ int zpci_disable_device(struct zpci_dev *);
+ int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
+--- a/arch/s390/pci/pci.c
++++ b/arch/s390/pci/pci.c
+@@ -682,16 +682,36 @@ int zpci_disable_device(struct zpci_dev
+ }
+ EXPORT_SYMBOL_GPL(zpci_disable_device);
+
+-void zpci_remove_device(struct zpci_dev *zdev)
++/* zpci_remove_device - Removes the given zdev from the PCI core
++ * @zdev: the zdev to be removed from the PCI core
++ * @set_error: if true the device's error state is set to permanent failure
++ *
++ * Sets a zPCI device to a configured but offline state; the zPCI
++ * device is still accessible through its hotplug slot and the zPCI
++ * API but is removed from the common code PCI bus, making it
++ * no longer available to drivers.
++ */
++void zpci_remove_device(struct zpci_dev *zdev, bool set_error)
+ {
+ struct zpci_bus *zbus = zdev->zbus;
+ struct pci_dev *pdev;
+
++ if (!zdev->zbus->bus)
++ return;
++
+ pdev = pci_get_slot(zbus->bus, zdev->devfn);
+ if (pdev) {
+- if (pdev->is_virtfn)
+- return zpci_iov_remove_virtfn(pdev, zdev->vfn);
++ if (set_error)
++ pdev->error_state = pci_channel_io_perm_failure;
++ if (pdev->is_virtfn) {
++ zpci_iov_remove_virtfn(pdev, zdev->vfn);
++ /* balance pci_get_slot */
++ pci_dev_put(pdev);
++ return;
++ }
+ pci_stop_and_remove_bus_device_locked(pdev);
++ /* balance pci_get_slot */
++ pci_dev_put(pdev);
+ }
+ }
+
+@@ -765,7 +785,7 @@ void zpci_release_device(struct kref *kr
+ struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
+
+ if (zdev->zbus->bus)
+- zpci_remove_device(zdev);
++ zpci_remove_device(zdev, false);
+
+ switch (zdev->state) {
+ case ZPCI_FN_STATE_ONLINE:
+--- a/arch/s390/pci/pci_event.c
++++ b/arch/s390/pci/pci_event.c
+@@ -76,13 +76,10 @@ void zpci_event_error(void *data)
+ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
+ {
+ struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+- struct pci_dev *pdev = NULL;
+ enum zpci_state state;
++ struct pci_dev *pdev;
+ int ret;
+
+- if (zdev && zdev->zbus->bus)
+- pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
+-
+ zpci_err("avail CCDF:\n");
+ zpci_err_hex(ccdf, sizeof(*ccdf));
+
+@@ -124,8 +121,7 @@ static void __zpci_event_availability(st
+ case 0x0303: /* Deconfiguration requested */
+ if (!zdev)
+ break;
+- if (pdev)
+- zpci_remove_device(zdev);
++ zpci_remove_device(zdev, false);
+
+ ret = zpci_disable_device(zdev);
+ if (ret)
+@@ -140,12 +136,10 @@ static void __zpci_event_availability(st
+ case 0x0304: /* Configured -> Standby|Reserved */
+ if (!zdev)
+ break;
+- if (pdev) {
+- /* Give the driver a hint that the function is
+- * already unusable. */
+- pdev->error_state = pci_channel_io_perm_failure;
+- zpci_remove_device(zdev);
+- }
++ /* Give the driver a hint that the function is
++ * already unusable.
++ */
++ zpci_remove_device(zdev, true);
+
+ zdev->fh = ccdf->fh;
+ zpci_disable_device(zdev);
+--- a/drivers/pci/hotplug/s390_pci_hpc.c
++++ b/drivers/pci/hotplug/s390_pci_hpc.c
+@@ -93,8 +93,9 @@ static int disable_slot(struct hotplug_s
+ pci_dev_put(pdev);
+ return -EBUSY;
+ }
++ pci_dev_put(pdev);
+
+- zpci_remove_device(zdev);
++ zpci_remove_device(zdev, false);
+
+ rc = zpci_disable_device(zdev);
+ if (rc)
--- /dev/null
+From ba764dd703feacb5a9c410d191af1b6cfbe96845 Mon Sep 17 00:00:00 2001
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+Date: Wed, 22 Jul 2020 16:53:54 +0200
+Subject: s390/pci: refactor zpci_create_device()
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+commit ba764dd703feacb5a9c410d191af1b6cfbe96845 upstream.
+
+Currently zpci_create_device() is only called in clp_add_pci_device()
+which allocates the memory for the struct zpci_dev being created. There
+is little separation of concerns as only both functions together can
+create a zpci_dev and the only CLP specific code in
+clp_add_pci_device() is a call to clp_query_pci_fn().
+
+Improve this by removing clp_add_pci_device() and refactor
+zpci_create_device() such that it alone creates and initializes the
+zpci_dev given the FID and Function Handle. For this we need to make
+clp_query_pci_fn() non-static. While at it remove the function handle
+parameter since we can just take that from the zpci_dev. Also move
+adding to the zpci_list to after the zdev has been fully created which
+eliminates a window where a partially initialized zdev can be found by
+get_zdev_by_fid().
+
+Acked-by: Pierre Morel <pmorel@linux.ibm.com>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/pci.h | 4 +--
+ arch/s390/pci/pci.c | 57 +++++++++++++++++++++++++++++++-------------
+ arch/s390/pci/pci_clp.c | 40 ++----------------------------
+ arch/s390/pci/pci_event.c | 4 +--
+ 4 files changed, 48 insertions(+), 57 deletions(-)
+
+--- a/arch/s390/include/asm/pci.h
++++ b/arch/s390/include/asm/pci.h
+@@ -201,7 +201,7 @@ extern unsigned int s390_pci_no_rid;
+ Prototypes
+ ----------------------------------------------------------------------------- */
+ /* Base stuff */
+-int zpci_create_device(struct zpci_dev *);
++int zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
+ void zpci_remove_device(struct zpci_dev *zdev);
+ int zpci_enable_device(struct zpci_dev *);
+ int zpci_disable_device(struct zpci_dev *);
+@@ -212,7 +212,7 @@ void zpci_remove_reserved_devices(void);
+ /* CLP */
+ int clp_setup_writeback_mio(void);
+ int clp_scan_pci_devices(void);
+-int clp_add_pci_device(u32, u32, int);
++int clp_query_pci_fn(struct zpci_dev *zdev);
+ int clp_enable_fh(struct zpci_dev *, u8);
+ int clp_disable_fh(struct zpci_dev *);
+ int clp_get_state(u32 fid, enum zpci_state *state);
+--- a/arch/s390/pci/pci.c
++++ b/arch/s390/pci/pci.c
+@@ -695,43 +695,68 @@ void zpci_remove_device(struct zpci_dev
+ }
+ }
+
+-int zpci_create_device(struct zpci_dev *zdev)
++/**
++ * zpci_create_device() - Create a new zpci_dev and add it to the zbus
++ * @fid: Function ID of the device to be created
++ * @fh: Current Function Handle of the device to be created
++ * @state: Initial state after creation either Standby or Configured
++ *
++ * Creates a new zpci device and adds it to its, possibly newly created, zbus
++ * as well as zpci_list.
++ *
++ * Returns: 0 on success, an error value otherwise
++ */
++int zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
+ {
++ struct zpci_dev *zdev;
+ int rc;
+
+- kref_init(&zdev->kref);
++ zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, state);
++ zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
++ if (!zdev)
++ return -ENOMEM;
++
++ /* FID and Function Handle are the static/dynamic identifiers */
++ zdev->fid = fid;
++ zdev->fh = fh;
+
+- spin_lock(&zpci_list_lock);
+- list_add_tail(&zdev->entry, &zpci_list);
+- spin_unlock(&zpci_list_lock);
++ /* Query function properties and update zdev */
++ rc = clp_query_pci_fn(zdev);
++ if (rc)
++ goto error;
++ zdev->state = state;
++
++ kref_init(&zdev->kref);
++ mutex_init(&zdev->lock);
+
+ rc = zpci_init_iommu(zdev);
+ if (rc)
+- goto out;
++ goto error;
+
+- mutex_init(&zdev->lock);
+ if (zdev->state == ZPCI_FN_STATE_CONFIGURED) {
+ rc = zpci_enable_device(zdev);
+ if (rc)
+- goto out_destroy_iommu;
++ goto error_destroy_iommu;
+ }
+
+ rc = zpci_bus_device_register(zdev, &pci_root_ops);
+ if (rc)
+- goto out_disable;
++ goto error_disable;
++
++ spin_lock(&zpci_list_lock);
++ list_add_tail(&zdev->entry, &zpci_list);
++ spin_unlock(&zpci_list_lock);
+
+ return 0;
+
+-out_disable:
++error_disable:
+ if (zdev->state == ZPCI_FN_STATE_ONLINE)
+ zpci_disable_device(zdev);
+-
+-out_destroy_iommu:
++error_destroy_iommu:
+ zpci_destroy_iommu(zdev);
+-out:
+- spin_lock(&zpci_list_lock);
+- list_del(&zdev->entry);
+- spin_unlock(&zpci_list_lock);
++error:
++ zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc);
++ kfree(zdev);
+ return rc;
+ }
+
+--- a/arch/s390/pci/pci_clp.c
++++ b/arch/s390/pci/pci_clp.c
+@@ -181,7 +181,7 @@ static int clp_store_query_pci_fn(struct
+ return 0;
+ }
+
+-static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
++int clp_query_pci_fn(struct zpci_dev *zdev)
+ {
+ struct clp_req_rsp_query_pci *rrb;
+ int rc;
+@@ -194,7 +194,7 @@ static int clp_query_pci_fn(struct zpci_
+ rrb->request.hdr.len = sizeof(rrb->request);
+ rrb->request.hdr.cmd = CLP_QUERY_PCI_FN;
+ rrb->response.hdr.len = sizeof(rrb->response);
+- rrb->request.fh = fh;
++ rrb->request.fh = zdev->fh;
+
+ rc = clp_req(rrb, CLP_LPS_PCI);
+ if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
+@@ -212,40 +212,6 @@ out:
+ return rc;
+ }
+
+-int clp_add_pci_device(u32 fid, u32 fh, int configured)
+-{
+- struct zpci_dev *zdev;
+- int rc = -ENOMEM;
+-
+- zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured);
+- zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
+- if (!zdev)
+- goto error;
+-
+- zdev->fh = fh;
+- zdev->fid = fid;
+-
+- /* Query function properties and update zdev */
+- rc = clp_query_pci_fn(zdev, fh);
+- if (rc)
+- goto error;
+-
+- if (configured)
+- zdev->state = ZPCI_FN_STATE_CONFIGURED;
+- else
+- zdev->state = ZPCI_FN_STATE_STANDBY;
+-
+- rc = zpci_create_device(zdev);
+- if (rc)
+- goto error;
+- return 0;
+-
+-error:
+- zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc);
+- kfree(zdev);
+- return rc;
+-}
+-
+ static int clp_refresh_fh(u32 fid);
+ /*
+ * Enable/Disable a given PCI function and update its function handle if
+@@ -408,7 +374,7 @@ static void __clp_add(struct clp_fh_list
+
+ zdev = get_zdev_by_fid(entry->fid);
+ if (!zdev)
+- clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
++ zpci_create_device(entry->fid, entry->fh, entry->config_state);
+ }
+
+ int clp_scan_pci_devices(void)
+--- a/arch/s390/pci/pci_event.c
++++ b/arch/s390/pci/pci_event.c
+@@ -89,7 +89,7 @@ static void __zpci_event_availability(st
+ switch (ccdf->pec) {
+ case 0x0301: /* Reserved|Standby -> Configured */
+ if (!zdev) {
+- ret = clp_add_pci_device(ccdf->fid, ccdf->fh, 1);
++ zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED);
+ break;
+ }
+ /* the configuration request may be stale */
+@@ -116,7 +116,7 @@ static void __zpci_event_availability(st
+ break;
+ case 0x0302: /* Reserved -> Standby */
+ if (!zdev) {
+- clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
++ zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
+ break;
+ }
+ zdev->fh = ccdf->fh;
--- /dev/null
+From e1bff843cde62a45a287b7f9b4cd5e824e8e49e2 Mon Sep 17 00:00:00 2001
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+Date: Tue, 19 Jan 2021 08:49:37 +0100
+Subject: s390/pci: remove superfluous zdev->zbus check
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+commit e1bff843cde62a45a287b7f9b4cd5e824e8e49e2 upstream.
+
+Checking zdev->zbus for NULL in __zpci_event_availability() is
+superfluous as it can never be NULL at this point. While harmless this
+check causes smatch warnings because we later access zdev->zbus with
+only having checked zdev != NULL which is sufficient.
+
+The reason zdev->zbus can never be NULL is since with zdev != NULL given
+we know the zdev came from get_zdev_by_fid() and thus the zpci_list.
+Now on first glance at zpci_create_device() one may assume that there is
+a window where the zdev is in the list without a zdev, however this
+window can't overlap with __zpci_event_availability() as
+zpci_create_device() either runs on the same kthread as part of
+availability events, or during the initial CLP List PCI at which point
+the __zpci_event_availability() is not yet called as zPCI is not yet
+initialized.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/pci/pci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/pci/pci_event.c
++++ b/arch/s390/pci/pci_event.c
+@@ -80,7 +80,7 @@ static void __zpci_event_availability(st
+ enum zpci_state state;
+ int ret;
+
+- if (zdev && zdev->zbus && zdev->zbus->bus)
++ if (zdev && zdev->zbus->bus)
+ pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
+
+ zpci_err("avail CCDF:\n");
--- /dev/null
+From d54cb7d54877d529bc1e0e1f47a3dd082f73add3 Mon Sep 17 00:00:00 2001
+From: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Date: Wed, 10 Mar 2021 14:23:37 +0100
+Subject: s390/vtime: fix increased steal time accounting
+
+From: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+
+commit d54cb7d54877d529bc1e0e1f47a3dd082f73add3 upstream.
+
+Commit 152e9b8676c6e ("s390/vtime: steal time exponential moving average")
+inadvertently changed the input value for account_steal_time() from
+"cputime_to_nsecs(steal)" to just "steal", resulting in broken increased
+steal time accounting.
+
+Fix this by changing it back to "cputime_to_nsecs(steal)".
+
+Fixes: 152e9b8676c6e ("s390/vtime: steal time exponential moving average")
+Cc: <stable@vger.kernel.org> # 5.1
+Reported-by: Sabine Forkel <sabine.forkel@de.ibm.com>
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/vtime.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/kernel/vtime.c
++++ b/arch/s390/kernel/vtime.c
+@@ -217,7 +217,7 @@ void vtime_flush(struct task_struct *tsk
+ avg_steal = S390_lowcore.avg_steal_timer / 2;
+ if ((s64) steal > 0) {
+ S390_lowcore.steal_timer = 0;
+- account_steal_time(steal);
++ account_steal_time(cputime_to_nsecs(steal));
+ avg_steal += steal;
+ }
+ S390_lowcore.avg_steal_timer = avg_steal;
+asoc-ak4458-add-module_device_table.patch
+asoc-ak5558-add-module_device_table.patch
+spi-cadence-set-cqspi-to-the-driver_data-field-of-struct-device.patch
+alsa-dice-fix-null-pointer-dereference-when-node-is-disconnected.patch
+alsa-hda-realtek-apply-pin-quirk-for-xiaominotebook-pro.patch
+alsa-hda-generic-fix-the-micmute-led-init-state.patch
+alsa-hda-realtek-apply-headset-mic-quirks-for-xiaomi-redmibook-air.patch
+alsa-hda-realtek-fix-mute-micmute-leds-for-hp-840-g8.patch
+alsa-hda-realtek-fix-mute-micmute-leds-for-hp-440-g8.patch
+alsa-hda-realtek-fix-mute-micmute-leds-for-hp-850-g8.patch
+revert-pm-runtime-update-device-status-before-letting-suppliers-suspend.patch
+s390-vtime-fix-increased-steal-time-accounting.patch
+s390-pci-refactor-zpci_create_device.patch
+s390-pci-remove-superfluous-zdev-zbus-check.patch
+s390-pci-fix-leak-of-pci-device-structure.patch
+zonefs-fix-o_append-async-write-handling.patch
+zonefs-prevent-use-of-seq-files-as-swap-file.patch
+zonefs-fix-to-update-.i_wr_refcnt-correctly-in-zonefs_open_zone.patch
--- /dev/null
+From ea94191e584b146878f0b7fd4b767500d7aae870 Mon Sep 17 00:00:00 2001
+From: Meng Li <Meng.Li@windriver.com>
+Date: Thu, 11 Mar 2021 17:12:20 +0800
+Subject: spi: cadence: set cqspi to the driver_data field of struct device
+
+From: Meng Li <Meng.Li@windriver.com>
+
+commit ea94191e584b146878f0b7fd4b767500d7aae870 upstream.
+
+When initialize cadence qspi controller, it is need to set cqspi
+to the driver_data field of struct device, because it will be
+used in function cqspi_remove/suspend/resume(). Otherwise, there
+will be a crash trace as below when invoking these finctions.
+
+Fixes: 31fb632b5d43 ("spi: Move cadence-quadspi driver to drivers/spi/")
+Cc: stable@vger.kernel.org
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Link: https://lore.kernel.org/r/20210311091220.3615-1-Meng.Li@windriver.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-cadence-quadspi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1198,6 +1198,7 @@ static int cqspi_probe(struct platform_d
+ cqspi = spi_master_get_devdata(master);
+
+ cqspi->pdev = pdev;
++ platform_set_drvdata(pdev, cqspi);
+
+ /* Obtain configuration from OF. */
+ ret = cqspi_of_get_pdata(cqspi);
--- /dev/null
+From ebfd68cd0c1e81267c757332385cb96df30dacce Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <damien.lemoal@wdc.com>
+Date: Wed, 10 Mar 2021 15:20:28 +0900
+Subject: zonefs: Fix O_APPEND async write handling
+
+From: Damien Le Moal <damien.lemoal@wdc.com>
+
+commit ebfd68cd0c1e81267c757332385cb96df30dacce upstream.
+
+zonefs updates the size of a sequential zone file inode only on
+completion of direct writes. When executing asynchronous append writes
+(with a file open with O_APPEND or using RWF_APPEND), the use of the
+current inode size in generic_write_checks() to set an iocb offset thus
+leads to unaligned write if an application issues an append write
+operation with another write already being executed.
+
+Fix this problem by introducing zonefs_write_checks() as a modified
+version of generic_write_checks() using the file inode wp_offset for an
+append write iocb offset. Also introduce zonefs_write_check_limits() to
+replace generic_write_check_limits() call. This zonefs special helper
+makes sure that the maximum file limit used is the maximum size of the
+file being accessed.
+
+Since zonefs_write_checks() already truncates the iov_iter, the calls
+to iov_iter_truncate() in zonefs_file_dio_write() and
+zonefs_file_buffered_write() are removed.
+
+Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/zonefs/super.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 68 insertions(+), 10 deletions(-)
+
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -720,6 +720,68 @@ out_release:
+ }
+
+ /*
++ * Do not exceed the LFS limits nor the file zone size. If pos is under the
++ * limit it becomes a short access. If it exceeds the limit, return -EFBIG.
++ */
++static loff_t zonefs_write_check_limits(struct file *file, loff_t pos,
++ loff_t count)
++{
++ struct inode *inode = file_inode(file);
++ struct zonefs_inode_info *zi = ZONEFS_I(inode);
++ loff_t limit = rlimit(RLIMIT_FSIZE);
++ loff_t max_size = zi->i_max_size;
++
++ if (limit != RLIM_INFINITY) {
++ if (pos >= limit) {
++ send_sig(SIGXFSZ, current, 0);
++ return -EFBIG;
++ }
++ count = min(count, limit - pos);
++ }
++
++ if (!(file->f_flags & O_LARGEFILE))
++ max_size = min_t(loff_t, MAX_NON_LFS, max_size);
++
++ if (unlikely(pos >= max_size))
++ return -EFBIG;
++
++ return min(count, max_size - pos);
++}
++
++static ssize_t zonefs_write_checks(struct kiocb *iocb, struct iov_iter *from)
++{
++ struct file *file = iocb->ki_filp;
++ struct inode *inode = file_inode(file);
++ struct zonefs_inode_info *zi = ZONEFS_I(inode);
++ loff_t count;
++
++ if (IS_SWAPFILE(inode))
++ return -ETXTBSY;
++
++ if (!iov_iter_count(from))
++ return 0;
++
++ if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT))
++ return -EINVAL;
++
++ if (iocb->ki_flags & IOCB_APPEND) {
++ if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
++ return -EINVAL;
++ mutex_lock(&zi->i_truncate_mutex);
++ iocb->ki_pos = zi->i_wpoffset;
++ mutex_unlock(&zi->i_truncate_mutex);
++ }
++
++ count = zonefs_write_check_limits(file, iocb->ki_pos,
++ iov_iter_count(from));
++ if (count < 0)
++ return count;
++
++ iov_iter_truncate(from, count);
++ return iov_iter_count(from);
++}
++
++/*
+ * Handle direct writes. For sequential zone files, this is the only possible
+ * write path. For these files, check that the user is issuing writes
+ * sequentially from the end of the file. This code assumes that the block layer
+@@ -736,8 +798,7 @@ static ssize_t zonefs_file_dio_write(str
+ struct super_block *sb = inode->i_sb;
+ bool sync = is_sync_kiocb(iocb);
+ bool append = false;
+- size_t count;
+- ssize_t ret;
++ ssize_t ret, count;
+
+ /*
+ * For async direct IOs to sequential zone files, refuse IOCB_NOWAIT
+@@ -755,12 +816,11 @@ static ssize_t zonefs_file_dio_write(str
+ inode_lock(inode);
+ }
+
+- ret = generic_write_checks(iocb, from);
+- if (ret <= 0)
++ count = zonefs_write_checks(iocb, from);
++ if (count <= 0) {
++ ret = count;
+ goto inode_unlock;
+-
+- iov_iter_truncate(from, zi->i_max_size - iocb->ki_pos);
+- count = iov_iter_count(from);
++ }
+
+ if ((iocb->ki_pos | count) & (sb->s_blocksize - 1)) {
+ ret = -EINVAL;
+@@ -820,12 +880,10 @@ static ssize_t zonefs_file_buffered_writ
+ inode_lock(inode);
+ }
+
+- ret = generic_write_checks(iocb, from);
++ ret = zonefs_write_checks(iocb, from);
+ if (ret <= 0)
+ goto inode_unlock;
+
+- iov_iter_truncate(from, zi->i_max_size - iocb->ki_pos);
+-
+ ret = iomap_file_buffered_write(iocb, from, &zonefs_iomap_ops);
+ if (ret > 0)
+ iocb->ki_pos += ret;
--- /dev/null
+From 6980d29ce4da223ad7f0751c7f1d61d3c6b54ab3 Mon Sep 17 00:00:00 2001
+From: Chao Yu <yuchao0@huawei.com>
+Date: Tue, 16 Mar 2021 20:30:26 +0800
+Subject: zonefs: fix to update .i_wr_refcnt correctly in zonefs_open_zone()
+
+From: Chao Yu <yuchao0@huawei.com>
+
+commit 6980d29ce4da223ad7f0751c7f1d61d3c6b54ab3 upstream.
+
+In zonefs_open_zone(), if opened zone count is larger than
+.s_max_open_zones threshold, we missed to recover .i_wr_refcnt,
+fix this.
+
+Fixes: b5c00e975779 ("zonefs: open/close zone on file open/close")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/zonefs/super.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -1032,9 +1032,7 @@ static int zonefs_open_zone(struct inode
+
+ mutex_lock(&zi->i_truncate_mutex);
+
+- zi->i_wr_refcnt++;
+- if (zi->i_wr_refcnt == 1) {
+-
++ if (!zi->i_wr_refcnt) {
+ if (atomic_inc_return(&sbi->s_open_zones) > sbi->s_max_open_zones) {
+ atomic_dec(&sbi->s_open_zones);
+ ret = -EBUSY;
+@@ -1044,7 +1042,6 @@ static int zonefs_open_zone(struct inode
+ if (i_size_read(inode) < zi->i_max_size) {
+ ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_OPEN);
+ if (ret) {
+- zi->i_wr_refcnt--;
+ atomic_dec(&sbi->s_open_zones);
+ goto unlock;
+ }
+@@ -1052,6 +1049,8 @@ static int zonefs_open_zone(struct inode
+ }
+ }
+
++ zi->i_wr_refcnt++;
++
+ unlock:
+ mutex_unlock(&zi->i_truncate_mutex);
+
--- /dev/null
+From 1601ea068b886da1f8f8d4e18b9403e9e24adef6 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <damien.lemoal@wdc.com>
+Date: Mon, 15 Mar 2021 12:43:55 +0900
+Subject: zonefs: prevent use of seq files as swap file
+
+From: Damien Le Moal <damien.lemoal@wdc.com>
+
+commit 1601ea068b886da1f8f8d4e18b9403e9e24adef6 upstream.
+
+The sequential write constraint of sequential zone file prevent their
+use as swap files. Only allow conventional zone files to be used as swap
+files.
+
+Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/zonefs/super.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -159,6 +159,21 @@ static int zonefs_writepages(struct addr
+ return iomap_writepages(mapping, wbc, &wpc, &zonefs_writeback_ops);
+ }
+
++static int zonefs_swap_activate(struct swap_info_struct *sis,
++ struct file *swap_file, sector_t *span)
++{
++ struct inode *inode = file_inode(swap_file);
++ struct zonefs_inode_info *zi = ZONEFS_I(inode);
++
++ if (zi->i_ztype != ZONEFS_ZTYPE_CNV) {
++ zonefs_err(inode->i_sb,
++ "swap file: not a conventional zone file\n");
++ return -EINVAL;
++ }
++
++ return iomap_swapfile_activate(sis, swap_file, span, &zonefs_iomap_ops);
++}
++
+ static const struct address_space_operations zonefs_file_aops = {
+ .readpage = zonefs_readpage,
+ .readahead = zonefs_readahead,
+@@ -171,6 +186,7 @@ static const struct address_space_operat
+ .is_partially_uptodate = iomap_is_partially_uptodate,
+ .error_remove_page = generic_error_remove_page,
+ .direct_IO = noop_direct_IO,
++ .swap_activate = zonefs_swap_activate,
+ };
+
+ static void zonefs_update_stats(struct inode *inode, loff_t new_isize)