Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1337167 > unrolled thread
| Started by | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| First post | 2016-02-18 10:00 +0100 |
| Last post | 2016-02-19 17:00 +0100 |
| Articles | 9 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH 0/7] Runtime PM support for AHCI host controller driver Mika Westerberg <mika.westerberg@linux.intel.com> - 2016-02-18 10:00 +0100
[PATCH 2/7] scsi: Set request queue runtime PM status back to active on resume Mika Westerberg <mika.westerberg@linux.intel.com> - 2016-02-18 10:00 +0100
[PATCH 4/7] ahci: Cache host controller version Mika Westerberg <mika.westerberg@linux.intel.com> - 2016-02-18 10:00 +0100
[PATCH 7/7] ahci: Add runtime PM support for the host controller Mika Westerberg <mika.westerberg@linux.intel.com> - 2016-02-18 10:00 +0100
[PATCH 6/7] ahci: Add functions to manage runtime PM of AHCI ports Mika Westerberg <mika.westerberg@linux.intel.com> - 2016-02-18 10:00 +0100
Re: [PATCH 0/7] Runtime PM support for AHCI host controller driver Tejun Heo <tj@kernel.org> - 2016-02-18 17:50 +0100
Re: [PATCH 0/7] Runtime PM support for AHCI host controller driver Mika Westerberg <mika.westerberg@linux.intel.com> - 2016-02-19 09:50 +0100
Re: [PATCH 0/7] Runtime PM support for AHCI host controller driver Jens Axboe <axboe@kernel.dk> - 2016-02-19 16:20 +0100
Re: [PATCH 0/7] Runtime PM support for AHCI host controller driver Tejun Heo <tj@kernel.org> - 2016-02-19 17:00 +0100
| From | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| Date | 2016-02-18 10:00 +0100 |
| Subject | [PATCH 0/7] Runtime PM support for AHCI host controller driver |
| Message-ID | <r3sBk-311-7@gated-at.bofh.it> |
Hi,
Linux already supports runtime PM of disks (drivers/scsi/sd.c) so that
after certain amount of idle time the disk is suspended automatically. This
series extends the support to AHCI host controllers. Whenever SATA ports
are determined to be idle (all children are runtime suspended) the host
controller is also suspended.
On recent Intel CPUs like Broxton this allows the CPU to go low power idle
states like S0ix runtime (given that all necessary blocks are also in their
correesponding low power states).
Patches [1-2/7] fix a lockup where disk is runtime suspended and the system
is put to sleep. They are independent of the rest of the series.
Patch [3/7] makes it possible for SATA ports to be runtime suspended when
there is not disk connected. For example on Lenovo Yoga 900 there are two
SATA ports which only one of them has disk connected. This patch allows the
host controller to runtime suspend whenever the disk is idle.
Rest of the patches bring runtime PM support for the AHCI driver. By
default runtime PM is blocked and needs to be unblocked from userspace
(following what other PCI drivers do). I've used following script to
unblock runtime PM for the whole stack (with 15 seconds of idle time):
------8<------8<------8<------8<------8<------8<------8<------
#!/bin/sh
TIMEOUT=${1:-15}
HOST=$(lspci -D | grep "SATA controller" | cut -f 1 -d ' ')
DISK=sda
# Enable runtime PM for all SATA ports
for port in /sys/bus/pci/devices/$HOST/ata*; do
echo auto > $port/power/control
done
# Then for the host controller
echo auto > /sys/bus/pci/devices/$HOST/power/control
# And last for the disk
echo auto > /sys/block/$DISK/device/power/control
echo $(($TIMEOUT * 1000)) > /sys/block/$DISK/device/power/autosuspend_delay_ms
------8<------8<------8<------8<------8<------8<------8<------
Mika Westerberg (7):
block: Add blk_set_runtime_active()
scsi: Set request queue runtime PM status back to active on resume
scsi: Drop runtime PM usage count after host is added
ahci: Cache host controller version
ahci: Convert driver to use modern PM hooks
ahci: Add functions to manage runtime PM of AHCI ports
ahci: Add runtime PM support for the host controller
block/blk-core.c | 24 ++++++++++++
drivers/ata/ahci.c | 102 +++++++++++++++++++++++++++++++++++--------------
drivers/ata/ahci.h | 1 +
drivers/ata/libahci.c | 55 +++++++++++++++++++++++---
drivers/scsi/hosts.c | 7 ++++
drivers/scsi/scsi_pm.c | 10 +++++
include/linux/blkdev.h | 2 +
7 files changed, 167 insertions(+), 34 deletions(-)
--
2.7.0
[toc] | [next] | [standalone]
| From | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| Date | 2016-02-18 10:00 +0100 |
| Subject | [PATCH 2/7] scsi: Set request queue runtime PM status back to active on resume |
| Message-ID | <r3sBk-311-21@gated-at.bofh.it> |
| In reply to | #1337167 |
We treat system suspend of SCSI devices pretty much the same as runtime
suspend. If the device is already runtime suspended we leave it to that
state during system suspend. On resume from system sleep we then resume the
device and correct the runtime PM status back to "active".
There is a problem with this because runtime PM status of the request queue
in question is not changed (it will be in "suspended" state). When SCSI
disk driver (sd.c) resumes the disk it sends START message to the device
and because the request queue is still in "suspended" state
blk_pm_peek_request() returns NULL preventing resume of the disk.
The issue can be reproduced with following commands:
# echo auto > /sys/block/sda/device/power/control
# echo 15000 > /sys/block/sda/device/power/autosuspend_delay_ms
[ 57.191706] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[ 57.380015] sd 0:0:0:0: [sda] Stopping disk
Now suspend the machine:
# rtcwake -s10 -mmem
This ends up in soft lockup because resume is not proceeding accordingly
and userspace is never restarted. Also there is nothing printed to the
console.
Fix this by forcing request queue status to "active" before the disk is
resumed.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/scsi/scsi_pm.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index 459abe1dcc87..b44c1bb687a2 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -139,6 +139,16 @@ static int scsi_bus_resume_common(struct device *dev,
else
fn = NULL;
+ /*
+ * Forcibly set runtime PM status of request queue to "active" to
+ * make sure we can again get requests from the queue (see also
+ * blk_pm_peek_request()).
+ *
+ * The resume hook will correct runtime PM status of the disk.
+ */
+ if (scsi_is_sdev_device(dev) && pm_runtime_suspended(dev))
+ blk_set_runtime_active(to_scsi_device(dev)->request_queue);
+
if (fn) {
async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| Date | 2016-02-18 10:00 +0100 |
| Subject | [PATCH 4/7] ahci: Cache host controller version |
| Message-ID | <r3sBl-311-31@gated-at.bofh.it> |
| In reply to | #1337167 |
This allows sysfs nodes to read the cached value directly instead of
powering up possibly runtime suspended controller.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/ata/ahci.h | 1 +
drivers/ata/libahci.c | 7 +++----
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index a44c75d4c284..8138bc967eda 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -336,6 +336,7 @@ struct ahci_host_priv {
void __iomem * mmio; /* bus-independent mem map */
u32 cap; /* cap to use */
u32 cap2; /* cap2 to use */
+ u32 version; /* cached version */
u32 port_map; /* port map to use */
u32 saved_cap; /* saved initial cap */
u32 saved_cap2; /* saved initial cap2 */
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 402967902cbe..2ce4c638714e 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -250,9 +250,8 @@ static ssize_t ahci_show_host_version(struct device *dev,
struct Scsi_Host *shost = class_to_shost(dev);
struct ata_port *ap = ata_shost_to_port(shost);
struct ahci_host_priv *hpriv = ap->host->private_data;
- void __iomem *mmio = hpriv->mmio;
- return sprintf(buf, "%x\n", readl(mmio + HOST_VERSION));
+ return sprintf(buf, "%x\n", hpriv->version);
}
static ssize_t ahci_show_port_cmd(struct device *dev,
@@ -508,6 +507,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
/* record values to use during operation */
hpriv->cap = cap;
hpriv->cap2 = cap2;
+ hpriv->version = readl(mmio + HOST_VERSION);
hpriv->port_map = port_map;
if (!hpriv->start_engine)
@@ -2389,11 +2389,10 @@ static void ahci_port_stop(struct ata_port *ap)
void ahci_print_info(struct ata_host *host, const char *scc_s)
{
struct ahci_host_priv *hpriv = host->private_data;
- void __iomem *mmio = hpriv->mmio;
u32 vers, cap, cap2, impl, speed;
const char *speed_s;
- vers = readl(mmio + HOST_VERSION);
+ vers = hpriv->version;
cap = hpriv->cap;
cap2 = hpriv->cap2;
impl = hpriv->port_map;
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| Date | 2016-02-18 10:00 +0100 |
| Subject | [PATCH 7/7] ahci: Add runtime PM support for the host controller |
| Message-ID | <r3sBl-311-39@gated-at.bofh.it> |
| In reply to | #1337167 |
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
[toc] | [prev] | [next] | [standalone]
| From | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| Date | 2016-02-18 10:00 +0100 |
| Subject | [PATCH 6/7] ahci: Add functions to manage runtime PM of AHCI ports |
| Message-ID | <r3sBl-311-33@gated-at.bofh.it> |
| In reply to | #1337167 |
Add new functions ahci_rpm_get_port()/ahci_rpm_put_port() that change
runtime PM status of AHCI ports. Depending if the AHCI host has runtime PM
enabled or disabled calling these may trigger runtime suspend/resume of the
host controller.
We also call these functions in appropriate places to make sure host
controller registers are available before using them.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/ata/libahci.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 2ce4c638714e..a5dc80810a5e 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -224,6 +224,31 @@ static void ahci_enable_ahci(void __iomem *mmio)
WARN_ON(1);
}
+/**
+ * ahci_rpm_get_port - Make sure the port is powered on
+ * @ap: Port to power on
+ *
+ * Whenever there is need to access the AHCI host registers outside of
+ * normal execution paths, call this function to make sure the host is
+ * actually powered on.
+ */
+static int ahci_rpm_get_port(struct ata_port *ap)
+{
+ return pm_runtime_get_sync(ap->dev);
+}
+
+/**
+ * ahci_rpm_put_port - Undoes ahci_rpm_get_port()
+ * @ap: Port to power down
+ *
+ * Undoes ahci_rpm_get_port() and possibly powers down the AHCI host
+ * if it has no more active users.
+ */
+static void ahci_rpm_put_port(struct ata_port *ap)
+{
+ pm_runtime_put(ap->dev);
+}
+
static ssize_t ahci_show_host_caps(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -260,8 +285,13 @@ static ssize_t ahci_show_port_cmd(struct device *dev,
struct Scsi_Host *shost = class_to_shost(dev);
struct ata_port *ap = ata_shost_to_port(shost);
void __iomem *port_mmio = ahci_port_base(ap);
+ ssize_t ret;
- return sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD));
+ ahci_rpm_get_port(ap);
+ ret = sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD));
+ ahci_rpm_put_port(ap);
+
+ return ret;
}
static ssize_t ahci_read_em_buffer(struct device *dev,
@@ -277,17 +307,20 @@ static ssize_t ahci_read_em_buffer(struct device *dev,
size_t count;
int i;
+ ahci_rpm_get_port(ap);
spin_lock_irqsave(ap->lock, flags);
em_ctl = readl(mmio + HOST_EM_CTL);
if (!(ap->flags & ATA_FLAG_EM) || em_ctl & EM_CTL_XMT ||
!(hpriv->em_msg_type & EM_MSG_TYPE_SGPIO)) {
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
return -EINVAL;
}
if (!(em_ctl & EM_CTL_MR)) {
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
return -EAGAIN;
}
@@ -315,6 +348,7 @@ static ssize_t ahci_read_em_buffer(struct device *dev,
}
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
return i;
}
@@ -339,11 +373,13 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
size % 4 || size > hpriv->em_buf_sz)
return -EINVAL;
+ ahci_rpm_get_port(ap);
spin_lock_irqsave(ap->lock, flags);
em_ctl = readl(mmio + HOST_EM_CTL);
if (em_ctl & EM_CTL_TM) {
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
return -EBUSY;
}
@@ -356,6 +392,7 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
return size;
}
@@ -369,7 +406,9 @@ static ssize_t ahci_show_em_supported(struct device *dev,
void __iomem *mmio = hpriv->mmio;
u32 em_ctl;
+ ahci_rpm_get_port(ap);
em_ctl = readl(mmio + HOST_EM_CTL);
+ ahci_rpm_put_port(ap);
return sprintf(buf, "%s%s%s%s\n",
em_ctl & EM_CTL_LED ? "led " : "",
@@ -1010,6 +1049,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
else
return -EINVAL;
+ ahci_rpm_get_port(ap);
spin_lock_irqsave(ap->lock, flags);
/*
@@ -1019,6 +1059,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
em_ctl = readl(mmio + HOST_EM_CTL);
if (em_ctl & EM_CTL_TM) {
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
return -EBUSY;
}
@@ -1046,6 +1087,8 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
emp->led_state = state;
spin_unlock_irqrestore(ap->lock, flags);
+ ahci_rpm_put_port(ap);
+
return size;
}
@@ -2248,6 +2291,8 @@ static void ahci_pmp_detach(struct ata_port *ap)
int ahci_port_resume(struct ata_port *ap)
{
+ ahci_rpm_get_port(ap);
+
ahci_power_up(ap);
ahci_start_port(ap);
@@ -2274,6 +2319,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
ata_port_freeze(ap);
}
+ ahci_rpm_put_port(ap);
return rc;
}
#endif
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Tejun Heo <tj@kernel.org> |
|---|---|
| Date | 2016-02-18 17:50 +0100 |
| Message-ID | <r3zWb-8pq-17@gated-at.bofh.it> |
| In reply to | #1337167 |
Hello, Patchset looks good to me. Once Jens acks the first patch, I'll apply the whole series to libata/for-4.6 w/ the field initialization updated. Thanks. -- tejun
[toc] | [prev] | [next] | [standalone]
| From | Mika Westerberg <mika.westerberg@linux.intel.com> |
|---|---|
| Date | 2016-02-19 09:50 +0100 |
| Message-ID | <r3OVc-2o2-15@gated-at.bofh.it> |
| In reply to | #1337519 |
On Thu, Feb 18, 2016 at 11:40:29AM -0500, Tejun Heo wrote: > Hello, > > Patchset looks good to me. Once Jens acks the first patch, I'll apply > the whole series to libata/for-4.6 w/ the field initialization > updated. Thanks!
[toc] | [prev] | [next] | [standalone]
| From | Jens Axboe <axboe@kernel.dk> |
|---|---|
| Date | 2016-02-19 16:20 +0100 |
| Message-ID | <r3V0C-6Wq-13@gated-at.bofh.it> |
| In reply to | #1337519 |
On 02/18/2016 09:40 AM, Tejun Heo wrote: > Hello, > > Patchset looks good to me. Once Jens acks the first patch, I'll apply > the whole series to libata/for-4.6 w/ the field initialization > updated. You can add my acked-by to that one, looks good to me. -- Jens Axboe
[toc] | [prev] | [next] | [standalone]
| From | Tejun Heo <tj@kernel.org> |
|---|---|
| Date | 2016-02-19 17:00 +0100 |
| Message-ID | <r3VDk-7j5-5@gated-at.bofh.it> |
| In reply to | #1337167 |
On Thu, Feb 18, 2016 at 10:54:10AM +0200, Mika Westerberg wrote: > Linux already supports runtime PM of disks (drivers/scsi/sd.c) so that > after certain amount of idle time the disk is suspended automatically. This > series extends the support to AHCI host controllers. Whenever SATA ports > are determined to be idle (all children are runtime suspended) the host > controller is also suspended. > > On recent Intel CPUs like Broxton this allows the CPU to go low power idle > states like S0ix runtime (given that all necessary blocks are also in their > correesponding low power states). > > Patches [1-2/7] fix a lockup where disk is runtime suspended and the system > is put to sleep. They are independent of the rest of the series. > > Patch [3/7] makes it possible for SATA ports to be runtime suspended when > there is not disk connected. For example on Lenovo Yoga 900 there are two > SATA ports which only one of them has disk connected. This patch allows the > host controller to runtime suspend whenever the disk is idle. Applied to libata/for-4.6. Thanks. -- tejun
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web