All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Seyfried <seife@suse.de>
To: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: suspend-devel List <suspend-devel@lists.sourceforge.net>,
	linux-acpi@vger.kernel.org, Miroslav Ruda <ruda@ics.muni.cz>
Subject: Re: suspend to RAM on lifebook 7110
Date: Mon, 18 Dec 2006 18:48:51 +0100	[thread overview]
Message-ID: <20061218174851.GE13541@suse.de> (raw)
In-Reply-To: <20061218120551.GA27546@srcf.ucam.org>

On Mon, Dec 18, 2006 at 12:05:51PM +0000, Matthew Garrett wrote:
> On Mon, Dec 18, 2006 at 12:29:16PM +0100, Stefan Seyfried wrote:

> >  - implement this as a workaround in userspace?
> 
> Might be easier for the moment, though I agree that it's less than 
> ideal.

Ok, so how about that (compiled, not really tested. I tested the 
"save_vga_pci" by outputting to a file and comparing to /proc and sysfs),
but i have no hardware here that needs this:

Warning: watch out for my maybe creative usage of "*" and "&" and complain
if you find obvious errors ;-)

Index: s2ram.c
===================================================================
RCS file: /cvsroot/suspend/suspend/s2ram.c,v
retrieving revision 1.45
diff -u -p -r1.45 s2ram.c
--- s2ram.c	20 Sep 2006 16:23:51 -0000	1.45
+++ s2ram.c	18 Dec 2006 16:44:47 -0000
@@ -11,12 +11,16 @@
 #include <errno.h>
 #include <string.h>
 
+#include <pci/pci.h>
+
 #define S2RAM
 #include "vbetool/vbetool.h"
 #include "vt.h"
 #include "s2ram.h"
 
 static void *vbe_buffer;
+unsigned char vga_pci_state[256];
+struct pci_dev vga_dev;
 /* Flags set from whitelist */
 static int flags, vbe_mode = -1;
 char bios_version[1024], sys_vendor[1024], sys_product[1024], sys_version[1024];
@@ -36,6 +40,7 @@ char bios_version[1024], sys_vendor[1024
 #define UNSURE      0x20	/* unverified entries from acpi-support 0.59 */
 #define NOFB        0x40	/* must not use a frame buffer */
 #define VBE_MODE    0x80	/* machine needs "vbetool vbemode get / set" */
+#define PCI_SAVE   0x100	/* we need to save the VGA PCI registers */
 
 #include "whitelist.c"
 
@@ -67,14 +72,15 @@ void machine_known(int i)
 	       "    bios_version = '%s'\n", i,
 	       whitelist[i].sys_vendor, whitelist[i].sys_product,
 	       whitelist[i].sys_version, whitelist[i].bios_version);
-	printf("Fixes: 0x%x  %s%s%s%s%s%s%s\n", flags,
+	printf("Fixes: 0x%x  %s%s%s%s%s%s%s%s\n", flags,
 	       (flags & VBE_SAVE) ? "VBE_SAVE " : "",
 	       (flags & VBE_POST) ? "VBE_POST " : "",
 	       (flags & VBE_MODE) ? "VBE_MODE " : "",
 	       (flags & RADEON_OFF) ? "RADEON_OFF " : "",
 	       (flags & S3_BIOS) ? "S3_BIOS " : "",
 	       (flags & S3_MODE) ? "S3_MODE " : "",
-	       (flags & NOFB) ? "NOFB " : "");
+	       (flags & NOFB) ? "NOFB " : "",
+	       (flags & PCI_SAVE) ? "PCI_SAVE " : "");
 	if (flags & UNSURE)
 		printf("Machine is in the whitelist but perhaps using "
 		       "vbetool unnecessarily.\n"
@@ -143,6 +149,35 @@ int s2ram_check(int id)
 	return ret;
 }
 
+struct pci_dev find_vga(void)
+{
+	struct pci_access *pacc;
+	struct pci_dev *dev;
+
+	pacc = pci_alloc();	/* Get the pci_access structure */
+	pci_init(pacc);		/* Initialize the PCI library */
+	pci_scan_bus(pacc);	/* We want to get the list of devices */
+
+	for (dev=pacc->devices; dev; dev=dev->next) {
+		pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS);
+		if (dev->device_class == 0x300)
+			break;
+	}
+	pci_cleanup(pacc);
+
+	return *dev;
+}
+
+void save_vga_pci(struct pci_dev dev)
+{
+	pci_read_block(&dev, 0, vga_pci_state, 256);
+}
+
+void restore_vga_pci(struct pci_dev dev)
+{
+	pci_write_block(&dev, 0, vga_pci_state, 256);
+}
+
 /* warning: we have to be on a text console when calling this */
 int s2ram_hacks(void)
 {
@@ -171,6 +206,12 @@ int s2ram_hacks(void)
 		printf("Calling radeon_cmd_light(0)\n");
 		radeon_cmd_light(0);
 	}
+	if (flags & PCI_SAVE) {
+		vga_dev = find_vga();
+		printf("saving PCI config of device %02x:%02x.%d\n",
+			 vga_dev.bus, vga_dev.dev, vga_dev.func);
+		save_vga_pci(vga_dev);
+	}
 
 	return 0;
 }
@@ -216,6 +257,11 @@ int s2ram_do(void)
 
 void s2ram_resume(void)
 {
+	if (flags & PCI_SAVE) {
+		printf("saving PCI config of device %02x:%02x.%d\n",
+			 vga_dev.bus, vga_dev.dev, vga_dev.func);
+		restore_vga_pci(vga_dev);
+	}
 	// FIXME: can we call vbetool_init() multiple times without cleaning up?
 	if (flags & VBE_POST) {
 		vbetool_init();
@@ -260,6 +306,7 @@ static void usage(void)
 	       "    -a, --acpi_sleep: set the acpi_sleep parameter before "
 				       "suspend\n"
 	       "                      1=s3_bios, 2=s3_mode, 3=both\n"
+	       "    -v, --pci_save:   save the PCI config space for the VGA card.\n"
 	       "\n");
 	exit(1);
 }
@@ -278,10 +325,11 @@ int main(int argc, char *argv[])
 		{ "radeontool",	no_argument,		NULL, 'r'},
 		{ "identify",	no_argument,		NULL, 'i'},
 		{ "acpi_sleep",	required_argument,	NULL, 'a'},
+		{ "pci_save",	no_argument,		NULL, 'v'},
 		{ NULL,		0,			NULL,  0 }
 	};
 
-	while ((i = getopt_long(argc, argv, "nhfspmria:", options, NULL)) != -1) {
+	while ((i = getopt_long(argc, argv, "nhfspmriva:", options, NULL)) != -1) {
 		switch (i) {
 		case 'h':
 			usage();
@@ -311,6 +359,9 @@ int main(int argc, char *argv[])
 		case 'a':
 			flags |= (atoi(optarg) & (S3_BIOS | S3_MODE));
 			break;
+		case 'v':
+			flags |= PCI_SAVE;
+			break;
 		default:
 			usage();
 			break;

-- 
Stefan Seyfried                  \ "I didn't want to write for pay. I
QA / R&D Team Mobile Devices      \ wanted to be paid for what I write."
SUSE LINUX Products GmbH, Nürnberg \                    -- Leonard Cohen

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

  reply	other threads:[~2006-12-18 17:48 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-08 12:33 suspend to RAM on lifebook 7110 Frank Ursel
2006-12-08 21:13 ` Miroslav Ruda
2006-12-18  6:51   ` Stefan Seyfried
2006-12-18 11:11     ` Matthew Garrett
2006-12-18 11:29       ` Stefan Seyfried
2006-12-18 12:05         ` Matthew Garrett
2006-12-18 17:48           ` Stefan Seyfried [this message]
2006-12-18 20:00             ` Rafael J. Wysocki
2006-12-18 12:16         ` Pavel Machek
2006-12-18 15:55           ` Rafael J. Wysocki
  -- strict thread matches above, loose matches on Subject: below --
2006-12-07 22:18 Miroslav Ruda
2006-12-18  6:38 ` Stefan Seyfried
2006-12-18  9:30   ` Frank Ursel
2006-12-18 16:53   ` Miroslav Ruda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20061218174851.GE13541@suse.de \
    --to=seife@suse.de \
    --cc=linux-acpi@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    --cc=ruda@ics.muni.cz \
    --cc=suspend-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.