#include <linux/pm.h>
#include <linux/agp_backend.h>
#include <linux/vmalloc.h>
+#include <linux/mm.h>
#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/pgtable.h>
#include "agp.h"
__u32 *agp_gatt_table;
*/
EXPORT_SYMBOL_GPL(agp_memory_reserved);
+#if defined(CONFIG_X86)
+int map_page_into_agp(struct page *page)
+{
+ int i;
+ i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
+ global_flush_tlb();
+ return i;
+}
+EXPORT_SYMBOL_GPL(map_page_into_agp);
+
+int unmap_page_from_agp(struct page *page)
+{
+ int i;
+ i = change_page_attr(page, 1, PAGE_KERNEL);
+ global_flush_tlb();
+ return i;
+}
+EXPORT_SYMBOL_GPL(unmap_page_from_agp);
+#endif
+
/*
* Generic routines for handling agp_memory structures -
* They use the basic page allocation routines to do the brunt of the work.
agp_free_memory(new);
return NULL;
}
- new->memory[i] =
- agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
+ new->memory[i] = virt_to_phys(addr);
new->page_count++;
}
u32 tmp;
u32 agp3;
- while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
+ for_each_pci_dev(device) {
cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!cap_ptr)
continue;
if (agp_v3)
mode *= 4;
- while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
+ for_each_pci_dev(device) {
u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!agp)
continue;
agp_bridge->gatt_bus_addr = virt_to_phys(agp_bridge->gatt_table_real);
/* AK: bogus, should encode addresses > 4GB */
- for (i = 0; i < num_entries; i++)
+ for (i = 0; i < num_entries; i++) {
writel(agp_bridge->scratch_page, agp_bridge->gatt_table+i);
+ readl(agp_bridge->gatt_table+i); /* PCI Posting. */
+ }
return 0;
}
mem->is_flushed = TRUE;
}
- for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type), agp_bridge->gatt_table+j);
+ readl(agp_bridge->gatt_table+j); /* PCI Posting. */
+ }
agp_bridge->driver->tlb_flush(mem);
return 0;
}
/* AK: bogus, should encode addresses > 4GB */
- for (i = pg_start; i < (mem->page_count + pg_start); i++)
+ for (i = pg_start; i < (mem->page_count + pg_start); i++) {
writel(agp_bridge->scratch_page, agp_bridge->gatt_table+i);
+ readl(agp_bridge->gatt_table+i); /* PCI Posting. */
+ }
+ global_cache_flush();
agp_bridge->driver->tlb_flush(mem);
return 0;
}
EXPORT_SYMBOL(agp_enable);
-#ifdef CONFIG_SMP
static void ipi_handler(void *null)
{
flush_agp_cache();
}
-#endif
void global_cache_flush(void)
{
-#ifdef CONFIG_SMP
if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)
panic(PFX "timed out waiting for the other CPUs!\n");
-#else
- flush_agp_cache();
-#endif
}
EXPORT_SYMBOL(global_cache_flush);