diff options
Diffstat (limited to 'target/linux/sunxi/patches-3.13/160-9-ahci-plat-libraryise-suspend-resume.patch')
-rw-r--r-- | target/linux/sunxi/patches-3.13/160-9-ahci-plat-libraryise-suspend-resume.patch | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-3.13/160-9-ahci-plat-libraryise-suspend-resume.patch b/target/linux/sunxi/patches-3.13/160-9-ahci-plat-libraryise-suspend-resume.patch new file mode 100644 index 0000000000..49ddac0b5e --- /dev/null +++ b/target/linux/sunxi/patches-3.13/160-9-ahci-plat-libraryise-suspend-resume.patch @@ -0,0 +1,188 @@ +From 041cf8356a4eb91ee8118004b2bc9c78cdd7866c Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Mon, 20 Jan 2014 15:52:07 +0100 +Subject: [PATCH] ahci-platform: "Library-ise" suspend / resume functionality + +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 <hdegoede@redhat.com> +--- + 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 @@ static int ahci_resume(struct device *dev) + + 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.8.5.5 + |