diff options
Diffstat (limited to 'drivers/gpu/drm/drm_cache.c')
-rw-r--r-- | drivers/gpu/drm/drm_cache.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 0e994a0e46d4..0e3bd5b54b78 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c | |||
@@ -45,6 +45,23 @@ drm_clflush_page(struct page *page) | |||
45 | clflush(page_virtual + i); | 45 | clflush(page_virtual + i); |
46 | kunmap_atomic(page_virtual, KM_USER0); | 46 | kunmap_atomic(page_virtual, KM_USER0); |
47 | } | 47 | } |
48 | |||
49 | static void drm_cache_flush_clflush(struct page *pages[], | ||
50 | unsigned long num_pages) | ||
51 | { | ||
52 | unsigned long i; | ||
53 | |||
54 | mb(); | ||
55 | for (i = 0; i < num_pages; i++) | ||
56 | drm_clflush_page(*pages++); | ||
57 | mb(); | ||
58 | } | ||
59 | |||
60 | static void | ||
61 | drm_clflush_ipi_handler(void *null) | ||
62 | { | ||
63 | wbinvd(); | ||
64 | } | ||
48 | #endif | 65 | #endif |
49 | 66 | ||
50 | void | 67 | void |
@@ -53,17 +70,30 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) | |||
53 | 70 | ||
54 | #if defined(CONFIG_X86) | 71 | #if defined(CONFIG_X86) |
55 | if (cpu_has_clflush) { | 72 | if (cpu_has_clflush) { |
56 | unsigned long i; | 73 | drm_cache_flush_clflush(pages, num_pages); |
57 | |||
58 | mb(); | ||
59 | for (i = 0; i < num_pages; ++i) | ||
60 | drm_clflush_page(*pages++); | ||
61 | mb(); | ||
62 | |||
63 | return; | 74 | return; |
64 | } | 75 | } |
65 | 76 | ||
66 | wbinvd(); | 77 | if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) |
78 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); | ||
79 | |||
80 | #elif defined(__powerpc__) | ||
81 | unsigned long i; | ||
82 | for (i = 0; i < num_pages; i++) { | ||
83 | struct page *page = pages[i]; | ||
84 | void *page_virtual; | ||
85 | |||
86 | if (unlikely(page == NULL)) | ||
87 | continue; | ||
88 | |||
89 | page_virtual = kmap_atomic(page, KM_USER0); | ||
90 | flush_dcache_range((unsigned long)page_virtual, | ||
91 | (unsigned long)page_virtual + PAGE_SIZE); | ||
92 | kunmap_atomic(page_virtual, KM_USER0); | ||
93 | } | ||
94 | #else | ||
95 | printk(KERN_ERR "Architecture has no drm_cache.c support\n"); | ||
96 | WARN_ON_ONCE(1); | ||
67 | #endif | 97 | #endif |
68 | } | 98 | } |
69 | EXPORT_SYMBOL(drm_clflush_pages); | 99 | EXPORT_SYMBOL(drm_clflush_pages); |