Signed-off-by: JiSheng Zhang <jszhang3@xxxxxxxxx> --- drivers/ata/ahci_platform.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+), 0 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 45edba9..b8ffc02 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -202,11 +202,63 @@ static int __devexit ahci_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int ahci_suspend(struct device *dev) +{ + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + void __iomem *mmio = hpriv->mmio; + u32 ctl; + + /* AHCI spec rev1.1 section 8.3.3: + * Software must disable interrupts prior to requesting a + * transition of the HBA to D3 state. + */ + ctl = readl(mmio + HOST_CTL); + ctl &= ~HOST_IRQ_EN; + writel(ctl, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + + return ata_host_suspend(host, PMSG_SUSPEND); +} + +static int ahci_resume(struct device *dev) +{ + struct ahci_platform_data *pdata = dev_get_platdata(dev); + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + int rc; + + if (pdata && pdata->init) { + rc = pdata->init(dev, hpriv->mmio); + if (rc) + return rc; + } + + rc = ahci_reset_controller(host); + if (rc) + return rc; + + ahci_init_controller(host); + ata_host_resume(host); + + return 0; +} + +static const struct dev_pm_ops ahci_pm_ops = { + .suspend = ahci_suspend, + .resume = ahci_resume, +}; +#endif + static struct platform_driver ahci_driver = { .remove = __devexit_p(ahci_remove), .driver = { .name = "ahci", .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &ahci_pm_ops, +#endif }, .id_table = ahci_devtype, }; -- 1.7.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html