From bd07928c0f9c3dbe53baf28eae4de4c579772c4c Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Thu, 21 Aug 2008 10:46:17 +0800 Subject: [PATCH] agp: add agp_generic_destroy_pages() Add agp_generic_destroy_pages(), it uses new pageattr array interface API. Signed-off-by: Dave Airlie Signed-off-by: Shaohua Li Signed-off-by: Ingo Molnar --- drivers/char/agp/agp.h | 2 ++ drivers/char/agp/generic.c | 55 ++++++++++++++++++++++++++++++------ drivers/char/agp/intel-agp.c | 14 +++++++++ 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 55d2c9d14177..338b0b4dce9c 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -118,6 +118,7 @@ struct agp_bridge_driver { void *(*agp_alloc_page)(struct agp_bridge_data *); int (*agp_alloc_pages)(struct agp_bridge_data *, struct agp_memory *, size_t); void (*agp_destroy_page)(void *, int flags); + void (*agp_destroy_pages)(struct agp_memory *); int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); void (*chipset_flush)(struct agp_bridge_data *); }; @@ -278,6 +279,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge); int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge, struct agp_memory *memory, size_t page_count); void agp_generic_destroy_page(void *addr, int flags); +void agp_generic_destroy_pages(struct agp_memory *memory); void agp_free_key(int key); int agp_num_entries(void); u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 13a5577ee434..dd370be00d68 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -201,14 +201,22 @@ void agp_free_memory(struct agp_memory *curr) return; } if (curr->page_count != 0) { - for (i = 0; i < curr->page_count; i++) { - curr->memory[i] = (unsigned long)gart_to_virt(curr->memory[i]); - curr->bridge->driver->agp_destroy_page((void *)curr->memory[i], - AGP_PAGE_DESTROY_UNMAP); - } - for (i = 0; i < curr->page_count; i++) { - curr->bridge->driver->agp_destroy_page((void *)curr->memory[i], - AGP_PAGE_DESTROY_FREE); + if (curr->bridge->driver->agp_destroy_pages) { + curr->bridge->driver->agp_destroy_pages(curr); + } else { + + for (i = 0; i < curr->page_count; i++) { + curr->memory[i] = (unsigned long)gart_to_virt( + curr->memory[i]); + curr->bridge->driver->agp_destroy_page( + (void *)curr->memory[i], + AGP_PAGE_DESTROY_UNMAP); + } + for (i = 0; i < curr->page_count; i++) { + curr->bridge->driver->agp_destroy_page( + (void *)curr->memory[i], + AGP_PAGE_DESTROY_FREE); + } } } agp_free_key(curr->key); @@ -1236,6 +1244,37 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) } EXPORT_SYMBOL(agp_generic_alloc_page); +void agp_generic_destroy_pages(struct agp_memory *mem) +{ + int i; + void *addr; + struct page *page; + + if (!mem) + return; + + for (i = 0; i < mem->page_count; i++) + mem->memory[i] = (unsigned long)gart_to_virt(mem->memory[i]); + +#ifdef CONFIG_X86 + set_memory_array_wb(mem->memory, mem->page_count); +#endif + + for (i = 0; i < mem->page_count; i++) { + addr = (void *)mem->memory[i]; + page = virt_to_page(addr); + +#ifndef CONFIG_X86 + unmap_page_from_agp(page); +#endif + + put_page(page); + free_page((unsigned long)addr); + atomic_dec(&agp_bridge->current_memory_agp); + mem->memory[i] = 0; + } +} +EXPORT_SYMBOL(agp_generic_destroy_pages); void agp_generic_destroy_page(void *addr, int flags) { diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 2cff0976a668..290a1cf63925 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1705,6 +1705,7 @@ static const struct agp_bridge_driver intel_generic_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1731,6 +1732,7 @@ static const struct agp_bridge_driver intel_810_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1756,6 +1758,7 @@ static const struct agp_bridge_driver intel_815_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1782,6 +1785,7 @@ static const struct agp_bridge_driver intel_830_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i830_chipset_flush, }; @@ -1808,6 +1812,7 @@ static const struct agp_bridge_driver intel_820_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1833,6 +1838,7 @@ static const struct agp_bridge_driver intel_830mp_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1858,6 +1864,7 @@ static const struct agp_bridge_driver intel_840_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1883,6 +1890,7 @@ static const struct agp_bridge_driver intel_845_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, .chipset_flush = intel_i830_chipset_flush, }; @@ -1909,6 +1917,7 @@ static const struct agp_bridge_driver intel_850_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1934,6 +1943,7 @@ static const struct agp_bridge_driver intel_860_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -1960,6 +1970,7 @@ static const struct agp_bridge_driver intel_915_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i915_chipset_flush, }; @@ -1987,6 +1998,7 @@ static const struct agp_bridge_driver intel_i965_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i915_chipset_flush, }; @@ -2013,6 +2025,7 @@ static const struct agp_bridge_driver intel_7505_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; @@ -2039,6 +2052,7 @@ static const struct agp_bridge_driver intel_g33_driver = { .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i915_chipset_flush, };