summaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/backend.c
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyu.z.wang@intel.com>2009-07-23 18:25:49 +0200
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-08-03 10:04:47 +0200
commitff663cf8705bea101d5f73cf471855c85242575e (patch)
tree4b338298e69d2401cab848b4b9082bef07e5d9aa /drivers/char/agp/backend.c
parentagp: Switch mask_memory() method to take address argument again, not page (diff)
downloadlinux-ff663cf8705bea101d5f73cf471855c85242575e.tar.xz
linux-ff663cf8705bea101d5f73cf471855c85242575e.zip
agp: Add generic support for graphics dma remapping
New driver hooks for support graphics memory dma remapping are introduced in this patch. It makes generic code can tell if current device needs dma remapping, then call driver provided interfaces for mapping and unmapping. Change has also been made to handle scratch_page in remapping case. Signed-off-by: Zhenyu Wang <zhenyu.z.wang@intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/char/agp/backend.c')
-rw-r--r--drivers/char/agp/backend.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 3bd7e503de41..19ac3663acdc 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -152,6 +152,15 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
bridge->scratch_page_real = phys_to_gart(page_to_phys(page));
bridge->scratch_page = bridge->driver->mask_memory(bridge,
phys_to_gart(page_to_phys(page)), 0);
+
+ if (bridge->driver->agp_map_page &&
+ bridge->driver->agp_map_page(phys_to_virt(page_to_phys(page)),
+ &bridge->scratch_page_dma)) {
+ dev_err(&bridge->dev->dev,
+ "unable to dma-map scratch page\n");
+ rc = -ENOMEM;
+ goto err_out_nounmap;
+ }
}
size_value = bridge->driver->fetch_size();
@@ -191,6 +200,13 @@ 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) {
+ void *va = gart_to_virt(bridge->scratch_page_real);
+
+ bridge->driver->agp_unmap_page(va, bridge->scratch_page_dma);
+ }
+err_out_nounmap:
if (bridge->driver->needs_scratch_page) {
void *va = gart_to_virt(bridge->scratch_page_real);
@@ -221,6 +237,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
bridge->driver->needs_scratch_page) {
void *va = gart_to_virt(bridge->scratch_page_real);
+ if (bridge->driver->agp_unmap_page)
+ bridge->driver->agp_unmap_page(va,
+ bridge->scratch_page_dma);
+
bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
}