|
@@ -1503,12 +1503,10 @@ EXPORT_SYMBOL(set_memory_uc);
|
|
|
static int _set_memory_array(unsigned long *addr, int addrinarray,
|
|
|
enum page_cache_mode new_type)
|
|
|
{
|
|
|
+ enum page_cache_mode set_type;
|
|
|
int i, j;
|
|
|
int ret;
|
|
|
|
|
|
- /*
|
|
|
- * for now UC MINUS. see comments in ioremap_nocache()
|
|
|
- */
|
|
|
for (i = 0; i < addrinarray; i++) {
|
|
|
ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE,
|
|
|
new_type, NULL);
|
|
@@ -1516,9 +1514,12 @@ static int _set_memory_array(unsigned long *addr, int addrinarray,
|
|
|
goto out_free;
|
|
|
}
|
|
|
|
|
|
+ /* If WC, set to UC- first and then WC */
|
|
|
+ set_type = (new_type == _PAGE_CACHE_MODE_WC) ?
|
|
|
+ _PAGE_CACHE_MODE_UC_MINUS : new_type;
|
|
|
+
|
|
|
ret = change_page_attr_set(addr, addrinarray,
|
|
|
- cachemode2pgprot(_PAGE_CACHE_MODE_UC_MINUS),
|
|
|
- 1);
|
|
|
+ cachemode2pgprot(set_type), 1);
|
|
|
|
|
|
if (!ret && new_type == _PAGE_CACHE_MODE_WC)
|
|
|
ret = change_page_attr_set_clr(addr, addrinarray,
|
|
@@ -1550,6 +1551,12 @@ int set_memory_array_wc(unsigned long *addr, int addrinarray)
|
|
|
}
|
|
|
EXPORT_SYMBOL(set_memory_array_wc);
|
|
|
|
|
|
+int set_memory_array_wt(unsigned long *addr, int addrinarray)
|
|
|
+{
|
|
|
+ return _set_memory_array(addr, addrinarray, _PAGE_CACHE_MODE_WT);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(set_memory_array_wt);
|
|
|
+
|
|
|
int _set_memory_wc(unsigned long addr, int numpages)
|
|
|
{
|
|
|
int ret;
|
|
@@ -1575,21 +1582,39 @@ int set_memory_wc(unsigned long addr, int numpages)
|
|
|
ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
|
|
|
_PAGE_CACHE_MODE_WC, NULL);
|
|
|
if (ret)
|
|
|
- goto out_err;
|
|
|
+ return ret;
|
|
|
|
|
|
ret = _set_memory_wc(addr, numpages);
|
|
|
if (ret)
|
|
|
- goto out_free;
|
|
|
+ free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
|
|
|
|
|
|
- return 0;
|
|
|
-
|
|
|
-out_free:
|
|
|
- free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
|
|
|
-out_err:
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL(set_memory_wc);
|
|
|
|
|
|
+int _set_memory_wt(unsigned long addr, int numpages)
|
|
|
+{
|
|
|
+ return change_page_attr_set(&addr, numpages,
|
|
|
+ cachemode2pgprot(_PAGE_CACHE_MODE_WT), 0);
|
|
|
+}
|
|
|
+
|
|
|
+int set_memory_wt(unsigned long addr, int numpages)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
|
|
|
+ _PAGE_CACHE_MODE_WT, NULL);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ ret = _set_memory_wt(addr, numpages);
|
|
|
+ if (ret)
|
|
|
+ free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(set_memory_wt);
|
|
|
+
|
|
|
int _set_memory_wb(unsigned long addr, int numpages)
|
|
|
{
|
|
|
/* WB cache mode is hard wired to all cache attribute bits being 0 */
|
|
@@ -1680,6 +1705,7 @@ static int _set_pages_array(struct page **pages, int addrinarray,
|
|
|
{
|
|
|
unsigned long start;
|
|
|
unsigned long end;
|
|
|
+ enum page_cache_mode set_type;
|
|
|
int i;
|
|
|
int free_idx;
|
|
|
int ret;
|
|
@@ -1693,8 +1719,12 @@ static int _set_pages_array(struct page **pages, int addrinarray,
|
|
|
goto err_out;
|
|
|
}
|
|
|
|
|
|
+ /* If WC, set to UC- first and then WC */
|
|
|
+ set_type = (new_type == _PAGE_CACHE_MODE_WC) ?
|
|
|
+ _PAGE_CACHE_MODE_UC_MINUS : new_type;
|
|
|
+
|
|
|
ret = cpa_set_pages_array(pages, addrinarray,
|
|
|
- cachemode2pgprot(_PAGE_CACHE_MODE_UC_MINUS));
|
|
|
+ cachemode2pgprot(set_type));
|
|
|
if (!ret && new_type == _PAGE_CACHE_MODE_WC)
|
|
|
ret = change_page_attr_set_clr(NULL, addrinarray,
|
|
|
cachemode2pgprot(
|
|
@@ -1728,6 +1758,12 @@ int set_pages_array_wc(struct page **pages, int addrinarray)
|
|
|
}
|
|
|
EXPORT_SYMBOL(set_pages_array_wc);
|
|
|
|
|
|
+int set_pages_array_wt(struct page **pages, int addrinarray)
|
|
|
+{
|
|
|
+ return _set_pages_array(pages, addrinarray, _PAGE_CACHE_MODE_WT);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(set_pages_array_wt);
|
|
|
+
|
|
|
int set_pages_wb(struct page *page, int numpages)
|
|
|
{
|
|
|
unsigned long addr = (unsigned long)page_address(page);
|