Commit a5ee3634 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart

parents 28d838cc 49ebd7c6
...@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
return -ENOMEM; return -ENOMEM;
} }
global_flush_tlb();
bridge->scratch_page_real = virt_to_gart(addr); bridge->scratch_page_real = virt_to_gart(addr);
bridge->scratch_page = bridge->scratch_page =
...@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
return 0; return 0;
err_out: err_out:
if (bridge->driver->needs_scratch_page) if (bridge->driver->needs_scratch_page) {
bridge->driver->agp_destroy_page( bridge->driver->agp_destroy_page(
gart_to_virt(bridge->scratch_page_real)); gart_to_virt(bridge->scratch_page_real));
global_flush_tlb();
}
if (got_gatt) if (got_gatt)
bridge->driver->free_gatt_table(bridge); bridge->driver->free_gatt_table(bridge);
if (got_keylist) { if (got_keylist) {
...@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) ...@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
bridge->key_list = NULL; bridge->key_list = NULL;
if (bridge->driver->agp_destroy_page && if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page) bridge->driver->needs_scratch_page) {
bridge->driver->agp_destroy_page( bridge->driver->agp_destroy_page(
gart_to_virt(bridge->scratch_page_real)); gart_to_virt(bridge->scratch_page_real));
global_flush_tlb();
}
} }
/* When we remove the global variable agp_bridge from all drivers /* When we remove the global variable agp_bridge from all drivers
......
...@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page) ...@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page)
{ {
int i; int i;
i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
global_flush_tlb(); /* Caller's responsibility to call global_flush_tlb() for
* performance reasons */
return i; return i;
} }
EXPORT_SYMBOL_GPL(map_page_into_agp); EXPORT_SYMBOL_GPL(map_page_into_agp);
...@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page) ...@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page)
{ {
int i; int i;
i = change_page_attr(page, 1, PAGE_KERNEL); i = change_page_attr(page, 1, PAGE_KERNEL);
global_flush_tlb(); /* Caller's responsibility to call global_flush_tlb() for
* performance reasons */
return i; return i;
} }
EXPORT_SYMBOL_GPL(unmap_page_from_agp); EXPORT_SYMBOL_GPL(unmap_page_from_agp);
...@@ -153,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr) ...@@ -153,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr)
for (i = 0; i < curr->page_count; i++) { for (i = 0; i < curr->page_count; i++) {
curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
} }
global_flush_tlb();
} }
agp_free_key(curr->key); agp_free_key(curr->key);
vfree(curr->memory); vfree(curr->memory);
...@@ -210,7 +213,9 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, ...@@ -210,7 +213,9 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
new->memory[i] = virt_to_gart(addr); new->memory[i] = virt_to_gart(addr);
new->page_count++; new->page_count++;
} }
new->bridge = bridge; global_flush_tlb();
new->bridge = bridge;
flush_agp_mappings(); flush_agp_mappings();
......
...@@ -111,8 +111,10 @@ static int i460_fetch_size (void) ...@@ -111,8 +111,10 @@ static int i460_fetch_size (void)
if (i460.io_page_shift != I460_IO_PAGE_SHIFT) { if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
printk(KERN_ERR PFX printk(KERN_ERR PFX
"I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n", "I/O (GART) page-size %luKB doesn't match expected "
1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT)); "size %luKB\n",
1UL << (i460.io_page_shift - 10),
1UL << (I460_IO_PAGE_SHIFT));
return 0; return 0;
} }
...@@ -514,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge) ...@@ -514,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
{ {
void *page; void *page;
if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
page = agp_generic_alloc_page(agp_bridge); page = agp_generic_alloc_page(agp_bridge);
else global_flush_tlb();
} else
/* Returning NULL would cause problems */ /* Returning NULL would cause problems */
/* AK: really dubious code. */ /* AK: really dubious code. */
page = (void *)~0UL; page = (void *)~0UL;
...@@ -525,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge) ...@@ -525,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
static void i460_destroy_page (void *page) static void i460_destroy_page (void *page)
{ {
if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
agp_generic_destroy_page(page); agp_generic_destroy_page(page);
global_flush_tlb();
}
} }
#endif /* I460_LARGE_IO_PAGES */ #endif /* I460_LARGE_IO_PAGES */
...@@ -536,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, ...@@ -536,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
{ {
/* Make sure the returned address is a valid GATT entry */ /* Make sure the returned address is a valid GATT entry */
return bridge->driver->masks[0].mask return bridge->driver->masks[0].mask
| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12); | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
} }
struct agp_bridge_driver intel_i460_driver = { struct agp_bridge_driver intel_i460_driver = {
......
...@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) ...@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
switch (pg_count) { switch (pg_count) {
case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
global_flush_tlb();
break; break;
case 4: case 4:
/* kludge to get 4 physical pages for ARGB cursor */ /* kludge to get 4 physical pages for ARGB cursor */
...@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr) ...@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
if(curr->type == AGP_PHYS_MEMORY) { if(curr->type == AGP_PHYS_MEMORY) {
if (curr->page_count == 4) if (curr->page_count == 4)
i8xx_destroy_pages(gart_to_virt(curr->memory[0])); i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
else else {
agp_bridge->driver->agp_destroy_page( agp_bridge->driver->agp_destroy_page(
gart_to_virt(curr->memory[0])); gart_to_virt(curr->memory[0]));
global_flush_tlb();
}
vfree(curr->memory); vfree(curr->memory);
} }
kfree(curr); kfree(curr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment