Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28a73a94 authored by Prabhakar Kushwaha's avatar Prabhakar Kushwaha Committed by Greg Kroah-Hartman
Browse files

ata: ahci: Add shutdown to freeze hardware resources of ahci



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: default avatarPrabhakar Kushwaha <pkushwaha@marvell.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 43cac315
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -96,6 +96,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,
@@ -609,6 +610,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,
	},
@@ -1897,6 +1899,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	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);
+21 −0
Original line number Diff line number Diff line
@@ -6780,6 +6780,26 @@ void ata_pci_remove_one(struct pci_dev *pdev)
	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)
{
@@ -7400,6 +7420,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);
+1 −0
Original line number Diff line number Diff line
@@ -1236,6 +1236,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