From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: linux-block@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>, Tejun Heo <tj@kernel.org>,
James Bottomley <James.Bottomley@HansenPartnership.com>,
"Martin K . Petersen" <martin.petersen@oracle.com>,
Mika Westerberg <mika.westerberg@linux.intel.com>,
linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org,
linux-scsi@vger.kernel.org
Subject: [PATCH 7/7] ahci: Add runtime PM support for the host controller
Date: Thu, 18 Feb 2016 10:54:17 +0200 [thread overview]
Message-ID: <1455785657-22924-8-git-send-email-mika.westerberg@linux.intel.com> (raw)
In-Reply-To: <1455785657-22924-1-git-send-email-mika.westerberg@linux.intel.com>
This patch adds runtime PM support for the AHCI host controller driver so
that the host controller is powered down when all SATA ports are runtime
suspended. Powering down the AHCI host controller can reduce power
consumption and possibly allow the CPU to enter lower power idle states
(S0ix) during runtime.
Runtime PM is blocked by default and needs to be unblocked from userspace
as needed (via power/* sysfs nodes).
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/ata/ahci.c | 73 +++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 61 insertions(+), 12 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 44f9d1c09bbe..fb0c23ae3ce9 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -85,6 +85,7 @@ enum board_ids {
};
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void ahci_remove_one(struct pci_dev *dev);
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -93,10 +94,14 @@ static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
static bool is_mcp89_apple(struct pci_dev *pdev);
static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
+#ifdef CONFIG_PM
+static int ahci_pci_device_runtime_suspend(struct device *dev);
+static int ahci_pci_device_runtime_resume(struct device *dev);
#ifdef CONFIG_PM_SLEEP
static int ahci_pci_device_suspend(struct device *dev);
static int ahci_pci_device_resume(struct device *dev);
#endif
+#endif /* CONFIG_PM */
static struct scsi_host_template ahci_sht = {
AHCI_SHT("ahci"),
@@ -559,13 +564,15 @@ static const struct pci_device_id ahci_pci_tbl[] = {
static const struct dev_pm_ops ahci_pci_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(ahci_pci_device_suspend, ahci_pci_device_resume)
+ SET_RUNTIME_PM_OPS(ahci_pci_device_runtime_suspend,
+ ahci_pci_device_runtime_resume, NULL)
};
static struct pci_driver ahci_pci_driver = {
.name = DRV_NAME,
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
- .remove = ata_pci_remove_one,
+ .remove = ahci_remove_one,
.driver.pm = &ahci_pci_pm_ops,
};
@@ -794,21 +801,13 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
}
-#ifdef CONFIG_PM_SLEEP
-static int ahci_pci_device_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static void ahci_pci_disable_interrupts(struct ata_host *host)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct ata_host *host = pci_get_drvdata(pdev);
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->mmio;
u32 ctl;
- if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
- dev_err(&pdev->dev,
- "BIOS update required for suspend/resume\n");
- return -EIO;
- }
-
/* AHCI spec rev1.1 section 8.3.3:
* Software must disable interrupts prior to requesting a
* transition of the HBA to D3 state.
@@ -817,7 +816,44 @@ static int ahci_pci_device_suspend(struct device *dev)
ctl &= ~HOST_IRQ_EN;
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */
+}
+
+static int ahci_pci_device_runtime_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ata_host *host = pci_get_drvdata(pdev);
+ ahci_pci_disable_interrupts(host);
+ return 0;
+}
+
+static int ahci_pci_device_runtime_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ata_host *host = pci_get_drvdata(pdev);
+ int rc;
+
+ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+ ahci_pci_init_controller(host);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ahci_pci_device_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ata_host *host = pci_get_drvdata(pdev);
+ struct ahci_host_priv *hpriv = host->private_data;
+
+ if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
+ dev_err(&pdev->dev,
+ "BIOS update required for suspend/resume\n");
+ return -EIO;
+ }
+
+ ahci_pci_disable_interrupts(host);
return ata_host_suspend(host, PMSG_SUSPEND);
}
@@ -845,6 +881,8 @@ static int ahci_pci_device_resume(struct device *dev)
}
#endif
+#endif /* CONFIG_PM */
+
static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
{
int rc;
@@ -1664,7 +1702,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- return ahci_host_activate(host, &ahci_sht);
+ rc = ahci_host_activate(host, &ahci_sht);
+ if (rc)
+ return rc;
+
+ pm_runtime_put_noidle(&pdev->dev);
+ return 0;
+}
+
+static void ahci_remove_one(struct pci_dev *pdev)
+{
+ pm_runtime_get_noresume(&pdev->dev);
+ ata_pci_remove_one(pdev);
}
module_pci_driver(ahci_pci_driver);
--
2.7.0
next prev parent reply other threads:[~2016-02-18 8:54 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-18 8:54 [PATCH 0/7] Runtime PM support for AHCI host controller driver Mika Westerberg
2016-02-18 8:54 ` [PATCH 1/7] block: Add blk_set_runtime_active() Mika Westerberg
2016-02-18 8:54 ` [PATCH 2/7] scsi: Set request queue runtime PM status back to active on resume Mika Westerberg
2016-02-18 8:54 ` [PATCH 3/7] scsi: Drop runtime PM usage count after host is added Mika Westerberg
2016-02-18 22:50 ` Julian Calaby
2016-02-19 8:18 ` Mika Westerberg
2016-02-18 8:54 ` [PATCH 4/7] ahci: Cache host controller version Mika Westerberg
2016-02-18 8:54 ` [PATCH 5/7] ahci: Convert driver to use modern PM hooks Mika Westerberg
2016-02-18 10:45 ` Andy Shevchenko
2016-02-18 13:12 ` Tejun Heo
2016-02-18 14:41 ` Christoph Hellwig
2016-02-18 8:54 ` [PATCH 6/7] ahci: Add functions to manage runtime PM of AHCI ports Mika Westerberg
2016-02-18 8:54 ` Mika Westerberg [this message]
2016-02-18 16:40 ` [PATCH 0/7] Runtime PM support for AHCI host controller driver Tejun Heo
2016-02-19 8:39 ` Mika Westerberg
2016-02-19 15:12 ` Jens Axboe
2016-02-19 15:54 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1455785657-22924-8-git-send-email-mika.westerberg@linux.intel.com \
--to=mika.westerberg@linux.intel.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=axboe@kernel.dk \
--cc=linux-block@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).