intel driver suspend/resume failure
Wang Zhenyu
zhenyu.z.wang at intel.com
Mon Jun 11 18:35:59 PDT 2007
On 2007.06.11 23:49:20 +0000, Wang Zhenyu wrote:
> > Why is there a check for intel_private.pcidev in the resume path but not
> > the suspend path?
>
> yep, I should also check it in suspend path, in case like my dell 875p
> desktop, which has no gfx chip on MCH. Thanks.
Here's the revised patch I'd like to send lkml for comment.
---
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index d383168..bc18241 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,33 @@ 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);
+
+ if (intel_private.pcidev) {
+ 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 +2009,24 @@ 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_set_power_state(intel_private.pcidev, PCI_D0);
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,
+ 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 +2103,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