From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hans de Goede Subject: [PATCH v7 06/15] ahci-platform: "Library-ise" suspend / resume functionality Date: Sat, 22 Feb 2014 16:53:35 +0100 Message-ID: <1393084424-31099-7-git-send-email-hdegoede@redhat.com> References: <1393084424-31099-1-git-send-email-hdegoede@redhat.com> Reply-To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Return-path: In-Reply-To: <1393084424-31099-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> List-Post: , List-Help: , List-Archive: Sender: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org List-Subscribe: , List-Unsubscribe: , To: Tejun Heo , Maxime Ripard Cc: Oliver Schinagl , Richard Zhu , Roger Quadros , Lee Jones , linux-ide-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, devicetree , linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org, Hans de Goede List-Id: devicetree@vger.kernel.org Split suspend / resume code into host suspend / resume functionality and resource enable / disabling phases, and export the new suspend_ / resume_host functions. Signed-off-by: Hans de Goede --- drivers/ata/ahci_platform.c | 109 ++++++++++++++++++++++++++++++++++++------ include/linux/ahci_platform.h | 5 ++ 2 files changed, 99 insertions(+), 15 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 7f3f2ac..bdadec1 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -452,14 +452,26 @@ static void ahci_host_stop(struct ata_host *host) } #ifdef CONFIG_PM_SLEEP -static int ahci_suspend(struct device *dev) +/** + * ahci_platform_suspend_host - Suspend an ahci-platform host + * @dev: device pointer for the host + * + * This function does all the usual steps needed to suspend an + * ahci-platform host, note any necessary resources (ie clks, phy, etc.) + * must be disabled after calling this. + * + * LOCKING: + * None. + * + * RETURNS: + * 0 on success otherwise a negative error code + */ +int ahci_platform_suspend_host(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; void __iomem *mmio = hpriv->mmio; u32 ctl; - int rc; if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { dev_err(dev, "firmware update required for suspend/resume\n"); @@ -476,7 +488,64 @@ static int ahci_suspend(struct device *dev) writel(ctl, mmio + HOST_CTL); readl(mmio + HOST_CTL); /* flush */ - rc = ata_host_suspend(host, PMSG_SUSPEND); + return ata_host_suspend(host, PMSG_SUSPEND); +} +EXPORT_SYMBOL_GPL(ahci_platform_suspend_host); + +/** + * ahci_platform_resume_host - Resume an ahci-platform host + * @dev: device pointer for the host + * + * This function does all the usual steps needed to resume an + * ahci-platform host, note any necessary resources (ie clks, phy, etc.) + * must be initialized / enabled before calling this. + * + * LOCKING: + * None. + * + * RETURNS: + * 0 on success otherwise a negative error code + */ +int ahci_platform_resume_host(struct device *dev) +{ + struct ata_host *host = dev_get_drvdata(dev); + int rc; + + if (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; +} +EXPORT_SYMBOL_GPL(ahci_platform_resume_host); + +/** + * ahci_platform_suspend - Suspend an ahci-platform device + * @dev: the platform device to suspend + * + * This function suspends the host associated with the device, followed + * by disabling all the resources of the device. + * + * LOCKING: + * None. + * + * RETURNS: + * 0 on success otherwise a negative error code + */ +int ahci_platform_suspend(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; + + rc = ahci_platform_suspend_host(dev); if (rc) return rc; @@ -487,8 +556,22 @@ static int ahci_suspend(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(ahci_platform_suspend); -static int ahci_resume(struct device *dev) +/** + * ahci_platform_resume - Resume an ahci-platform device + * @dev: the platform device to resume + * + * This function enables all the resources of the device followed by + * resuming the host associated with the device. + * + * LOCKING: + * None. + * + * RETURNS: + * 0 on success otherwise a negative error code + */ +int ahci_platform_resume(struct device *dev) { struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ata_host *host = dev_get_drvdata(dev); @@ -505,15 +588,9 @@ static int ahci_resume(struct device *dev) goto disable_resources; } - if (dev->power.power_state.event == PM_EVENT_SUSPEND) { - rc = ahci_reset_controller(host); - if (rc) - goto disable_resources; - - ahci_init_controller(host); - } - - ata_host_resume(host); + rc = ahci_platform_resume_host(dev); + if (rc) + goto disable_resources; return 0; @@ -522,9 +599,11 @@ disable_resources: return rc; } +EXPORT_SYMBOL_GPL(ahci_platform_resume); #endif -static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, + ahci_platform_resume); static const struct of_device_id ahci_of_match[] = { { .compatible = "snps,spear-ahci", }, diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index b80c51c..542f268 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -50,4 +50,9 @@ int ahci_platform_init_host(struct platform_device *pdev, unsigned int force_port_map, unsigned int mask_port_map); +int ahci_platform_suspend_host(struct device *dev); +int ahci_platform_resume_host(struct device *dev); +int ahci_platform_suspend(struct device *dev); +int ahci_platform_resume(struct device *dev); + #endif /* _AHCI_PLATFORM_H */ -- 1.9.0