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