diff --git a/fix-memremap-on-ARM.patch b/fix-memremap-on-ARM.patch new file mode 100644 index 000000000..be8a2e608 --- /dev/null +++ b/fix-memremap-on-ARM.patch @@ -0,0 +1,156 @@ +From ddce00e38e06f10a12191df6830eb4975364ff99 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Wed, 30 Mar 2016 12:17:33 +0100 +Subject: [PATCH] fix memremap on ARM + +http://www.spinics.net/lists/arm-kernel/msg488703.html +--- + arch/arm/include/asm/io.h | 12 ++++++++++++ + arch/arm/mm/ioremap.c | 16 ++++++++++++++-- + drivers/mtd/maps/pxa2xx-flash.c | 6 +++--- + kernel/memremap.c | 11 ++++++++--- + 4 files changed, 37 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h +index 4859820..781ef5f 100644 +--- a/arch/arm/include/asm/io.h ++++ b/arch/arm/include/asm/io.h +@@ -392,9 +392,18 @@ void __iomem *ioremap(resource_size_t res_cookie, size_t size); + #define ioremap ioremap + #define ioremap_nocache ioremap + ++/* ++ * Do not use ioremap_cache for mapping memory. Use memremap instead. ++ */ + void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size); + #define ioremap_cache ioremap_cache + ++/* ++ * Do not use ioremap_cached in new code. Provided for the benefit of ++ * the pxa2xx-flash MTD driver only. ++ */ ++void __iomem *ioremap_cached(resource_size_t res_cookie, size_t size); ++ + void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size); + #define ioremap_wc ioremap_wc + #define ioremap_wt ioremap_wc +@@ -402,6 +411,9 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size); + void iounmap(volatile void __iomem *iomem_cookie); + #define iounmap iounmap + ++void *arch_memremap_wb(phys_addr_t phys_addr, size_t size); ++#define arch_memremap_wb arch_memremap_wb ++ + /* + * io{read,write}{16,32}be() macros + */ +diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c +index 66a978d..ff0eed2 100644 +--- a/arch/arm/mm/ioremap.c ++++ b/arch/arm/mm/ioremap.c +@@ -297,9 +297,10 @@ static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, + } + + /* +- * Don't allow RAM to be mapped - this causes problems with ARMv6+ ++ * Don't allow RAM to be mapped with mismatched attributes - this ++ * causes problems with ARMv6+ + */ +- if (WARN_ON(pfn_valid(pfn))) ++ if (WARN_ON(pfn_valid(pfn) && mtype != MT_MEMORY_RW)) + return NULL; + + area = get_vm_area_caller(size, VM_IOREMAP, caller); +@@ -380,11 +381,15 @@ void __iomem *ioremap(resource_size_t res_cookie, size_t size) + EXPORT_SYMBOL(ioremap); + + void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size) ++ __alias(ioremap_cached); ++ ++void __iomem *ioremap_cached(resource_size_t res_cookie, size_t size) + { + return arch_ioremap_caller(res_cookie, size, MT_DEVICE_CACHED, + __builtin_return_address(0)); + } + EXPORT_SYMBOL(ioremap_cache); ++EXPORT_SYMBOL(ioremap_cached); + + void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size) + { +@@ -414,6 +419,13 @@ __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached) + __builtin_return_address(0)); + } + ++void *arch_memremap_wb(phys_addr_t phys_addr, size_t size) ++{ ++ return (__force void *)arch_ioremap_caller(phys_addr, size, ++ MT_MEMORY_RW, ++ __builtin_return_address(0)); ++} ++ + void __iounmap(volatile void __iomem *io_addr) + { + void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); +diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c +index 7497090..2cde28e 100644 +--- a/drivers/mtd/maps/pxa2xx-flash.c ++++ b/drivers/mtd/maps/pxa2xx-flash.c +@@ -71,8 +71,8 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) + info->map.name); + return -ENOMEM; + } +- info->map.cached = memremap(info->map.phys, info->map.size, +- MEMREMAP_WB); ++ info->map.cached = ++ ioremap_cached(info->map.phys, info->map.size); + if (!info->map.cached) + printk(KERN_WARNING "Failed to ioremap cached %s\n", + info->map.name); +@@ -111,7 +111,7 @@ static int pxa2xx_flash_remove(struct platform_device *dev) + map_destroy(info->mtd); + iounmap(info->map.virt); + if (info->map.cached) +- memunmap(info->map.cached); ++ iounmap(info->map.cached); + kfree(info); + return 0; + } +diff --git a/kernel/memremap.c b/kernel/memremap.c +index a6d3823..6723c77 100644 +--- a/kernel/memremap.c ++++ b/kernel/memremap.c +@@ -27,6 +27,13 @@ __weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size) + } + #endif + ++#ifndef arch_memremap_wb ++static void *arch_memremap_wb(resource_size_t offset, unsigned long size) ++{ ++ return (__force void *)ioremap_cache(offset, size); ++} ++#endif ++ + static void *try_ram_remap(resource_size_t offset, size_t size) + { + unsigned long pfn = PHYS_PFN(offset); +@@ -34,7 +41,7 @@ static void *try_ram_remap(resource_size_t offset, size_t size) + /* In the simple case just return the existing linear address */ + if (pfn_valid(pfn) && !PageHighMem(pfn_to_page(pfn))) + return __va(offset); +- return NULL; /* fallback to ioremap_cache */ ++ return arch_memremap_wb(offset, size); + } + + /** +@@ -89,8 +96,6 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags) + */ + if (is_ram == REGION_INTERSECTS) + addr = try_ram_remap(offset, size); +- if (!addr) +- addr = ioremap_cache(offset, size); + } + + /* +-- +2.7.3 + diff --git a/kernel.spec b/kernel.spec index 131f167ef..a69c02c63 100644 --- a/kernel.spec +++ b/kernel.spec @@ -507,6 +507,9 @@ Patch422: geekbox-v4-device-tree-support.patch # http://www.spinics.net/lists/arm-kernel/msg483898.html Patch423: Initial-AllWinner-A64-and-PINE64-support.patch +# http://www.spinics.net/lists/arm-kernel/msg488703.html +Patch424: fix-memremap-on-ARM.patch + # http://patchwork.ozlabs.org/patch/587554/ Patch430: ARM-tegra-usb-no-reset.patch @@ -2158,6 +2161,7 @@ fi * Wed Mar 30 2016 Peter Robinson - Add ARMv7 mvebu fixes headed upstream - Minor ARMv7 cleanups +- Add patches to fix boot on 64K page aarch64 devices (eg Seattle) * Sun Mar 27 2016 Josh Boyer - 4.6.0-0.rc1.git0.1 - Linux v4.6-rc1