diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-15 20:18:07 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-15 20:18:07 +0400 |
commit | 66a4fe0cb80a9fde8cb173289afb863fd279466a (patch) | |
tree | e1180ba7cbd123fb2f0bf510a955704725465776 /drivers/char/agp/backend.c | |
parent | 18240904960a39e582ced8ba8ececb10b8c22dd3 (diff) | |
parent | 121264827656f5f06328b17983c796af17dc5949 (diff) | |
download | linux-66a4fe0cb80a9fde8cb173289afb863fd279466a.tar.xz |
Merge branch 'agp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/agp-2.6
* 'agp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/agp-2.6:
agp/intel: remove restore in resume
agp: fix uninorth build
intel-agp: Set dma mask for i915
agp: kill phys_to_gart() and gart_to_phys()
intel-agp: fix sglist allocation to avoid vmalloc()
intel-agp: Move repeated sglist free into separate function
agp: Switch agp_{un,}map_page() to take struct page * argument
agp: tidy up handling of scratch pages w.r.t. DMA API
intel_agp: Use PCI DMA API correctly on chipsets new enough to have IOMMU
agp: Add generic support for graphics dma remapping
agp: Switch mask_memory() method to take address argument again, not page
Diffstat (limited to 'drivers/char/agp/backend.c')
-rw-r--r-- | drivers/char/agp/backend.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index cfa5a649dfe7..ad87753f6de4 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -149,9 +149,21 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) return -ENOMEM; } - bridge->scratch_page_real = phys_to_gart(page_to_phys(page)); - bridge->scratch_page = - bridge->driver->mask_memory(bridge, page, 0); + bridge->scratch_page_page = page; + if (bridge->driver->agp_map_page) { + if (bridge->driver->agp_map_page(page, + &bridge->scratch_page_dma)) { + dev_err(&bridge->dev->dev, + "unable to dma-map scratch page\n"); + rc = -ENOMEM; + goto err_out_nounmap; + } + } else { + bridge->scratch_page_dma = page_to_phys(page); + } + + bridge->scratch_page = bridge->driver->mask_memory(bridge, + bridge->scratch_page_dma, 0); } size_value = bridge->driver->fetch_size(); @@ -191,8 +203,14 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) return 0; err_out: + if (bridge->driver->needs_scratch_page && + bridge->driver->agp_unmap_page) { + bridge->driver->agp_unmap_page(bridge->scratch_page_page, + bridge->scratch_page_dma); + } +err_out_nounmap: if (bridge->driver->needs_scratch_page) { - void *va = gart_to_virt(bridge->scratch_page_real); + void *va = page_address(bridge->scratch_page_page); bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); @@ -219,7 +237,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) { - void *va = gart_to_virt(bridge->scratch_page_real); + void *va = page_address(bridge->scratch_page_page); + + if (bridge->driver->agp_unmap_page) + bridge->driver->agp_unmap_page(bridge->scratch_page_page, + bridge->scratch_page_dma); bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); |