From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- arch/sh/kernel/cpu/clock.c | 4 ++ arch/sh/kernel/cpu/init.c | 6 +- arch/sh/kernel/cpu/proc.c | 1 + arch/sh/kernel/cpu/sh2/Makefile | 4 ++ arch/sh/kernel/cpu/sh2/entry.S | 55 ++++++++++++++++ arch/sh/kernel/cpu/sh2/probe.c | 39 ++++++++++- arch/sh/kernel/cpu/sh2/smp-j2.c | 139 ++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/dma-nommu.c | 4 +- arch/sh/kernel/dwarf.c | 6 +- arch/sh/kernel/head_32.S | 6 +- arch/sh/kernel/perf_event.c | 23 ++----- arch/sh/kernel/setup.c | 6 +- arch/sh/kernel/syscalls_32.S | 14 ++++ arch/sh/kernel/syscalls_64.S | 14 ++++ arch/sh/kernel/time.c | 36 ++++++----- 15 files changed, 311 insertions(+), 46 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh2/smp-j2.c (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 4187cf4fe..fca9b1e78 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -24,11 +24,13 @@ int __init clk_init(void) { int ret; +#ifndef CONFIG_COMMON_CLK ret = arch_clk_init(); if (unlikely(ret)) { pr_err("%s: CPU clock registration failed.\n", __func__); return ret; } +#endif if (sh_mv.mv_clk_init) { ret = sh_mv.mv_clk_init(); @@ -39,11 +41,13 @@ int __init clk_init(void) } } +#ifndef CONFIG_COMMON_CLK /* Kick the child clocks.. */ recalculate_root_clocks(); /* Enable the necessary init clocks */ clk_enable_init_clocks(); +#endif return ret; } diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 0d7360d54..c8b3be1b5 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -106,7 +106,7 @@ void __attribute__ ((weak)) l2_cache_init(void) /* * Generic first-level cache init */ -#ifdef CONFIG_SUPERH32 +#if defined(CONFIG_SUPERH32) && !defined(CONFIG_CPU_J2) static void cache_init(void) { unsigned long ccr, flags; @@ -323,9 +323,13 @@ asmlinkage void cpu_init(void) cache_init(); if (raw_smp_processor_id() == 0) { +#ifdef CONFIG_MMU shm_align_mask = max_t(unsigned long, current_cpu_data.dcache.way_size - 1, PAGE_SIZE - 1); +#else + shm_align_mask = PAGE_SIZE - 1; +#endif /* Boot CPU sets the cache shape */ detect_cache_shape(); diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c index 9e6624c91..4df4b284f 100644 --- a/arch/sh/kernel/cpu/proc.c +++ b/arch/sh/kernel/cpu/proc.c @@ -27,6 +27,7 @@ static const char *cpu_name[] = { [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724", [CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734", + [CPU_J2] = "J2", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/kernel/cpu/sh2/Makefile b/arch/sh/kernel/cpu/sh2/Makefile index f0f059acf..904c4283d 100644 --- a/arch/sh/kernel/cpu/sh2/Makefile +++ b/arch/sh/kernel/cpu/sh2/Makefile @@ -5,3 +5,7 @@ obj-y := ex.o probe.o entry.o obj-$(CONFIG_CPU_SUBTYPE_SH7619) += setup-sh7619.o clock-sh7619.o + +# SMP setup +smp-$(CONFIG_CPU_J2) := smp-j2.o +obj-$(CONFIG_SMP) += $(smp-y) diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index a1505956e..1ee0a6e77 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -47,6 +47,13 @@ ENTRY(exception_handler) mov.l r3,@-sp cli mov.l $cpu_mode,r2 +#ifdef CONFIG_SMP + mov.l $cpuid,r3 + mov.l @r3,r3 + mov.l @r3,r3 + shll2 r3 + add r3,r2 +#endif mov.l @r2,r0 mov.l @(5*4,r15),r3 ! previous SR or r0,r3 ! set MD @@ -57,6 +64,13 @@ ENTRY(exception_handler) mov.l __md_bit,r0 mov.l r0,@r2 ! enter kernel mode mov.l $current_thread_info,r2 +#ifdef CONFIG_SMP + mov.l $cpuid,r0 + mov.l @r0,r0 + mov.l @r0,r0 + shll2 r0 + add r0,r2 +#endif mov.l @r2,r2 mov #(THREAD_SIZE >> 8),r0 shll8 r0 @@ -147,6 +161,11 @@ ENTRY(exception_handler) mov #31,r8 cmp/hs r8,r9 bt trap_entry ! 64 > vec >= 31 is trap +#ifdef CONFIG_CPU_J2 + mov #16,r8 + cmp/hs r8,r9 + bt interrupt_entry ! 31 > vec >= 16 is interrupt +#endif mov.l 4f,r8 mov r9,r4 @@ -260,6 +279,13 @@ restore_all: lds.l @r0+,macl mov r15,r0 mov.l $cpu_mode,r2 +#ifdef CONFIG_SMP + mov.l $cpuid,r3 + mov.l @r3,r3 + mov.l @r3,r3 + shll2 r3 + add r3,r2 +#endif mov #OFF_SR,r3 mov.l @(r0,r3),r1 mov.l __md_bit,r3 @@ -276,6 +302,13 @@ restore_all: mov.l r1,@r2 ! set pc get_current_thread_info r0, r1 mov.l $current_thread_info,r1 +#ifdef CONFIG_SMP + mov.l $cpuid,r3 + mov.l @r3,r3 + mov.l @r3,r3 + shll2 r3 + add r3,r1 +#endif mov.l r0,@r1 mov.l @r15+,r0 mov.l @r15+,r1 @@ -303,19 +336,41 @@ $current_thread_info: .long __current_thread_info $cpu_mode: .long __cpu_mode +#ifdef CONFIG_SMP +$cpuid: + .long sh2_cpuid_addr +#endif ! common exception handler #include "../../entry-common.S" + +#ifdef CONFIG_NR_CPUS +#define NR_CPUS CONFIG_NR_CPUS +#else +#define NR_CPUS 1 +#endif .data ! cpu operation mode ! bit30 = MD (compatible SH3/4) __cpu_mode: + .rept NR_CPUS .long 0x40000000 + .endr + +#ifdef CONFIG_SMP +.global sh2_cpuid_addr +sh2_cpuid_addr: + .long dummy_cpuid +dummy_cpuid: + .long 0 +#endif .section .bss __current_thread_info: + .rept NR_CPUS .long 0 + .endr ENTRY(exception_handling_table) .space 4*32 diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 6c687ae81..4205f6d42 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -10,10 +10,27 @@ * for more details. */ #include +#include +#include +#include #include #include -void cpu_probe(void) +#if defined(CONFIG_CPU_J2) +extern u32 __iomem *j2_ccr_base; +static int __init scan_cache(unsigned long node, const char *uname, + int depth, void *data) +{ + if (!of_flat_dt_is_compatible(node, "jcore,cache")) + return 0; + + j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node); + + return 1; +} +#endif + +void __ref cpu_probe(void) { #if defined(CONFIG_CPU_SUBTYPE_SH7619) boot_cpu_data.type = CPU_SH7619; @@ -24,10 +41,30 @@ void cpu_probe(void) boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; boot_cpu_data.dcache.flags = 0; #endif + +#if defined(CONFIG_CPU_J2) + unsigned cpu = hard_smp_processor_id(); + if (cpu == 0) of_scan_flat_dt(scan_cache, NULL); + if (j2_ccr_base) __raw_writel(0x80000303, j2_ccr_base + 4*cpu); + if (cpu != 0) return; + boot_cpu_data.type = CPU_J2; + + /* These defaults are appropriate for the original/current + * J2 cache. Once there is a proper framework for getting cache + * info from device tree, we should switch to that. */ + boot_cpu_data.dcache.ways = 1; + boot_cpu_data.dcache.sets = 256; + boot_cpu_data.dcache.entry_shift = 5; + boot_cpu_data.dcache.linesz = 32; + boot_cpu_data.dcache.flags = 0; + + boot_cpu_data.flags |= CPU_HAS_CAS_L; +#else /* * SH-2 doesn't have separate caches */ boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; +#endif boot_cpu_data.icache = boot_cpu_data.dcache; boot_cpu_data.family = CPU_FAMILY_SH2; } diff --git a/arch/sh/kernel/cpu/sh2/smp-j2.c b/arch/sh/kernel/cpu/sh2/smp-j2.c new file mode 100644 index 000000000..6ccd7e4dc --- /dev/null +++ b/arch/sh/kernel/cpu/sh2/smp-j2.c @@ -0,0 +1,139 @@ +/* + * SMP support for J2 processor + * + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include + +DEFINE_PER_CPU(unsigned, j2_ipi_messages); + +extern u32 *sh2_cpuid_addr; +static u32 *j2_ipi_trigger; +static int j2_ipi_irq; + +static irqreturn_t j2_ipi_interrupt_handler(int irq, void *arg) +{ + unsigned cpu = hard_smp_processor_id(); + volatile unsigned *pmsg = &per_cpu(j2_ipi_messages, cpu); + unsigned messages, i; + + do messages = *pmsg; + while (cmpxchg(pmsg, messages, 0) != messages); + + if (!messages) return IRQ_NONE; + + for (i=0; inum_events > MAX_HWEVENTS); perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); - perf_cpu_notifier(sh_pmu_notifier); + cpuhp_setup_state(CPUHP_PERF_SUPERH, "PERF_SUPERH", sh_pmu_prepare_cpu, + NULL); return 0; } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 5d34605b5..e7b49d810 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -242,7 +242,7 @@ void __init __weak plat_early_device_setup(void) { } -#ifdef CONFIG_OF +#ifdef CONFIG_OF_FLATTREE void __ref sh_fdt_init(phys_addr_t dt_phys) { static int done = 0; @@ -251,7 +251,11 @@ void __ref sh_fdt_init(phys_addr_t dt_phys) /* Avoid calling an __init function on secondary cpus. */ if (done) return; +#ifdef CONFIG_USE_BUILTIN_DTB + dt_virt = __dtb_start; +#else dt_virt = phys_to_virt(dt_phys); +#endif if (!dt_virt || !early_init_dt_scan(dt_virt)) { pr_crit("Error: invalid device tree blob" diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 734234be2..254bc22ee 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -386,3 +386,17 @@ ENTRY(sys_call_table) .long sys_process_vm_writev .long sys_kcmp .long sys_finit_module + .long sys_sched_getattr + .long sys_sched_setattr /* 370 */ + .long sys_renameat2 + .long sys_seccomp + .long sys_getrandom + .long sys_memfd_create + .long sys_bpf /* 375 */ + .long sys_execveat + .long sys_userfaultfd + .long sys_membarrier + .long sys_mlock2 + .long sys_copy_file_range /* 380 */ + .long sys_preadv2 + .long sys_pwritev2 diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 579fcb9a8..d6a27f7a4 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S @@ -406,3 +406,17 @@ sys_call_table: .long sys_process_vm_writev .long sys_kcmp .long sys_finit_module + .long sys_sched_getattr /* 380 */ + .long sys_sched_setattr + .long sys_renameat2 + .long sys_seccomp + .long sys_getrandom + .long sys_memfd_create /* 385 */ + .long sys_bpf + .long sys_execveat + .long sys_userfaultfd + .long sys_membarrier + .long sys_mlock2 /* 390 */ + .long sys_copy_file_range + .long sys_preadv2 + .long sys_pwritev2 diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index d6d0a986c..fcd5e4197 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -11,7 +11,6 @@ * for more details. */ #include -#include #include #include #include @@ -50,27 +49,31 @@ int update_persistent_clock(struct timespec now) } #endif -unsigned int get_rtc_time(struct rtc_time *tm) +static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) { - if (rtc_sh_get_time != null_rtc_get_time) { - struct timespec tv; + struct timespec tv; - rtc_sh_get_time(&tv); - rtc_time_to_tm(tv.tv_sec, tm); - } - - return RTC_24H; + rtc_sh_get_time(&tv); + rtc_time_to_tm(tv.tv_sec, tm); + return 0; } -EXPORT_SYMBOL(get_rtc_time); -int set_rtc_time(struct rtc_time *tm) +static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) { unsigned long secs; rtc_tm_to_time(tm, &secs); - return rtc_sh_set_time(secs); + if ((rtc_sh_set_time == null_rtc_set_time) || + (rtc_sh_set_time(secs) < 0)) + return -EOPNOTSUPP; + + return 0; } -EXPORT_SYMBOL(set_rtc_time); + +static const struct rtc_class_ops rtc_generic_ops = { + .read_time = rtc_generic_get_time, + .set_time = rtc_generic_set_time, +}; static int __init rtc_generic_init(void) { @@ -79,11 +82,14 @@ static int __init rtc_generic_init(void) if (rtc_sh_get_time == null_rtc_get_time) return -ENODEV; - pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); + pdev = platform_device_register_data(NULL, "rtc-generic", -1, + &rtc_generic_ops, + sizeof(rtc_generic_ops)); + return PTR_ERR_OR_ZERO(pdev); } -module_init(rtc_generic_init); +device_initcall(rtc_generic_init); void (*board_time_init)(void); -- cgit v1.2.3-54-g00ecf