comgt-3g: enable modem before to setpin
[openwrt/openwrt.git] / target / linux / generic / patches-4.4 / 101-MIPS-fix-cache-flushing-for-highmem-pages.patch
index 6a6c581bc557a2e58bf9506dc16b3ed3ed52c74f..e4ac2cd583bb94fc65e2adb033d64e9afe3261b8 100644 (file)
@@ -1,4 +1,4 @@
-From: Felix Fietkau <nbd@openwrt.org>
+From: Felix Fietkau <nbd@nbd.name>
 Date: Sun, 24 Jan 2016 01:03:51 +0100
 Subject: [PATCH] MIPS: fix cache flushing for highmem pages
 
@@ -10,92 +10,22 @@ Fix this by always flushing highmem pages using kmap/kunmap_atomic
 around the actual cache flush. This might be a bit inefficient, but at
 least it's stable.
 
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
 ---
 
 --- a/arch/mips/mm/cache.c
 +++ b/arch/mips/mm/cache.c
-@@ -14,6 +14,7 @@
- #include <linux/sched.h>
- #include <linux/syscalls.h>
- #include <linux/mm.h>
-+#include <linux/highmem.h>
- #include <asm/cacheflush.h>
- #include <asm/processor.h>
-@@ -78,18 +79,29 @@ SYSCALL_DEFINE3(cacheflush, unsigned lon
-       return 0;
- }
-+static void
-+flush_highmem_page(struct page *page)
-+{
-+      void *addr = kmap_atomic(page);
-+      flush_data_cache_page((unsigned long)addr);
-+      kunmap_atomic(addr);
-+}
-+
- void __flush_dcache_page(struct page *page)
- {
-       struct address_space *mapping = page_mapping(page);
-       unsigned long addr;
--      if (PageHighMem(page))
--              return;
-       if (mapping && !mapping_mapped(mapping)) {
-               SetPageDcacheDirty(page);
-               return;
-       }
-+      if (PageHighMem(page)) {
-+              flush_highmem_page(page);
-+              return;
-+      }
-+
-       /*
-        * We could delay the flush for the !page_mapping case too.  But that
-        * case is for exec env/arg pages and those are %99 certainly going to
-@@ -105,6 +117,11 @@ void __flush_anon_page(struct page *page
+@@ -111,6 +111,13 @@ void __flush_anon_page(struct page *page
  {
        unsigned long addr = (unsigned long) page_address(page);
  
 +      if (PageHighMem(page)) {
-+              flush_highmem_page(page);
++              addr = (unsigned long)kmap_atomic(page);
++              flush_data_cache_page(addr);
++              __kunmap_atomic((void *)addr);
 +              return;
 +      }
 +
        if (pages_do_alias(addr, vmaddr)) {
                if (page_mapped(page) && !Page_dcache_dirty(page)) {
                        void *kaddr;
-@@ -123,8 +140,10 @@ void __flush_icache_page(struct vm_area_
- {
-       unsigned long addr;
--      if (PageHighMem(page))
-+      if (PageHighMem(page)) {
-+              flush_highmem_page(page);
-               return;
-+      }
-       addr = (unsigned long) page_address(page);
-       flush_data_cache_page(addr);
-@@ -142,12 +161,17 @@ void __update_cache(struct vm_area_struc
-       if (unlikely(!pfn_valid(pfn)))
-               return;
-       page = pfn_to_page(pfn);
--      if (page_mapping(page) && Page_dcache_dirty(page)) {
-+      if (!Page_dcache_dirty(page) || !page_mapping(page))
-+              return;
-+
-+      if (PageHighMem(page)) {
-+              flush_highmem_page(page);
-+      } else {
-               addr = (unsigned long) page_address(page);
-               if (exec || pages_do_alias(addr, address & PAGE_MASK))
-                       flush_data_cache_page(addr);
--              ClearPageDcacheDirty(page);
-       }
-+      ClearPageDcacheDirty(page);
- }
- unsigned long _page_cachable_default;