mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
arch/sh changes for 4.6. They include minor cleanups, a fix for a
crash that likely affects all sh models with MMU, and introduction of a framework for boards described by device tree, which sets the stage for future J2 support. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAABAgAGBQJW7IIaAAoJELcQ+SIFb8HaDMYH/1tb4FhXGJyVZed7LlK/cpRm wgdl30DPvi8V595GX6fnLS7XKvmekrH2LN0rUHS59H6W56SBu/BdsjH/DfrlId5I Dc19cZYTOFuhwKa75egyEeYrUqkdJMzyDx7maAZSN4BvQ0WL83x4UJwE24vsswW8 h/7s5xFr9XZZ82HqJ6FDyR9beE7RePCnshNVKqTI7q15ht9SFNeJ35bUQxIwCXYl 85eEU0EbPKF15E96eHo1YkAswyohshSMC5474wNwwhpsGmXzc71EtbPCvSGwMlxh 1krA0kUrZAp/3S6/2qENosQqcK0mLhK2ibrNUZGgKc5J/iLwLzfCKxULVIt1IAw= =yg5n -----END PGP SIGNATURE----- Merge tag 'tag-sh-for-4.6' of git://git.libc.org/linux-sh Pull arch/sh updates from Rich Felker: "This includes minor cleanups, a fix for a crash that likely affects all sh models with MMU, and introduction of a framework for boards described by device tree, which sets the stage for future J2 support" * tag 'tag-sh-for-4.6' of git://git.libc.org/linux-sh: sched/preempt, sh: kmap_coherent relies on disabled preemption sh: add SMP method selection to device tree pseudo-board sh: add device tree support and generic board using device tree sh: remove arch-specific localtimer and use generic one sh: make MMU-specific SMP code conditional on CONFIG_MMU sh: provide unified syscall trap compatible with all SH models sh: New gcc support sh: Disable trace for kernel uncompressing. sh: Use generic clkdev.h header
This commit is contained in:
commit
b31a3bc3db
22 changed files with 397 additions and 145 deletions
|
@ -16,6 +16,7 @@ Table of Contents
|
|||
2) Entry point for arch/powerpc
|
||||
3) Entry point for arch/x86
|
||||
4) Entry point for arch/mips/bmips
|
||||
5) Entry point for arch/sh
|
||||
|
||||
II - The DT block format
|
||||
1) Header
|
||||
|
@ -316,6 +317,18 @@ it with special cases.
|
|||
This convention is defined for 32-bit systems only, as there are not
|
||||
currently any 64-bit BMIPS implementations.
|
||||
|
||||
5) Entry point for arch/sh
|
||||
--------------------------
|
||||
|
||||
Device-tree-compatible SH bootloaders are expected to provide the physical
|
||||
address of the device tree blob in r4. Since legacy bootloaders did not
|
||||
guarantee any particular initial register state, kernels built to
|
||||
inter-operate with old bootloaders must either use a builtin DTB or
|
||||
select a legacy board option (something other than CONFIG_SH_DEVICE_TREE)
|
||||
that does not use device tree. Support for the latter is being phased out
|
||||
in favor of device tree.
|
||||
|
||||
|
||||
II - The DT block format
|
||||
========================
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
config SUPERH
|
||||
def_bool y
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT
|
||||
select HAVE_PATA_PLATFORM
|
||||
select CLKDEV_LOOKUP
|
||||
|
|
|
@ -6,6 +6,21 @@ config SOLUTION_ENGINE
|
|||
config SH_ALPHA_BOARD
|
||||
bool
|
||||
|
||||
config SH_DEVICE_TREE
|
||||
bool "Board Described by Device Tree"
|
||||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
select CLKSRC_OF
|
||||
select GENERIC_CALIBRATE_DELAY
|
||||
help
|
||||
Select Board Described by Device Tree to build a kernel that
|
||||
does not hard-code any board-specific knowledge but instead uses
|
||||
a device tree blob provided by the boot-loader. You must enable
|
||||
drivers for any hardware you want to use separately. At this
|
||||
time, only boards based on the open-hardware J-Core processors
|
||||
have sufficient driver coverage to use this option; do not
|
||||
select it if you are using original SuperH hardware.
|
||||
|
||||
config SH_SOLUTION_ENGINE
|
||||
bool "SolutionEngine"
|
||||
select SOLUTION_ENGINE
|
||||
|
|
|
@ -15,3 +15,5 @@ obj-$(CONFIG_SH_TITAN) += board-titan.o
|
|||
obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o
|
||||
obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o
|
||||
obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o
|
||||
|
||||
obj-$(CONFIG_SH_DEVICE_TREE) += of-generic.o
|
||||
|
|
196
arch/sh/boards/of-generic.c
Normal file
196
arch/sh/boards/of-generic.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* SH generic board support, using device tree
|
||||
*
|
||||
* 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 <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_iommu.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/rtc.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
static void dummy_smp_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void dummy_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
}
|
||||
|
||||
static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned int dummy_smp_processor_id(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dummy_send_ipi(unsigned int cpu, unsigned int message)
|
||||
{
|
||||
}
|
||||
|
||||
static struct plat_smp_ops dummy_smp_ops = {
|
||||
.smp_setup = dummy_smp_setup,
|
||||
.prepare_cpus = dummy_prepare_cpus,
|
||||
.start_cpu = dummy_start_cpu,
|
||||
.smp_processor_id = dummy_smp_processor_id,
|
||||
.send_ipi = dummy_send_ipi,
|
||||
.cpu_die = native_cpu_die,
|
||||
.cpu_disable = native_cpu_disable,
|
||||
.play_dead = native_play_dead,
|
||||
};
|
||||
|
||||
extern const struct of_cpu_method __cpu_method_of_table[];
|
||||
const struct of_cpu_method __cpu_method_of_table_sentinel
|
||||
__section(__cpu_method_of_table_end);
|
||||
|
||||
static void sh_of_smp_probe(void)
|
||||
{
|
||||
struct device_node *np = 0;
|
||||
const char *method = 0;
|
||||
const struct of_cpu_method *m = __cpu_method_of_table;
|
||||
|
||||
pr_info("SH generic board support: scanning for cpus\n");
|
||||
|
||||
init_cpu_possible(cpumask_of(0));
|
||||
|
||||
while ((np = of_find_node_by_type(np, "cpu"))) {
|
||||
const __be32 *cell = of_get_property(np, "reg", NULL);
|
||||
u64 id = -1;
|
||||
if (cell) id = of_read_number(cell, of_n_addr_cells(np));
|
||||
if (id < NR_CPUS) {
|
||||
if (!method)
|
||||
of_property_read_string(np, "enable-method", &method);
|
||||
set_cpu_possible(id, true);
|
||||
set_cpu_present(id, true);
|
||||
__cpu_number_map[id] = id;
|
||||
__cpu_logical_map[id] = id;
|
||||
}
|
||||
}
|
||||
if (!method) {
|
||||
np = of_find_node_by_name(NULL, "cpus");
|
||||
of_property_read_string(np, "enable-method", &method);
|
||||
}
|
||||
|
||||
pr_info("CPU enable method: %s\n", method);
|
||||
if (method)
|
||||
for (; m->method; m++)
|
||||
if (!strcmp(m->method, method)) {
|
||||
register_smp_ops(m->ops);
|
||||
return;
|
||||
}
|
||||
|
||||
register_smp_ops(&dummy_smp_ops);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void sh_of_smp_probe(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void noop(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int noopi(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init sh_of_mem_reserve(void)
|
||||
{
|
||||
early_init_fdt_reserve_self();
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
}
|
||||
|
||||
static void __init sh_of_time_init(void)
|
||||
{
|
||||
pr_info("SH generic board support: scanning for clocksource devices\n");
|
||||
clocksource_probe();
|
||||
}
|
||||
|
||||
static void __init sh_of_setup(char **cmdline_p)
|
||||
{
|
||||
unflatten_device_tree();
|
||||
|
||||
board_time_init = sh_of_time_init;
|
||||
|
||||
sh_mv.mv_name = of_flat_dt_get_machine_name();
|
||||
if (!sh_mv.mv_name)
|
||||
sh_mv.mv_name = "Unknown SH model";
|
||||
|
||||
sh_of_smp_probe();
|
||||
}
|
||||
|
||||
static int sh_of_irq_demux(int irq)
|
||||
{
|
||||
/* FIXME: eventually this should not be used at all;
|
||||
* the interrupt controller should set_handle_irq(). */
|
||||
return irq;
|
||||
}
|
||||
|
||||
static void __init sh_of_init_irq(void)
|
||||
{
|
||||
pr_info("SH generic board support: scanning for interrupt controllers\n");
|
||||
irqchip_init();
|
||||
}
|
||||
|
||||
static int __init sh_of_clk_init(void)
|
||||
{
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
/* Disabled pending move to COMMON_CLK framework. */
|
||||
pr_info("SH generic board support: scanning for clk providers\n");
|
||||
of_clk_init(NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sh_machine_vector __initmv sh_of_generic_mv = {
|
||||
.mv_setup = sh_of_setup,
|
||||
.mv_name = "devicetree", /* replaced by DT root's model */
|
||||
.mv_irq_demux = sh_of_irq_demux,
|
||||
.mv_init_irq = sh_of_init_irq,
|
||||
.mv_clk_init = sh_of_clk_init,
|
||||
.mv_mode_pins = noopi,
|
||||
.mv_mem_init = noop,
|
||||
.mv_mem_reserve = sh_of_mem_reserve,
|
||||
};
|
||||
|
||||
struct sh_clk_ops;
|
||||
|
||||
void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
|
||||
{
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int __init sh_of_device_init(void)
|
||||
{
|
||||
pr_info("SH generic board support: populating platform devices\n");
|
||||
if (of_have_populated_dt()) {
|
||||
of_iommu_init();
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
NULL, NULL);
|
||||
} else {
|
||||
pr_crit("Device tree not populated\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
arch_initcall_sync(sh_of_device_init);
|
|
@ -48,7 +48,7 @@ ifeq ($(BITS),64)
|
|||
lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir))
|
||||
endif
|
||||
|
||||
KBUILD_CFLAGS += -I$(lib1funcs-dir)
|
||||
KBUILD_CFLAGS += -I$(lib1funcs-dir) -DDISABLE_BRANCH_PROFILING
|
||||
|
||||
$(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE
|
||||
$(call cmd,shipped)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
generic-y += bitsperlong.h
|
||||
generic-y += clkdev.h
|
||||
generic-y += cputime.h
|
||||
generic-y += current.h
|
||||
generic-y += delay.h
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Paul Mundt <lethal@linux-sh.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Helper for the clk API to assist looking up a struct clk.
|
||||
*/
|
||||
|
||||
#ifndef __CLKDEV__H_
|
||||
#define __CLKDEV__H_
|
||||
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/clock.h>
|
||||
|
||||
static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
|
||||
{
|
||||
if (!slab_is_available())
|
||||
return alloc_bootmem_low_pages(size);
|
||||
else
|
||||
return kzalloc(size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_COMMON_CLK
|
||||
#define __clk_put(clk)
|
||||
#define __clk_get(clk) ({ 1; })
|
||||
#endif
|
||||
|
||||
#endif /* __CLKDEV_H__ */
|
|
@ -69,6 +69,16 @@ static inline int hard_smp_processor_id(void)
|
|||
return mp_ops->smp_processor_id();
|
||||
}
|
||||
|
||||
struct of_cpu_method {
|
||||
const char *method;
|
||||
struct plat_smp_ops *ops;
|
||||
};
|
||||
|
||||
#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
|
||||
static const struct of_cpu_method __cpu_method_of_table_##name \
|
||||
__used __section(__cpu_method_of_table) \
|
||||
= { .method = _method, .ops = _ops }
|
||||
|
||||
#else
|
||||
|
||||
#define hard_smp_processor_id() (0)
|
||||
|
|
|
@ -46,6 +46,5 @@ obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
|
|||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
|
||||
|
||||
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
|
||||
|
||||
ccflags-y := -Werror
|
||||
|
|
|
@ -144,9 +144,9 @@ ENTRY(exception_handler)
|
|||
mov #64,r8
|
||||
cmp/hs r8,r9
|
||||
bt interrupt_entry ! vec >= 64 is interrupt
|
||||
mov #32,r8
|
||||
mov #31,r8
|
||||
cmp/hs r8,r9
|
||||
bt trap_entry ! 64 > vec >= 32 is trap
|
||||
bt trap_entry ! 64 > vec >= 31 is trap
|
||||
|
||||
mov.l 4f,r8
|
||||
mov r9,r4
|
||||
|
@ -178,9 +178,9 @@ interrupt_entry:
|
|||
|
||||
trap_entry:
|
||||
mov #0x30,r8
|
||||
cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
|
||||
cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
|
||||
bt 1f
|
||||
add #-0x10,r9 ! convert SH2 to SH3/4 ABI
|
||||
mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
|
||||
1:
|
||||
shll2 r9 ! TRA
|
||||
bra system_call ! jump common systemcall entry
|
||||
|
|
|
@ -109,9 +109,9 @@ ENTRY(exception_handler)
|
|||
mov #64,r8
|
||||
cmp/hs r8,r9
|
||||
bt interrupt_entry ! vec >= 64 is interrupt
|
||||
mov #32,r8
|
||||
mov #31,r8
|
||||
cmp/hs r8,r9
|
||||
bt trap_entry ! 64 > vec >= 32 is trap
|
||||
bt trap_entry ! 64 > vec >= 31 is trap
|
||||
|
||||
mov.l 4f,r8
|
||||
mov r9,r4
|
||||
|
@ -143,9 +143,9 @@ interrupt_entry:
|
|||
|
||||
trap_entry:
|
||||
mov #0x30,r8
|
||||
cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
|
||||
cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
|
||||
bt 1f
|
||||
add #-0x10,r9 ! convert SH2 to SH3/4 ABI
|
||||
mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
|
||||
1:
|
||||
shll2 r9 ! TRA
|
||||
bra system_call ! jump common systemcall entry
|
||||
|
|
|
@ -268,20 +268,29 @@ debug_trap:
|
|||
* Syscall #: R3
|
||||
* Arguments #0 to #3: R4--R7
|
||||
* Arguments #4 to #6: R0, R1, R2
|
||||
* TRA: (number of arguments + ABI revision) x 4
|
||||
* TRA: See following table.
|
||||
*
|
||||
* This code also handles delegating other traps to the BIOS/gdb stub
|
||||
* according to:
|
||||
*
|
||||
* Trap number
|
||||
* (TRA>>2) Purpose
|
||||
* -------- -------
|
||||
* 0x00-0x0f original SH-3/4 syscall ABI (not in general use).
|
||||
* 0x10-0x1f general SH-3/4 syscall ABI.
|
||||
* 0x20-0x2f syscall ABI for SH-2 parts.
|
||||
* 0x1f unified SH-2/3/4 syscall ABI (preferred).
|
||||
* 0x20-0x2f original SH-2 syscall ABI.
|
||||
* 0x30-0x3f debug traps used by the kernel.
|
||||
* 0x40-0xff Not supported by all parts, so left unhandled.
|
||||
*
|
||||
* For making system calls, any trap number in the range for the
|
||||
* given cpu model may be used, but the unified trap number 0x1f is
|
||||
* preferred for compatibility with all models.
|
||||
*
|
||||
* The low bits of the trap number were once documented as matching
|
||||
* the number of arguments, but they were never actually used as such
|
||||
* by the kernel. SH-2 originally used its own separate trap range
|
||||
* because several hardware exceptions fell in the range used for the
|
||||
* SH-3/4 syscall ABI.
|
||||
*
|
||||
* This code also handles delegating other traps to the BIOS/gdb stub.
|
||||
*
|
||||
* Note: When we're first called, the TRA value must be shifted
|
||||
* right 2 bits in order to get the value that was used as the "trapa"
|
||||
* argument.
|
||||
|
|
|
@ -67,6 +67,10 @@ ENTRY(_stext)
|
|||
ldc r0, r6_bank
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
mov r4, r12 ! Store device tree blob pointer in r12
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prefetch if possible to reduce cache miss penalty.
|
||||
*
|
||||
|
@ -314,6 +318,12 @@ ENTRY(_stext)
|
|||
10:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
mov.l 8f, r0 ! Make flat device tree available early.
|
||||
jsr @r0
|
||||
mov r12, r4
|
||||
#endif
|
||||
|
||||
! Additional CPU initialization
|
||||
mov.l 6f, r0
|
||||
jsr @r0
|
||||
|
@ -339,6 +349,9 @@ ENTRY(stack_start)
|
|||
5: .long start_kernel
|
||||
6: .long cpu_init
|
||||
7: .long init_thread_union
|
||||
#if defined(CONFIG_OF)
|
||||
8: .long sh_fdt_init
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PMB
|
||||
.LPMB_ADDR: .long PMB_ADDR
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Dummy local timer
|
||||
*
|
||||
* Copyright (C) 2008 Paul Mundt
|
||||
*
|
||||
* cloned from:
|
||||
*
|
||||
* linux/arch/arm/mach-realview/localtimer.c
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
|
||||
|
||||
/*
|
||||
* Used on SMP for either the local timer or SMP_MSG_TIMER
|
||||
*/
|
||||
void local_timer_interrupt(void)
|
||||
{
|
||||
struct clock_event_device *clk = this_cpu_ptr(&local_clockevent);
|
||||
|
||||
irq_enter();
|
||||
clk->event_handler(clk);
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
void local_timer_setup(unsigned int cpu)
|
||||
{
|
||||
struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
|
||||
|
||||
clk->name = "dummy_timer";
|
||||
clk->features = CLOCK_EVT_FEAT_ONESHOT |
|
||||
CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_DUMMY;
|
||||
clk->rating = 400;
|
||||
clk->mult = 1;
|
||||
clk->broadcast = smp_timer_broadcast;
|
||||
clk->cpumask = cpumask_of(cpu);
|
||||
|
||||
clockevents_register_device(clk);
|
||||
}
|
||||
|
||||
void local_timer_stop(unsigned int cpu)
|
||||
{
|
||||
}
|
|
@ -29,6 +29,8 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/page.h>
|
||||
|
@ -172,6 +174,7 @@ void __init check_for_initrd(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
|
||||
void calibrate_delay(void)
|
||||
{
|
||||
struct clk *clk = clk_get(NULL, "cpu_clk");
|
||||
|
@ -187,6 +190,7 @@ void calibrate_delay(void)
|
|||
(loops_per_jiffy/(5000/HZ)) % 100,
|
||||
loops_per_jiffy);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
|
||||
unsigned long end_pfn)
|
||||
|
@ -238,6 +242,29 @@ void __init __weak plat_early_device_setup(void)
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
void __ref sh_fdt_init(phys_addr_t dt_phys)
|
||||
{
|
||||
static int done = 0;
|
||||
void *dt_virt;
|
||||
|
||||
/* Avoid calling an __init function on secondary cpus. */
|
||||
if (done) return;
|
||||
|
||||
dt_virt = phys_to_virt(dt_phys);
|
||||
|
||||
if (!dt_virt || !early_init_dt_scan(dt_virt)) {
|
||||
pr_crit("Error: invalid device tree blob"
|
||||
" at physical address %p\n", (void *)dt_phys);
|
||||
|
||||
while (true)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
done = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
enable_mmu();
|
||||
|
|
|
@ -34,6 +34,9 @@ DECLARE_EXPORT(__sdivsi3);
|
|||
DECLARE_EXPORT(__lshrsi3);
|
||||
DECLARE_EXPORT(__ashrsi3);
|
||||
DECLARE_EXPORT(__ashlsi3);
|
||||
DECLARE_EXPORT(__lshrsi3_r0);
|
||||
DECLARE_EXPORT(__ashrsi3_r0);
|
||||
DECLARE_EXPORT(__ashlsi3_r0);
|
||||
DECLARE_EXPORT(__ashiftrt_r4_6);
|
||||
DECLARE_EXPORT(__ashiftrt_r4_7);
|
||||
DECLARE_EXPORT(__ashiftrt_r4_8);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/smp.h>
|
||||
|
@ -140,17 +141,14 @@ int __cpu_disable(void)
|
|||
*/
|
||||
migrate_irqs();
|
||||
|
||||
/*
|
||||
* Stop the local timer for this CPU.
|
||||
*/
|
||||
local_timer_stop(cpu);
|
||||
|
||||
/*
|
||||
* Flush user cache and TLB mappings, and then remove this CPU
|
||||
* from the vm mask set of all processes.
|
||||
*/
|
||||
flush_cache_all();
|
||||
#ifdef CONFIG_MMU
|
||||
local_flush_tlb_all();
|
||||
#endif
|
||||
|
||||
clear_tasks_mm_cpumask(cpu);
|
||||
|
||||
|
@ -183,8 +181,10 @@ asmlinkage void start_secondary(void)
|
|||
atomic_inc(&mm->mm_count);
|
||||
atomic_inc(&mm->mm_users);
|
||||
current->active_mm = mm;
|
||||
#ifdef CONFIG_MMU
|
||||
enter_lazy_tlb(mm, current);
|
||||
local_flush_tlb_all();
|
||||
#endif
|
||||
|
||||
per_cpu_trap_init();
|
||||
|
||||
|
@ -194,8 +194,6 @@ asmlinkage void start_secondary(void)
|
|||
|
||||
local_irq_enable();
|
||||
|
||||
/* Enable local timers */
|
||||
local_timer_setup(cpu);
|
||||
calibrate_delay();
|
||||
|
||||
smp_store_cpu_info(cpu);
|
||||
|
@ -285,7 +283,8 @@ void arch_send_call_function_single_ipi(int cpu)
|
|||
mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
|
||||
}
|
||||
|
||||
void smp_timer_broadcast(const struct cpumask *mask)
|
||||
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
|
||||
void tick_broadcast(const struct cpumask *mask)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
|
@ -296,9 +295,10 @@ void smp_timer_broadcast(const struct cpumask *mask)
|
|||
static void ipi_timer(void)
|
||||
{
|
||||
irq_enter();
|
||||
local_timer_interrupt();
|
||||
tick_receive_broadcast();
|
||||
irq_exit();
|
||||
}
|
||||
#endif
|
||||
|
||||
void smp_message_recv(unsigned int msg)
|
||||
{
|
||||
|
@ -312,9 +312,11 @@ void smp_message_recv(unsigned int msg)
|
|||
case SMP_MSG_FUNCTION_SINGLE:
|
||||
generic_smp_call_function_single_interrupt();
|
||||
break;
|
||||
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
|
||||
case SMP_MSG_TIMER:
|
||||
ipi_timer();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n",
|
||||
smp_processor_id(), __func__, msg);
|
||||
|
@ -328,6 +330,8 @@ int setup_profiling_timer(unsigned int multiplier)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
static void flush_tlb_all_ipi(void *info)
|
||||
{
|
||||
local_flush_tlb_all();
|
||||
|
@ -467,3 +471,5 @@ void flush_tlb_one(unsigned long asid, unsigned long vaddr)
|
|||
smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1);
|
||||
local_flush_tlb_one(asid, vaddr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,21 +54,38 @@ Boston, MA 02110-1301, USA. */
|
|||
!
|
||||
! (none)
|
||||
!
|
||||
! __ashlsi3_r0
|
||||
!
|
||||
! Entry:
|
||||
!
|
||||
! r4: Value to shift
|
||||
! r0: Shifts
|
||||
!
|
||||
! Exit:
|
||||
!
|
||||
! r0: Result
|
||||
!
|
||||
! Destroys:
|
||||
!
|
||||
! (none)
|
||||
|
||||
|
||||
.global __ashlsi3
|
||||
.global __ashlsi3_r0
|
||||
|
||||
.align 2
|
||||
__ashlsi3:
|
||||
mov #31,r0
|
||||
and r0,r5
|
||||
mov r5,r0
|
||||
.align 2
|
||||
__ashlsi3_r0:
|
||||
and #31,r0
|
||||
mov.l r4,@-r15
|
||||
mov r0,r4
|
||||
mova ashlsi3_table,r0
|
||||
mov.b @(r0,r5),r5
|
||||
#ifdef __sh1__
|
||||
add r5,r0
|
||||
mov.b @(r0,r4),r4
|
||||
add r4,r0
|
||||
jmp @r0
|
||||
#else
|
||||
braf r5
|
||||
#endif
|
||||
mov r4,r0
|
||||
mov.l @r15+,r0
|
||||
|
||||
.align 2
|
||||
ashlsi3_table:
|
||||
|
|
|
@ -54,22 +54,37 @@ Boston, MA 02110-1301, USA. */
|
|||
!
|
||||
! (none)
|
||||
!
|
||||
! __ashrsi3_r0
|
||||
!
|
||||
! Entry:
|
||||
!
|
||||
! r4: Value to shift
|
||||
! r0: Shifts
|
||||
!
|
||||
! Exit:
|
||||
!
|
||||
! r0: Result
|
||||
!
|
||||
! Destroys:
|
||||
!
|
||||
! (none)
|
||||
|
||||
.global __ashrsi3
|
||||
.global __ashrsi3_r0
|
||||
|
||||
.align 2
|
||||
__ashrsi3:
|
||||
mov #31,r0
|
||||
and r0,r5
|
||||
mov r5,r0
|
||||
.align 2
|
||||
__ashrsi3_r0:
|
||||
and #31,r0
|
||||
mov.l r4,@-r15
|
||||
mov r0,r4
|
||||
mova ashrsi3_table,r0
|
||||
mov.b @(r0,r5),r5
|
||||
#ifdef __sh1__
|
||||
add r5,r0
|
||||
mov.b @(r0,r4),r4
|
||||
add r4,r0
|
||||
jmp @r0
|
||||
#else
|
||||
braf r5
|
||||
#endif
|
||||
mov r4,r0
|
||||
mov.l @r15+,r0
|
||||
|
||||
.align 2
|
||||
ashrsi3_table:
|
||||
|
|
|
@ -53,22 +53,38 @@ Boston, MA 02110-1301, USA. */
|
|||
! Destroys:
|
||||
!
|
||||
! (none)
|
||||
!
|
||||
! __lshrsi3_r0
|
||||
!
|
||||
! Entry:
|
||||
!
|
||||
! r0: Value to shift
|
||||
! r5: Shifts
|
||||
!
|
||||
! Exit:
|
||||
!
|
||||
! r0: Result
|
||||
!
|
||||
! Destroys:
|
||||
!
|
||||
! (none)
|
||||
!
|
||||
.global __lshrsi3
|
||||
.global __lshrsi3_r0
|
||||
|
||||
.align 2
|
||||
__lshrsi3:
|
||||
mov #31,r0
|
||||
and r0,r5
|
||||
mov r5,r0
|
||||
.align 2
|
||||
__lshrsi3_r0:
|
||||
and #31,r0
|
||||
mov.l r4,@-r15
|
||||
mov r0,r4
|
||||
mova lshrsi3_table,r0
|
||||
mov.b @(r0,r5),r5
|
||||
#ifdef __sh1__
|
||||
add r5,r0
|
||||
mov.b @(r0,r4),r4
|
||||
add r4,r0
|
||||
jmp @r0
|
||||
#else
|
||||
braf r5
|
||||
#endif
|
||||
mov r4,r0
|
||||
mov.l @r15+,r0
|
||||
|
||||
.align 2
|
||||
lshrsi3_table:
|
||||
|
|
|
@ -36,6 +36,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
|
|||
|
||||
BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
|
||||
|
||||
preempt_disable();
|
||||
pagefault_disable();
|
||||
|
||||
idx = FIX_CMAP_END -
|
||||
|
@ -64,4 +65,5 @@ void kunmap_coherent(void *kvaddr)
|
|||
}
|
||||
|
||||
pagefault_enable();
|
||||
preempt_enable();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue