From: Matthew Garrett When leaving S3 state, the AGP bridge may not have all PCI configuration registers set in the same way as they were at boot. This should be fixed by pci_restore_state - however, the APBASE register cannot be set to conflict with the APSIZE register. If APSIZE is larger than it was before suspend, pci_restore_state will not restore APBASE correctly. The attached patch adds an extra item to the agp_bridge_data structure and uses it to store the value of APBASE. On resume, this is then written after APSIZE has been set. This patch only touches the path used for Intel chipsets without integrated graphics, and may need to be extended to work with the others. Without this patch, I get the symptoms described in bug 4921 - APBASE ends up overlapping various PCI devices, and as a result they fail to work after resume. Signed-off-by: Matthew Garrett Cc: Dave Jones Signed-off-by: Andrew Morton --- dev/null | 0 drivers/char/agp/agp.h | 1 + drivers/char/agp/intel-agp.c | 12 +++++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff -puN drivers/char/agp/agp.h~agp-restore-apbase-after-setting-apsize drivers/char/agp/agp.h --- devel/drivers/char/agp/agp.h~agp-restore-apbase-after-setting-apsize 2005-07-25 22:07:54.000000000 -0700 +++ devel-akpm/drivers/char/agp/agp.h 2005-07-25 22:07:54.000000000 -0700 @@ -143,6 +143,7 @@ struct agp_bridge_data { char major_version; char minor_version; struct list_head list; + u32 apbase_config; }; #define KB(x) ((x) * 1024) diff -puN drivers/char/agp/intel-agp.c~agp-restore-apbase-after-setting-apsize drivers/char/agp/intel-agp.c --- devel/drivers/char/agp/intel-agp.c~agp-restore-apbase-after-setting-apsize 2005-07-25 22:07:54.000000000 -0700 +++ devel-akpm/drivers/char/agp/intel-agp.c 2005-07-25 22:07:54.000000000 -0700 @@ -1047,9 +1047,15 @@ static int intel_845_configure(void) /* aperture size */ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); - /* address to map to */ - pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); - agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + if (agp_bridge->apbase_config != 0) { + pci_write_config_dword(agp_bridge->dev, AGP_APBASE, + agp_bridge->apbase_config); + } else { + /* address to map to */ + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->apbase_config = temp; + } /* attbase - aperture base */ pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); diff -L drivers/char/agp.new/agp.h -puN /dev/null /dev/null diff -L drivers/char/agp.new/intel-agp.c -puN /dev/null /dev/null _