diff options
| -rw-r--r-- | drivers/char/agp/agp.h | 3 | ||||
| -rw-r--r-- | drivers/char/agp/backend.c | 2 | ||||
| -rw-r--r-- | drivers/char/agp/generic.c | 28 | ||||
| -rw-r--r-- | drivers/char/agp/intel-agp.c | 5 | ||||
| -rw-r--r-- | include/linux/agp_backend.h | 5 |
5 files changed, 43 insertions, 0 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 81e14bea54bd..4bada0e8b812 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
| @@ -148,6 +148,9 @@ struct agp_bridge_data { | |||
| 148 | char minor_version; | 148 | char minor_version; |
| 149 | struct list_head list; | 149 | struct list_head list; |
| 150 | u32 apbase_config; | 150 | u32 apbase_config; |
| 151 | /* list of agp_memory mapped to the aperture */ | ||
| 152 | struct list_head mapped_list; | ||
| 153 | spinlock_t mapped_lock; | ||
| 151 | }; | 154 | }; |
| 152 | 155 | ||
| 153 | #define KB(x) ((x) * 1024) | 156 | #define KB(x) ((x) * 1024) |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 9626d3bda096..3a3cc03d401c 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
| @@ -185,6 +185,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
| 185 | rc = -EINVAL; | 185 | rc = -EINVAL; |
| 186 | goto err_out; | 186 | goto err_out; |
| 187 | } | 187 | } |
| 188 | INIT_LIST_HEAD(&bridge->mapped_list); | ||
| 189 | spin_lock_init(&bridge->mapped_lock); | ||
| 188 | 190 | ||
| 189 | return 0; | 191 | return 0; |
| 190 | 192 | ||
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 54c91000646f..118dbde25dc7 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
| @@ -429,6 +429,10 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start) | |||
| 429 | 429 | ||
| 430 | curr->is_bound = true; | 430 | curr->is_bound = true; |
| 431 | curr->pg_start = pg_start; | 431 | curr->pg_start = pg_start; |
| 432 | spin_lock(&agp_bridge->mapped_lock); | ||
| 433 | list_add(&curr->mapped_list, &agp_bridge->mapped_list); | ||
| 434 | spin_unlock(&agp_bridge->mapped_lock); | ||
| 435 | |||
| 432 | return 0; | 436 | return 0; |
| 433 | } | 437 | } |
| 434 | EXPORT_SYMBOL(agp_bind_memory); | 438 | EXPORT_SYMBOL(agp_bind_memory); |
| @@ -461,10 +465,34 @@ int agp_unbind_memory(struct agp_memory *curr) | |||
| 461 | 465 | ||
| 462 | curr->is_bound = false; | 466 | curr->is_bound = false; |
| 463 | curr->pg_start = 0; | 467 | curr->pg_start = 0; |
| 468 | spin_lock(&curr->bridge->mapped_lock); | ||
| 469 | list_del(&curr->mapped_list); | ||
| 470 | spin_unlock(&curr->bridge->mapped_lock); | ||
| 464 | return 0; | 471 | return 0; |
| 465 | } | 472 | } |
| 466 | EXPORT_SYMBOL(agp_unbind_memory); | 473 | EXPORT_SYMBOL(agp_unbind_memory); |
| 467 | 474 | ||
| 475 | /** | ||
| 476 | * agp_rebind_emmory - Rewrite the entire GATT, useful on resume | ||
| 477 | */ | ||
| 478 | int agp_rebind_memory(void) | ||
| 479 | { | ||
| 480 | struct agp_memory *curr; | ||
| 481 | int ret_val = 0; | ||
| 482 | |||
| 483 | spin_lock(&agp_bridge->mapped_lock); | ||
| 484 | list_for_each_entry(curr, &agp_bridge->mapped_list, mapped_list) { | ||
| 485 | ret_val = curr->bridge->driver->insert_memory(curr, | ||
| 486 | curr->pg_start, | ||
| 487 | curr->type); | ||
| 488 | if (ret_val != 0) | ||
| 489 | break; | ||
| 490 | } | ||
| 491 | spin_unlock(&agp_bridge->mapped_lock); | ||
| 492 | return ret_val; | ||
| 493 | } | ||
| 494 | EXPORT_SYMBOL(agp_rebind_memory); | ||
| 495 | |||
| 468 | /* End - Routines for handling swapping of agp_memory into the GATT */ | 496 | /* End - Routines for handling swapping of agp_memory into the GATT */ |
| 469 | 497 | ||
| 470 | 498 | ||
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 57c552ee046f..016fdf0623a4 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
| @@ -2244,6 +2244,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev) | |||
| 2244 | static int agp_intel_resume(struct pci_dev *pdev) | 2244 | static int agp_intel_resume(struct pci_dev *pdev) |
| 2245 | { | 2245 | { |
| 2246 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 2246 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
| 2247 | int ret_val; | ||
| 2247 | 2248 | ||
| 2248 | pci_restore_state(pdev); | 2249 | pci_restore_state(pdev); |
| 2249 | 2250 | ||
| @@ -2271,6 +2272,10 @@ static int agp_intel_resume(struct pci_dev *pdev) | |||
| 2271 | else if (bridge->driver == &intel_i965_driver) | 2272 | else if (bridge->driver == &intel_i965_driver) |
| 2272 | intel_i915_configure(); | 2273 | intel_i915_configure(); |
| 2273 | 2274 | ||
| 2275 | ret_val = agp_rebind_memory(); | ||
| 2276 | if (ret_val != 0) | ||
| 2277 | return ret_val; | ||
| 2278 | |||
| 2274 | return 0; | 2279 | return 0; |
| 2275 | } | 2280 | } |
| 2276 | #endif | 2281 | #endif |
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h index 972b12bcfb36..2b8df8b420fd 100644 --- a/include/linux/agp_backend.h +++ b/include/linux/agp_backend.h | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #ifndef _AGP_BACKEND_H | 30 | #ifndef _AGP_BACKEND_H |
| 31 | #define _AGP_BACKEND_H 1 | 31 | #define _AGP_BACKEND_H 1 |
| 32 | 32 | ||
| 33 | #include <linux/list.h> | ||
| 34 | |||
| 33 | enum chipset_type { | 35 | enum chipset_type { |
| 34 | NOT_SUPPORTED, | 36 | NOT_SUPPORTED, |
| 35 | SUPPORTED, | 37 | SUPPORTED, |
| @@ -78,6 +80,8 @@ struct agp_memory { | |||
| 78 | bool is_bound; | 80 | bool is_bound; |
| 79 | bool is_flushed; | 81 | bool is_flushed; |
| 80 | bool vmalloc_flag; | 82 | bool vmalloc_flag; |
| 83 | /* list of agp_memory mapped to the aperture */ | ||
| 84 | struct list_head mapped_list; | ||
| 81 | }; | 85 | }; |
| 82 | 86 | ||
| 83 | #define AGP_NORMAL_MEMORY 0 | 87 | #define AGP_NORMAL_MEMORY 0 |
| @@ -96,6 +100,7 @@ extern struct agp_memory *agp_allocate_memory(struct agp_bridge_data *, size_t, | |||
| 96 | extern int agp_copy_info(struct agp_bridge_data *, struct agp_kern_info *); | 100 | extern int agp_copy_info(struct agp_bridge_data *, struct agp_kern_info *); |
| 97 | extern int agp_bind_memory(struct agp_memory *, off_t); | 101 | extern int agp_bind_memory(struct agp_memory *, off_t); |
| 98 | extern int agp_unbind_memory(struct agp_memory *); | 102 | extern int agp_unbind_memory(struct agp_memory *); |
| 103 | extern int agp_rebind_memory(void); | ||
| 99 | extern void agp_enable(struct agp_bridge_data *, u32); | 104 | extern void agp_enable(struct agp_bridge_data *, u32); |
| 100 | extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); | 105 | extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); |
| 101 | extern void agp_backend_release(struct agp_bridge_data *); | 106 | extern void agp_backend_release(struct agp_bridge_data *); |
