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