--- /dev/null
+From 17956b40bce0ede58a32de3a59913fa8aa90b4a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2019 21:58:14 +1000
+Subject: powerpc/powernv: Fix CPU idle to be called with IRQs disabled
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 7d6475051fb3d9339c5c760ed9883bc0a9048b21 ]
+
+Commit e78a7614f3876 ("idle: Prevent late-arriving interrupts from
+disrupting offline") changes arch_cpu_idle_dead to be called with
+interrupts disabled, which triggers the WARN in pnv_smp_cpu_kill_self.
+
+Fix this by fixing up irq_happened after hard disabling, rather than
+requiring there are no pending interrupts, similarly to what was done
+done until commit 2525db04d1cc5 ("powerpc/powernv: Simplify lazy IRQ
+handling in CPU offline").
+
+Fixes: e78a7614f3876 ("idle: Prevent late-arriving interrupts from disrupting offline")
+Reported-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+[mpe: Add unexpected_mask rather than checking for known bad values,
+ change the WARN_ON() to a WARN_ON_ONCE()]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20191022115814.22456-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/powernv/smp.c | 53 +++++++++++++++++++---------
+ 1 file changed, 37 insertions(+), 16 deletions(-)
+
+diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
+index db09c7022635b..fdd9577d17980 100644
+--- a/arch/powerpc/platforms/powernv/smp.c
++++ b/arch/powerpc/platforms/powernv/smp.c
+@@ -150,20 +150,25 @@ static int pnv_smp_cpu_disable(void)
+ return 0;
+ }
+
++static void pnv_flush_interrupts(void)
++{
++ if (cpu_has_feature(CPU_FTR_ARCH_300)) {
++ if (xive_enabled())
++ xive_flush_interrupt();
++ else
++ icp_opal_flush_interrupt();
++ } else {
++ icp_native_flush_interrupt();
++ }
++}
++
+ static void pnv_smp_cpu_kill_self(void)
+ {
++ unsigned long srr1, unexpected_mask, wmask;
+ unsigned int cpu;
+- unsigned long srr1, wmask;
+ u64 lpcr_val;
+
+ /* Standard hot unplug procedure */
+- /*
+- * This hard disables local interurpts, ensuring we have no lazy
+- * irqs pending.
+- */
+- WARN_ON(irqs_disabled());
+- hard_irq_disable();
+- WARN_ON(lazy_irq_pending());
+
+ idle_task_exit();
+ current->active_mm = NULL; /* for sanity */
+@@ -176,6 +181,27 @@ static void pnv_smp_cpu_kill_self(void)
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ wmask = SRR1_WAKEMASK_P8;
+
++ /*
++ * This turns the irq soft-disabled state we're called with, into a
++ * hard-disabled state with pending irq_happened interrupts cleared.
++ *
++ * PACA_IRQ_DEC - Decrementer should be ignored.
++ * PACA_IRQ_HMI - Can be ignored, processing is done in real mode.
++ * PACA_IRQ_DBELL, EE, PMI - Unexpected.
++ */
++ hard_irq_disable();
++ if (generic_check_cpu_restart(cpu))
++ goto out;
++
++ unexpected_mask = ~(PACA_IRQ_DEC | PACA_IRQ_HMI | PACA_IRQ_HARD_DIS);
++ if (local_paca->irq_happened & unexpected_mask) {
++ if (local_paca->irq_happened & PACA_IRQ_EE)
++ pnv_flush_interrupts();
++ DBG("CPU%d Unexpected exit while offline irq_happened=%lx!\n",
++ cpu, local_paca->irq_happened);
++ }
++ local_paca->irq_happened = PACA_IRQ_HARD_DIS;
++
+ /*
+ * We don't want to take decrementer interrupts while we are
+ * offline, so clear LPCR:PECE1. We keep PECE2 (and
+@@ -201,6 +227,7 @@ static void pnv_smp_cpu_kill_self(void)
+
+ srr1 = pnv_cpu_offline(cpu);
+
++ WARN_ON_ONCE(!irqs_disabled());
+ WARN_ON(lazy_irq_pending());
+
+ /*
+@@ -216,13 +243,7 @@ static void pnv_smp_cpu_kill_self(void)
+ */
+ if (((srr1 & wmask) == SRR1_WAKEEE) ||
+ ((srr1 & wmask) == SRR1_WAKEHVI)) {
+- if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+- if (xive_enabled())
+- xive_flush_interrupt();
+- else
+- icp_opal_flush_interrupt();
+- } else
+- icp_native_flush_interrupt();
++ pnv_flush_interrupts();
+ } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
+ unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
+ asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
+@@ -270,7 +291,7 @@ static void pnv_smp_cpu_kill_self(void)
+ */
+ lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1;
+ pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
+-
++out:
+ DBG("CPU%d coming online...\n", cpu);
+ }
+
+--
+2.20.1
+
--- /dev/null
+From 1099563178b4b04ca088ecfdcb63e336a15dbffc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2019 09:10:56 +0100
+Subject: Revert "ALSA: hda: Flush interrupts on disabling"
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 1a7f60b9df614bb36d14dc0c0bc898a31b2b506f ]
+
+This reverts commit caa8422d01e983782548648e125fd617cadcec3f.
+
+It turned out that this commit caused a regression at shutdown /
+reboot, as the synchronize_irq() calls seems blocking the whole
+shutdown. Also another part of the change about shuffling the call
+order looks suspicious; the azx_stop_chip() call disables the CORB /
+RIRB while the others may still need the CORB/RIRB update.
+
+Since the original commit itself was a cargo-fix, let's revert the
+whole patch.
+
+Fixes: caa8422d01e9 ("ALSA: hda: Flush interrupts on disabling")
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205333
+BugLinK: https://bugs.freedesktop.org/show_bug.cgi?id=111174
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Link: https://lore.kernel.org/r/20191028081056.22010-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/hda/hdac_controller.c | 2 --
+ sound/pci/hda/hda_intel.c | 2 +-
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
+index e858b6fa0c3ad..74244d8e29090 100644
+--- a/sound/hda/hdac_controller.c
++++ b/sound/hda/hdac_controller.c
+@@ -443,8 +443,6 @@ static void azx_int_disable(struct hdac_bus *bus)
+ list_for_each_entry(azx_dev, &bus->stream_list, list)
+ snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
+
+- synchronize_irq(bus->irq);
+-
+ /* disable SIE for all streams */
+ snd_hdac_chip_writeb(bus, INTCTL, 0);
+
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index bfc45086cf793..0b24c5ce2fd6a 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1455,9 +1455,9 @@ static int azx_free(struct azx *chip)
+ }
+
+ if (bus->chip_init) {
+- azx_stop_chip(chip);
+ azx_clear_irq_pending(chip);
+ azx_stop_all_streams(chip);
++ azx_stop_chip(chip);
+ }
+
+ if (bus->irq >= 0)
+--
+2.20.1
+