summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/agp.h3
-rw-r--r--drivers/char/agp/backend.c2
-rw-r--r--drivers/char/agp/generic.c28
-rw-r--r--drivers/char/agp/intel-agp.c5
4 files changed, 38 insertions, 0 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 81e14bea54b..4bada0e8b81 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -148,6 +148,9 @@ struct agp_bridge_data {
char minor_version;
struct list_head list;
u32 apbase_config;
+ /* list of agp_memory mapped to the aperture */
+ struct list_head mapped_list;
+ spinlock_t mapped_lock;
};
#define KB(x) ((x) * 1024)
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 9626d3bda09..3a3cc03d401 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)
rc = -EINVAL;
goto err_out;
}
+ INIT_LIST_HEAD(&bridge->mapped_list);
+ spin_lock_init(&bridge->mapped_lock);
return 0;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 54c91000646..118dbde25dc 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)
curr->is_bound = true;
curr->pg_start = pg_start;
+ spin_lock(&agp_bridge->mapped_lock);
+ list_add(&curr->mapped_list, &agp_bridge->mapped_list);
+ spin_unlock(&agp_bridge->mapped_lock);
+
return 0;
}
EXPORT_SYMBOL(agp_bind_memory);
@@ -461,10 +465,34 @@ int agp_unbind_memory(struct agp_memory *curr)
curr->is_bound = false;
curr->pg_start = 0;
+ spin_lock(&curr->bridge->mapped_lock);
+ list_del(&curr->mapped_list);
+ spin_unlock(&curr->bridge->mapped_lock);
return 0;
}
EXPORT_SYMBOL(agp_unbind_memory);
+/**
+ * agp_rebind_emmory - Rewrite the entire GATT, useful on resume
+ */
+int agp_rebind_memory(void)
+{
+ struct agp_memory *curr;
+ int ret_val = 0;
+
+ spin_lock(&agp_bridge->mapped_lock);
+ list_for_each_entry(curr, &agp_bridge->mapped_list, mapped_list) {
+ ret_val = curr->bridge->driver->insert_memory(curr,
+ curr->pg_start,
+ curr->type);
+ if (ret_val != 0)
+ break;
+ }
+ spin_unlock(&agp_bridge->mapped_lock);
+ return ret_val;
+}
+EXPORT_SYMBOL(agp_rebind_memory);
+
/* End - Routines for handling swapping of agp_memory into the GATT */
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 57c552ee046..016fdf0623a 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)
static int agp_intel_resume(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
+ int ret_val;
pci_restore_state(pdev);
@@ -2271,6 +2272,10 @@ static int agp_intel_resume(struct pci_dev *pdev)
else if (bridge->driver == &intel_i965_driver)
intel_i915_configure();
+ ret_val = agp_rebind_memory();
+ if (ret_val != 0)
+ return ret_val;
+
return 0;
}
#endif