Skip to content

Commit

Permalink
ahci-platform: "Library-ise" suspend / resume functionality
Browse files Browse the repository at this point in the history
Split suspend / resume code into host suspend / resume functionality and
resource enable / disabling phases, and export the new suspend_ / resume_host
functions.

tj: Minor comment formatting updates.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
  • Loading branch information
Hans de Goede authored and Tejun Heo committed Feb 22, 2014
1 parent 23b07d4 commit 648cb6f
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 15 deletions.
97 changes: 82 additions & 15 deletions drivers/ata/ahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,14 +432,23 @@ 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.
*
* 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");
Expand All @@ -456,7 +465,58 @@ 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.
*
* 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.
*
* 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;

Expand All @@ -467,8 +527,19 @@ 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.
*
* 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);
Expand All @@ -485,15 +556,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;

Expand All @@ -502,9 +567,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", },
Expand Down
5 changes: 5 additions & 0 deletions include/linux/ahci_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 648cb6f

Please sign in to comment.