Message ID | 20111030142122.560216e2@ustc |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Adding linux-pm mailing list to CC, since this is PM related. On 10/30/2011 11:51 AM, JiSheng Zhang wrote: > > Signed-off-by: JiSheng Zhang <jszhang3@gmail.com> > --- > drivers/ata/ahci_platform.c | 54 +++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 54 insertions(+), 0 deletions(-) > > diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c > index c03277d..60ff9eb 100644 > --- a/drivers/ata/ahci_platform.c > +++ b/drivers/ata/ahci_platform.c > @@ -202,12 +202,66 @@ static int __devexit ahci_remove(struct platform_device *pdev) > return 0; > } > > +#ifdef CONFIG_PM > +static int ahci_suspend(struct platform_device *pdev, pm_message_t mesg) > +{ > + struct ata_host *host = dev_get_drvdata(&pdev->dev); > + struct ahci_host_priv *hpriv = host->private_data; > + void __iomem *mmio = hpriv->mmio; > + u32 ctl; > + > + if (mesg.event & PM_EVENT_SLEEP) { > + /* 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, mesg); > +} > + > +static int ahci_resume(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct ahci_platform_data *pdata = dev->platform_data; > + 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; > + } > + > + if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { > + rc = ahci_reset_controller(host); > + if (rc) > + return rc; > + > + ahci_init_controller(host); > + } > + > + ata_host_resume(host); > + > + return 0; > +} > +#endif > + > static struct platform_driver ahci_driver = { > .remove = __devexit_p(ahci_remove), > .driver = { > .name = "ahci", > .owner = THIS_MODULE, > }, > +#ifdef CONFIG_PM > + .suspend = ahci_suspend, > + .resume = ahci_resume, > +#endif > .id_table = ahci_devtype, > }; >
Hello. On 30.10.2011 8:21, JiSheng Zhang wrote: > Signed-off-by: JiSheng Zhang<jszhang3@gmail.com> > --- > drivers/ata/ahci_platform.c | 54 +++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 54 insertions(+), 0 deletions(-) > > diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c > index c03277d..60ff9eb 100644 > --- a/drivers/ata/ahci_platform.c > +++ b/drivers/ata/ahci_platform.c > @@ -202,12 +202,66 @@ static int __devexit ahci_remove(struct platform_device *pdev) > return 0; > } > > +#ifdef CONFIG_PM > +static int ahci_suspend(struct platform_device *pdev, pm_message_t mesg) > +{ > + struct ata_host *host = dev_get_drvdata(&pdev->dev); You can also call platform_get_drvdata(pdev). > +static int ahci_resume(struct platform_device *pdev) > +{ > + struct device *dev =&pdev->dev; > + struct ahci_platform_data *pdata = dev->platform_data; There's dev_get_platdata(). WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index c03277d..60ff9eb 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -202,12 +202,66 @@ static int __devexit ahci_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int ahci_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ahci_host_priv *hpriv = host->private_data; + void __iomem *mmio = hpriv->mmio; + u32 ctl; + + if (mesg.event & PM_EVENT_SLEEP) { + /* 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, mesg); +} + +static int ahci_resume(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ahci_platform_data *pdata = dev->platform_data; + 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; + } + + if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { + rc = ahci_reset_controller(host); + if (rc) + return rc; + + ahci_init_controller(host); + } + + ata_host_resume(host); + + return 0; +} +#endif + static struct platform_driver ahci_driver = { .remove = __devexit_p(ahci_remove), .driver = { .name = "ahci", .owner = THIS_MODULE, }, +#ifdef CONFIG_PM + .suspend = ahci_suspend, + .resume = ahci_resume, +#endif .id_table = ahci_devtype, };
Signed-off-by: JiSheng Zhang <jszhang3@gmail.com> --- drivers/ata/ahci_platform.c | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-)