From 7423cc0caee7a42735ee2908f24ec69957c9bc85 Mon Sep 17 00:00:00 2001 From: Adam Buchbinder Date: Tue, 23 Feb 2016 15:24:55 -0800 Subject: ARC: Fix misspellings in comments. Signed-off-by: Adam Buchbinder Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index af7a2db..a444be6 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -149,7 +149,7 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, * Since xchg() doesn't always do that, it would seem that following defintion * is incorrect. But here's the rationale: * SMP : Even xchg() takes the atomic_ops_lock, so OK. - * LLSC: atomic_ops_lock are not relevent at all (even if SMP, since LLSC + * LLSC: atomic_ops_lock are not relevant at all (even if SMP, since LLSC * is natively "SMP safe", no serialization required). * UP : other atomics disable IRQ, so no way a difft ctxt atomic_xchg() * could clobber them. atomic_xchg() itself would be 1 insn, so it diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index 1aff3be..1d8f57c 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -231,7 +231,7 @@ /* free up r9 as scratchpad */ PROLOG_FREEUP_REG r9, @int\LVL\()_saved_reg - /* Which mode (user/kernel) was the system in when intr occured */ + /* Which mode (user/kernel) was the system in when intr occurred */ lr r9, [status32_l\LVL\()] SWITCH_TO_KERNEL_STK diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index d426d42..ec2af62 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -12,7 +12,7 @@ * - Utilise some unused free bits to confine PTE flags to 12 bits * This is a must for 4k pg-sz * - * vineetg: Mar 2011 - changes to accomodate MMU TLB Page Descriptor mods + * vineetg: Mar 2011 - changes to accommodate MMU TLB Page Descriptor mods * -TLB Locking never really existed, except for initial specs * -SILENT_xxx not needed for our port * -Per my request, MMU V3 changes the layout of some of the bits diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index 001de4c..e0efff1 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -232,7 +232,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) } /* Another API expected by schedular, shows up in "ps" as Wait Channel - * Ofcourse just returning schedule( ) would be pointless so unwind until + * Of course just returning schedule( ) would be pointless so unwind until * the function is not in schedular code */ unsigned int get_wchan(struct task_struct *tsk) diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 156d983..7d9a736 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -55,8 +55,8 @@ #define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */ #define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */ -#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */ -#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ +#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ +#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ #define ARC_TIMER_MAX 0xFFFFFFFF diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index b65f797..e1d71dc 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -650,7 +650,7 @@ static void __dma_cache_wback_l1(unsigned long start, unsigned long sz) /* * DMA ops for systems with both L1 and L2 caches, but without IOC - * Both L1 and L2 lines need to be explicity flushed/invalidated + * Both L1 and L2 lines need to be explicitly flushed/invalidated */ static void __dma_cache_wback_inv_slc(unsigned long start, unsigned long sz) { diff --git a/arch/arc/mm/highmem.c b/arch/arc/mm/highmem.c index 92dd92c..04f8332 100644 --- a/arch/arc/mm/highmem.c +++ b/arch/arc/mm/highmem.c @@ -18,7 +18,7 @@ /* * HIGHMEM API: * - * kmap() API provides sleep semantics hence refered to as "permanent maps" + * kmap() API provides sleep semantics hence referred to as "permanent maps" * It allows mapping LAST_PKMAP pages, using @last_pkmap_nr as the cursor * for book-keeping * diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index daf2bf5..7046c12 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -45,7 +45,7 @@ * in interrupt-safe region. * * Vineetg: April 23rd Bug #93131 - * Problem: tlb_flush_kernel_range() doesnt do anything if the range to + * Problem: tlb_flush_kernel_range() doesn't do anything if the range to * flush is more than the size of TLB itself. * * Rahul Trivedi : Codito Technologies 2004 @@ -167,7 +167,7 @@ static void utlb_invalidate(void) /* MMU v2 introduced the uTLB Flush command. * There was however an obscure hardware bug, where uTLB flush would * fail when a prior probe for J-TLB (both totally unrelated) would - * return lkup err - because the entry didnt exist in MMU. + * return lkup err - because the entry didn't exist in MMU. * The Workround was to set Index reg with some valid value, prior to * flush. This was fixed in MMU v3 hence not needed any more */ @@ -210,7 +210,7 @@ static void tlb_entry_insert(unsigned int pd0, pte_t pd1) /* * Commit the Entry to MMU - * It doesnt sound safe to use the TLBWriteNI cmd here + * It doesn't sound safe to use the TLBWriteNI cmd here * which doesn't flush uTLBs. I'd rather be safe than sorry. */ write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite); @@ -636,7 +636,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, * support. * * Normal and Super pages can co-exist (ofcourse not overlap) in TLB with a - * new bit "SZ" in TLB page desciptor to distinguish between them. + * new bit "SZ" in TLB page descriptor to distinguish between them. * Super Page size is configurable in hardware (4K to 16M), but fixed once * RTL builds. * -- cgit v0.10.2 From 2a41b6dc28dc71c1a3f1622612a26edc58f7561e Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 8 Mar 2016 19:31:24 +0530 Subject: ARC: bitops: Remove non relevant comments commit 80f420842ff42 removed the ARC bitops microoptimization but failed to prune the comments to same effect Fixes: 80f420842ff42 ("ARC: Make ARC bitops "safer" (add anti-optimization)") Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index 57c1f33..0352fb8 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h @@ -35,21 +35,6 @@ static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\ \ m += nr >> 5; \ \ - /* \ - * ARC ISA micro-optimization: \ - * \ - * Instructions dealing with bitpos only consider lower 5 bits \ - * e.g (x << 33) is handled like (x << 1) by ASL instruction \ - * (mem pointer still needs adjustment to point to next word) \ - * \ - * Hence the masking to clamp @nr arg can be elided in general. \ - * \ - * However if @nr is a constant (above assumed in a register), \ - * and greater than 31, gcc can optimize away (x << 33) to 0, \ - * as overflow, given the 32-bit ISA. Thus masking needs to be \ - * done for const @nr, but no code is generated due to gcc \ - * const prop. \ - */ \ nr &= 0x1f; \ \ __asm__ __volatile__( \ -- cgit v0.10.2 From 89a269285fe350346b794676c79119b31015292f Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 11 Mar 2016 12:47:58 +0530 Subject: ARC: [BE] Select correct CROSS_COMPILE prefix This allows CONFIG_CPU_BIG_ENDIAN=y to build correctly out of the box, w/o any other tweaks. Cc: Noam Camus Cc: Alexey Brodkin Cc: Anton Kolesov Signed-off-by: Vineet Gupta diff --git a/arch/arc/Makefile b/arch/arc/Makefile index c8230f3..babc09c 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -9,7 +9,11 @@ UTS_MACHINE := arc ifeq ($(CROSS_COMPILE),) +ifndef CONFIG_CPU_BIG_ENDIAN CROSS_COMPILE := arc-linux- +else +CROSS_COMPILE := arceb-linux- +endif endif KBUILD_DEFCONFIG := nsim_700_defconfig -- cgit v0.10.2 From 2d746eeb4f70e3602dea0aec174072adc0ab8ce5 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 11 Mar 2016 12:40:17 +0530 Subject: ARC: [*defconfig] No need to specify CONFIG_CROSS_COMPILE The problem is with CONFIG_CPU_BIG_ENDIAN=y we still needed .config fixup to override the the defconfig prefix to arceb-linux- So remove these from defconfig and let user pass this via CROSS_COMPILE environment var or use the default for ENDIAN (per previous patch) No other arch carries them in defconfigs anyways ! Cc: Noam Camus Cc: Alexey Brodkin Cc: Anton Kolesov Signed-off-by: Vineet Gupta diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index 5d4e2a0..6cdffea 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index 87ee46b..f8b396c 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index d80daf4..56128ea 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig index f410953..7314f53 100644 --- a/arch/arc/configs/nsim_700_defconfig +++ b/arch/arc/configs/nsim_700_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig index cfaa33c..a99dc7a 100644 --- a/arch/arc/configs/nsim_hs_defconfig +++ b/arch/arc/configs/nsim_hs_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig index bb2a8dc..59f221f 100644 --- a/arch/arc/configs/nsim_hs_smp_defconfig +++ b/arch/arc/configs/nsim_hs_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig index 646182e..0972e75 100644 --- a/arch/arc/configs/nsimosci_defconfig +++ b/arch/arc/configs/nsimosci_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig index ceca254..24d9d0e 100644 --- a/arch/arc/configs/nsimosci_hs_defconfig +++ b/arch/arc/configs/nsimosci_hs_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig index 4b6da90..6746d01 100644 --- a/arch/arc/configs/nsimosci_hs_smp_defconfig +++ b/arch/arc/configs/nsimosci_hs_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig index 9b342ea..4c51183 100644 --- a/arch/arc/configs/tb10x_defconfig +++ b/arch/arc/configs/tb10x_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="tb10x" CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig index a07f20d..c0d6a01 100644 --- a/arch/arc/configs/vdk_hs38_defconfig +++ b/arch/arc/configs/vdk_hs38_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_CROSS_MEMORY_ATTACH is not set diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index 7359859..52ec315 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_CROSS_MEMORY_ATTACH is not set -- cgit v0.10.2 From f778cc65717687a3d3f26dd21bef62cd059f1b8b Mon Sep 17 00:00:00 2001 From: Lada Trimasova Date: Wed, 9 Mar 2016 20:21:04 +0300 Subject: ARC: [BE] readl()/writel() to work in Big Endian CPU configuration read{l,w}() write{l,w}() primitives should use le{16,32}_to_cpu() and cpu_to_le{16,32}() respectively to ensure device registers are read correctly in Big Endian CPU configuration. Per Arnd Bergmann | Most drivers using readl() or readl_relaxed() expect those to perform byte | swaps on big-endian architectures, as the registers tend to be fixed endian This was needed for getting UART to work correctly on a Big Endian ARC. The ARC accessors originally were fine, and the bug got introduced inadventently by commit b8a033023994 ("ARCv2: barriers") Fixes: b8a033023994 ("ARCv2: barriers") Link: http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de Cc: Alexey Brodkin Cc: stable@vger.kernel.org [4.2+] Cc: Arnd Bergmann Signed-off-by: Lada Trimasova [vgupta: beefed up changelog, added Fixes/stable tags] Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h index 694ece8..27b17ad 100644 --- a/arch/arc/include/asm/io.h +++ b/arch/arc/include/asm/io.h @@ -129,15 +129,23 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) /* - * Relaxed API for drivers which can handle any ordering themselves + * Relaxed API for drivers which can handle barrier ordering themselves + * + * Also these are defined to perform little endian accesses. + * To provide the typical device register semantics of fixed endian, + * swap the byte order for Big Endian + * + * http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de */ #define readb_relaxed(c) __raw_readb(c) -#define readw_relaxed(c) __raw_readw(c) -#define readl_relaxed(c) __raw_readl(c) +#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \ + __raw_readw(c)); __r; }) +#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ + __raw_readl(c)); __r; }) #define writeb_relaxed(v,c) __raw_writeb(v,c) -#define writew_relaxed(v,c) __raw_writew(v,c) -#define writel_relaxed(v,c) __raw_writel(v,c) +#define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c) +#define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c) #include -- cgit v0.10.2 From 7cab91b87dd8eeee5911ec34be8bb0288ebba18b Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 17 Feb 2016 19:37:33 +0530 Subject: ARCv2: Allow enabling PAE40 w/o HIGHMEM This allows for regression testing in PAE specific code as we lack a 32+ bit physical memory platform other than nSIM. Signed-off-by: Vineet Gupta diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 8a188bc..7981ea8 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -458,7 +458,6 @@ config ARC_HAS_PAE40 bool "Support for the 40-bit Physical Address Extension" default n depends on ISA_ARCV2 - select HIGHMEM help Enable access to physical memory beyond 4G, only supported on ARC cores with 40 bit Physical Addressing support -- cgit v0.10.2 From 20d780374c81cf237834af2202c26df2100ddd69 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 25 Feb 2016 22:04:38 +0530 Subject: ARC: build: Better way to detect ISA compatible toolchain ARC architecture has 2 instruction sets: ARCompact/ARCv2. While same gcc supports compiling for either (using appropriate toggles), we can't use the same toolchain to build kernel because libgcc needs to be unique and the toolchian (uClibc based) is not multilibed. uClibc toolchain is convenient since it allows all userspace and kernel to be built with a single install for an ISA. This however means 2 gnu installs (with same triplet prefix) are needed for building for 2 ISA and need to be in PATH. As developers we keep switching the builds, but would occassionally fail to update the PATH leading to usage of wrong tools. And this would only show up at the end of kernel build when linking incompatible libgcc. So the initial solution was to have gcc define a special preprocessor macro DEFAULT_CPU_xxx which is unique for default toolchain configuration. Claudiu proposed using grep for an existing preprocessor macro which is again uniquely defined per ISA. Cc: Michal Marek Suggested-by: Claudiu Zissulescu Signed-off-by: Vineet Gupta diff --git a/arch/arc/Makefile b/arch/arc/Makefile index babc09c..fed12f3 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -22,6 +22,20 @@ cflags-y += -fno-common -pipe -fno-builtin -D__linux__ cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7 cflags-$(CONFIG_ISA_ARCV2) += -mcpu=archs +is_700 = $(shell $(CC) -dM -E - < /dev/null | grep -q "ARC700" && echo 1 || echo 0) + +ifdef CONFIG_ISA_ARCOMPACT +ifeq ($(is_700), 0) + $(error Toolchain not configured for ARCompact builds) +endif +endif + +ifdef CONFIG_ISA_ARCV2 +ifeq ($(is_700), 1) + $(error Toolchain not configured for ARCv2 builds) +endif +endif + ifdef CONFIG_ARC_CURR_IN_REG # For a global register defintion, make sure it gets passed to every file # We had a customer reported bug where some code built in kernel was NOT using diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index f9f4c6f..7fbaea0 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -381,12 +381,6 @@ static inline int is_isa_arcompact(void) return IS_ENABLED(CONFIG_ISA_ARCOMPACT); } -#if defined(CONFIG_ISA_ARCOMPACT) && !defined(_CPU_DEFAULT_A7) -#error "Toolchain not configured for ARCompact builds" -#elif defined(CONFIG_ISA_ARCV2) && !defined(_CPU_DEFAULT_HS) -#error "Toolchain not configured for ARCv2 builds" -#endif - #endif /* __ASEMBLY__ */ #endif /* _ASM_ARC_ARCREGS_H */ -- cgit v0.10.2 From 0b291635fce2bda983e1d2865a8bb5f46a8382bf Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 18 Dec 2015 17:32:49 +0530 Subject: ARC: [plat-nsim] document ranges Signed-off-by: Vineet Gupta diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts index fc81879..f46633e 100644 --- a/arch/arc/boot/dts/nsim_hs.dts +++ b/arch/arc/boot/dts/nsim_hs.dts @@ -35,7 +35,8 @@ #address-cells = <1>; #size-cells = <1>; - /* only perip space at end of low mem accessible */ + /* only perip space at end of low mem accessible + bus addr, parent bus addr, size */ ranges = <0x80000000 0x0 0x80000000 0x80000000>; core_intc: core-interrupt-controller { -- cgit v0.10.2 From c2ff5cf2735c57542b8e630e63d6983013a2e1c3 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 18 Dec 2015 13:57:41 +0530 Subject: ARC: mm: Use virt_to_pfn() for addr >> PAGE_SHIFT pattern Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 429957f..9a7cf52 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -10,7 +10,6 @@ #include - #ifndef __ASSEMBLY__ #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) @@ -76,30 +75,26 @@ typedef unsigned long pgprot_t; typedef pte_t * pgtable_t; -#define ARCH_PFN_OFFSET (CONFIG_LINUX_LINK_BASE >> PAGE_SHIFT) +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) + +#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) -#define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) +#define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) /* * __pa, __va, virt_to_page (ALERT: deprecated, don't use them) * * These macros have historically been misnamed * virt here means link-address/program-address as embedded in object code. - * So if kernel img is linked at 0x8000_0000 onwards, 0x8010_0000 will be - * 128th page, and virt_to_page( ) will return the struct page corresp to it. - * mem_map[ ] is an array of struct page for each page frame in the system - * - * Independent of where linux is linked at, link-addr = physical address - * So the old macro __pa = vaddr + PAGE_OFFSET - CONFIG_LINUX_LINK_BASE - * would have been wrong in case kernel is not at 0x8zs + * And for ARC, link-addr = physical address */ #define __pa(vaddr) ((unsigned long)vaddr) #define __va(paddr) ((void *)((unsigned long)(paddr))) #define virt_to_page(kaddr) \ - (mem_map + ((__pa(kaddr) - CONFIG_LINUX_LINK_BASE) >> PAGE_SHIFT)) + (mem_map + virt_to_pfn((kaddr) - CONFIG_LINUX_LINK_BASE)) -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) /* Default Permissions for stack/heaps pages (Non Executable) */ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE) diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index ec2af62..7d6c93e 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -278,15 +278,14 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) #define pmd_present(x) (pmd_val(x)) #define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0) -#define pte_page(x) (mem_map + \ - (unsigned long)(((pte_val(x) - CONFIG_LINUX_LINK_BASE) >> \ - PAGE_SHIFT))) +#define pte_page(pte) \ + (mem_map + virt_to_pfn(pte_val(pte) - CONFIG_LINUX_LINK_BASE)) #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) -#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pte_pfn(pte) virt_to_pfn(pte_val(pte)) #define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | \ pgprot_val(prot))) -#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define __pte_index(addr) (virt_to_pfn(addr) & (PTRS_PER_PTE - 1)) /* * pte_offset gets a @ptr to PMD entry (PGD in our 2-tier paging system) -- cgit v0.10.2 From b31ac42697bef4a3aa5d0aa42375a55657f57174 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 15 Mar 2016 11:36:43 +0530 Subject: ARCv2: LLSC: software backoff is NOT needed starting HS2.1c Signed-off-by: Vineet Gupta diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 7981ea8..8ce0928 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -387,7 +387,7 @@ config ARC_HAS_LLSC config ARC_STAR_9000923308 bool "Workaround for llock/scond livelock" - default y + default n depends on ISA_ARCV2 && SMP && ARC_HAS_LLSC config ARC_HAS_SWAPE diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index cdc821d..fa1fa9a 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -357,11 +357,6 @@ static void arc_chk_core_config(void) pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n"); else if (!cpu->extn.fpu_dp && fpu_enabled) panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); - - if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic && - IS_ENABLED(CONFIG_ARC_HAS_LLSC) && - !IS_ENABLED(CONFIG_ARC_STAR_9000923308)) - panic("llock/scond livelock workaround missing\n"); } /* -- cgit v0.10.2 From df420fd68811c98e2a563e8b6ff7eb04aa9c8141 Mon Sep 17 00:00:00 2001 From: Lada Trimasova Date: Mon, 14 Mar 2016 17:11:57 +0300 Subject: arc: [plat-nsimosci*] use ezchip network driver Since ezchip network driver was adapted to little endian architecture this patch provides the corresponding arch/arc/{boot/dts,configs}/ updates so we can switch over to this device-model/driver for OSCI platform. Cc: Alexey Brodkin Signed-off-by: Lada Trimasova Signed-off-by: Vineet Gupta diff --git a/arch/arc/boot/dts/nsimosci.dts b/arch/arc/boot/dts/nsimosci.dts index 1c169dc..d94b4ce 100644 --- a/arch/arc/boot/dts/nsimosci.dts +++ b/arch/arc/boot/dts/nsimosci.dts @@ -65,10 +65,9 @@ }; eth0: ethernet@f0003000 { - compatible = "snps,oscilan"; + compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; - interrupts = <7>, <8>; - interrupt-names = "rx", "tx"; + interrupts = <7>; }; }; }; diff --git a/arch/arc/boot/dts/nsimosci_hs.dts b/arch/arc/boot/dts/nsimosci_hs.dts index d64a96f..034a313 100644 --- a/arch/arc/boot/dts/nsimosci_hs.dts +++ b/arch/arc/boot/dts/nsimosci_hs.dts @@ -65,10 +65,9 @@ }; eth0: ethernet@f0003000 { - compatible = "snps,oscilan"; + compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; - interrupts = <25>, <26>; - interrupt-names = "rx", "tx"; + interrupts = <25>; }; arcpct0: pct { diff --git a/arch/arc/boot/dts/nsimosci_hs_idu.dts b/arch/arc/boot/dts/nsimosci_hs_idu.dts index f6bf0ca..8a1297e 100644 --- a/arch/arc/boot/dts/nsimosci_hs_idu.dts +++ b/arch/arc/boot/dts/nsimosci_hs_idu.dts @@ -85,11 +85,10 @@ }; eth0: ethernet@f0003000 { - compatible = "snps,oscilan"; + compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; interrupt-parent = <&idu_intc>; - interrupts = <1 2>, <2 2>; - interrupt-names = "rx", "tx"; + interrupts = <1 2>; }; arcpct0: pct { diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig index 0972e75..42bafa5 100644 --- a/arch/arc/configs/nsimosci_defconfig +++ b/arch/arc/configs/nsimosci_defconfig @@ -38,6 +38,7 @@ CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_BLK_DEV is not set CONFIG_NETDEVICES=y +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_MOUSE_PS2_ALPS is not set diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig index 24d9d0e..4bb60c1 100644 --- a/arch/arc/configs/nsimosci_hs_defconfig +++ b/arch/arc/configs/nsimosci_hs_defconfig @@ -39,6 +39,7 @@ CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_BLK_DEV is not set CONFIG_NETDEVICES=y +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y CONFIG_INPUT_EVDEV=y # CONFIG_MOUSE_PS2_ALPS is not set # CONFIG_MOUSE_PS2_LOGIPS2PP is not set diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig index 6746d01..7e88f4c 100644 --- a/arch/arc/configs/nsimosci_hs_smp_defconfig +++ b/arch/arc/configs/nsimosci_hs_smp_defconfig @@ -20,6 +20,7 @@ CONFIG_MODULES=y CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y +# CONFIG_ARC_HAS_GFRC is not set CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu" CONFIG_PREEMPT=y # CONFIG_COMPACTION is not set @@ -45,6 +46,7 @@ CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_ARC is not set # CONFIG_NET_CADENCE is not set # CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set -- cgit v0.10.2 From c511eaaa7851cda0657b2d5a401d33cf4dba52ad Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 17 Mar 2016 15:00:59 +0530 Subject: ARC: thp: unbork !CONFIG_TRANSPARENT_HUGEPAGE build linux-next for 4.6-rc1 timeline reported ARC build failures !THP | arch/arc/include/asm/tlbflush.h:29:0: warning: "flush_pmd_tlb_range" redefined [enabled by default] | arch/arc/include/asm/tlbflush.h:29:0: warning: "flush_pmd_tlb_range" redefined [enabled by default] | arch/arc/include/asm/tlbflush.h:29:0: warning: "flush_pmd_tlb_range" redefined [enabled by default] Turns out that commit ("mm/thp/migration: switch from flush_tlb_range to flush_pmd_tlb_range") triggered the issue while the problem was in ARC code where THP specific helpers were not guarded with #ifdef. Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/tlbflush.h b/arch/arc/include/asm/tlbflush.h index 1fe9c8c..f0d42f1 100644 --- a/arch/arc/include/asm/tlbflush.h +++ b/arch/arc/include/asm/tlbflush.h @@ -17,8 +17,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page); void local_flush_tlb_kernel_range(unsigned long start, unsigned long end); void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +#endif #ifndef CONFIG_SMP #define flush_tlb_range(vma, s, e) local_flush_tlb_range(vma, s, e) @@ -26,7 +28,9 @@ void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, #define flush_tlb_kernel_range(s, e) local_flush_tlb_kernel_range(s, e) #define flush_tlb_all() local_flush_tlb_all() #define flush_tlb_mm(mm) local_flush_tlb_mm(mm) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE #define flush_pmd_tlb_range(vma, s, e) local_flush_pmd_tlb_range(vma, s, e) +#endif #else extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); @@ -34,7 +38,8 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); extern void flush_tlb_all(void); extern void flush_tlb_mm(struct mm_struct *mm); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE extern void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); - +#endif #endif /* CONFIG_SMP */ #endif -- cgit v0.10.2 From 26cf9cc5d88e008eac517c8bfa44a2fdbfd6a674 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Wed, 16 Mar 2016 15:35:33 +0800 Subject: arc: use of_platform_default_populate() to populate default bus Use helper of_platform_default_populate() in linux/of_platform when possible, instead of calling of_platform_populate() with the default match table. Signed-off-by: Kefeng Wang Signed-off-by: Vineet Gupta diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index fa1fa9a..e4dc7ba 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -459,7 +459,7 @@ static int __init customize_machine(void) * Traverses flattened DeviceTree - registering platform devices * (if any) complete with their resources */ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + of_platform_default_populate(NULL, NULL, NULL); if (machine_desc->init_machine) machine_desc->init_machine(); -- cgit v0.10.2 From 667a490bdb6e27db0887d2ca515b907d6aa87118 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 17 Mar 2016 12:41:52 +0300 Subject: ARC: [plat-axs10x] add Ethernet PHY description in .dts Commit e34d65696d2e ("stmmac: create of compatible mdio bus for stmmac driver") broke DW GMAC functionality on ARC AXS10x boards: That's what happens on eth0 up: --------------------------->8------------------------ | libphy: PHY stmmac-0:ffffffff not found | eth0: Could not attach to PHY | stmmac_open: Cannot attach to PHY (error: -19) --------------------------->8------------------------ Simplest solution is to add PHY description in board's .dts. And so we do here. Signed-off-by: Alexey Brodkin Cc: Rob Herring Cc: Phil Reid Cc: David S. Miller Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: stable@vger.kernel.org # 4.5 Reviewed-by: Sergei Shtylyov Signed-off-by: Vineet Gupta diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index 44a578c..ab5d570 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -47,6 +47,14 @@ clocks = <&apbclk>; clock-names = "stmmaceth"; max-speed = <100>; + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; }; ehci@0x40000 { -- cgit v0.10.2 From a69fe1a2c9b2bd35046cb8f4e61337825cef9239 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 18 Mar 2016 13:58:01 +0530 Subject: ARC: build: Turn off -Wmaybe-uninitialized for ARC gcc 4.8 linux-next has been reporting gazillion warnings for ARC build and I finally decided to take a bite: http://kisskb.ellerman.id.au/kisskb/buildresult/12638735/ Most of the them are due to -Wmaybe-uninitialized | ../kernel/sysctl.c: In function '__do_proc_doulongvec_minmax': | ../kernel/sysctl.c:1928:12: warning: 'p' may be used uninitialized in this function [-Wmaybe-uninitialized] | ret = tmp - *buf; | ^ | ../kernel/sysctl.c:2342:29: note: 'p' was declared here | char *kbuf = NULL, *p; | ^ | ... | ... Cursory look at code seemed fine and a definite gcc false positive in say kernel/sysctl.c Mystery was why only for ARC (and not with ARM linaro toolchain based off same gcc 4.8). Turns out that -O3 (default for ARC) triggers these and if I enable -O3 for ARM kernel build, I see the same splat. I initially wanted to disable this only for gcc 4.8, but Arnd reported it is seen even on gcc 6.0 for ARM with -O3. Thus better to disable this independent of gcc version. Cc: Claudiu Zissulescu Cc: Arnd Bergmann Cc: Michal Marek Cc: Geert Uytterhoeven Cc: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Vineet Gupta diff --git a/arch/arc/Makefile b/arch/arc/Makefile index fed12f3..def69e3 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -76,7 +76,9 @@ endif ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE # Generic build system uses -O2, we want -O3 # Note: No need to add to cflags-y as that happens anyways -ARCH_CFLAGS += -O3 +# +# Disable the false maybe-uninitialized warings gcc spits out at -O3 +ARCH_CFLAGS += -O3 $(call cc-disable-warning,maybe-uninitialized,) endif # small data is default for elf32 tool-chain. If not usable, disable it -- cgit v0.10.2 From d98a15a5653bfae5bccc68a06a60ccf035b2c4cc Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Mon, 14 Mar 2016 15:03:59 +0530 Subject: ARC: dma: Use struct page based page allocator helpers vs. the ones which reutne void *, so that we can handle pages > 4GB in subsequent patches Also plug a potential page leak in case ioremap fails Signed-off-by: Vineet Gupta diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 01eaf88..6cf1d92 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -24,15 +24,20 @@ static void *arc_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) { - void *paddr, *kvaddr; + unsigned long order = get_order(size); + struct page *page; + phys_addr_t paddr; + void *kvaddr; - /* This is linear addr (0x8000_0000 based) */ - paddr = alloc_pages_exact(size, gfp); - if (!paddr) + page = alloc_pages(gfp, order); + if (!page) return NULL; - /* This is bus address, platform dependent */ - *dma_handle = (dma_addr_t)paddr; + /* This is linear addr (0x8000_0000 based) */ + paddr = page_to_phys(page); + + /* For now bus address is exactly same as paddr */ + *dma_handle = paddr; /* * IOC relies on all data (even coherent DMA data) being in cache @@ -51,8 +56,10 @@ static void *arc_dma_alloc(struct device *dev, size_t size, /* This is kernel Virtual address (0x7000_0000 based) */ kvaddr = ioremap_nocache((unsigned long)paddr, size); - if (kvaddr == NULL) + if (kvaddr == NULL) { + __free_pages(page, order); return NULL; + } /* * Evict any existing L1 and/or L2 lines for the backing page @@ -72,11 +79,13 @@ static void *arc_dma_alloc(struct device *dev, size_t size, static void arc_dma_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) { + struct page *page = virt_to_page(dma_handle); + if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) && !(is_isa_arcv2() && ioc_exists)) iounmap((void __force __iomem *)vaddr); - free_pages_exact((void *)dma_handle, size); + __free_pages(page, get_order(size)); } /* -- cgit v0.10.2 From 6b7003930e010eeb976632c1a374246b7cbc2995 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Mon, 14 Mar 2016 15:34:36 +0530 Subject: ARC: dma: non-coherent pages need V-P mapping if in HIGHMEM Previously a non-coherent page (hardware IOC or simply driver needs) could be handled by cpu with paddr alone (kvaddr used to be needed for coherent mappings to enforce uncached semantics via a MMU mapping). Now however such a page might still require a V-P mapping if it was in physical address space > 32bits due to PAE40, which the CPU can't access directly with a paddr So decouple decision of kvaddr allocation from type of alloc request (coh/non-coh) Signed-off-by: Vineet Gupta diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 6cf1d92..4b428a4 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -28,23 +28,18 @@ static void *arc_dma_alloc(struct device *dev, size_t size, struct page *page; phys_addr_t paddr; void *kvaddr; + int need_coh = 1, need_kvaddr = 0; page = alloc_pages(gfp, order); if (!page) return NULL; - /* This is linear addr (0x8000_0000 based) */ - paddr = page_to_phys(page); - - /* For now bus address is exactly same as paddr */ - *dma_handle = paddr; - /* * IOC relies on all data (even coherent DMA data) being in cache * Thus allocate normal cached memory * * The gains with IOC are two pronged: - * -For streaming data, elides needs for cache maintenance, saving + * -For streaming data, elides need for cache maintenance, saving * cycles in flush code, and bus bandwidth as all the lines of a * buffer need to be flushed out to memory * -For coherent data, Read/Write to buffers terminate early in cache @@ -52,13 +47,31 @@ static void *arc_dma_alloc(struct device *dev, size_t size, */ if ((is_isa_arcv2() && ioc_exists) || dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) - return paddr; + need_coh = 0; + + /* + * - A coherent buffer needs MMU mapping to enforce non-cachability + * - A highmem page needs a virtual handle (hence MMU mapping) + * independent of cachability + */ + if (PageHighMem(page) || need_coh) + need_kvaddr = 1; + + /* This is linear addr (0x8000_0000 based) */ + paddr = page_to_phys(page); + + /* For now bus address is exactly same as paddr */ + *dma_handle = paddr; /* This is kernel Virtual address (0x7000_0000 based) */ - kvaddr = ioremap_nocache((unsigned long)paddr, size); - if (kvaddr == NULL) { - __free_pages(page, order); - return NULL; + if (need_kvaddr) { + kvaddr = ioremap_nocache((unsigned long)paddr, size); + if (kvaddr == NULL) { + __free_pages(page, order); + return NULL; + } + } else { + kvaddr = (void *)paddr; } /* @@ -71,7 +84,8 @@ static void *arc_dma_alloc(struct device *dev, size_t size, * Currently flush_cache_vmap nukes the L1 cache completely which * will be optimized as a separate commit */ - dma_cache_wback_inv((unsigned long)paddr, size); + if (need_coh) + dma_cache_wback_inv((unsigned long)paddr, size); return kvaddr; } @@ -80,9 +94,12 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) { struct page *page = virt_to_page(dma_handle); + int is_non_coh = 1; + + is_non_coh = dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) || + (is_isa_arcv2() && ioc_exists); - if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) && - !(is_isa_arcv2() && ioc_exists)) + if (PageHighMem(page) || !is_non_coh) iounmap((void __force __iomem *)vaddr); __free_pages(page, get_order(size)); -- cgit v0.10.2 From 971573cf57394775deb591c3920e565c80cbc800 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 16 Mar 2016 14:51:33 +0530 Subject: ARC: dma: pass_phys() not sg_virt() to cache ops Signed-off-by: Vineet Gupta diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 4b428a4..d6b30f6 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -170,7 +170,7 @@ static void arc_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg; for_each_sg(sglist, sg, nelems, i) - _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir); + _dma_cache_sync(sg_phys(sg), sg->length, dir); } static void arc_dma_sync_sg_for_device(struct device *dev, @@ -181,7 +181,7 @@ static void arc_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg; for_each_sg(sglist, sg, nelems, i) - _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir); + _dma_cache_sync(sg_phys(sg), sg->length, dir); } static int arc_dma_supported(struct device *dev, u64 dma_mask) -- cgit v0.10.2 From f5db19e93f680160a0fb3e2b05ceb4832b24d486 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 16 Mar 2016 15:04:39 +0530 Subject: ARC: dma: ioremap: use phys_addr_t consistenctly in code paths To support dma in physical memory beyond 4GB with PAE40 Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h index fbe3587..a093adb 100644 --- a/arch/arc/include/asm/cacheflush.h +++ b/arch/arc/include/asm/cacheflush.h @@ -40,9 +40,9 @@ void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr); void flush_dcache_page(struct page *page); -void dma_cache_wback_inv(unsigned long start, unsigned long sz); -void dma_cache_inv(unsigned long start, unsigned long sz); -void dma_cache_wback(unsigned long start, unsigned long sz); +void dma_cache_wback_inv(phys_addr_t start, unsigned long sz); +void dma_cache_inv(phys_addr_t start, unsigned long sz); +void dma_cache_wback(phys_addr_t start, unsigned long sz); #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h index 27b17ad..1a20a62 100644 --- a/arch/arc/include/asm/io.h +++ b/arch/arc/include/asm/io.h @@ -13,8 +13,8 @@ #include #include -extern void __iomem *ioremap(unsigned long physaddr, unsigned long size); -extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size, +extern void __iomem *ioremap(phys_addr_t paddr, unsigned long size); +extern void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, unsigned long flags); extern void iounmap(const void __iomem *addr); diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index e1d71dc..635cd8c 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -28,9 +28,9 @@ volatile int slc_enable = 1, ioc_enable = 1; void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr, unsigned long sz, const int cacheop); -void (*__dma_cache_wback_inv)(unsigned long start, unsigned long sz); -void (*__dma_cache_inv)(unsigned long start, unsigned long sz); -void (*__dma_cache_wback)(unsigned long start, unsigned long sz); +void (*__dma_cache_wback_inv)(phys_addr_t start, unsigned long sz); +void (*__dma_cache_inv)(phys_addr_t start, unsigned long sz); +void (*__dma_cache_wback)(phys_addr_t start, unsigned long sz); char *arc_cache_mumbojumbo(int c, char *buf, int len) { @@ -633,17 +633,17 @@ EXPORT_SYMBOL(flush_dcache_page); * DMA ops for systems with L1 cache only * Make memory coherent with L1 cache by flushing/invalidating L1 lines */ -static void __dma_cache_wback_inv_l1(unsigned long start, unsigned long sz) +static void __dma_cache_wback_inv_l1(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH_N_INV); } -static void __dma_cache_inv_l1(unsigned long start, unsigned long sz) +static void __dma_cache_inv_l1(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_INV); } -static void __dma_cache_wback_l1(unsigned long start, unsigned long sz) +static void __dma_cache_wback_l1(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH); } @@ -652,19 +652,19 @@ static void __dma_cache_wback_l1(unsigned long start, unsigned long sz) * DMA ops for systems with both L1 and L2 caches, but without IOC * Both L1 and L2 lines need to be explicitly flushed/invalidated */ -static void __dma_cache_wback_inv_slc(unsigned long start, unsigned long sz) +static void __dma_cache_wback_inv_slc(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH_N_INV); slc_op(start, sz, OP_FLUSH_N_INV); } -static void __dma_cache_inv_slc(unsigned long start, unsigned long sz) +static void __dma_cache_inv_slc(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_INV); slc_op(start, sz, OP_INV); } -static void __dma_cache_wback_slc(unsigned long start, unsigned long sz) +static void __dma_cache_wback_slc(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH); slc_op(start, sz, OP_FLUSH); @@ -675,26 +675,26 @@ static void __dma_cache_wback_slc(unsigned long start, unsigned long sz) * IOC hardware snoops all DMA traffic keeping the caches consistent with * memory - eliding need for any explicit cache maintenance of DMA buffers */ -static void __dma_cache_wback_inv_ioc(unsigned long start, unsigned long sz) {} -static void __dma_cache_inv_ioc(unsigned long start, unsigned long sz) {} -static void __dma_cache_wback_ioc(unsigned long start, unsigned long sz) {} +static void __dma_cache_wback_inv_ioc(phys_addr_t start, unsigned long sz) {} +static void __dma_cache_inv_ioc(phys_addr_t start, unsigned long sz) {} +static void __dma_cache_wback_ioc(phys_addr_t start, unsigned long sz) {} /* * Exported DMA API */ -void dma_cache_wback_inv(unsigned long start, unsigned long sz) +void dma_cache_wback_inv(phys_addr_t start, unsigned long sz) { __dma_cache_wback_inv(start, sz); } EXPORT_SYMBOL(dma_cache_wback_inv); -void dma_cache_inv(unsigned long start, unsigned long sz) +void dma_cache_inv(phys_addr_t start, unsigned long sz) { __dma_cache_inv(start, sz); } EXPORT_SYMBOL(dma_cache_inv); -void dma_cache_wback(unsigned long start, unsigned long sz) +void dma_cache_wback(phys_addr_t start, unsigned long sz) { __dma_cache_wback(start, sz); } diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index d6b30f6..608c143 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -65,13 +65,13 @@ static void *arc_dma_alloc(struct device *dev, size_t size, /* This is kernel Virtual address (0x7000_0000 based) */ if (need_kvaddr) { - kvaddr = ioremap_nocache((unsigned long)paddr, size); + kvaddr = ioremap_nocache(paddr, size); if (kvaddr == NULL) { __free_pages(page, order); return NULL; } } else { - kvaddr = (void *)paddr; + kvaddr = (void *)(u32)paddr; } /* @@ -85,7 +85,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size, * will be optimized as a separate commit */ if (need_coh) - dma_cache_wback_inv((unsigned long)paddr, size); + dma_cache_wback_inv(paddr, size); return kvaddr; } @@ -110,7 +110,7 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr, * CPU accesses page via normal paddr, thus needs to explicitly made * consistent before each use */ -static void _dma_cache_sync(unsigned long paddr, size_t size, +static void _dma_cache_sync(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { switch (dir) { @@ -124,7 +124,7 @@ static void _dma_cache_sync(unsigned long paddr, size_t size, dma_cache_wback_inv(paddr, size); break; default: - pr_err("Invalid DMA dir [%d] for OP @ %lx\n", dir, paddr); + pr_err("Invalid DMA dir [%d] for OP @ %pa[p]\n", dir, &paddr); } } @@ -132,7 +132,7 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - unsigned long paddr = page_to_phys(page) + offset; + phys_addr_t paddr = page_to_phys(page) + offset; _dma_cache_sync(paddr, size, dir); return (dma_addr_t)paddr; } diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c index 739e65f..75b0ca6 100644 --- a/arch/arc/mm/ioremap.c +++ b/arch/arc/mm/ioremap.c @@ -14,18 +14,21 @@ #include #include -void __iomem *ioremap(unsigned long paddr, unsigned long size) +void __iomem *ioremap(phys_addr_t paddr, unsigned long size) { - unsigned long end; + phys_addr_t end; /* Don't allow wraparound or zero size */ end = paddr + size - 1; if (!size || (end < paddr)) return NULL; - /* If the region is h/w uncached, avoid MMU mappings */ + /* + * If the region is h/w uncached, MMU mapping can be elided as optim + * The cast to u32 is fine as this region can only be inside 4GB + */ if (paddr >= ARC_UNCACHED_ADDR_SPACE) - return (void __iomem *)paddr; + return (void __iomem *)(u32)paddr; return ioremap_prot(paddr, size, PAGE_KERNEL_NO_CACHE); } @@ -41,9 +44,9 @@ EXPORT_SYMBOL(ioremap); void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, unsigned long flags) { - void __iomem *vaddr; + unsigned long vaddr; struct vm_struct *area; - unsigned long off, end; + phys_addr_t off, end; pgprot_t prot = __pgprot(flags); /* Don't allow wraparound, zero size */ @@ -70,9 +73,8 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, if (!area) return NULL; area->phys_addr = paddr; - vaddr = (void __iomem *)area->addr; - if (ioremap_page_range((unsigned long)vaddr, - (unsigned long)vaddr + size, paddr, prot)) { + vaddr = (unsigned long)area->addr; + if (ioremap_page_range(vaddr, vaddr + size, paddr, prot)) { vunmap((void __force *)vaddr); return NULL; } -- cgit v0.10.2 From f2e3d55397ff7ad62e159e14281b346760857935 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 16 Mar 2016 16:38:57 +0530 Subject: ARC: dma: reintroduce platform specific dma<->phys Signed-off-by: Vineet Gupta diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 8ce0928..5c086d5 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -468,6 +468,9 @@ config ARCH_PHYS_ADDR_T_64BIT config ARCH_DMA_ADDR_T_64BIT bool +config ARC_PLAT_NEEDS_PHYS_TO_DMA + bool + config ARC_CURR_IN_REG bool "Dedicate Register r25 for current_task pointer" default y diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h index 6602054..266f11c 100644 --- a/arch/arc/include/asm/dma-mapping.h +++ b/arch/arc/include/asm/dma-mapping.h @@ -11,6 +11,13 @@ #ifndef ASM_ARC_DMA_MAPPING_H #define ASM_ARC_DMA_MAPPING_H +#ifndef CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA +#define plat_dma_to_phys(dev, dma_handle) ((phys_addr_t)(dma_handle)) +#define plat_phys_to_dma(dev, paddr) ((dma_addr_t)(paddr)) +#else +#include +#endif + extern struct dma_map_ops arc_dma_ops; static inline struct dma_map_ops *get_dma_ops(struct device *dev) diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 608c143..8c8e36f 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -60,8 +60,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size, /* This is linear addr (0x8000_0000 based) */ paddr = page_to_phys(page); - /* For now bus address is exactly same as paddr */ - *dma_handle = paddr; + *dma_handle = plat_phys_to_dma(dev, paddr); /* This is kernel Virtual address (0x7000_0000 based) */ if (need_kvaddr) { @@ -134,7 +133,7 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page, { phys_addr_t paddr = page_to_phys(page) + offset; _dma_cache_sync(paddr, size, dir); - return (dma_addr_t)paddr; + return plat_phys_to_dma(dev, paddr); } static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, @@ -153,13 +152,13 @@ static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, static void arc_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE); + _dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_FROM_DEVICE); } static void arc_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE); + _dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_TO_DEVICE); } static void arc_dma_sync_sg_for_cpu(struct device *dev, -- cgit v0.10.2 From deaf7565eb618a80534844300aeacffa14125182 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Sat, 24 Oct 2015 19:31:16 +0530 Subject: ARCv2: ioremap: Support dynamic peripheral address space The peripheral address space is architectural address window which is uncached and typically used to wire up peripherals. For ARC700 cores (ARCompact ISA based) this was fixed to 1GB region 0xC000_0000 - 0xFFFF_FFFF. For ARCv2 based HS38 cores the start address is flexible and can be 0xC, 0xD, 0xE, 0xF 000_000 by programming AUX_NON_VOLATILE_LIMIT reg (typically done in bootloader) Further in cas of PAE, the physical address can extend beyond 4GB so need to confine this check, otherwise all pages beyond 4GB will be treated as uncached Signed-off-by: Vineet Gupta diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 210ef3e..23706c6 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -54,6 +54,7 @@ extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); extern void read_decode_cache_bcr(void); extern int ioc_exists; +extern unsigned long perip_base; #endif /* !__ASSEMBLY__ */ diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index e4dc7ba..151acf0 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -91,11 +91,9 @@ static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu) static void read_arc_build_cfg_regs(void) { - struct bcr_perip uncached_space; struct bcr_timer timer; struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; - unsigned long perip_space; FIX_PTR(cpu); READ_BCR(AUX_IDENTITY, cpu->core); @@ -108,14 +106,6 @@ static void read_arc_build_cfg_regs(void) cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); - READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); - if (uncached_space.ver < 3) - perip_space = uncached_space.start << 24; - else - perip_space = read_aux_reg(AUX_NON_VOL) & 0xF0000000; - - BUG_ON(perip_space != ARC_UNCACHED_ADDR_SPACE); - READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy); cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */ @@ -288,8 +278,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) FIX_PTR(cpu); n += scnprintf(buf + n, len - n, - "Vector Table\t: %#x\nUncached Base\t: %#x\n", - cpu->vec_base, ARC_UNCACHED_ADDR_SPACE); + "Vector Table\t: %#x\nUncached Base\t: %#lx\n", + cpu->vec_base, perip_base); if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 635cd8c..d7709e3 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -24,6 +24,7 @@ static int l2_line_sz; int ioc_exists; volatile int slc_enable = 1, ioc_enable = 1; +unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */ void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr, unsigned long sz, const int cacheop); @@ -75,6 +76,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) static void read_decode_cache_bcr_arcv2(int cpu) { struct cpuinfo_arc_cache *p_slc = &cpuinfo_arc700[cpu].slc; + struct bcr_generic uncached_space; struct bcr_generic sbcr; struct bcr_slc_cfg { @@ -104,6 +106,11 @@ static void read_decode_cache_bcr_arcv2(int cpu) READ_BCR(ARC_REG_CLUSTER_BCR, cbcr); if (cbcr.c && ioc_enable) ioc_exists = 1; + + /* Legacy Data Uncached BCR is deprecated from v3 onwards */ + READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); + if (uncached_space.ver > 2) + perip_base = read_aux_reg(AUX_NON_VOL) & 0xF0000000; } void read_decode_cache_bcr(void) diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c index 75b0ca6..49b8abd 100644 --- a/arch/arc/mm/ioremap.c +++ b/arch/arc/mm/ioremap.c @@ -14,6 +14,18 @@ #include #include +static inline bool arc_uncached_addr_space(phys_addr_t paddr) +{ + if (is_isa_arcompact()) { + if (paddr >= ARC_UNCACHED_ADDR_SPACE) + return true; + } else if (paddr >= perip_base && paddr <= 0xFFFFFFFF) { + return true; + } + + return false; +} + void __iomem *ioremap(phys_addr_t paddr, unsigned long size) { phys_addr_t end; @@ -27,7 +39,7 @@ void __iomem *ioremap(phys_addr_t paddr, unsigned long size) * If the region is h/w uncached, MMU mapping can be elided as optim * The cast to u32 is fine as this region can only be inside 4GB */ - if (paddr >= ARC_UNCACHED_ADDR_SPACE) + if (arc_uncached_addr_space(paddr)) return (void __iomem *)(u32)paddr; return ioremap_prot(paddr, size, PAGE_KERNEL_NO_CACHE); @@ -85,7 +97,8 @@ EXPORT_SYMBOL(ioremap_prot); void iounmap(const void __iomem *addr) { - if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE) + /* weird double cast to handle phys_addr_t > 32 bits */ + if (arc_uncached_addr_space((phys_addr_t)(u32)addr)) return; vfree((void *)(PAGE_MASK & (unsigned long __force)addr)); -- cgit v0.10.2