--- /dev/null
+From 10a663a1b15134a5a714aa515e11425a44d4fdf7 Mon Sep 17 00:00:00 2001
+From: Prabhakar Kushwaha <pkushwaha@marvell.com>
+Date: Sat, 25 Jan 2020 03:37:29 +0000
+Subject: ata: ahci: Add shutdown to freeze hardware resources of ahci
+
+From: Prabhakar Kushwaha <pkushwaha@marvell.com>
+
+commit 10a663a1b15134a5a714aa515e11425a44d4fdf7 upstream.
+
+device_shutdown() called from reboot or power_shutdown expect
+all devices to be shutdown. Same is true for even ahci pci driver.
+As no ahci shutdown function is implemented, the ata subsystem
+always remains alive with DMA & interrupt support. File system
+related calls should not be honored after device_shutdown().
+
+So defining ahci pci driver shutdown to freeze hardware (mask
+interrupt, stop DMA engine and free DMA resources).
+
+Signed-off-by: Prabhakar Kushwaha <pkushwaha@marvell.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci.c | 7 +++++++
+ drivers/ata/libata-core.c | 21 +++++++++++++++++++++
+ include/linux/libata.h | 1 +
+ 3 files changed, 29 insertions(+)
+
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -81,6 +81,7 @@ enum board_ids {
+
+ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+ static void ahci_remove_one(struct pci_dev *dev);
++static void ahci_shutdown_one(struct pci_dev *dev);
+ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+@@ -606,6 +607,7 @@ static struct pci_driver ahci_pci_driver
+ .id_table = ahci_pci_tbl,
+ .probe = ahci_init_one,
+ .remove = ahci_remove_one,
++ .shutdown = ahci_shutdown_one,
+ .driver = {
+ .pm = &ahci_pci_pm_ops,
+ },
+@@ -1877,6 +1879,11 @@ static int ahci_init_one(struct pci_dev
+ return 0;
+ }
+
++static void ahci_shutdown_one(struct pci_dev *pdev)
++{
++ ata_pci_shutdown_one(pdev);
++}
++
+ static void ahci_remove_one(struct pci_dev *pdev)
+ {
+ pm_runtime_get_noresume(&pdev->dev);
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -6767,6 +6767,26 @@ void ata_pci_remove_one(struct pci_dev *
+ ata_host_detach(host);
+ }
+
++void ata_pci_shutdown_one(struct pci_dev *pdev)
++{
++ struct ata_host *host = pci_get_drvdata(pdev);
++ int i;
++
++ for (i = 0; i < host->n_ports; i++) {
++ struct ata_port *ap = host->ports[i];
++
++ ap->pflags |= ATA_PFLAG_FROZEN;
++
++ /* Disable port interrupts */
++ if (ap->ops->freeze)
++ ap->ops->freeze(ap);
++
++ /* Stop the port DMA engines */
++ if (ap->ops->port_stop)
++ ap->ops->port_stop(ap);
++ }
++}
++
+ /* move to PCI subsystem */
+ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
+ {
+@@ -7387,6 +7407,7 @@ EXPORT_SYMBOL_GPL(ata_timing_cycle2mode)
+
+ #ifdef CONFIG_PCI
+ EXPORT_SYMBOL_GPL(pci_test_config_bits);
++EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
+ EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+ #ifdef CONFIG_PM
+ EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -1221,6 +1221,7 @@ struct pci_bits {
+ };
+
+ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
++extern void ata_pci_shutdown_one(struct pci_dev *pdev);
+ extern void ata_pci_remove_one(struct pci_dev *pdev);
+
+ #ifdef CONFIG_PM