Re: [linux-pm] [demo patch/RFC] sleepy linux
- From: Randy Dunlap <randy.dunlap@xxxxxxxxxx>
- Date: Tue, 26 Feb 2008 08:54:22 -0800
On Tue, 26 Feb 2008 11:26:53 +0100 Pavel Machek wrote:
Hi Pavel,
Is this limited to UP and only one disk?
[comments below]
Sleepy linux support, demo version, but it works on my thinkpad x60 ;-).
Signed-off-by: Pavel Machek <pavel@xxxxxxx>
diff --git a/Documentation/power/sleepy.txt b/Documentation/power/sleepy.txt
new file mode 100644
index 0000000..a9caf05
--- /dev/null
+++ b/Documentation/power/sleepy.txt
@@ -0,0 +1,55 @@
+ Sleepy Linux
+ ~~~~~~~~~~~~
+
+Copyright 2007 Pavel Machek <pavel@xxxxxxx>
+ GPLv2
+
+Current Linux versions can enter suspend-to-RAM just fine, but only
+can do it on explicit request. But suspend-to-RAM is important, eating
Usually "can only do it" AFAIK.
+something like 10% of power needed for idle system. Starting suspend
+manually is not too convinient; it is not an option on multiuser
convenient;
+machine, and even on single user machine, some things are not easy:
+
+1) Download this big chunk in mozilla, then go to sleep
+
+2) Compile this, then go to sleep
+
+3) You can sleep now, but wake me up in 8:30 with mp3 player
+
+Todays hardware is mostly capable of doing better: with correctly set
Today's
+up wakeups, machine can sleep and successfully pretend it is not
+sleeping -- by waking up whenever something interesting happens. Of
+course, it is easier on machines not connected to the network, and on
+notebook computers.
+
+Requirements:
+
+0) Working suspend-to-RAM, with kernel being able to bring video back.
+
+1) RTC clock that can wake up system
+
+2) Lid that can wake up a system,
+ or keyboard that can wake up system and does not loose keypress
lose
+ or special screensaver setup
+
+3) Network card that is either down
+ or can wake up system on any packet (and not loose too many packets)
lose
+
+How to use it
+~~~~~~~~~~~~~
+
+First, make sure your config is tiny enough that cpu sleeps at least
CPU (please)
+five or so seconds between wakeups. You'll probably need to disable
+USB, make some kernel timers way longer than default and boot with
+init=/bin/bash.
+
+Then, enable SCSI powersave by something like:
+
+mount /sys
Isn't /sys auto-mounted by kernel?
+echo auto > /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/power/level
+echo 3 > /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/power/autosuspend
+echo adisk > /sys/power/state
+mount / -oremount,commit=900
+
+Then, echo auto > /sys/power/state should enable sleepy support. Do it
+twice, and it will ignore open lid and sleep anyway.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 29e71bd..0197b1f 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -268,6 +269,41 @@ static struct class_device_attribute *ah
NULL
};
+struct pci_dev *my_pdev;
+int autosuspend_enabled;
+
+struct sleep_disabled_reason ahci_active = {
+ "ahci"
+};
+
+/* The host and its devices are all idle so we can autosuspend */
+static int autosuspend(struct Scsi_Host *host)
+{
+ if (my_pdev && autosuspend_enabled) {
+ printk("ahci: should autosuspend\n");
Use printk() KERN_* levels (multiple places).
+ ahci_pci_device_suspend(my_pdev, PMSG_SUSPEND);...
+ enable_auto_sleep(&ahci_active);
+ return 0;
+ }
+ printk("ahci: autosuspend disabled\n");
+ return -EINVAL;
+}
+
+}
+
+
+
static struct scsi_host_template ahci_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -1820,6 +1858,10 @@ static void ahci_thaw(struct ata_port *a
static void ahci_error_handler(struct ata_port *ap)
{
+ struct ata_host *host = ap->host;
+ int rc;
+ extern int slept;
Eh?
+
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
/* restart engine */
ahci_stop_engine(ap);
General comment: Lots of the comment fixes in libata should be part
of a standalone patch, not part of this patch.
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 78bbaca..df2dd4f 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -298,6 +298,13 @@ enum {
SCR_ACTIVE = 3,
SCR_NOTIFICATION = 4,
+ /* SControl subfields, each field is 4 bit wide */
bits
+ ATA_SCTL_DET = 0, /* lsb */
+ ATA_SCTL_SPD = 1,
+ ATA_SCTL_IPM = 2,
+ ATA_SCTL_SPM = 3,
+ ATA_SCTL_PMP = 4,
+
/* SError bits */
SERR_DATA_RECOVERED = (1 << 0), /* recovered data error */
SERR_COMM_RECOVERED = (1 << 1), /* recovered comm failure */
diff --git a/kernel/power/main.c b/kernel/power/main.c
index a29da58..2470e94 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
+ * Copyright (c) 2007 Pavel Machek <pavel@xxxxxxx>
It's 2008 now.
*
* This file is released under the GPLv2
*
@@ -22,7 +23,10 @@ #include <linux/freezer.h>
#include <linux/vmstat.h>
#include <linux/syscalls.h>
+#include <asm/percpu.h>
+
#include "power.h"
+#include "../../drivers/scsi/scsi_priv.h"
ugh.
DEFINE_MUTEX(pm_mutex);
@@ -426,6 +437,76 @@ static int enter_state(suspend_state_t s
return error;
}
+/* Returns how long it waited in ms */
+//extern long (*panic_blink)(long time);
+
+int slept;
+
+
+struct sleep_disabled_reason wakeup_tasks = {
+ "wakeup_tasks"
+};
+
+int device_suspend_fake(pm_message_t state);
+
+int
+do_auto_sleep(void)
All on one line.
+{
+ int error,i;
space after comma.
+ int state = PM_SUSPEND_MEM;
+
+ /* add baby "morning tasks" to the lists. BUG if it is not
+ the only baby */
+
+ if (slept)
+ return;
+ slept++;
+ disable_auto_sleep(&wakeup_tasks);
+// device_suspend_fake(PMSG_SUSPEND);
+ suspend_enter(state);
+
+ /* FIXME: run "morning tasks" in process context; drivers need to check why
+ machine was woken, and perhaps put themselves back to crying babies list
+ if lid was opened or something. */
+
+ enable_auto_sleep(&wakeup_tasks);
+
+#if 0
+ printk("finishing\n");
+ if (suspend_ops->finish)
+ suspend_ops->finish();
+#endif
+
+ return 0;
+}
+
+extern int set_alarm(int length);
+
+void
+enter_auto_sleep(int length)
All on one line.
+{
+ int error;
+
+ if (atomic_read(&cpu_needed))
+ return;
+
+ printk("Auto sleeping\n");
+ set_alarm(length);
+
+ error = do_auto_sleep();
+ if (error)
+ printk("enter auto sleep failed: %d\n", error);
+}
/**
* pm_suspend - Externally visible function for suspending system.
@@ -481,6 +562,12 @@ #endif
return (s - buf);
}
+extern struct pci_dev *my_pdev;
+extern int autosuspend_enabled;
+extern struct device *my_scsi_disk;
+extern int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
+extern int ahci_pci_device_resume(struct pci_dev *pdev);
+
Externs in header files, please.
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,...
const char *buf, size_t n)
{
---
~Randy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
- Follow-Ups:
- Re: [linux-pm] [demo patch/RFC] sleepy linux
- From: Pavel Machek
- Re: [linux-pm] [demo patch/RFC] sleepy linux
- References:
- [demo patch/RFC] sleepy linux
- From: Pavel Machek
- [demo patch/RFC] sleepy linux
- Prev by Date: Hello
- Next by Date: Re: 2.6.24.2-rt2
- Previous by thread: [demo patch/RFC] sleepy linux
- Next by thread: Re: [linux-pm] [demo patch/RFC] sleepy linux
- Index(es):
Relevant Pages
|