227 lines
5.7 KiB
Bash
Executable File
227 lines
5.7 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Copyright 2006-2007 Richard Hughes <richard@hughsie.com>
|
|
# Copyright 2007 Peter Jones <pjones@redhat.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of version 2 of the GNU General Public License as
|
|
# published by the Free Software Foundation.
|
|
|
|
# Handle video quirks. If you are having suspend/resume issues,
|
|
# troubleshooting using this hook is probably the best place to start.
|
|
# If it weren't for video card quirks, suspend/resume on Linux would be
|
|
# a whole lot more stable.
|
|
|
|
# only needed on x86, quickly exit on other architectures as this is rather
|
|
# expensive
|
|
ARCH=`uname -m`
|
|
if [ "$ARCH" = "${ARCH%86}" -a "$ARCH" = "${ARCH#x86}" ]; then
|
|
exit 0;
|
|
fi
|
|
|
|
. "${PM_FUNCTIONS}"
|
|
|
|
for opt in $PM_CMDLINE; do
|
|
case "${opt##--quirk-}" in # just quirks, please
|
|
dpms-on) QUIRK_DPMS_ON="true" ;;
|
|
dpms-suspend) QUIRK_DPMS_SUSPEND="true" ;;
|
|
radeon-off) QUIRK_RADEON_OFF="true" ;;
|
|
reset-brightness) QUIRK_RESET_BRIGHTNESS="true" ;;
|
|
s3-bios) QUIRK_S3_BIOS="true" ;;
|
|
s3-mode) QUIRK_S3_MODE="true" ;;
|
|
vbe-post) QUIRK_VBE_POST="true" ;;
|
|
vbemode-restore) QUIRK_VBEMODE_RESTORE="true" ;;
|
|
vbestate-restore) QUIRK_VBESTATE_RESTORE="true" ;;
|
|
vga-mode-3) QUIRK_VGA_MODE_3="true" ;;
|
|
no-fb) QUIRK_NOFB="true" ;;
|
|
save-pci) QUIRK_SAVE_PCI="true" ;;
|
|
no-chvt) QUIRK_NO_CHVT="true" ;;
|
|
none) QUIRK_NONE="true" ;;
|
|
*) continue ;;
|
|
esac
|
|
done
|
|
|
|
reset_brightness()
|
|
{
|
|
for bl in /sys/class/backlight/* ; do
|
|
[ -f "$bl/brightness" ] || continue
|
|
BR="$(cat $bl/brightness)"
|
|
echo 0 > "$bl/brightness"
|
|
echo "$BR" > "$bl/brightness"
|
|
done
|
|
}
|
|
|
|
if command_exists vbetool; then
|
|
vbe() { vbetool "$@"; }
|
|
else
|
|
vbe() { echo "vbetool not installed!" 1>&2; return 1; }
|
|
fi
|
|
|
|
if command_exists radeontool; then
|
|
radeon() { radeontool "$@"; }
|
|
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
|
|
for con in /sys/class/graphics/*/state; do
|
|
[ -f $con ] || continue
|
|
echo 1 >"${con}"
|
|
done
|
|
}
|
|
|
|
resume_fbcon()
|
|
{
|
|
local con
|
|
for con in /sys/class/graphics/*/state; do
|
|
[ -f $con ] || continue
|
|
echo 0 >"${con}"
|
|
done
|
|
}
|
|
|
|
maybe_chvt()
|
|
{
|
|
is_set "$QUIRK_NO_CHVT" && return
|
|
fgconsole |savestate console
|
|
chvt 63
|
|
}
|
|
|
|
maybe_deallocvt()
|
|
{
|
|
state_exists console || return 0
|
|
chvt $(restorestate console)
|
|
deallocvt 63
|
|
}
|
|
|
|
# Some tiny helper functions for quirk handling
|
|
quirk() { is_set "$1" && [ -z $QUIRK_NONE ]; }
|
|
|
|
# save/restore vbe state
|
|
vbe_savestate() { vbe vbestate save |savestate vbestate; }
|
|
vbe_restorestate() { restorestate vbestate |vbe vbestate restore; }
|
|
|
|
# save/restore the vbe mode
|
|
vbe_savemode() { vbe vbemode get |savestate vbemode; }
|
|
vbe_restoremode()
|
|
{
|
|
# this is a little mode complicated to handle special-casing mode 3.
|
|
local vbemode=$(restorestate vbemode)
|
|
if [ "$vbemode" = "3" ]; then
|
|
vbe vgamode set $vbemode
|
|
else
|
|
vbe vbemode set $vbemode
|
|
fi
|
|
}
|
|
|
|
# post the video card
|
|
vbe_post()
|
|
{
|
|
local rom="/var/run/video.rom"
|
|
# if we do not have a romfile, do not post with it.
|
|
[ -f "$rom" ] || unset rom
|
|
vbe post $rom
|
|
sleep 0.1
|
|
}
|
|
|
|
# turn critical bits of radeon cards off/on
|
|
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
|
|
local acpi_flag=0
|
|
quirk "${QUIRK_S3_BIOS}" && acpi_flag=$(($acpi_flag + 1))
|
|
quirk "${QUIRK_S3_MODE}" && acpi_flag=$(($acpi_flag + 2))
|
|
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_SAVE_PCI}" && save_pci
|
|
quirk "${QUIRK_VGA_MODE_3}" && vbe vbemode set 3
|
|
quirk "${QUIRK_DPMS_SUSPEND}" && vbe dpms suspend
|
|
save_fbcon
|
|
}
|
|
resume_video()
|
|
{
|
|
# We might need to do one or many of these quirks
|
|
quirk "${QUIRK_SAVE_PCI}" && restore_pci
|
|
quirk "${QUIRK_VBE_POST}" && vbe_post
|
|
quirk "${QUIRK_VBESTATE_RESTORE}" && vbe_restorestate
|
|
quirk "${QUIRK_VBEMODE_RESTORE}" && vbe_restoremode
|
|
resume_fbcon # also should be handled by a quirk.
|
|
quirk "${QUIRK_RADEON_OFF}" && radeon_on
|
|
quirk "${QUIRK_DPMS_ON}" && vbe dpms on
|
|
quirk "${QUIRK_RESET_BRIGHTNESS}" && reset_brightness
|
|
return 0 # avoid spurious hook exit failure message.
|
|
}
|
|
|
|
help() {
|
|
echo # first echo makes it look nicer.
|
|
echo "Video quirk handler options:"
|
|
echo
|
|
echo " --quirk-dpms-on"
|
|
echo " --quirk-dpms-suspend"
|
|
echo " --quirk-radeon-off"
|
|
echo " --quirk-reset-brightness"
|
|
echo " --quirk-s3-bios"
|
|
echo " --quirk-s3-mode"
|
|
echo " --quirk-vbe-post"
|
|
echo " --quirk-vbemode-restore"
|
|
echo " --quirk-vbestate-restore"
|
|
echo " --quirk-vga-mode-3"
|
|
echo " --quirk-none"
|
|
}
|
|
|
|
case "$1" in
|
|
suspend) maybe_chvt; suspend_video ;;
|
|
hibernate) maybe_chvt
|
|
if is_set "$HIBERNATE_RESUME_POST_VIDEO"; then
|
|
suspend_video
|
|
fi
|
|
;;
|
|
resume) resume_video; maybe_deallocvt;;
|
|
thaw)
|
|
if is_set "${HIBERNATE_RESUME_POST_VIDEO}"; then
|
|
resume_video
|
|
fi
|
|
maybe_deallocvt
|
|
;;
|
|
help) help ;;
|
|
esac
|