intel-agp: fixup resource handling in flush code.

The flush code resource handling was having problems where some BIOS
reserve the resource in a pnp block and some don't.

Also there was a bug in that configure was being called at resume
and resetting some of the structs.

Signed-off-by: Dave Airlie <airlied@linux.ie>

authored by Dave Airlie and committed by Dave Airlie 4d64dd9e 4e8b6e25

+23 -10
+23 -10
drivers/char/agp/intel-agp.c
··· 126 126 }; 127 127 struct page *i8xx_page; 128 128 struct resource ifp_resource; 129 + int resource_valid; 129 130 } intel_private; 130 131 131 132 static int intel_i810_fetch_size(void) ··· 604 603 flush_agp_mappings(); 605 604 606 605 __free_page(intel_private.i8xx_page); 606 + intel_private.i8xx_page = NULL; 607 607 } 608 608 609 609 static void intel_i830_setup_flush(void) 610 610 { 611 + /* return if we've already set the flush mechanism up */ 612 + if (intel_private.i8xx_page) 613 + return; 611 614 612 615 intel_private.i8xx_page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); 613 616 if (!intel_private.i8xx_page) { ··· 851 846 pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp); 852 847 if (!(temp & 0x1)) { 853 848 intel_alloc_chipset_flush_resource(); 854 - 849 + intel_private.resource_valid = 1; 855 850 pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); 856 851 } else { 857 852 temp &= ~1; 858 853 854 + intel_private.resource_valid = 1; 859 855 intel_private.ifp_resource.start = temp; 860 856 intel_private.ifp_resource.end = temp + PAGE_SIZE; 861 857 ret = request_resource(&iomem_resource, &intel_private.ifp_resource); 862 - if (ret) { 863 - intel_private.ifp_resource.start = 0; 864 - printk("Failed inserting resource into tree\n"); 865 - } 858 + /* some BIOSes reserve this area in a pnp some don't */ 859 + if (ret) 860 + intel_private.resource_valid = 0; 866 861 } 867 862 } 868 863 ··· 878 873 879 874 intel_alloc_chipset_flush_resource(); 880 875 876 + intel_private.resource_valid = 1; 881 877 pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4, 882 878 upper_32_bits(intel_private.ifp_resource.start)); 883 879 pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); ··· 888 882 temp_lo &= ~0x1; 889 883 l64 = ((u64)temp_hi << 32) | temp_lo; 890 884 885 + intel_private.resource_valid = 1; 891 886 intel_private.ifp_resource.start = l64; 892 887 intel_private.ifp_resource.end = l64 + PAGE_SIZE; 893 888 ret = request_resource(&iomem_resource, &intel_private.ifp_resource); 894 - if (!ret) { 895 - printk("Failed inserting resource into tree - continuing\n"); 896 - } 889 + /* some BIOSes reserve this area in a pnp some don't */ 890 + if (ret) 891 + intel_private.resource_valid = 0; 897 892 } 898 893 } 899 894 900 895 static void intel_i9xx_setup_flush(void) 901 896 { 902 - /* setup a resource for this object */ 903 - memset(&intel_private.ifp_resource, 0, sizeof(intel_private.ifp_resource)); 897 + /* return if already configured */ 898 + if (intel_private.ifp_resource.start) 899 + return; 904 900 901 + /* setup a resource for this object */ 905 902 intel_private.ifp_resource.name = "Intel Flush Page"; 906 903 intel_private.ifp_resource.flags = IORESOURCE_MEM; 907 904 ··· 960 951 { 961 952 if (intel_private.i9xx_flush_page) 962 953 iounmap(intel_private.i9xx_flush_page); 954 + if (intel_private.resource_valid) 955 + release_resource(&intel_private.ifp_resource); 956 + intel_private.ifp_resource.start = 0; 957 + intel_private.resource_valid = 0; 963 958 iounmap(intel_private.gtt); 964 959 iounmap(intel_private.registers); 965 960 }