summaryrefslogtreecommitdiffstats
path: root/arch/riscv
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-01-16 09:37:50 +0100
committerPalmer Dabbelt <palmer@dabbelt.com>2018-01-30 19:14:27 -0800
commit5ec9c4ff0430e33b602cc0ff8ab9dec8ef548d28 (patch)
tree3fb2ff5397466ecc5516d7e8d56e71e17e15ca41 /arch/riscv
parentf1b65f20fb05d1dd94656904848b96cc6df52bc0 (diff)
downloadlinux-5ec9c4ff0430e33b602cc0ff8ab9dec8ef548d28.tar.gz
linux-5ec9c4ff0430e33b602cc0ff8ab9dec8ef548d28.tar.bz2
linux-5ec9c4ff0430e33b602cc0ff8ab9dec8ef548d28.zip
riscv: add ZONE_DMA32
This patch allows devices that require memory that can be addressed using 32-bit addresses to work easily on RISC-V systems. The newly improved dma-direct ops will tap into this pool automatically for 32-bit addressing. Based on an earlier patch from Wesley W. Terpstra. CC: Wesley W. Terpstra <terpstra@sifive.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/Kconfig5
-rw-r--r--arch/riscv/kernel/setup.c9
-rw-r--r--arch/riscv/mm/init.c10
3 files changed, 20 insertions, 4 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 504ba386b22e..0e66993f44cc 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,6 +22,7 @@ config RISCV
select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_MEMBLOCK
+ select HAVE_MEMBLOCK_NODE_MAP
select HAVE_DMA_API_DEBUG
select HAVE_DMA_CONTIGUOUS
select HAVE_GENERIC_DMA_COHERENT
@@ -43,6 +44,10 @@ config MMU
config ARCH_PHYS_ADDR_T_64BIT
def_bool y
+config ZONE_DMA32
+ bool
+ default y
+
config ARCH_DMA_ADDR_T_64BIT
def_bool y
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index c6d095ff5ab8..09f7064e898c 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -181,6 +181,15 @@ static void __init setup_bootmem(void)
early_init_fdt_scan_reserved_mem();
memblock_allow_resize();
memblock_dump_all();
+
+ for_each_memblock(memory, reg) {
+ unsigned long start_pfn = memblock_region_memory_base_pfn(reg);
+ unsigned long end_pfn = memblock_region_memory_end_pfn(reg);
+
+ memblock_set_node(PFN_PHYS(start_pfn),
+ PFN_PHYS(end_pfn - start_pfn),
+ &memblock.memory, 0);
+ }
}
void __init setup_arch(char **cmdline_p)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 9f4bee5e51fd..a6c0e8e7d888 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -17,6 +17,7 @@
#include <linux/initrd.h>
#include <linux/memblock.h>
#include <linux/swap.h>
+#include <linux/sizes.h>
#include <asm/tlbflush.h>
#include <asm/sections.h>
@@ -25,11 +26,12 @@
static void __init zone_sizes_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, };
- memset(zones_size, 0, sizeof(zones_size));
- zones_size[ZONE_NORMAL] = max_mapnr;
- free_area_init_node(0, zones_size, pfn_base, NULL);
+ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn));
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+
+ free_area_init_nodes(max_zone_pfns);
}
void setup_zero_page(void)