Merge branch 'fix/soundcore' into for-linus
[pandora-kernel.git] / drivers / char / agp / i460-agp.c
index 10da687..60cc35b 100644 (file)
@@ -60,6 +60,9 @@
  */
 #define WR_FLUSH_GATT(index)   RD_GATT(index)
 
+static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
+                                      unsigned long addr, int type);
+
 static struct {
        void *gatt;                             /* ioremap'd GATT area */
 
@@ -74,6 +77,7 @@ static struct {
                unsigned long *alloced_map;     /* bitmap of kernel-pages in use */
                int refcount;                   /* number of kernel pages using the large page */
                u64 paddr;                      /* physical address of large page */
+               struct page *page;              /* page pointer */
        } *lp_desc;
 } i460;
 
@@ -294,7 +298,7 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
        void *temp;
 
        pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
-                mem, pg_start, type, mem->memory[0]);
+                mem, pg_start, type, page_to_phys(mem->pages[0]));
 
        if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
                return -EINVAL;
@@ -321,10 +325,9 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
 
        io_page_size = 1UL << I460_IO_PAGE_SHIFT;
        for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
-               paddr = mem->memory[i];
+               paddr = phys_to_gart(page_to_phys(mem->pages[i]));
                for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
-                       WR_GATT(j, agp_bridge->driver->mask_memory(agp_bridge,
-                               paddr, mem->type));
+                       WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type));
        }
        WR_FLUSH_GATT(j - 1);
        return 0;
@@ -364,10 +367,9 @@ static int i460_alloc_large_page (struct lp_desc *lp)
 {
        unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT;
        size_t map_size;
-       void *lpage;
 
-       lpage = (void *) __get_free_pages(GFP_KERNEL, order);
-       if (!lpage) {
+       lp->page = alloc_pages(GFP_KERNEL, order);
+       if (!lp->page) {
                printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n");
                return -ENOMEM;
        }
@@ -375,12 +377,12 @@ static int i460_alloc_large_page (struct lp_desc *lp)
        map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
        lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
        if (!lp->alloced_map) {
-               free_pages((unsigned long) lpage, order);
+               __free_pages(lp->page, order);
                printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
                return -ENOMEM;
        }
 
-       lp->paddr = virt_to_gart(lpage);
+       lp->paddr = phys_to_gart(page_to_phys(lp->page));
        lp->refcount = 0;
        atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
        return 0;
@@ -391,7 +393,7 @@ static void i460_free_large_page (struct lp_desc *lp)
        kfree(lp->alloced_map);
        lp->alloced_map = NULL;
 
-       free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
+       __free_pages(lp->page, I460_IO_PAGE_SHIFT - PAGE_SHIFT);
        atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 }
 
@@ -439,8 +441,8 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem,
                        if (i460_alloc_large_page(lp) < 0)
                                return -ENOMEM;
                        pg = lp - i460.lp_desc;
-                       WR_GATT(pg, agp_bridge->driver->mask_memory(agp_bridge,
-                               lp->paddr, 0));
+                       WR_GATT(pg, i460_mask_memory(agp_bridge,
+                                                    lp->paddr, 0));
                        WR_FLUSH_GATT(pg);
                }
 
@@ -448,7 +450,7 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem,
                     idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
                     idx++, i++)
                {
-                       mem->memory[i] = lp->paddr + idx*PAGE_SIZE;
+                       mem->pages[i] = lp->page;
                        __set_bit(idx, lp->alloced_map);
                        ++lp->refcount;
                }
@@ -463,7 +465,7 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem,
        struct lp_desc *start, *end, *lp;
        void *temp;
 
-       temp = agp_bridge->driver->current_size;
+       temp = agp_bridge->current_size;
        num_entries = A_SIZE_8(temp)->num_entries;
 
        /* Figure out what pg_start means in terms of our large GART pages */
@@ -477,7 +479,7 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem,
                     idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
                     idx++, i++)
                {
-                       mem->memory[i] = 0;
+                       mem->pages[i] = NULL;
                        __clear_bit(idx, lp->alloced_map);
                        --lp->refcount;
                }
@@ -521,7 +523,7 @@ static int i460_remove_memory (struct agp_memory *mem,
  * Let's just hope nobody counts on the allocated AGP memory being there before bind time
  * (I don't think current drivers do)...
  */
-static void *i460_alloc_page (struct agp_bridge_data *bridge)
+static struct page *i460_alloc_page (struct agp_bridge_data *bridge)
 {
        void *page;
 
@@ -534,7 +536,7 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
        return page;
 }
 
-static void i460_destroy_page (void *page, int flags)
+static void i460_destroy_page (struct page *page, int flags)
 {
        if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
                agp_generic_destroy_page(page, flags);
@@ -544,13 +546,20 @@ static void i460_destroy_page (void *page, int flags)
 #endif /* I460_LARGE_IO_PAGES */
 
 static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
-       unsigned long addr, int type)
+                                      unsigned long addr, int type)
 {
        /* Make sure the returned address is a valid GATT entry */
        return bridge->driver->masks[0].mask
                | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
 }
 
+static unsigned long i460_page_mask_memory(struct agp_bridge_data *bridge,
+                                          struct page *page, int type)
+{
+       unsigned long addr = phys_to_gart(page_to_phys(page));
+       return i460_mask_memory(bridge, addr, type);
+}
+
 const struct agp_bridge_driver intel_i460_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = i460_sizes,
@@ -560,7 +569,7 @@ const struct agp_bridge_driver intel_i460_driver = {
        .fetch_size             = i460_fetch_size,
        .cleanup                = i460_cleanup,
        .tlb_flush              = i460_tlb_flush,
-       .mask_memory            = i460_mask_memory,
+       .mask_memory            = i460_page_mask_memory,
        .masks                  = i460_masks,
        .agp_enable             = agp_generic_enable,
        .cache_flush            = global_cache_flush,