intel driver suspend/resume failure

Wang Zhenyu zhenyu.z.wang at intel.com
Mon Jun 11 01:41:44 PDT 2007


On 2007.06.11 09:20:28 +0000, Wang Zhenyu wrote:
> 
> DRM should be the way to go, thinking about many users are struggled in
> mystery vbios post issue in resume. One thing to note is that even we go 
> DRM for better resume support, we still need to fix .suspend/.resume in 
> intel_agp, as I said it's in hand of pci state save/restore. From Andreas
> Mohr's experience on i815 and your 256 bytes dump/restore of pci state,
> I think we can fix it by simply always save whole 256 bytes state, which
> can eliminate those possible broken cases. 

I just made one for this, also include Andreas Mohr in cc list. I think we
can simply hook this one to intel-agp. It's based on latest kernel git and
patch set on Dave Jone's agpgart.git tip. 
http://git.kernel.org/?p=linux/kernel/git/davej/agpgart.git;a=summary

---
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index d383168..8f73814 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -110,6 +110,7 @@ static struct _intel_private {
 	 * popup and for the GTT.
 	 */
 	int gtt_entries;			/* i830+ */
+	u32 extra_saved_config[48];	/* suspend/resume */
 } intel_private;
 
 static int intel_i810_fetch_size(void)
@@ -1974,9 +1975,30 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
+static int agp_intel_suspend (struct pci_dev *pdev, pm_message_t state)
+{
+	int i;
+
+	pci_save_state(pdev);
+	pci_save_state(intel_private.pcidev);
+
+	for (i = 0; i < 48; i++)
+	    pci_read_config_dword(intel_private.pcidev, i*4+64,
+		    &intel_private.extra_saved_config[i]);
+
+	pci_set_power_state(intel_private.pcidev,
+		pci_choose_state(intel_private.pcidev, state));
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
 static int agp_intel_resume(struct pci_dev *pdev)
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
+	int i = 0;
+	u32 val;
 
 	pci_restore_state(pdev);
 
@@ -1984,8 +2006,21 @@ static int agp_intel_resume(struct pci_dev *pdev)
 	 * as host bridge (00:00) resumes before graphics device (02:00),
 	 * then our access to its pci space can work right.
 	 */
-	if (intel_private.pcidev)
+	if (intel_private.pcidev) {
 		pci_restore_state(intel_private.pcidev);
+		for (i = 0; i < 48; i++) {
+			pci_read_config_dword(intel_private.pcidev, i*4+64, &val);
+			if (val != intel_private.extra_saved_config[i]) {
+				printk(KERN_DEBUG "intel-agp: Writing back config space"
+					" at offset %x (was %x, writing %x)\n",
+					i*4+64, val,
+					(int)intel_private.extra_saved_config[i]);
+				pci_write_config_dword(intel_private.pcidev,
+					i*4+64,
+					intel_private.extra_saved_config[i]);
+			}
+		}
+	}
 
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
@@ -2062,6 +2097,7 @@ static struct pci_driver agp_intel_pci_driver = {
 	.probe		= agp_intel_probe,
 	.remove		= __devexit_p(agp_intel_remove),
 #ifdef CONFIG_PM
+	.suspend	= agp_intel_suspend,
 	.resume		= agp_intel_resume,
 #endif
 };
---



More information about the xorg mailing list