From 8fda64c23c2a2d421704d349696565b3a8366864 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 5 Feb 2015 21:20:26 +0100 Subject: CRIS: enable GPIOLIB Enable GPIOLIB on CRIS so that we can use the generic GPIO APIs. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 4a03911053ab..319660ed2994 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -52,6 +52,7 @@ config CRIS select CLONE_BACKWARDS2 select OLD_SIGSUSPEND select OLD_SIGACTION + select ARCH_REQUIRE_GPIOLIB config HZ int -- cgit v1.2.3-59-g8ed1b From 43f7071e107ede92ac9e499d218233c8bb4c3607 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 8 Feb 2015 16:15:19 +0100 Subject: CRISv32: add irq domains support Add support for IRQ domains to the CRISv32 interrupt controller. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 1 + arch/cris/arch-v32/kernel/irq.c | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 319660ed2994..c34561869856 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -53,6 +53,7 @@ config CRIS select OLD_SIGSUSPEND select OLD_SIGACTION select ARCH_REQUIRE_GPIOLIB + select IRQ_DOMAIN if ETRAX_ARCH_V32 config HZ int diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index 25437ae28128..bc871d2c594a 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -431,6 +433,19 @@ crisv32_do_multiple(struct pt_regs* regs) irq_exit(); } +static int crisv32_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw_irq_num) +{ + irq_set_chip_and_handler(virq, &crisv32_irq_type, handle_simple_irq); + + return 0; +} + +static struct irq_domain_ops crisv32_irq_ops = { + .map = crisv32_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + /* * This is called by start_kernel. It fixes the IRQ masks and setup the * interrupt vector table to point to bad_interrupt pointers. @@ -441,6 +456,8 @@ init_IRQ(void) int i; int j; reg_intr_vect_rw_mask vect_mask = {0}; + struct device_node *np; + struct irq_domain *domain; /* Clear all interrupts masks. */ for (i = 0; i < NBR_REGS; i++) @@ -449,10 +466,15 @@ init_IRQ(void) for (i = 0; i < 256; i++) etrax_irv->v[i] = weird_irq; - /* Point all IRQ's to bad handlers. */ + np = of_find_compatible_node(NULL, NULL, "axis,crisv32-intc"); + domain = irq_domain_add_legacy(np, NR_IRQS - FIRST_IRQ, + FIRST_IRQ, FIRST_IRQ, + &crisv32_irq_ops, NULL); + BUG_ON(!domain); + irq_set_default_host(domain); + of_node_put(np); + for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { - irq_set_chip_and_handler(j, &crisv32_irq_type, - handle_simple_irq); set_exception_vector(i, interrupt[j]); } -- cgit v1.2.3-59-g8ed1b From a9f75ac5a24cb94c2373daa3d73f90d22cf5d94b Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 8 Feb 2015 16:14:06 +0100 Subject: CRISv32: add device tree support Add support for booting CRISv32 with a built-in device tree. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 6 ++++++ arch/cris/Makefile | 4 ++++ arch/cris/boot/dts/Makefile | 6 ++++++ arch/cris/kernel/Makefile | 1 + arch/cris/kernel/devicetree.c | 14 ++++++++++++++ arch/cris/kernel/setup.c | 15 +++++++++++++++ 6 files changed, 46 insertions(+) create mode 100644 arch/cris/boot/dts/Makefile create mode 100644 arch/cris/kernel/devicetree.c diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index c34561869856..23fb82f3715e 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -54,6 +54,8 @@ config CRIS select OLD_SIGACTION select ARCH_REQUIRE_GPIOLIB select IRQ_DOMAIN if ETRAX_ARCH_V32 + select OF if ETRAX_ARCH_V32 + select OF_EARLY_FLATTREE if ETRAX_ARCH_V32 config HZ int @@ -63,6 +65,10 @@ config NR_CPUS int default "1" +config BUILTIN_DTB + string "DTB to build into the kernel image" + depends on OF + source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/arch/cris/Makefile b/arch/cris/Makefile index 39dc7d00083e..4a5404b3d0e4 100644 --- a/arch/cris/Makefile +++ b/arch/cris/Makefile @@ -40,6 +40,10 @@ else MACH := endif +ifneq ($(CONFIG_BUILTIN_DTB),"") +core-$(CONFIG_OF) += arch/cris/boot/dts/ +endif + LD = $(CROSS_COMPILE)ld -mcrislinux OBJCOPYFLAGS := -O binary -R .note -R .comment -S diff --git a/arch/cris/boot/dts/Makefile b/arch/cris/boot/dts/Makefile new file mode 100644 index 000000000000..faf69fb9919f --- /dev/null +++ b/arch/cris/boot/dts/Makefile @@ -0,0 +1,6 @@ +BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o +ifneq ($(CONFIG_BUILTIN_DTB),"") +obj-$(CONFIG_OF) += $(BUILTIN_DTB) +endif + +clean-files := *.dtb.S diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile index b45640b3e600..edef71f12bb8 100644 --- a/arch/cris/kernel/Makefile +++ b/arch/cris/kernel/Makefile @@ -7,6 +7,7 @@ CPPFLAGS_vmlinux.lds := -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE) extra-y := vmlinux.lds obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o +obj-y += devicetree.o obj-$(CONFIG_MODULES) += crisksyms.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/cris/kernel/devicetree.c b/arch/cris/kernel/devicetree.c new file mode 100644 index 000000000000..53ff8d73e7e1 --- /dev/null +++ b/arch/cris/kernel/devicetree.c @@ -0,0 +1,14 @@ +#include +#include +#include + +void __init early_init_dt_add_memory_arch(u64 base, u64 size) +{ + pr_err("%s(%llx, %llx)\n", + __func__, base, size); +} + +void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) +{ + return alloc_bootmem_align(size, align); +} diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 905b70ea9939..bb12aa93201d 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include @@ -64,6 +67,10 @@ void __init setup_arch(char **cmdline_p) unsigned long start_pfn, max_pfn; unsigned long memory_start; +#ifdef CONFIG_OF + early_init_dt_scan(__dtb_start); +#endif + /* register an initial console printing routine for printk's */ init_etrax_debug(); @@ -141,6 +148,8 @@ void __init setup_arch(char **cmdline_p) reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size, BOOTMEM_DEFAULT); + unflatten_and_copy_device_tree(); + /* paging_init() sets up the MMU and marks all pages as reserved */ paging_init(); @@ -204,3 +213,9 @@ static int __init topology_init(void) subsys_initcall(topology_init); +static int __init cris_of_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + return 0; +} +core_initcall(cris_of_init); -- cgit v1.2.3-59-g8ed1b From c8e840d8578a68a77cfd29f8cd68fb210855ce87 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 19 Jan 2015 22:26:06 +0100 Subject: CRIS: add Axis 88 board device tree Add a minimal device tree for the ETRAX FS SoC and the Axis 88 developer board. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/boot/dts/dev88.dts | 18 ++++++++++++++++++ arch/cris/boot/dts/etraxfs.dtsi | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 arch/cris/boot/dts/dev88.dts create mode 100644 arch/cris/boot/dts/etraxfs.dtsi diff --git a/arch/cris/boot/dts/dev88.dts b/arch/cris/boot/dts/dev88.dts new file mode 100644 index 000000000000..4fa5a3f9d0ec --- /dev/null +++ b/arch/cris/boot/dts/dev88.dts @@ -0,0 +1,18 @@ +/dts-v1/; + +/include/ "etraxfs.dtsi" + +/ { + model = "Axis 88 Developer Board"; + compatible = "axis,dev88"; + + aliases { + serial0 = &uart0; + }; + + soc { + uart0: serial@b00260000 { + status = "okay"; + }; + }; +}; diff --git a/arch/cris/boot/dts/etraxfs.dtsi b/arch/cris/boot/dts/etraxfs.dtsi new file mode 100644 index 000000000000..909bcedc3565 --- /dev/null +++ b/arch/cris/boot/dts/etraxfs.dtsi @@ -0,0 +1,38 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&intc>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "axis,crisv32"; + reg = <0>; + }; + }; + + soc { + compatible = "simple-bus"; + model = "etraxfs"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + intc: interrupt-controller { + compatible = "axis,crisv32-intc"; + reg = <0xb001c000 0x1000>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + serial@b00260000 { + compatible = "axis,etraxfs-uart"; + reg = <0xb0026000 0x1000>; + interrupts = <68>; + status = "disabled"; + }; + }; +}; -- cgit v1.2.3-59-g8ed1b From 1eb1390bb21b1aa3b303627eb254296f097988cb Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Wed, 25 Mar 2015 10:06:21 +0100 Subject: Add binding documentation for CRIS Only includes the devboard 88 (CRISv32) at the moment. Signed-off-by: Jesper Nilsson --- Documentation/devicetree/bindings/cris/axis.txt | 9 +++++++++ Documentation/devicetree/bindings/cris/boards.txt | 8 ++++++++ .../devicetree/bindings/cris/interrupts.txt | 23 ++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/cris/axis.txt create mode 100644 Documentation/devicetree/bindings/cris/boards.txt create mode 100644 Documentation/devicetree/bindings/cris/interrupts.txt diff --git a/Documentation/devicetree/bindings/cris/axis.txt b/Documentation/devicetree/bindings/cris/axis.txt new file mode 100644 index 000000000000..d209ca2a47c0 --- /dev/null +++ b/Documentation/devicetree/bindings/cris/axis.txt @@ -0,0 +1,9 @@ +Axis Communications AB +ARTPEC series SoC Device Tree Bindings + + +CRISv32 based SoCs are ETRAX FS and ARTPEC-3: + + - compatible = "axis,crisv32"; + + diff --git a/Documentation/devicetree/bindings/cris/boards.txt b/Documentation/devicetree/bindings/cris/boards.txt new file mode 100644 index 000000000000..533dd273ccf7 --- /dev/null +++ b/Documentation/devicetree/bindings/cris/boards.txt @@ -0,0 +1,8 @@ +Boards based on the CRIS SoCs: + +Required root node properties: + - compatible = should be one or more of the following: + - "axis,dev88" - for Axis devboard 88 with ETRAX FS + +Optional: + diff --git a/Documentation/devicetree/bindings/cris/interrupts.txt b/Documentation/devicetree/bindings/cris/interrupts.txt new file mode 100644 index 000000000000..e8b123b0a5e6 --- /dev/null +++ b/Documentation/devicetree/bindings/cris/interrupts.txt @@ -0,0 +1,23 @@ +* CRISv32 Interrupt Controller + +Interrupt controller for the CRISv32 SoCs. + +Main node required properties: + +- compatible : should be: + "axis,crisv32-intc" +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The type shall be a and the value shall be 1. +- reg: physical base address and size of the intc registers map. + +Example: + + intc: interrupt-controller { + compatible = "axis,crisv32-intc"; + reg = <0xb001c000 0x1000>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + -- cgit v1.2.3-59-g8ed1b From db4a35c651a10eddc6b48b69e1db1f46bea303fa Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 8 Feb 2015 16:57:40 +0100 Subject: CRISv32: don't attempt syscall restart on irq exit r9 is used to determine whether syscall restarting must be performed or not. Unfortunately, r9 is never set to zero in the non-syscall path, and r9 is on top of that a callee-saved register which can be set to non-zero by the C functions that are called during IRQ handling. This means that if r10 (used for the syscall return value) is one of the -ERESTART* values when a hardware interrupt occurs which leads to a signal being delivered to the process, the kernel will "restart" a syscall which never occurred. This will lead to the PC being moved back by 2 on return to user space. Fix the problem by setting r9 to zero in the interrupt path. Test case (should loop forever but ends up executing the break 8 trap instruction): #include #include #include void f(int n) { register int r9 asm ("r9") = 1; register int r10 asm ("r10") = n; __asm__ __volatile__( "ba 1f \n" "nop \n" "break 8 \n" "1: ba . \n" "nop \n" : : "r" (r9), "r" (r10) : "memory"); } void handler1(int sig) { } int main(int argc, char *argv[]) { struct itimerval t1 = { .it_value = {1} }; signal(SIGALRM, handler1); setitimer(ITIMER_REAL, &t1, NULL); f(-513); /* -ERESTARTNOINTR */ return 0; } Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/arch-v32/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 2f19ac6217aa..d4c088b4044c 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -99,6 +99,8 @@ ret_from_kernel_thread: .type ret_from_intr,@function ret_from_intr: + moveq 0, $r9 ; not a syscall + ;; Check for resched if preemptive kernel, or if we're going back to ;; user-mode. This test matches the user_regs(regs) macro. Don't simply ;; test CCS since that doesn't necessarily reflect what mode we'll -- cgit v1.2.3-59-g8ed1b From 0f72e5c0df732658d5e9e3c556c9c6928034e291 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 8 Feb 2015 17:53:22 +0100 Subject: CRISv32: prevent bogus restarts on sigreturn Al Viro noted that CRIS is vulnerable to bogus restarts on sigreturn. The fixes CRISv32 by using regs->exs as an additional indicator to whether we should attempt to restart the syscall or not. EXS is only used in the sigtrap handling, and in that path we already have r9 (the other indicator, which indicates if we're in a syscall or not) cleared. Test case, a port of Al's ARM version from 653d48b22166db2d8 ("arm: fix really nasty sigreturn bug"): #include #include #include #include #include void f(int n) { register int r10 asm ("r10") = n; __asm__ __volatile__( "ba 1f \n" "nop \n" "break 8 \n" "1: ba . \n" "nop \n" : : "r" (r10) : "memory"); } void handler1(int sig) { } void handler2(int sig) { raise(1); } void handler3(int sig) { exit(0); } int main(int argc, char *argv[]) { struct sigaction s = {.sa_handler = handler2}; struct itimerval t1 = { .it_value = {1} }; struct itimerval t2 = { .it_value = {2} }; signal(1, handler1); sigemptyset(&s.sa_mask); sigaddset(&s.sa_mask, 1); sigaction(SIGALRM, &s, NULL); signal(SIGVTALRM, handler3); setitimer(ITIMER_REAL, &t1, NULL); setitimer(ITIMER_VIRTUAL, &t2, NULL); f(-513); /* -ERESTARTNOINTR */ return 0; } Reported-by: Al Viro Link: http://lkml.kernel.org/r/20121208074429.GC4939@ZenIV.linux.org.uk Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/arch-v32/kernel/entry.S | 5 +++-- arch/cris/arch-v32/kernel/signal.c | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index d4c088b4044c..1ea29b7f263c 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -147,7 +147,7 @@ system_call: ;; Stack-frame similar to the irq heads, which is reversed in ;; ret_from_sys_call. - sub.d 92, $sp ; Skip EXS and EDA. + sub.d 92, $sp ; Skip EDA. movem $r13, [$sp] move.d $sp, $r8 addq 14*4, $r8 @@ -158,8 +158,9 @@ system_call: move $ccs, $r4 move $srp, $r5 move $erp, $r6 + move.d $r9, $r7 ; Store syscall number in EXS subq 4, $sp - movem $r6, [$r8] + movem $r7, [$r8] ei ; Enable interrupts while processing syscalls. move.d $r10, [$sp] diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index 870e3e069318..d8d13beafc02 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c @@ -72,6 +72,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) /* Make that the user-mode flag is set. */ regs->ccs |= (1 << (U_CCS_BITNR + CCS_SHIFT)); + /* Don't perform syscall restarting */ + regs->exs = -1; + /* Restore the old USP. */ err |= __get_user(old_usp, &sc->usp); wrusp(old_usp); @@ -427,6 +430,8 @@ do_signal(int canrestart, struct pt_regs *regs) { struct ksignal ksig; + canrestart = canrestart && ((int)regs->exs >= 0); + /* * The common case should go fast, which is why this point is * reached from kernel-mode. If that's the case, just return -- cgit v1.2.3-59-g8ed1b From 9a7449d3e975fe5c5ca12b7fea4f4bd69188a5f9 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 8 Feb 2015 18:19:17 +0100 Subject: CRISv32: handle multiple signals Al Viro noted that CRIS fails to handle multiple signals. This fixes the problem for CRISv32 by making it use a C work_pending handling loop similar to the ARM implementation in 0a267fa6a15d41c ("ARM: 7472/1: pull all work_pending logics into C function"). This also happens to fixes the warnings which currently trigger on CRISv32 due to do_signal() being called with interrupts disabled. Test case (should die of the SIGSEGV which gets raised when setting up the stack for SIGALRM, but instead reaches and executes the _exit(1)): #include #include #include #include static void handler(int sig) { } int main(int argc, char *argv[]) { int ret; struct itimerval t1 = { .it_value = {1} }; stack_t ss = { .ss_sp = NULL, .ss_size = SIGSTKSZ, }; struct sigaction action = { .sa_handler = handler, .sa_flags = SA_ONSTACK, }; ret = sigaltstack(&ss, NULL); if (ret < 0) err(1, "sigaltstack"); sigaction(SIGALRM, &action, NULL); setitimer(ITIMER_REAL, &t1, NULL); pause(); _exit(1); return 0; } Reported-by: Al Viro Link: http://lkml.kernel.org/r/20121208074429.GC4939@ZenIV.linux.org.uk Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/arch-v32/kernel/entry.S | 35 +++-------------------------------- arch/cris/kernel/ptrace.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 1ea29b7f263c..026a0b21b8f0 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -280,44 +280,15 @@ _syscall_exit_work: .type _work_pending,@function _work_pending: - addoq +TI_flags, $r0, $acr - move.d [$acr], $r10 - btstq TIF_NEED_RESCHED, $r10 ; Need resched? - bpl _work_notifysig ; No, must be signal/notify. - nop - .size _work_pending, . - _work_pending - - .type _work_resched,@function -_work_resched: - move.d $r9, $r1 ; Preserve R9. - jsr schedule - nop - move.d $r1, $r9 - di - - addoq +TI_flags, $r0, $acr - move.d [$acr], $r1 - and.d _TIF_WORK_MASK, $r1 ; Ignore sycall trace counter. - beq _Rexit - nop - btstq TIF_NEED_RESCHED, $r1 - bmi _work_resched ; current->work.need_resched. - nop - .size _work_resched, . - _work_resched - - .type _work_notifysig,@function -_work_notifysig: - ;; Deal with pending signals and notify-resume requests. - addoq +TI_flags, $r0, $acr move.d [$acr], $r12 ; The thread_info_flags parameter. move.d $sp, $r11 ; The regs param. - jsr do_notify_resume - move.d $r9, $r10 ; do_notify_resume syscall/irq param. + jsr do_work_pending + move.d $r9, $r10 ; The syscall/irq param. ba _Rexit nop - .size _work_notifysig, . - _work_notifysig + .size _work_pending, . - _work_pending ;; We get here as a sidetrack when we've entered a syscall with the ;; trace-bit set. We need to call do_syscall_trace and then continue diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c index 58d44ee1a71f..fd3427e563c5 100644 --- a/arch/cris/kernel/ptrace.c +++ b/arch/cris/kernel/ptrace.c @@ -42,3 +42,26 @@ void do_notify_resume(int canrestart, struct pt_regs *regs, tracehook_notify_resume(regs); } } + +void do_work_pending(int syscall, struct pt_regs *regs, + unsigned int thread_flags) +{ + do { + if (likely(thread_flags & _TIF_NEED_RESCHED)) { + schedule(); + } else { + if (unlikely(!user_mode(regs))) + return; + local_irq_enable(); + if (thread_flags & _TIF_SIGPENDING) { + do_signal(syscall, regs); + syscall = 0; + } else { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + } + } + local_irq_disable(); + thread_flags = current_thread_info()->flags; + } while (thread_flags & _TIF_WORK_MASK); +} -- cgit v1.2.3-59-g8ed1b From 06aca92424c2a53a9e26cb81c1d6a829af9491b8 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 19 Feb 2015 18:20:09 +0100 Subject: CRISv32: don't enable irqs in INIT_THREAD INIT_THREAD enables interrupts in the thread_struct's saved flags. This means that interrupts get enabled in the middle of context_switch() while switching to new tasks that get forked off the init task during boot. Don't do this. Fixes the following splat on boot with spinlock debugging on: BUG: spinlock cpu recursion on CPU#0, swapper/2 lock: runqueues+0x0/0x47c, .magic: dead4ead, .owner: swapper/0, .owner_cpu: 0 CPU: 0 PID: 2 Comm: swapper Not tainted 3.19.0-08796-ga747b55 #285 Call Trace: [] spin_bug+0x2a/0x36 [] do_raw_spin_lock+0xa2/0x126 [] _raw_spin_lock+0x20/0x2a [] scheduler_tick+0x22/0x76 [] update_process_times+0x5e/0x72 [] timer_interrupt+0x4e/0x6a [] handle_irq_event_percpu+0x54/0xf2 [] handle_irq_event+0x50/0x74 [] handle_simple_irq+0x6c/0xbe [] generic_handle_irq+0x2a/0x36 [] do_IRQ+0x38/0x84 [] crisv32_do_IRQ+0x54/0x60 [] IRQ0x4b_interrupt+0x34/0x3c [] __schedule+0x24a/0x532 [] ret_from_kernel_thread+0x0/0x14 Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/include/arch-v32/arch/processor.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/cris/include/arch-v32/arch/processor.h b/arch/cris/include/arch-v32/arch/processor.h index a024b7d32fed..568759271ab5 100644 --- a/arch/cris/include/arch-v32/arch/processor.h +++ b/arch/cris/include/arch-v32/arch/processor.h @@ -25,8 +25,7 @@ struct thread_struct { */ #define TASK_SIZE (0xB0000000UL) -/* CCS I=1, enable interrupts. */ -#define INIT_THREAD { 0, 0, (1 << I_CCS_BITNR) } +#define INIT_THREAD { } #define KSTK_EIP(tsk) \ ({ \ -- cgit v1.2.3-59-g8ed1b From 47a8f6fb349c977ff752f979b159aef96a0bb352 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 19 Feb 2015 17:35:28 +0100 Subject: CRIS: remove SMP code The CRIS SMP code cannot be built since there is no (and appears to never have been) a CONFIG_SMP Kconfig option in arch/cris/. Remove it. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 1 - arch/cris/arch-v32/kernel/Makefile | 1 - arch/cris/arch-v32/kernel/head.S | 32 --- arch/cris/arch-v32/kernel/irq.c | 3 - arch/cris/arch-v32/kernel/setup.c | 5 - arch/cris/arch-v32/kernel/smp.c | 358 ----------------------------- arch/cris/arch-v32/kernel/time.c | 3 - arch/cris/arch-v32/lib/Makefile | 2 +- arch/cris/arch-v32/lib/spinlock.S | 40 ---- arch/cris/arch-v32/mm/init.c | 11 - arch/cris/arch-v32/mm/mmu.S | 4 - arch/cris/include/arch-v32/arch/atomic.h | 28 --- arch/cris/include/arch-v32/arch/spinlock.h | 131 ----------- arch/cris/include/asm/cmpxchg.h | 2 - arch/cris/include/asm/smp.h | 10 - arch/cris/include/asm/spinlock.h | 1 - arch/cris/include/asm/tlbflush.h | 7 - 17 files changed, 1 insertion(+), 638 deletions(-) delete mode 100644 arch/cris/arch-v32/kernel/smp.c delete mode 100644 arch/cris/arch-v32/lib/spinlock.S delete mode 100644 arch/cris/include/arch-v32/arch/spinlock.h delete mode 100644 arch/cris/include/asm/smp.h delete mode 100644 arch/cris/include/asm/spinlock.h diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 23fb82f3715e..97d3936ffe92 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -46,7 +46,6 @@ config CRIS select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_IRQ_SHOW select GENERIC_IOMAP - select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 select GENERIC_CMOS_UPDATE select MODULES_USE_ELF_RELA select CLONE_BACKWARDS2 diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile index 40358355d0cb..d9fc617ea253 100644 --- a/arch/cris/arch-v32/kernel/Makefile +++ b/arch/cris/arch-v32/kernel/Makefile @@ -9,7 +9,6 @@ obj-y := entry.o traps.o irq.o debugport.o \ process.o ptrace.o setup.o signal.o traps.o time.o \ cache.o cacheflush.o -obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o obj-$(CONFIG_MODULES) += crisksyms.o diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S index 51e34165ece7..74a66e0e3777 100644 --- a/arch/cris/arch-v32/kernel/head.S +++ b/arch/cris/arch-v32/kernel/head.S @@ -52,11 +52,6 @@ tstart: GIO_INIT -#ifdef CONFIG_SMP -secondary_cpu_entry: /* Entry point for secondary CPUs */ - di -#endif - ;; Setup and enable the MMU. Use same configuration for both the data ;; and the instruction MMU. ;; @@ -164,33 +159,6 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */ nop nop -#ifdef CONFIG_SMP - ;; Read CPU ID - move 0, $srs - nop - nop - nop - move $s12, $r0 - cmpq 0, $r0 - beq master_cpu - nop -slave_cpu: - ; Time to boot-up. Get stack location provided by master CPU. - move.d smp_init_current_idle_thread, $r1 - move.d [$r1], $sp - add.d 8192, $sp - move.d ebp_start, $r0 ; Defined in linker-script. - move $r0, $ebp - jsr smp_callin - nop -master_cpu: - /* Set up entry point for secondary CPUs. The boot ROM has set up - * EBP at start of internal memory. The CPU will get there - * later when we issue an IPI to them... */ - move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0 - move.d secondary_cpu_entry, $r1 - move.d $r1, [$r0] -#endif ; Check if starting from DRAM (network->RAM boot or unpacked ; compressed kernel), or directly from flash. lapcq ., $r0 diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index bc871d2c594a..6a881e0e92b4 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -58,9 +58,6 @@ struct cris_irq_allocation irq_allocations[NR_REAL_IRQS] = static unsigned long irq_regs[NR_CPUS] = { regi_irq, -#ifdef CONFIG_SMP - regi_irq2, -#endif }; #if NR_REAL_IRQS > 32 diff --git a/arch/cris/arch-v32/kernel/setup.c b/arch/cris/arch-v32/kernel/setup.c index 61e10ae65296..231927bba7c2 100644 --- a/arch/cris/arch-v32/kernel/setup.c +++ b/arch/cris/arch-v32/kernel/setup.c @@ -63,11 +63,6 @@ int show_cpuinfo(struct seq_file *m, void *v) info = &cpinfo[ARRAY_SIZE(cpinfo) - 1]; -#ifdef CONFIG_SMP - if (!cpu_online(cpu)) - return 0; -#endif - revision = rdvr(); for (i = 0; i < ARRAY_SIZE(cpinfo); i++) { diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c deleted file mode 100644 index 0698582467ca..000000000000 --- a/arch/cris/arch-v32/kernel/smp.c +++ /dev/null @@ -1,358 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define IPI_SCHEDULE 1 -#define IPI_CALL 2 -#define IPI_FLUSH_TLB 4 -#define IPI_BOOT 8 - -#define FLUSH_ALL (void*)0xffffffff - -/* Vector of locks used for various atomic operations */ -spinlock_t cris_atomic_locks[] = { - [0 ... LOCK_COUNT - 1] = __SPIN_LOCK_UNLOCKED(cris_atomic_locks) -}; - -/* CPU masks */ -cpumask_t phys_cpu_present_map = CPU_MASK_NONE; -EXPORT_SYMBOL(phys_cpu_present_map); - -/* Variables used during SMP boot */ -volatile int cpu_now_booting = 0; -volatile struct thread_info *smp_init_current_idle_thread; - -/* Variables used during IPI */ -static DEFINE_SPINLOCK(call_lock); -static DEFINE_SPINLOCK(tlbstate_lock); - -struct call_data_struct { - void (*func) (void *info); - void *info; - int wait; -}; - -static struct call_data_struct * call_data; - -static struct mm_struct* flush_mm; -static struct vm_area_struct* flush_vma; -static unsigned long flush_addr; - -/* Mode registers */ -static unsigned long irq_regs[NR_CPUS] = { - regi_irq, - regi_irq2 -}; - -static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id); -static int send_ipi(int vector, int wait, cpumask_t cpu_mask); -static struct irqaction irq_ipi = { - .handler = crisv32_ipi_interrupt, - .flags = 0, - .name = "ipi", -}; - -extern void cris_mmu_init(void); -extern void cris_timer_init(void); - -/* SMP initialization */ -void __init smp_prepare_cpus(unsigned int max_cpus) -{ - int i; - - /* From now on we can expect IPIs so set them up */ - setup_irq(IPI_INTR_VECT, &irq_ipi); - - /* Mark all possible CPUs as present */ - for (i = 0; i < max_cpus; i++) - cpumask_set_cpu(i, &phys_cpu_present_map); -} - -void smp_prepare_boot_cpu(void) -{ - /* PGD pointer has moved after per_cpu initialization so - * update the MMU. - */ - pgd_t **pgd; - pgd = (pgd_t**)&per_cpu(current_pgd, smp_processor_id()); - - SUPP_BANK_SEL(1); - SUPP_REG_WR(RW_MM_TLB_PGD, pgd); - SUPP_BANK_SEL(2); - SUPP_REG_WR(RW_MM_TLB_PGD, pgd); - - set_cpu_online(0, true); - cpumask_set_cpu(0, &phys_cpu_present_map); - set_cpu_possible(0, true); -} - -void __init smp_cpus_done(unsigned int max_cpus) -{ -} - -/* Bring one cpu online.*/ -static int __init -smp_boot_one_cpu(int cpuid, struct task_struct idle) -{ - unsigned timeout; - cpumask_t cpu_mask; - - cpumask_clear(&cpu_mask); - task_thread_info(idle)->cpu = cpuid; - - /* Information to the CPU that is about to boot */ - smp_init_current_idle_thread = task_thread_info(idle); - cpu_now_booting = cpuid; - - /* Kick it */ - set_cpu_online(cpuid, true); - cpumask_set_cpu(cpuid, &cpu_mask); - send_ipi(IPI_BOOT, 0, cpu_mask); - set_cpu_online(cpuid, false); - - /* Wait for CPU to come online */ - for (timeout = 0; timeout < 10000; timeout++) { - if(cpu_online(cpuid)) { - cpu_now_booting = 0; - smp_init_current_idle_thread = NULL; - return 0; /* CPU online */ - } - udelay(100); - barrier(); - } - - printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid); - return -1; -} - -/* Secondary CPUs starts using C here. Here we need to setup CPU - * specific stuff such as the local timer and the MMU. */ -void __init smp_callin(void) -{ - int cpu = cpu_now_booting; - reg_intr_vect_rw_mask vect_mask = {0}; - - /* Initialise the idle task for this CPU */ - atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; - - /* Set up MMU */ - cris_mmu_init(); - __flush_tlb_all(); - - /* Setup local timer. */ - cris_timer_init(); - - /* Enable IRQ and idle */ - REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); - crisv32_unmask_irq(IPI_INTR_VECT); - crisv32_unmask_irq(TIMER0_INTR_VECT); - preempt_disable(); - notify_cpu_starting(cpu); - local_irq_enable(); - - set_cpu_online(cpu, true); - cpu_startup_entry(CPUHP_ONLINE); -} - -/* Stop execution on this CPU.*/ -void stop_this_cpu(void* dummy) -{ - local_irq_disable(); - asm volatile("halt"); -} - -/* Other calls */ -void smp_send_stop(void) -{ - smp_call_function(stop_this_cpu, NULL, 0); -} - -int setup_profiling_timer(unsigned int multiplier) -{ - return -EINVAL; -} - - -/* cache_decay_ticks is used by the scheduler to decide if a process - * is "hot" on one CPU. A higher value means a higher penalty to move - * a process to another CPU. Our cache is rather small so we report - * 1 tick. - */ -unsigned long cache_decay_ticks = 1; - -int __cpu_up(unsigned int cpu, struct task_struct *tidle) -{ - smp_boot_one_cpu(cpu, tidle); - return cpu_online(cpu) ? 0 : -ENOSYS; -} - -void smp_send_reschedule(int cpu) -{ - cpumask_t cpu_mask; - cpumask_clear(&cpu_mask); - cpumask_set_cpu(cpu, &cpu_mask); - send_ipi(IPI_SCHEDULE, 0, cpu_mask); -} - -/* TLB flushing - * - * Flush needs to be done on the local CPU and on any other CPU that - * may have the same mapping. The mm->cpu_vm_mask is used to keep track - * of which CPUs that a specific process has been executed on. - */ -void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned long addr) -{ - unsigned long flags; - cpumask_t cpu_mask; - - spin_lock_irqsave(&tlbstate_lock, flags); - cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - flush_mm = mm; - flush_vma = vma; - flush_addr = addr; - send_ipi(IPI_FLUSH_TLB, 1, cpu_mask); - spin_unlock_irqrestore(&tlbstate_lock, flags); -} - -void flush_tlb_all(void) -{ - __flush_tlb_all(); - flush_tlb_common(FLUSH_ALL, FLUSH_ALL, 0); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - __flush_tlb_mm(mm); - flush_tlb_common(mm, FLUSH_ALL, 0); - /* No more mappings in other CPUs */ - cpumask_clear(mm_cpumask(mm)); - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); -} - -void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) -{ - __flush_tlb_page(vma, addr); - flush_tlb_common(vma->vm_mm, vma, addr); -} - -/* Inter processor interrupts - * - * The IPIs are used for: - * * Force a schedule on a CPU - * * FLush TLB on other CPUs - * * Call a function on other CPUs - */ - -int send_ipi(int vector, int wait, cpumask_t cpu_mask) -{ - int i = 0; - reg_intr_vect_rw_ipi ipi = REG_RD(intr_vect, irq_regs[i], rw_ipi); - int ret = 0; - - /* Calculate CPUs to send to. */ - cpumask_and(&cpu_mask, &cpu_mask, cpu_online_mask); - - /* Send the IPI. */ - for_each_cpu(i, &cpu_mask) - { - ipi.vector |= vector; - REG_WR(intr_vect, irq_regs[i], rw_ipi, ipi); - } - - /* Wait for IPI to finish on other CPUS */ - if (wait) { - for_each_cpu(i, &cpu_mask) { - int j; - for (j = 0 ; j < 1000; j++) { - ipi = REG_RD(intr_vect, irq_regs[i], rw_ipi); - if (!ipi.vector) - break; - udelay(100); - } - - /* Timeout? */ - if (ipi.vector) { - printk("SMP call timeout from %d to %d\n", smp_processor_id(), i); - ret = -ETIMEDOUT; - dump_stack(); - } - } - } - return ret; -} - -/* - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -int smp_call_function(void (*func)(void *info), void *info, int wait) -{ - cpumask_t cpu_mask; - struct call_data_struct data; - int ret; - - cpumask_setall(&cpu_mask); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - - WARN_ON(irqs_disabled()); - - data.func = func; - data.info = info; - data.wait = wait; - - spin_lock(&call_lock); - call_data = &data; - ret = send_ipi(IPI_CALL, wait, cpu_mask); - spin_unlock(&call_lock); - - return ret; -} - -irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id) -{ - void (*func) (void *info) = call_data->func; - void *info = call_data->info; - reg_intr_vect_rw_ipi ipi; - - ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi); - - if (ipi.vector & IPI_SCHEDULE) { - scheduler_ipi(); - } - if (ipi.vector & IPI_CALL) { - func(info); - } - if (ipi.vector & IPI_FLUSH_TLB) { - if (flush_mm == FLUSH_ALL) - __flush_tlb_all(); - else if (flush_vma == FLUSH_ALL) - __flush_tlb_mm(flush_mm); - else - __flush_tlb_page(flush_vma, flush_addr); - } - - ipi.vector = 0; - REG_WR(intr_vect, irq_regs[smp_processor_id()], rw_ipi, ipi); - - return IRQ_HANDLED; -} - diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index c17b01abdc3b..aa2d94b7fb61 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -60,9 +60,6 @@ arch_initcall(etrax_init_cont_rotime); unsigned long timer_regs[NR_CPUS] = { regi_timer0, -#ifdef CONFIG_SMP - regi_timer2 -#endif }; extern int set_rtc_mmss(unsigned long nowtime); diff --git a/arch/cris/arch-v32/lib/Makefile b/arch/cris/arch-v32/lib/Makefile index dd296b9db034..e91cf02f625d 100644 --- a/arch/cris/arch-v32/lib/Makefile +++ b/arch/cris/arch-v32/lib/Makefile @@ -3,5 +3,5 @@ # lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o \ - csumcpfruser.o spinlock.o delay.o strcmp.o + csumcpfruser.o delay.o strcmp.o diff --git a/arch/cris/arch-v32/lib/spinlock.S b/arch/cris/arch-v32/lib/spinlock.S deleted file mode 100644 index fe610b9d775f..000000000000 --- a/arch/cris/arch-v32/lib/spinlock.S +++ /dev/null @@ -1,40 +0,0 @@ -;; Core of the spinlock implementation -;; -;; Copyright (C) 2004 Axis Communications AB. -;; -;; Author: Mikael Starvik - - - .global cris_spin_lock - .type cris_spin_lock,@function - .global cris_spin_trylock - .type cris_spin_trylock,@function - - .text - -cris_spin_lock: - clearf p -1: test.b [$r10] - beq 1b - clearf p - ax - clear.b [$r10] - bcs 1b - clearf p - ret - nop - - .size cris_spin_lock, . - cris_spin_lock - -cris_spin_trylock: - clearf p -1: move.b [$r10], $r11 - ax - clear.b [$r10] - bcs 1b - clearf p - ret - movu.b $r11,$r10 - - .size cris_spin_trylock, . - cris_spin_trylock - diff --git a/arch/cris/arch-v32/mm/init.c b/arch/cris/arch-v32/mm/init.c index 3deca5253d91..f5438ca8122d 100644 --- a/arch/cris/arch-v32/mm/init.c +++ b/arch/cris/arch-v32/mm/init.c @@ -40,17 +40,6 @@ void __init cris_mmu_init(void) */ per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd; -#ifdef CONFIG_SMP - { - pgd_t **pgd; - pgd = (pgd_t**)&per_cpu(current_pgd, smp_processor_id()); - SUPP_BANK_SEL(1); - SUPP_REG_WR(RW_MM_TLB_PGD, pgd); - SUPP_BANK_SEL(2); - SUPP_REG_WR(RW_MM_TLB_PGD, pgd); - } -#endif - /* Initialise the TLB. Function found in tlb.c. */ tlb_init(); diff --git a/arch/cris/arch-v32/mm/mmu.S b/arch/cris/arch-v32/mm/mmu.S index 72727c1d8e60..c0981044eccb 100644 --- a/arch/cris/arch-v32/mm/mmu.S +++ b/arch/cris/arch-v32/mm/mmu.S @@ -115,11 +115,7 @@ move.d $r0, [$r1] ; last_refill_cause = rw_mm_cause 3: ; Probably not in a loop, continue normal processing -#ifdef CONFIG_SMP - move $s7, $acr ; PGD -#else move.d current_pgd, $acr ; PGD -#endif ; Look up PMD in PGD lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31) move.d [$acr], $acr ; PGD for the current process diff --git a/arch/cris/include/arch-v32/arch/atomic.h b/arch/cris/include/arch-v32/arch/atomic.h index 852ceff8013f..9c7d105b894b 100644 --- a/arch/cris/include/arch-v32/arch/atomic.h +++ b/arch/cris/include/arch-v32/arch/atomic.h @@ -1,36 +1,8 @@ #ifndef __ASM_CRIS_ARCH_ATOMIC__ #define __ASM_CRIS_ARCH_ATOMIC__ -#include - -extern void cris_spin_unlock(void *l, int val); -extern void cris_spin_lock(void *l); -extern int cris_spin_trylock(void* l); - -#ifndef CONFIG_SMP #define cris_atomic_save(addr, flags) local_irq_save(flags); #define cris_atomic_restore(addr, flags) local_irq_restore(flags); -#else - -extern spinlock_t cris_atomic_locks[]; -#define LOCK_COUNT 128 -#define HASH_ADDR(a) (((int)a) & 127) - -#define cris_atomic_save(addr, flags) \ - local_irq_save(flags); \ - cris_spin_lock((void *)&cris_atomic_locks[HASH_ADDR(addr)].raw_lock.slock); - -#define cris_atomic_restore(addr, flags) \ - { \ - spinlock_t *lock = (void*)&cris_atomic_locks[HASH_ADDR(addr)]; \ - __asm__ volatile ("move.d %1,%0" \ - : "=m" (lock->raw_lock.slock) \ - : "r" (1) \ - : "memory"); \ - local_irq_restore(flags); \ - } - -#endif #endif diff --git a/arch/cris/include/arch-v32/arch/spinlock.h b/arch/cris/include/arch-v32/arch/spinlock.h deleted file mode 100644 index f13275522f4d..000000000000 --- a/arch/cris/include/arch-v32/arch/spinlock.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef __ASM_ARCH_SPINLOCK_H -#define __ASM_ARCH_SPINLOCK_H - -#include - -#define RW_LOCK_BIAS 0x01000000 - -extern void cris_spin_unlock(void *l, int val); -extern void cris_spin_lock(void *l); -extern int cris_spin_trylock(void *l); - -static inline int arch_spin_is_locked(arch_spinlock_t *x) -{ - return *(volatile signed char *)(&(x)->slock) <= 0; -} - -static inline void arch_spin_unlock(arch_spinlock_t *lock) -{ - __asm__ volatile ("move.d %1,%0" \ - : "=m" (lock->slock) \ - : "r" (1) \ - : "memory"); -} - -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - while (arch_spin_is_locked(lock)) - cpu_relax(); -} - -static inline int arch_spin_trylock(arch_spinlock_t *lock) -{ - return cris_spin_trylock((void *)&lock->slock); -} - -static inline void arch_spin_lock(arch_spinlock_t *lock) -{ - cris_spin_lock((void *)&lock->slock); -} - -static inline void -arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) -{ - arch_spin_lock(lock); -} - -/* - * Read-write spinlocks, allowing multiple readers - * but only one writer. - * - * NOTE! it is quite common to have readers in interrupts - * but no interrupt writers. For those circumstances we - * can "mix" irq-safe locks - any writer needs to get a - * irq-safe write-lock, but readers can get non-irqsafe - * read-locks. - * - */ - -static inline int arch_read_can_lock(arch_rwlock_t *x) -{ - return (int)(x)->lock > 0; -} - -static inline int arch_write_can_lock(arch_rwlock_t *x) -{ - return (x)->lock == RW_LOCK_BIAS; -} - -static inline void arch_read_lock(arch_rwlock_t *rw) -{ - arch_spin_lock(&rw->slock); - while (rw->lock == 0); - rw->lock--; - arch_spin_unlock(&rw->slock); -} - -static inline void arch_write_lock(arch_rwlock_t *rw) -{ - arch_spin_lock(&rw->slock); - while (rw->lock != RW_LOCK_BIAS); - rw->lock = 0; - arch_spin_unlock(&rw->slock); -} - -static inline void arch_read_unlock(arch_rwlock_t *rw) -{ - arch_spin_lock(&rw->slock); - rw->lock++; - arch_spin_unlock(&rw->slock); -} - -static inline void arch_write_unlock(arch_rwlock_t *rw) -{ - arch_spin_lock(&rw->slock); - while (rw->lock != RW_LOCK_BIAS); - rw->lock = RW_LOCK_BIAS; - arch_spin_unlock(&rw->slock); -} - -static inline int arch_read_trylock(arch_rwlock_t *rw) -{ - int ret = 0; - arch_spin_lock(&rw->slock); - if (rw->lock != 0) { - rw->lock--; - ret = 1; - } - arch_spin_unlock(&rw->slock); - return ret; -} - -static inline int arch_write_trylock(arch_rwlock_t *rw) -{ - int ret = 0; - arch_spin_lock(&rw->slock); - if (rw->lock == RW_LOCK_BIAS) { - rw->lock = 0; - ret = 1; - } - arch_spin_unlock(&rw->slock); - return ret; -} - -#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) -#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) - -#define arch_spin_relax(lock) cpu_relax() -#define arch_read_relax(lock) cpu_relax() -#define arch_write_relax(lock) cpu_relax() - -#endif /* __ASM_ARCH_SPINLOCK_H */ diff --git a/arch/cris/include/asm/cmpxchg.h b/arch/cris/include/asm/cmpxchg.h index b756dac8aa3f..deb9048a6003 100644 --- a/arch/cris/include/asm/cmpxchg.h +++ b/arch/cris/include/asm/cmpxchg.h @@ -46,8 +46,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz (unsigned long)(n), sizeof(*(ptr)))) #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) -#ifndef CONFIG_SMP #include -#endif #endif /* __ASM_CRIS_CMPXCHG__ */ diff --git a/arch/cris/include/asm/smp.h b/arch/cris/include/asm/smp.h deleted file mode 100644 index c615a06dd757..000000000000 --- a/arch/cris/include/asm/smp.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ASM_SMP_H -#define __ASM_SMP_H - -#include - -extern cpumask_t phys_cpu_present_map; - -#define raw_smp_processor_id() (current_thread_info()->cpu) - -#endif diff --git a/arch/cris/include/asm/spinlock.h b/arch/cris/include/asm/spinlock.h deleted file mode 100644 index ed816b57face..000000000000 --- a/arch/cris/include/asm/spinlock.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/cris/include/asm/tlbflush.h b/arch/cris/include/asm/tlbflush.h index 20697e7ef4f2..b424f43a9fd6 100644 --- a/arch/cris/include/asm/tlbflush.h +++ b/arch/cris/include/asm/tlbflush.h @@ -22,16 +22,9 @@ extern void __flush_tlb_mm(struct mm_struct *mm); extern void __flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); -#ifdef CONFIG_SMP -extern void flush_tlb_all(void); -extern void flush_tlb_mm(struct mm_struct *mm); -extern void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr); -#else #define flush_tlb_all __flush_tlb_all #define flush_tlb_mm __flush_tlb_mm #define flush_tlb_page __flush_tlb_page -#endif static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end) { -- cgit v1.2.3-59-g8ed1b From 3c2165f807570c936b8ed6714edff1ef44def50a Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 22 Feb 2015 20:45:46 +0100 Subject: CRISv10: remove redundant macros from system.h All of these are either unused or already provided by other headers, so they can be removed. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/include/arch-v10/arch/system.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/cris/include/arch-v10/arch/system.h b/arch/cris/include/arch-v10/arch/system.h index 935fde34aa15..9b5580f58b96 100644 --- a/arch/cris/include/arch-v10/arch/system.h +++ b/arch/cris/include/arch-v10/arch/system.h @@ -36,12 +36,4 @@ static inline unsigned long _get_base(char * addr) return 0; } -#define nop() __asm__ __volatile__ ("nop"); - -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) -#define tas(ptr) (xchg((ptr),1)) - -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((struct __xchg_dummy *)(x)) - #endif -- cgit v1.2.3-59-g8ed1b From f64751118b07579c7ebb7935b6fd8cc8e2c3291a Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 19 Feb 2015 17:53:33 +0100 Subject: CRIS: use generic atomic bitops The generic atomic bitops are the same as the CRIS-specific ones. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/include/asm/bitops.h | 111 +---------------------------------------- 1 file changed, 1 insertion(+), 110 deletions(-) diff --git a/arch/cris/include/asm/bitops.h b/arch/cris/include/asm/bitops.h index bd49a546f4f5..8062cb52d343 100644 --- a/arch/cris/include/asm/bitops.h +++ b/arch/cris/include/asm/bitops.h @@ -19,119 +19,10 @@ #endif #include -#include #include #include -/* - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ - -#define set_bit(nr, addr) (void)test_and_set_bit(nr, addr) - -/* - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic() - * in order to ensure changes are visible on other processors. - */ - -#define clear_bit(nr, addr) (void)test_and_clear_bit(nr, addr) - -/* - * change_bit - Toggle a bit in memory - * @nr: Bit to change - * @addr: Address to start counting from - * - * change_bit() is atomic and may not be reordered. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ - -#define change_bit(nr, addr) (void)test_and_change_bit(nr, addr) - -/** - * test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ - -static inline int test_and_set_bit(int nr, volatile unsigned long *addr) -{ - unsigned int mask, retval; - unsigned long flags; - unsigned int *adr = (unsigned int *)addr; - - adr += nr >> 5; - mask = 1 << (nr & 0x1f); - cris_atomic_save(addr, flags); - retval = (mask & *adr) != 0; - *adr |= mask; - cris_atomic_restore(addr, flags); - return retval; -} - -/** - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ - -static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) -{ - unsigned int mask, retval; - unsigned long flags; - unsigned int *adr = (unsigned int *)addr; - - adr += nr >> 5; - mask = 1 << (nr & 0x1f); - cris_atomic_save(addr, flags); - retval = (mask & *adr) != 0; - *adr &= ~mask; - cris_atomic_restore(addr, flags); - return retval; -} - -/** - * test_and_change_bit - Change a bit and return its old value - * @nr: Bit to change - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ - -static inline int test_and_change_bit(int nr, volatile unsigned long *addr) -{ - unsigned int mask, retval; - unsigned long flags; - unsigned int *adr = (unsigned int *)addr; - adr += nr >> 5; - mask = 1 << (nr & 0x1f); - cris_atomic_save(addr, flags); - retval = (mask & *adr) != 0; - *adr ^= mask; - cris_atomic_restore(addr, flags); - return retval; -} - +#include #include /* -- cgit v1.2.3-59-g8ed1b From e7db8a3c96970d847da5611e78b6bde998f13da8 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 19 Feb 2015 17:54:35 +0100 Subject: CRIS: use generic atomic.h CRIS can use asm-generic's atomic.h. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/include/arch-v10/arch/atomic.h | 7 -- arch/cris/include/arch-v32/arch/atomic.h | 8 -- arch/cris/include/asm/Kbuild | 2 +- arch/cris/include/asm/atomic.h | 149 ------------------------------- 4 files changed, 1 insertion(+), 165 deletions(-) delete mode 100644 arch/cris/include/arch-v10/arch/atomic.h delete mode 100644 arch/cris/include/arch-v32/arch/atomic.h delete mode 100644 arch/cris/include/asm/atomic.h diff --git a/arch/cris/include/arch-v10/arch/atomic.h b/arch/cris/include/arch-v10/arch/atomic.h deleted file mode 100644 index 6ef5e7d09024..000000000000 --- a/arch/cris/include/arch-v10/arch/atomic.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_CRIS_ARCH_ATOMIC__ -#define __ASM_CRIS_ARCH_ATOMIC__ - -#define cris_atomic_save(addr, flags) local_irq_save(flags); -#define cris_atomic_restore(addr, flags) local_irq_restore(flags); - -#endif diff --git a/arch/cris/include/arch-v32/arch/atomic.h b/arch/cris/include/arch-v32/arch/atomic.h deleted file mode 100644 index 9c7d105b894b..000000000000 --- a/arch/cris/include/arch-v32/arch/atomic.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ASM_CRIS_ARCH_ATOMIC__ -#define __ASM_CRIS_ARCH_ATOMIC__ - -#define cris_atomic_save(addr, flags) local_irq_save(flags); -#define cris_atomic_restore(addr, flags) local_irq_restore(flags); - -#endif - diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 889f2de050a3..2f2787e15b64 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -1,4 +1,4 @@ - +generic-y += atomic.h generic-y += barrier.h generic-y += clkdev.h generic-y += cputime.h diff --git a/arch/cris/include/asm/atomic.h b/arch/cris/include/asm/atomic.h deleted file mode 100644 index 279766a70664..000000000000 --- a/arch/cris/include/asm/atomic.h +++ /dev/null @@ -1,149 +0,0 @@ -/* $Id: atomic.h,v 1.3 2001/07/25 16:15:19 bjornw Exp $ */ - -#ifndef __ASM_CRIS_ATOMIC__ -#define __ASM_CRIS_ATOMIC__ - -#include -#include -#include -#include -#include -#include - -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - */ - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ACCESS_ONCE((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -/* These should be written in asm but we do it in C for now. */ - -#define ATOMIC_OP(op, c_op) \ -static inline void atomic_##op(int i, volatile atomic_t *v) \ -{ \ - unsigned long flags; \ - cris_atomic_save(v, flags); \ - v->counter c_op i; \ - cris_atomic_restore(v, flags); \ -} \ - -#define ATOMIC_OP_RETURN(op, c_op) \ -static inline int atomic_##op##_return(int i, volatile atomic_t *v) \ -{ \ - unsigned long flags; \ - int retval; \ - cris_atomic_save(v, flags); \ - retval = (v->counter c_op i); \ - cris_atomic_restore(v, flags); \ - return retval; \ -} - -#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op) - -ATOMIC_OPS(add, +=) -ATOMIC_OPS(sub, -=) - -#undef ATOMIC_OPS -#undef ATOMIC_OP_RETURN -#undef ATOMIC_OP - -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) - -static inline int atomic_sub_and_test(int i, volatile atomic_t *v) -{ - int retval; - unsigned long flags; - cris_atomic_save(v, flags); - retval = (v->counter -= i) == 0; - cris_atomic_restore(v, flags); - return retval; -} - -static inline void atomic_inc(volatile atomic_t *v) -{ - unsigned long flags; - cris_atomic_save(v, flags); - (v->counter)++; - cris_atomic_restore(v, flags); -} - -static inline void atomic_dec(volatile atomic_t *v) -{ - unsigned long flags; - cris_atomic_save(v, flags); - (v->counter)--; - cris_atomic_restore(v, flags); -} - -static inline int atomic_inc_return(volatile atomic_t *v) -{ - unsigned long flags; - int retval; - cris_atomic_save(v, flags); - retval = ++(v->counter); - cris_atomic_restore(v, flags); - return retval; -} - -static inline int atomic_dec_return(volatile atomic_t *v) -{ - unsigned long flags; - int retval; - cris_atomic_save(v, flags); - retval = --(v->counter); - cris_atomic_restore(v, flags); - return retval; -} -static inline int atomic_dec_and_test(volatile atomic_t *v) -{ - int retval; - unsigned long flags; - cris_atomic_save(v, flags); - retval = --(v->counter) == 0; - cris_atomic_restore(v, flags); - return retval; -} - -static inline int atomic_inc_and_test(volatile atomic_t *v) -{ - int retval; - unsigned long flags; - cris_atomic_save(v, flags); - retval = ++(v->counter) == 0; - cris_atomic_restore(v, flags); - return retval; -} - -static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -{ - int ret; - unsigned long flags; - - cris_atomic_save(v, flags); - ret = v->counter; - if (likely(ret == old)) - v->counter = new; - cris_atomic_restore(v, flags); - return ret; -} - -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) - -static inline int __atomic_add_unless(atomic_t *v, int a, int u) -{ - int ret; - unsigned long flags; - - cris_atomic_save(v, flags); - ret = v->counter; - if (ret != u) - v->counter += a; - cris_atomic_restore(v, flags); - return ret; -} - -#endif -- cgit v1.2.3-59-g8ed1b From f87a2f58e34857304b8a2c284d02360210186dd0 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 19 Feb 2015 18:56:17 +0100 Subject: CRIS: use generic cmpxchg.h CRIS can use asm-generic's cmpxchg.h Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/include/asm/Kbuild | 1 + arch/cris/include/asm/cmpxchg.h | 51 ----------------------------------------- 2 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 arch/cris/include/asm/cmpxchg.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 2f2787e15b64..e189931d7992 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += atomic.h generic-y += barrier.h generic-y += clkdev.h +generic-y += cmpxchg.h generic-y += cputime.h generic-y += exec.h generic-y += irq_work.h diff --git a/arch/cris/include/asm/cmpxchg.h b/arch/cris/include/asm/cmpxchg.h deleted file mode 100644 index deb9048a6003..000000000000 --- a/arch/cris/include/asm/cmpxchg.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __ASM_CRIS_CMPXCHG__ -#define __ASM_CRIS_CMPXCHG__ - -#include - -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -{ - /* since Etrax doesn't have any atomic xchg instructions, we need to disable - irq's (if enabled) and do it with move.d's */ - unsigned long flags,temp; - local_irq_save(flags); /* save flags, including irq enable bit and shut off irqs */ - switch (size) { - case 1: - *((unsigned char *)&temp) = x; - x = *(unsigned char *)ptr; - *(unsigned char *)ptr = *((unsigned char *)&temp); - break; - case 2: - *((unsigned short *)&temp) = x; - x = *(unsigned short *)ptr; - *(unsigned short *)ptr = *((unsigned short *)&temp); - break; - case 4: - temp = x; - x = *(unsigned long *)ptr; - *(unsigned long *)ptr = temp; - break; - } - local_irq_restore(flags); /* restore irq enable bit */ - return x; -} - -#define xchg(ptr,x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -#define tas(ptr) (xchg((ptr),1)) - -#include - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ - (unsigned long)(n), sizeof(*(ptr)))) -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#include - -#endif /* __ASM_CRIS_CMPXCHG__ */ -- cgit v1.2.3-59-g8ed1b From 16428f943d192390b4673612b1d3fb81772323d9 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 19 Feb 2015 18:13:43 +0100 Subject: CRIS: use generic headers via Kbuild Delete headers which do nothing but include the asm-generic versions and use Kbuild magic instead. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/include/asm/Kbuild | 12 ++++++++++++ arch/cris/include/asm/device.h | 7 ------- arch/cris/include/asm/div64.h | 1 - arch/cris/include/asm/emergency-restart.h | 6 ------ arch/cris/include/asm/futex.h | 6 ------ arch/cris/include/asm/hardirq.h | 7 ------- arch/cris/include/asm/irq_regs.h | 1 - arch/cris/include/asm/kdebug.h | 1 - arch/cris/include/asm/kmap_types.h | 10 ---------- arch/cris/include/asm/local.h | 1 - arch/cris/include/asm/local64.h | 1 - arch/cris/include/asm/percpu.h | 6 ------ arch/cris/include/asm/topology.h | 6 ------ 13 files changed, 12 insertions(+), 53 deletions(-) delete mode 100644 arch/cris/include/asm/device.h delete mode 100644 arch/cris/include/asm/div64.h delete mode 100644 arch/cris/include/asm/emergency-restart.h delete mode 100644 arch/cris/include/asm/futex.h delete mode 100644 arch/cris/include/asm/hardirq.h delete mode 100644 arch/cris/include/asm/irq_regs.h delete mode 100644 arch/cris/include/asm/kdebug.h delete mode 100644 arch/cris/include/asm/kmap_types.h delete mode 100644 arch/cris/include/asm/local.h delete mode 100644 arch/cris/include/asm/local64.h delete mode 100644 arch/cris/include/asm/percpu.h delete mode 100644 arch/cris/include/asm/topology.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index e189931d7992..057e51859b0a 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -3,15 +3,27 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += cmpxchg.h generic-y += cputime.h +generic-y += device.h +generic-y += div64.h generic-y += exec.h +generic-y += emergency-restart.h +generic-y += futex.h +generic-y += hardirq.h +generic-y += irq_regs.h generic-y += irq_work.h +generic-y += kdebug.h +generic-y += kmap_types.h generic-y += kvm_para.h generic-y += linkage.h +generic-y += local.h +generic-y += local64.h generic-y += mcs_spinlock.h generic-y += module.h +generic-y += percpu.h generic-y += preempt.h generic-y += scatterlist.h generic-y += sections.h +generic-y += topology.h generic-y += trace_clock.h generic-y += vga.h generic-y += xor.h diff --git a/arch/cris/include/asm/device.h b/arch/cris/include/asm/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/arch/cris/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/arch/cris/include/asm/div64.h b/arch/cris/include/asm/div64.h deleted file mode 100644 index 6cd978cefb28..000000000000 --- a/arch/cris/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/cris/include/asm/emergency-restart.h b/arch/cris/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42e..000000000000 --- a/arch/cris/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/cris/include/asm/futex.h b/arch/cris/include/asm/futex.h deleted file mode 100644 index 6a332a9f099c..000000000000 --- a/arch/cris/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include - -#endif diff --git a/arch/cris/include/asm/hardirq.h b/arch/cris/include/asm/hardirq.h deleted file mode 100644 index 04126f7bfab2..000000000000 --- a/arch/cris/include/asm/hardirq.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_HARDIRQ_H -#define __ASM_HARDIRQ_H - -#include -#include - -#endif /* __ASM_HARDIRQ_H */ diff --git a/arch/cris/include/asm/irq_regs.h b/arch/cris/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/cris/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/cris/include/asm/kdebug.h b/arch/cris/include/asm/kdebug.h deleted file mode 100644 index 6ece1b037665..000000000000 --- a/arch/cris/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/cris/include/asm/kmap_types.h b/arch/cris/include/asm/kmap_types.h deleted file mode 100644 index d2d643c4ea59..000000000000 --- a/arch/cris/include/asm/kmap_types.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ASM_KMAP_TYPES_H -#define _ASM_KMAP_TYPES_H - -/* Dummy header just to define km_type. None of this - * is actually used on cris. - */ - -#include - -#endif diff --git a/arch/cris/include/asm/local.h b/arch/cris/include/asm/local.h deleted file mode 100644 index c11c530f74d0..000000000000 --- a/arch/cris/include/asm/local.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/cris/include/asm/local64.h b/arch/cris/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/cris/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/cris/include/asm/percpu.h b/arch/cris/include/asm/percpu.h deleted file mode 100644 index 6db9b43cf80a..000000000000 --- a/arch/cris/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _CRIS_PERCPU_H -#define _CRIS_PERCPU_H - -#include - -#endif /* _CRIS_PERCPU_H */ diff --git a/arch/cris/include/asm/topology.h b/arch/cris/include/asm/topology.h deleted file mode 100644 index 2ac613d32a89..000000000000 --- a/arch/cris/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_CRIS_TOPOLOGY_H -#define _ASM_CRIS_TOPOLOGY_H - -#include - -#endif /* _ASM_CRIS_TOPOLOGY_H */ -- cgit v1.2.3-59-g8ed1b From ed9fd3ff0251783cb3943e71aac398b9064efae6 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 8 Mar 2015 16:29:12 +0100 Subject: CRISv32: use generic clockevents Implement a oneshot-capable clockevents device so we get support for things like hrtimers and NOHZ. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 1 + arch/cris/arch-v32/kernel/time.c | 145 +++++++++++++++++++++++---------------- 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 97d3936ffe92..366dc83019a5 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -55,6 +55,7 @@ config CRIS select IRQ_DOMAIN if ETRAX_ARCH_V32 select OF if ETRAX_ARCH_V32 select OF_EARLY_FLATTREE if ETRAX_ARCH_V32 + select GENERIC_CLOCKEVENTS if ETRAX_ARCH_V32 config HZ int diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index aa2d94b7fb61..77e241d6fa3d 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ /* Number of 763 counts before watchdog bites */ #define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1) +#define CRISV32_TIMER_FREQ (100000000lu) + /* Register the continuos readonly timer available in FS and ARTPEC-3. */ static cycle_t read_cont_rotime(struct clocksource *cs) { @@ -186,81 +189,99 @@ void handle_watchdog_bite(struct pt_regs *regs) #endif } -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "xtime_update()" routine every clocktick. - */ -extern void cris_do_profile(struct pt_regs *regs); +extern void cris_profile_sample(struct pt_regs *regs); +static void __iomem *timer_base; -static inline irqreturn_t timer_interrupt(int irq, void *dev_id) +static void crisv32_clkevt_mode(enum clock_event_mode mode, + struct clock_event_device *dev) { - struct pt_regs *regs = get_irq_regs(); - int cpu = smp_processor_id(); - reg_timer_r_masked_intr masked_intr; - reg_timer_rw_ack_intr ack_intr = { 0 }; - - /* Check if the timer interrupt is for us (a tmr0 int) */ - masked_intr = REG_RD(timer, timer_regs[cpu], r_masked_intr); - if (!masked_intr.tmr0) - return IRQ_NONE; + reg_timer_rw_tmr0_ctrl ctrl = { + .op = regk_timer_hold, + .freq = regk_timer_f100, + }; - /* Acknowledge the timer irq. */ - ack_intr.tmr0 = 1; - REG_WR(timer, timer_regs[cpu], rw_ack_intr, ack_intr); + REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl); +} - /* Reset watchdog otherwise it resets us! */ - reset_watchdog(); +static int crisv32_clkevt_next_event(unsigned long evt, + struct clock_event_device *dev) +{ + reg_timer_rw_tmr0_ctrl ctrl = { + .op = regk_timer_ld, + .freq = regk_timer_f100, + }; + + REG_WR(timer, timer_base, rw_tmr0_div, evt); + REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl); + + ctrl.op = regk_timer_run; + REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl); + + return 0; +} - /* Update statistics. */ - update_process_times(user_mode(regs)); +static irqreturn_t crisv32_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + reg_timer_rw_tmr0_ctrl ctrl = { + .op = regk_timer_hold, + .freq = regk_timer_f100, + }; + reg_timer_rw_ack_intr ack = { .tmr0 = 1 }; + reg_timer_r_masked_intr intr; + + intr = REG_RD(timer, timer_base, r_masked_intr); + if (!intr.tmr0) + return IRQ_NONE; + + REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl); + REG_WR(timer, timer_base, rw_ack_intr, ack); - cris_do_profile(regs); /* Save profiling information */ + reset_watchdog(); +#ifdef CONFIG_SYSTEM_PROFILER + cris_profile_sample(get_irq_regs()); +#endif - /* The master CPU is responsible for the time keeping. */ - if (cpu != 0) - return IRQ_HANDLED; + evt->event_handler(evt); - /* Call the real timer interrupt handler */ - xtime_update(1); return IRQ_HANDLED; } +static struct clock_event_device crisv32_clockevent = { + .name = "crisv32-timer", + .rating = 300, + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_mode = crisv32_clkevt_mode, + .set_next_event = crisv32_clkevt_next_event, +}; + /* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. */ static struct irqaction irq_timer = { - .handler = timer_interrupt, - .flags = IRQF_SHARED, - .name = "timer" + .handler = crisv32_timer_interrupt, + .flags = IRQF_TIMER | IRQF_SHARED, + .name = "crisv32-timer", + .dev_id = &crisv32_clockevent, }; -void __init cris_timer_init(void) +static void __init crisv32_timer_init(void) { - int cpu = smp_processor_id(); - reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 }; - reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV; reg_timer_rw_intr_mask timer_intr_mask; + reg_timer_rw_tmr0_ctrl ctrl = { + .op = regk_timer_hold, + .freq = regk_timer_f100, + }; - /* Setup the etrax timers. - * Base frequency is 100MHz, divider 1000000 -> 100 HZ - * We use timer0, so timer1 is free. - * The trig timer is used by the fasttimer API if enabled. - */ - - tmr0_ctrl.op = regk_timer_ld; - tmr0_ctrl.freq = regk_timer_f100; - REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div); - REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */ - tmr0_ctrl.op = regk_timer_run; - REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */ + REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl); - /* Enable the timer irq. */ - timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask); + timer_intr_mask = REG_RD(timer, timer_base, rw_intr_mask); timer_intr_mask.tmr0 = 1; - REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask); + REG_WR(timer, timer_base, rw_intr_mask, timer_intr_mask); } void __init time_init(void) { - reg_intr_vect_rw_mask intr_mask; + int irq; + int ret; /* Probe for the RTC and read it if it exists. * Before the RTC can be probed the loops_per_usec variable needs @@ -270,17 +291,21 @@ void __init time_init(void) */ loops_per_usec = 50; - /* Start CPU local timer. */ - cris_timer_init(); + irq = TIMER0_INTR_VECT; + timer_base = (void __iomem *) regi_timer0; + + crisv32_timer_init(); + + crisv32_clockevent.cpumask = cpu_possible_mask; + crisv32_clockevent.irq = irq; - /* Enable the timer irq in global config. */ - intr_mask = REG_RD_VECT(intr_vect, regi_irq, rw_mask, 1); - intr_mask.timer0 = 1; - REG_WR_VECT(intr_vect, regi_irq, rw_mask, 1, intr_mask); + ret = setup_irq(irq, &irq_timer); + if (ret) + pr_warn("failed to setup irq %d\n", irq); - /* Now actually register the timer irq handler that calls - * timer_interrupt(). */ - setup_irq(TIMER0_INTR_VECT, &irq_timer); + clockevents_config_and_register(&crisv32_clockevent, + CRISV32_TIMER_FREQ, + 2, 0xffffffff); /* Enable watchdog if we should use one. */ -- cgit v1.2.3-59-g8ed1b From edfb6d5f1a05627204d1640ba527312dc8ea745a Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 9 Mar 2015 18:48:25 +0100 Subject: CRISv32: use MMIO clocksource Use a generic MMIO clocksource and get rid of some lines of code. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 1 + arch/cris/arch-v32/kernel/time.c | 25 ++++--------------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 366dc83019a5..bd920ccbef6f 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -55,6 +55,7 @@ config CRIS select IRQ_DOMAIN if ETRAX_ARCH_V32 select OF if ETRAX_ARCH_V32 select OF_EARLY_FLATTREE if ETRAX_ARCH_V32 + select CLKSRC_MMIO if ETRAX_ARCH_V32 select GENERIC_CLOCKEVENTS if ETRAX_ARCH_V32 config HZ diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index 77e241d6fa3d..7c802121c0c3 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -39,27 +39,6 @@ #define CRISV32_TIMER_FREQ (100000000lu) -/* Register the continuos readonly timer available in FS and ARTPEC-3. */ -static cycle_t read_cont_rotime(struct clocksource *cs) -{ - return (u32)REG_RD(timer, regi_timer0, r_time); -} - -static struct clocksource cont_rotime = { - .name = "crisv32_rotime", - .rating = 300, - .read = read_cont_rotime, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init etrax_init_cont_rotime(void) -{ - clocksource_register_khz(&cont_rotime, 100000); - return 0; -} -arch_initcall(etrax_init_cont_rotime); - unsigned long timer_regs[NR_CPUS] = { regi_timer0, @@ -296,6 +275,10 @@ void __init time_init(void) crisv32_timer_init(); + clocksource_mmio_init(timer_base + REG_RD_ADDR_timer_r_time, + "crisv32-timer", CRISV32_TIMER_FREQ, + 300, 32, clocksource_mmio_readl_up); + crisv32_clockevent.cpumask = cpu_possible_mask; crisv32_clockevent.irq = irq; -- cgit v1.2.3-59-g8ed1b From d3dad475b2839b9964ef54211e135eb6fb9952f9 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 9 Mar 2015 18:51:31 +0100 Subject: CRISv32: use GENERIC_SCHED_CLOCK Provide a fast sched clock using the free-running timer and the generic sched_clock infrastructure. Signed-off-by: Rabin Vincent Signed-off-by: Jesper Nilsson --- arch/cris/Kconfig | 1 + arch/cris/arch-v32/kernel/time.c | 9 +++++++++ arch/cris/kernel/time.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index bd920ccbef6f..0314e325a669 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -57,6 +57,7 @@ config CRIS select OF_EARLY_FLATTREE if ETRAX_ARCH_V32 select CLKSRC_MMIO if ETRAX_ARCH_V32 select GENERIC_CLOCKEVENTS if ETRAX_ARCH_V32 + select GENERIC_SCHED_CLOCK if ETRAX_ARCH_V32 config HZ int diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index 7c802121c0c3..4fce9f1f7cc0 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -242,6 +243,11 @@ static struct irqaction irq_timer = { .dev_id = &crisv32_clockevent, }; +static u64 notrace crisv32_timer_sched_clock(void) +{ + return REG_RD(timer, timer_base, r_time); +} + static void __init crisv32_timer_init(void) { reg_timer_rw_intr_mask timer_intr_mask; @@ -275,6 +281,9 @@ void __init time_init(void) crisv32_timer_init(); + sched_clock_register(crisv32_timer_sched_clock, 32, + CRISV32_TIMER_FREQ); + clocksource_mmio_init(timer_base + REG_RD_ADDR_timer_r_time, "crisv32-timer", CRISV32_TIMER_FREQ, 300, 32, clocksource_mmio_readl_up); diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index fe6acdabbc8d..7780d379522f 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c @@ -79,11 +79,13 @@ cris_do_profile(struct pt_regs* regs) #endif } +#ifndef CONFIG_GENERIC_SCHED_CLOCK unsigned long long sched_clock(void) { return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ) + get_ns_in_jiffie(); } +#endif static int __init init_udelay(void) -- cgit v1.2.3-59-g8ed1b From d939b52abe0cee9cc3167f554da6b864db86d3f2 Mon Sep 17 00:00:00 2001 From: Andrey Ryabinin Date: Tue, 24 Mar 2015 18:31:23 +0300 Subject: cris: fix integer overflow in ELF_ET_DYN_BASE Almost all arches define ELF_ET_DYN_BASE as 2/3 of TASK_SIZE. Though it seems that some architectures do this in a wrong way. The problem is that 2*TASK_SIZE may overflow 32-bits so the real ELF_ET_DYN_BASE becomes wrong. Fix this overflow by dividing TASK_SIZE prior to multiplying: (TASK_SIZE / 3 * 2) Signed-off-by: Andrey Ryabinin Signed-off-by: Jesper Nilsson --- arch/cris/include/asm/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/cris/include/asm/elf.h b/arch/cris/include/asm/elf.h index 30ded8fbf592..c2a394ff55ff 100644 --- a/arch/cris/include/asm/elf.h +++ b/arch/cris/include/asm/elf.h @@ -71,7 +71,7 @@ typedef unsigned long elf_fpregset_t; the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space, -- cgit v1.2.3-59-g8ed1b