ata: ahci: Add shutdown to freeze hardware resources of ahci
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>
This commit is contained in:

committed by
Jens Axboe

parent
73e4eab0a8
commit
10a663a1b1
@@ -81,6 +81,7 @@ enum board_ids {
|
|||||||
|
|
||||||
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
|
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_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,
|
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
|
||||||
unsigned long deadline);
|
unsigned long deadline);
|
||||||
static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
|
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,
|
.id_table = ahci_pci_tbl,
|
||||||
.probe = ahci_init_one,
|
.probe = ahci_init_one,
|
||||||
.remove = ahci_remove_one,
|
.remove = ahci_remove_one,
|
||||||
|
.shutdown = ahci_shutdown_one,
|
||||||
.driver = {
|
.driver = {
|
||||||
.pm = &ahci_pci_pm_ops,
|
.pm = &ahci_pci_pm_ops,
|
||||||
},
|
},
|
||||||
@@ -1877,6 +1879,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
return 0;
|
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)
|
static void ahci_remove_one(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
pm_runtime_get_noresume(&pdev->dev);
|
pm_runtime_get_noresume(&pdev->dev);
|
||||||
|
@@ -6767,6 +6767,26 @@ void ata_pci_remove_one(struct pci_dev *pdev)
|
|||||||
ata_host_detach(host);
|
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 */
|
/* move to PCI subsystem */
|
||||||
int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
|
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
|
#ifdef CONFIG_PCI
|
||||||
EXPORT_SYMBOL_GPL(pci_test_config_bits);
|
EXPORT_SYMBOL_GPL(pci_test_config_bits);
|
||||||
|
EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
|
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
|
EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
|
||||||
|
@@ -1221,6 +1221,7 @@ struct pci_bits {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *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);
|
extern void ata_pci_remove_one(struct pci_dev *pdev);
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
Reference in New Issue
Block a user