Merge branch 'tracing/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic...
[linux-2.6-block.git] / drivers / gpu / drm / ttm / ttm_tt.c
index 9c2b1cc5dba5a10b586d4c8b9a6dc6ffeb02a376..3d47a2c12322173fa3621e9cb5886408dcb1c19e 100644 (file)
@@ -196,23 +196,34 @@ EXPORT_SYMBOL(ttm_tt_populate);
 
 #ifdef CONFIG_X86
 static inline int ttm_tt_set_page_caching(struct page *p,
-                                         enum ttm_caching_state c_state)
+                                         enum ttm_caching_state c_old,
+                                         enum ttm_caching_state c_new)
 {
+       int ret = 0;
+
        if (PageHighMem(p))
                return 0;
 
-       switch (c_state) {
-       case tt_cached:
-               return set_pages_wb(p, 1);
-       case tt_wc:
-           return set_memory_wc((unsigned long) page_address(p), 1);
-       default:
-               return set_pages_uc(p, 1);
+       if (c_old != tt_cached) {
+               /* p isn't in the default caching state, set it to
+                * writeback first to free its current memtype. */
+
+               ret = set_pages_wb(p, 1);
+               if (ret)
+                       return ret;
        }
+
+       if (c_new == tt_wc)
+               ret = set_memory_wc((unsigned long) page_address(p), 1);
+       else if (c_new == tt_uncached)
+               ret = set_pages_uc(p, 1);
+
+       return ret;
 }
 #else /* CONFIG_X86 */
 static inline int ttm_tt_set_page_caching(struct page *p,
-                                         enum ttm_caching_state c_state)
+                                         enum ttm_caching_state c_old,
+                                         enum ttm_caching_state c_new)
 {
        return 0;
 }
@@ -245,7 +256,9 @@ static int ttm_tt_set_caching(struct ttm_tt *ttm,
        for (i = 0; i < ttm->num_pages; ++i) {
                cur_page = ttm->pages[i];
                if (likely(cur_page != NULL)) {
-                       ret = ttm_tt_set_page_caching(cur_page, c_state);
+                       ret = ttm_tt_set_page_caching(cur_page,
+                                                     ttm->caching_state,
+                                                     c_state);
                        if (unlikely(ret != 0))
                                goto out_err;
                }
@@ -259,7 +272,7 @@ out_err:
        for (j = 0; j < i; ++j) {
                cur_page = ttm->pages[j];
                if (likely(cur_page != NULL)) {
-                       (void)ttm_tt_set_page_caching(cur_page,
+                       (void)ttm_tt_set_page_caching(cur_page, c_state,
                                                      ttm->caching_state);
                }
        }