Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 648cb6fd authored by Hans de Goede's avatar Hans de Goede Committed by Tejun Heo
Browse files

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.

tj: Minor comment formatting updates.

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 23b07d4c
Loading
Loading
Loading
Loading
+82 −15
Original line number Diff line number Diff line
@@ -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");
@@ -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;

@@ -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);
@@ -485,16 +556,10 @@ static int ahci_resume(struct device *dev)
			goto disable_resources;
	}

	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
		rc = ahci_reset_controller(host);
	rc = ahci_platform_resume_host(dev);
	if (rc)
		goto disable_resources;

		ahci_init_controller(host);
	}

	ata_host_resume(host);

	return 0;

disable_resources:
@@ -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", },
+5 −0
Original line number Diff line number Diff line
@@ -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 */