aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/agp.h6
-rw-r--r--drivers/char/agp/backend.c20
-rw-r--r--drivers/char/agp/generic.c9
3 files changed, 35 insertions, 0 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index ce110a3bf298..17e6d0d3ba36 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -121,6 +121,11 @@ struct agp_bridge_driver {
121 void (*agp_destroy_pages)(struct agp_memory *); 121 void (*agp_destroy_pages)(struct agp_memory *);
122 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); 122 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
123 void (*chipset_flush)(struct agp_bridge_data *); 123 void (*chipset_flush)(struct agp_bridge_data *);
124
125 int (*agp_map_page)(void *addr, dma_addr_t *ret);
126 void (*agp_unmap_page)(void *addr, dma_addr_t dma);
127 int (*agp_map_memory)(struct agp_memory *mem);
128 void (*agp_unmap_memory)(struct agp_memory *mem);
124}; 129};
125 130
126struct agp_bridge_data { 131struct agp_bridge_data {
@@ -135,6 +140,7 @@ struct agp_bridge_data {
135 u32 *gatt_table_real; 140 u32 *gatt_table_real;
136 unsigned long scratch_page; 141 unsigned long scratch_page;
137 unsigned long scratch_page_real; 142 unsigned long scratch_page_real;
143 dma_addr_t scratch_page_dma;
138 unsigned long gart_bus_addr; 144 unsigned long gart_bus_addr;
139 unsigned long gatt_bus_addr; 145 unsigned long gatt_bus_addr;
140 u32 mode; 146 u32 mode;
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)
152 bridge->scratch_page_real = phys_to_gart(page_to_phys(page)); 152 bridge->scratch_page_real = phys_to_gart(page_to_phys(page));
153 bridge->scratch_page = bridge->driver->mask_memory(bridge, 153 bridge->scratch_page = bridge->driver->mask_memory(bridge,
154 phys_to_gart(page_to_phys(page)), 0); 154 phys_to_gart(page_to_phys(page)), 0);
155
156 if (bridge->driver->agp_map_page &&
157 bridge->driver->agp_map_page(phys_to_virt(page_to_phys(page)),
158 &bridge->scratch_page_dma)) {
159 dev_err(&bridge->dev->dev,
160 "unable to dma-map scratch page\n");
161 rc = -ENOMEM;
162 goto err_out_nounmap;
163 }
155 } 164 }
156 165
157 size_value = bridge->driver->fetch_size(); 166 size_value = bridge->driver->fetch_size();
@@ -191,6 +200,13 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
191 return 0; 200 return 0;
192 201
193err_out: 202err_out:
203 if (bridge->driver->needs_scratch_page &&
204 bridge->driver->agp_unmap_page) {
205 void *va = gart_to_virt(bridge->scratch_page_real);
206
207 bridge->driver->agp_unmap_page(va, bridge->scratch_page_dma);
208 }
209err_out_nounmap:
194 if (bridge->driver->needs_scratch_page) { 210 if (bridge->driver->needs_scratch_page) {
195 void *va = gart_to_virt(bridge->scratch_page_real); 211 void *va = gart_to_virt(bridge->scratch_page_real);
196 212
@@ -221,6 +237,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
221 bridge->driver->needs_scratch_page) { 237 bridge->driver->needs_scratch_page) {
222 void *va = gart_to_virt(bridge->scratch_page_real); 238 void *va = gart_to_virt(bridge->scratch_page_real);
223 239
240 if (bridge->driver->agp_unmap_page)
241 bridge->driver->agp_unmap_page(va,
242 bridge->scratch_page_dma);
243
224 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); 244 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
225 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); 245 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
226 } 246 }
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index a3bcc7ef42f9..28f0208c66a6 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -437,6 +437,12 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
437 curr->bridge->driver->cache_flush(); 437 curr->bridge->driver->cache_flush();
438 curr->is_flushed = true; 438 curr->is_flushed = true;
439 } 439 }
440
441 if (curr->bridge->driver->agp_map_memory) {
442 ret_val = curr->bridge->driver->agp_map_memory(curr);
443 if (ret_val)
444 return ret_val;
445 }
440 ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); 446 ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type);
441 447
442 if (ret_val != 0) 448 if (ret_val != 0)
@@ -478,6 +484,9 @@ int agp_unbind_memory(struct agp_memory *curr)
478 if (ret_val != 0) 484 if (ret_val != 0)
479 return ret_val; 485 return ret_val;
480 486
487 if (curr->bridge->driver->agp_unmap_memory)
488 curr->bridge->driver->agp_unmap_memory(curr);
489
481 curr->is_bound = false; 490 curr->is_bound = false;
482 curr->pg_start = 0; 491 curr->pg_start = 0;
483 spin_lock(&curr->bridge->mapped_lock); 492 spin_lock(&curr->bridge->mapped_lock);