summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rwxr-xr-xpm/sleep.d/00auto-quirk88
-rwxr-xr-xpm/sleep.d/98smart-kernel-video12
-rwxr-xr-xpm/sleep.d/99video38
-rw-r--r--pm/sleep.d/Makefile.am1
5 files changed, 135 insertions, 8 deletions
diff --git a/TODO b/TODO
index 30cf665..bb3ab1d 100644
--- a/TODO
+++ b/TODO
@@ -27,7 +27,3 @@
* The man pages should be improved to document new configuration variables,
contain examples how to write hooks etc.
-* Provide an "--auto" option for pm-suspend, which tries to get the quirks from
- hal. Add an option (let's call it "--store-quirks-as-fdi" for now), which
- allows to easily generate an fdi file with the quirk parameters passed to
- pm-suspend.
diff --git a/pm/sleep.d/00auto-quirk b/pm/sleep.d/00auto-quirk
new file mode 100755
index 0000000..0781411
--- /dev/null
+++ b/pm/sleep.d/00auto-quirk
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+. "${PM_FUNCTIONS}"
+
+do_add_quirks()
+{
+ add_parameters $(lshal | \
+ awk -F '[. ]' \
+ '/ power_management.quirk.[a-z_]+ = true/ \
+ {gsub(/_/, "-", $5); printf("--quirk-%s", $5)}')
+}
+
+do_save_quirks()
+{
+ # better to gather too much information than not enough
+ hgp="hal-get-property --udi /org/freedesktop/Hal/devices/computer --key"
+ vendor=$($hgp system.hardware.vendor)
+ product=$($hgp system.hardware.product)
+ firmware=$($hgp system.firmware.version)
+ video_vendor=$($hgp system.hardware.primary_video.vendor --hex)
+ video_card=$($hgp system.hardware.primary_video.product --hex)
+ (
+ exec >"/tmp/pm-utils-created.fdi"
+ echo '<?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- -->'
+ echo '<!-- Created by pm-utils -->'
+ echo '<deviceinfo version="0.2">'
+ echo ' <device>'
+ echo " <match key=\"system.hardware.vendor\" string=\"${vendor}\">"
+ echo " <match key=\"system.hardware.product\" string=\"${product}\">"
+ echo " <match key=\"system.firmware.version\" string=\"${firmware}\">"
+ echo " <match key=\"system.hardware.primary_video.vendor\" int=\"0x${video_vendor}\">"
+ echo " <match key=\"system.hardware.primary_video.product\" int=\"0x${video_card}\">"
+ for p in ${PM_CMDLINE}; do
+ quirk="${p#--quirk-}"
+ [ "$p" = "$quirk" ] && continue
+ echo " <merge key=\"power_management.quirk.${quirk}\" type=\"bool\">true</merge>" |tr - _
+ done
+ echo " </match>"
+ echo " </match>"
+ echo " </match>"
+ echo " </match>"
+ echo " </match>"
+ echo " </device>"
+ echo "</deviceinfo>"
+ )
+ echo "FDI file created as /tmp/pm-utils-created.fdi"
+}
+
+maybe_add_quirks()
+{
+ [ -z "$PM_CMDLINE" ] && {
+ command_exists lshal || return $NA
+ do_add_quirks
+ return 0
+ }
+ command_exists lshal || {
+ echo "--auto-quirks requires HAL. Aborting"
+ return 1
+ }
+ has_parameter --auto-quirks || return 0
+ do_add_quirks
+ remove_parameters --auto-quirks
+}
+
+maybe_save_quirks()
+{
+ has_parameter --store-quirks-as-fdi && do_save_quirks
+ return 0
+}
+
+help()
+{
+ echo
+ echo "Auto quirk handler option:"
+ echo
+ echo " --auto-quirks"
+ echo " Running without any options will also invoke auto quirk."
+ echo
+ echo " --store-quirks-as-fdi"
+}
+
+case $1 in
+ suspend|hibernate) maybe_add_quirks ;;
+ thaw|resume) maybe_save_quirks ;;
+ help) help ;;
+ *) exit $NA ;;
+esac
+
diff --git a/pm/sleep.d/98smart-kernel-video b/pm/sleep.d/98smart-kernel-video
index 058149a..1043e94 100755
--- a/pm/sleep.d/98smart-kernel-video
+++ b/pm/sleep.d/98smart-kernel-video
@@ -28,7 +28,9 @@ smart_kernel_nvidia()
--quirk-vbemode-restore \
--quirk-vbestate-restore \
--quirk-reset-brightness \
- --quirk-radeon-off
+ --quirk-radeon-off \
+ --quirk-no-fb \
+ --quirk-pci-save
}
smart_kernel_fglrx()
@@ -45,7 +47,9 @@ smart_kernel_fglrx()
--quirk-vbemode-restore \
--quirk-vbestate-restore \
--quirk-reset-brightness \
- --quirk-radeon-off
+ --quirk-radeon-off \
+ --quirk-no-fb \
+ --quirk-pci-save
}
smart_kernel_intel()
@@ -65,7 +69,9 @@ smart_kernel_intel()
--quirk-vbemode-restore \
--quirk-vbestate-restore \
--quirk-reset-brightness \
- --quirk-radeon-off
+ --quirk-radeon-off \
+ --quirk-no-fb \
+ --quirk-pci-save
}
smart_kernel_video()
diff --git a/pm/sleep.d/99video b/pm/sleep.d/99video
index b927a1b..dc8590a 100755
--- a/pm/sleep.d/99video
+++ b/pm/sleep.d/99video
@@ -26,6 +26,8 @@ for opt in $PM_CMDLINE; do
vbemode-restore) QUIRK_VBEMODE_RESTORE="true" ;;
vbestate-restore) QUIRK_VBESTATE_RESTORE="true" ;;
vga-mode3) QUIRK_VGA_MODE_3="true" ;;
+ no-fb) QUIRK_NOFB="true" ;;
+ pci-save) QUIRK_PCI_SAVE="true" ;;
none) QUIRK_NONE="true" ;;
*) continue ;;
esac
@@ -53,6 +55,15 @@ else
radeon() { echo "radeontool not found" 1>&2; return 1; }
fi
+die_if_framebuffer()
+{
+ [ -d "/sys/class/graphics/fb0" ] || return
+ echo "--quirk-no-fb passed, but system is using a framebuffer."
+ echo "Aborting."
+ exit 1
+}
+
+
save_fbcon()
{
local con
@@ -105,6 +116,28 @@ vbe_post()
radeon_off() { radeon dac off; radeon light off; }
radeon_on() { radeon dac on; radeon light on; }
+# save and restore video card PCI config state
+save_pci()
+{
+ local pci="/sys/bus/pci/devices"
+ for dev in "${pci}"/*; do
+ [ -f "${dev}/class" ] || continue
+ [ $(cat "${dev}/class") = "0x030000" ] || continue
+ [ -f "${dev}/config" ] || continue
+ # it is a video card, it has a configuration. Save it.
+ savestate "pci_video_${dev##*/}" <${dev}/config
+ done
+}
+
+restore_pci()
+{
+ local pci="/sys/bus/pci/devices"
+ for dev in "${pci}"/*; do
+ state_exists "pci_video_${dev##*/}" || continue
+ restorestate "pci_video_${dev##*/}" > "${dev}/config"
+ done
+}
+
suspend_video()
{
# 0=nothing, 1=s3_bios, 2=s3_mode, 3=both
@@ -113,16 +146,19 @@ suspend_video()
quirk "${QUIRK_S3_MODE}" && acpi_flag=$(($acpi_flag + 2))
[ 0 -ne $acpi_flag ] && sysctl -w kernel.acpi_video_flags=$acpi_flag
+ quirk "${QUIRK_NOFB}" && die_if_framebuffer
quirk "${QUIRK_VBESTATE_RESTORE}" && vbe_savestate
quirk "${QUIRK_VBEMODE_RESTORE}" && vbe_savemode
quirk "${QUIRK_RADEON_OFF}" && radeon_off
+ quirk "${QUIRK_PCI_SAVE}" && pci_save
quirk "${QUIRK_VGA_MODE_3}" && vbe vbemode set 3
quirk "${QUIRK_DPMS_SUSPEND}" && vbe dpms suspend
- save_fbcon # there should be a quirk, but HAL does not pass it.
+ save_fbcon
}
resume_video()
{
# We might need to do one or many of these quirks
+ quirk "${QUIRK_PCI_SAVE}" && pci_restore
quirk "${QUIRK_VBE_POST}" && vbe_post
quirk "${QUIRK_VBESTATE_RESTORE}" && vbe_restorestate
quirk "${QUIRK_VBEMODE_RESTORE}" && vbe_restoremode
diff --git a/pm/sleep.d/Makefile.am b/pm/sleep.d/Makefile.am
index a2f31cc..2972d20 100644
--- a/pm/sleep.d/Makefile.am
+++ b/pm/sleep.d/Makefile.am
@@ -1,6 +1,7 @@
sleepdir = $(libdir)/pm-utils/sleep.d
sleep_SCRIPTS = \
+ 00auto-quirk \
00logging \
00powersave \
01grub \