aboutsummaryrefslogtreecommitdiff
path: root/linux-core/drm_compat.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-02-28 13:47:15 +0100
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-02-28 13:47:15 +0100
commit40c9e6a26dd251fe2bf207bb259ba7e4a7704fbe (patch)
treea1cb1e00d162d3c7dbf8ba02b8005dbd4fb20948 /linux-core/drm_compat.c
parent72983ff30183745cd96760aa07b857c44daebde7 (diff)
Add a compat kmap_atomic_prot_pfn to do quick kernel map / unmaps of
PCI- or high memory. This is substantially more efficient than drm_bo_kmap, since the mapping only lives on a single processor. Unmapping is done use kunmap_atomic(). Flushes only a single tlb() entry. Add a support utility int drm_bo_pfn_prot() that returns the pfn and desired page protection for a given bo offset. This is all intended for relocations in bound TTMS or vram. Mapping-accessing-unmapping must be atomic, either using preempt_xx() macros or a spinlock.
Diffstat (limited to 'linux-core/drm_compat.c')
-rw-r--r--linux-core/drm_compat.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c
index a745a7d9..32e43a0a 100644
--- a/linux-core/drm_compat.c
+++ b/linux-core/drm_compat.c
@@ -729,3 +729,35 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
}
EXPORT_SYMBOL(idr_replace);
#endif
+
+#if defined(CONFIG_X86)
+
+#define drm_kmap_get_fixmap_pte(vaddr) \
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr))
+
+void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type,
+ pgprot_t protection)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr;
+ static pte_t *km_pte;
+ static int initialized = 0;
+
+ if (unlikely(!initialized)) {
+ km_pte = drm_kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN));
+ initialized = 1;
+ }
+
+ pagefault_disable();
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte(km_pte-idx, pfn_pte(pfn, protection));
+
+ return (void*) vaddr;
+}
+
+EXPORT_SYMBOL(kmap_atomic_prot_pfn);
+
+#endif
+
+