diff options
author | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-02-28 13:47:15 +0100 |
---|---|---|
committer | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-02-28 13:47:15 +0100 |
commit | 40c9e6a26dd251fe2bf207bb259ba7e4a7704fbe (patch) | |
tree | a1cb1e00d162d3c7dbf8ba02b8005dbd4fb20948 /linux-core/drm_compat.c | |
parent | 72983ff30183745cd96760aa07b857c44daebde7 (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.c | 32 |
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 + + |