Skip to content

Commit

Permalink
ata: libahci_platform: comply to PHY framework
Browse files Browse the repository at this point in the history
Current implementation of the libahci does not take into account the
new PHY framework. Correct the situation by adding a call to
phy_set_mode() before phy_power_on().

PHYs should also be handled at suspend/resume time. For this, call
ahci_platform_enable/disable_phys() at suspend/resume_host() time. These
calls are guarded by a HFLAG (AHCI_HFLAG_SUSPEND_PHYS) that the user of
the libahci driver must set manually in hpriv->flags at probe time. This
is to avoid breaking users that have not been tested with this change.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Suggested-by: Grzegorz Jaszczyk <jaz@semihalf.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Miquel Raynal authored and Jens Axboe committed Jan 11, 2019
1 parent a39c330 commit 49e5418
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ enum {
AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use
SATA_MOBILE_LPM_POLICY
as default lpm_policy */
AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during
suspend/resume */

/* ap->flags bits */

Expand Down
13 changes: 13 additions & 0 deletions drivers/ata/libahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ static int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
if (rc)
goto disable_phys;

rc = phy_set_mode(hpriv->phys[i], PHY_MODE_SATA);
if (rc) {
phy_exit(hpriv->phys[i]);
goto disable_phys;
}

rc = phy_power_on(hpriv->phys[i]);
if (rc) {
phy_exit(hpriv->phys[i]);
Expand Down Expand Up @@ -738,6 +744,9 @@ int ahci_platform_suspend_host(struct device *dev)
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */

if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
ahci_platform_disable_phys(hpriv);

return ata_host_suspend(host, PMSG_SUSPEND);
}
EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
Expand All @@ -756,6 +765,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
int ahci_platform_resume_host(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data;
int rc;

if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
Expand All @@ -766,6 +776,9 @@ int ahci_platform_resume_host(struct device *dev)
ahci_init_controller(host);
}

if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
ahci_platform_enable_phys(hpriv);

ata_host_resume(host);

return 0;
Expand Down

0 comments on commit 49e5418

Please sign in to comment.