summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xpm/module.d/kernel38
-rwxr-xr-xpm/module.d/tuxonice57
-rwxr-xr-xpm/module.d/uswsusp87
-rw-r--r--pm/pm-functions.in75
-rwxr-xr-xsrc/pm-action.in4
-rw-r--r--src/pm-pmu.c56
6 files changed, 176 insertions, 141 deletions
diff --git a/pm/module.d/kernel b/pm/module.d/kernel
index 88a9e5d..157fc8a 100755
--- a/pm/module.d/kernel
+++ b/pm/module.d/kernel
@@ -1,38 +1,4 @@
#!/bin/sh
-check_suspend()
-{
- [ -c /dev/pmu ] || grep -q mem /sys/power/state
-}
-
-do_suspend()
-{
- if [ -c /dev/pmu ]; then
- pm-pmu --suspend
- else
- echo -n "mem" > /sys/power/state
- fi
-}
-
-check_hibernate()
-{
- [ -f /sys/power/disk ] && grep -q disk /sys/power/state
-}
-
-do_hibernate()
-{
- [ -n "${HIBERNATE_MODE}" ] && \
- grep -qw "${HIBERNATE_MODE}" /sys/power/disk && \
- echo -n "${HIBERNATE_MODE}" > /sys/power/disk
- echo -n "disk" > /sys/power/state
-}
-
-check_suspend_hybrid()
-{
- return 1
-}
-
-do_suspend_hybrid()
-{
- return 1
-}
+# this file is a stub -- pm-functions will always fall back to kernel methods
+# if nothing else is available. \ No newline at end of file
diff --git a/pm/module.d/tuxonice b/pm/module.d/tuxonice
index 57b7bb8..f4e3de9 100755
--- a/pm/module.d/tuxonice
+++ b/pm/module.d/tuxonice
@@ -11,41 +11,26 @@ for loc in "/sys/power/tuxonice" "/sys/power/suspend2"; do
[ -d "${loc}" ] && { TUXONICE_LOC="${loc}"; break; }
done
-check_suspend()
-{
- [ -c /dev/pmu ] || grep -q mem /sys/power/state
-}
+if [ -z "$HIBERNATE_MODULE" -a -n "$TUXONICE_LOC" ] && \
+ [ -f "${TUXONICE_LOC}/do_hibernate" ]; then
+ HIBERNATE_METHOD="tuxonice"
+ do_hibernate()
+ {
+ echo 5 > "${TUXONICE_LOC}/powerdown_method"
+ echo anything > "${TUXONICE_LOC}/do_hibernate"
+ }
+fi
-do_suspend()
-{
- if [ -c /dev/pmu ]; then
- pm-pmu --suspend
- else
- echo -n "mem" > /sys/power/state
- fi
-}
-
-check_hibernate()
-{
- [ -f "${TUXONICE_LOC}/do_hibernate" ]
-}
-
-do_hibernate()
-{
- echo 5 > "${TUXONICE_LOC}/powerdown_method"
- echo anything > "${TUXONICE_LOC}/do_hibernate"
-}
-
-check_suspend_hybrid()
-{
+if [ -z "$SUSPEND_HYBRID_MODULE" -a -n "$TUXONICE_LOC" ] && \
grep -q mem /sys/power/state && \
- [ -f "${TUXONICE_LOC}/do_hibernate" ]
-}
-do_suspend_hybrid()
-{
- echo 3 >"${TUXONICE_LOC}/powerdown_method"
- echo anything >"${TUXONICE_LOC}/do_hibernate"
- [ -f /sys/power/tuxonice/did_suspend_to_both ] && \
- [ "$(cat /sys/power/tuxonice/did_suspend_to_both)" != "1" ] && \
- REVERSE="thaw"
-}
+ [ -f "${TUXONICE_LOC}/do_hibernate" ]; then
+ SUSPEND_HYBRID_METHOD="tuxonice"
+ do_suspend_hybrid()
+ {
+ echo 3 >"${TUXONICE_LOC}/powerdown_method"
+ echo anything >"${TUXONICE_LOC}/do_hibernate"
+ [ -f /sys/power/tuxonice/did_suspend_to_both ] && \
+ [ "$(cat /sys/power/tuxonice/did_suspend_to_both)" != "1" ] && \
+ REVERSE="thaw"
+ }
+fi
diff --git a/pm/module.d/uswsusp b/pm/module.d/uswsusp
index 4647824..1bb1e68 100755
--- a/pm/module.d/uswsusp
+++ b/pm/module.d/uswsusp
@@ -1,13 +1,13 @@
#!/bin/sh
# disable processing of 99video
-before_hooks()
+uswsusp_hooks()
{
disablehook 90chvt "disabled by uswsusp"
disablehook 99video "disabled by uswsusp"
}
-get_quirks()
+uswsusp_get_quirks()
{
OPTS=""
ACPI_SLEEP=0
@@ -33,45 +33,7 @@ get_quirks()
[ "$QUIRK_NONE" = "true" ] && OPTS=""
}
-check_suspend()
-{
- command_exists s2ram || return 1
- [ -c /dev/pmu ] || grep -q mem /sys/power/state
-}
-
-do_suspend()
-{
- get_quirks
- s2ram --force $OPTS
-}
-
-check_hibernate()
-{
- [ -f /sys/power/disk ] && \
- grep -q disk /sys/power/state && \
- [ -c /dev/snapshot ] &&
- command_exists s2disk
-}
-
-do_hibernate()
-{
- s2disk
-}
-
-check_suspend_hybrid()
-{
- grep -q mem /sys/power/state && \
- command_exists s2both && \
- check_hibernate
-}
-
-do_suspend_hybrid()
-{
- get_quirks
- s2both --force $OPTS
-}
-
-sleep_method_help()
+uswsusp_help()
{
echo # first echo makes it look nicer.
echo "Video quirk handler options:"
@@ -89,3 +51,46 @@ sleep_method_help()
echo " --quirk-save-pci"
echo " --quirk-none"
}
+
+if [ -z "$SUSPEND_METHOD" ] && command_exists s2ram && \
+ ( grep -q mem /sys/power/state || \
+ ( [ -c /dev/pmu ] && pm-pmu --check; ); ); then
+ SUSPEND_METHOD="uswsusp"
+ do_suspend()
+ {
+ uswsusp_get_quirks
+ s2ram --force $OPTS
+ }
+ if [ "$METHOD" = "suspend" ]; then
+ add_before_hooks uswsusp_hooks
+ add_module_help uswsusp_help
+ fi
+fi
+
+if [ -z "$HIBERNATE_METHOD" ] && \
+ [ -f /sys/power/disk ] && \
+ grep -q disk /sys/power/state && \
+ [ -c /dev/snapshot ] &&
+ command_exists s2disk; then
+ HIBERNATE_METHOD="uswsusp"
+ do_hibernate()
+ {
+ s2disk
+ }
+fi
+
+if [ -z "$SUSPEND_HYBRID_METHOD" ] &&
+ grep -q mem /sys/power/state && \
+ command_exists s2both && \
+ check_hibernate; then
+ SUSPEND_HYBRID_METHOD="uswsusp"
+ do_suspend_hybrid()
+ {
+ uswsusp_get_quirks
+ s2both --force $OPTS
+ }
+ if [ "$METHOD" = "suspend_hybrid" ]; then
+ add_before_hooks uswsusp_hooks
+ add_module_help uswsusp_help
+ fi
+fi
diff --git a/pm/pm-functions.in b/pm/pm-functions.in
index f7492a0..dfbbc9f 100644
--- a/pm/pm-functions.in
+++ b/pm/pm-functions.in
@@ -44,6 +44,11 @@ DROP_PARAMETERS=""
PARAMETERS="${STORAGEDIR}/parameters"
INHIBIT="${STORAGEDIR}/inhibit"
PM_CMDLINE="$*"
+BEFORE_HOOKS=""
+MODULE_HELP=""
+SUSPEND_MODULE=""
+HIBERNATE_MODULE=""
+SUSPEND_HYBRID_MODULE=""
# when loading configuration files, allow stash-specific ones
# to override the pm-utils global ones.
@@ -90,6 +95,34 @@ log()
printf "$fmt" "$*"
}
+add_before_hooks() {
+ [ -z "$BEFORE_HOOKS" ] && BEFORE_HOOKS="$*" || \
+ BEFORE_HOOKS="$BEFORE_HOOKS $*"
+}
+
+add_module_help() {
+ [ -z "$MODULE_HELP" ] && MODULE_HELP="$*" || \
+ MODULE_HELP="$MODULE_HELP $*"
+}
+
+before_hooks()
+{
+ [ -z "$BEFORE_HOOKS" ] && return 0
+ local meth
+ for meth in $BEFORE_HOOKS; do
+ command_exists "$meth" && "$meth"
+ done
+}
+
+sleep_module_help()
+{
+ [ -z "$MODULE_HELP" ] && return 0
+ local meth
+ for meth in $MODULE_HELP; do
+ command_exists "$meth" && "$meth"
+ done
+}
+
# update PM_CMDLINE iff someone changed our parameters
update_parameters()
{
@@ -203,12 +236,42 @@ init_logfile()
exec > "$1" 2>&1
}
+check_suspend() { [ -n "$SUSPEND_MODULE" ]; }
+check_hibernate() { [ -n "$HIBERNATE_MODULE" ]; }
+check_suspend_hybrid() { [ -n "$SUSPEND_HYBRID_MODULE" ]; }
-SLEEP_FUNCTIONS="${PM_UTILS_LIBDIR}/module.d/${SLEEP_MODULE}"
-[ -f "${SLEEP_FUNCTIONS}" ] || {
- echo "Requested sleep module $SLEEP_MODULE not available."
- exit 1
-}
+# allow autodetection of sleep methods
+if [ "$SLEEP_MODULE" = "auto" ]; then
+ SLEEP_MODULE="tuxonice uswsusp"
+fi
+
+for mod in $SLEEP_MODULE; do
+ mod="${PM_UTILS_LIBDIR}/module.d/${mod}"
+ [ -f "$mod" ] || continue
+ . "$mod"
+done
-. "${SLEEP_FUNCTIONS}"
+# always fall back to kernel methods if nothing else was declared
+if [ -z "$SUSPEND_MODULE" ]; then
+ if grep -q mem /sys/power/state; then
+ SUSPEND_MODULE="kernel"
+ do_suspend() { echo -n "mem" >/sys/power/state; }
+ elif [ -c /dev/pmu ] && pm-pmu --check; then
+ SUSPEND_MODULE="kernel"
+ do_suspend() { pm-pmu --suspend; }
+ fi
+fi
+
+if [ -z "$HIBERNATE_MODULE" ] && \
+ [ -f /sys/power/disk ] && \
+ grep -q disk /sys/power/state; then
+ HIBERNATE_MODULE="kernel"
+ do_hibernate()
+ {
+ [ -n "${HIBERNATE_MODE}" ] && \
+ grep -qw "${HIBERNATE_MODE}" /sys/power/disk && \
+ echo -n "${HIBERNATE_MODE}" > /sys/power/disk
+ echo -n "disk" > /sys/power/state
+ }
+fi
diff --git a/src/pm-action.in b/src/pm-action.in
index bc83b3c..88bdb4e 100755
--- a/src/pm-action.in
+++ b/src/pm-action.in
@@ -26,6 +26,7 @@
# The rule here? Simplicity.
export STASHNAME=pm-suspend
+export METHOD="$(echo ${0##*pm-} |tr - _)"
. "@PM-UTILS-LIBDIR@/pm-functions"
help()
@@ -34,7 +35,7 @@ help()
echo
echo "Options can change how suspend or hibernate is done."
run_hooks sleep help
- command_exists sleep_method_help && sleep_method_help
+ sleep_module_help
exit 0
}
@@ -67,7 +68,6 @@ do
shift
done
-METHOD="$(echo ${0##*pm-} |tr - _)"
command_exists "check_$METHOD" && command_exists "do_$METHOD" || {
log "pm-utils does not know how to $METHOD on this system."
diff --git a/src/pm-pmu.c b/src/pm-pmu.c
index 475477e..1fa7b38 100644
--- a/src/pm-pmu.c
+++ b/src/pm-pmu.c
@@ -41,12 +41,18 @@ typedef u_int32_t __u32;
#endif
static int
-pmu_sleep(const int fd)
+pmu_can_sleep(const int fd)
{
unsigned long arg = 0;
-
if (ioctl(fd, PMU_IOC_CAN_SLEEP, &arg) < 0 || arg != 1)
return 1;
+ return 0;
+}
+
+static int
+pmu_sleep(const int fd)
+{
+ unsigned long arg = 0;
if (ioctl(fd, PMU_IOC_SLEEP, arg) < 0)
return 1;
@@ -56,33 +62,43 @@ pmu_sleep(const int fd)
static inline int
print_usage(FILE *output, int retval)
{
- fprintf(output, "usage: pm-pmu --suspend\n");
+ fprintf(output, "usage: pm-pmu --suspend | --check\n");
return retval;
}
int main(int argc, char *argv[])
{
+ int task=0,fd=0,ret=0;
if (argc != 2)
return print_usage(stderr, 1);
-
if (!strcmp(argv[1], "--help")) {
- return print_usage(stdout, 0);
- } else if (access("/dev/pmu", W_OK)) {
- return 1;
- } else if (!strcmp(argv[1], "--suspend")) {
- int fd, ret;
-
- if ((fd = open("/dev/pmu", O_RDWR)) < 0) {
- perror("open");
- return 1;
- }
-
- ret = pmu_sleep(fd);
- close(fd);
- return ret;
+ task=1;
+ } else if (!strcmp(argv[1],"--check")) {
+ task=2;
+ } else if (!strcmp(argv[1],"--suspend")) {
+ task=3;
}
-
- return print_usage(stderr, 1);
+ switch (task) {
+ case 0: ret = print_usage(stderr, 1); break;
+ case 1: ret = print_usage(stdout, 0); break;
+ case 2: /* this is intentional */
+ case 3:
+ if (access("/dev/pmu", W_OK)) {
+ ret = 1;
+ } else {
+ if ((fd = open("/dev/pmu", O_RDWR)) < 0) {
+ perror("open");
+ return 1;
+ }
+
+ ret = pmu_can_sleep(fd);
+ if (!ret && task == 3)
+ ret = pmu_sleep(fd);
+ close(fd);
+ }
+ break;
+ }
+ return ret;
}
/*