提交 7644a448 编写于 作者: L Linus Torvalds

Merge tag 'metag-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag

Pull Metag architecture changes from James Hogan:
 - Infrastructure and DT files for TZ1090 SoC (pin control drivers
   already merged via pinctrl tree).
 - Panic on boot instead of just warning if cache aliasing possible.
 - Various SMP/hotplug fixes.
 - Various other randconfig/sparse fixes.

* tag 'metag-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag: (24 commits)
  metag: move EXPORT_SYMBOL(csum_partial) to metag_ksyms.c
  metag: cpu hotplug: route_irq: preserve irq mask
  metag: kick: add missing irq_enter/exit to kick_handler()
  metag: smp: don't spin waiting for CPU to start
  metag: smp: enable irqs after set_cpu_online
  metag: use clear_tasks_mm_cpumask()
  metag: tz1090: select and instantiate pinctrl-tz1090-pdc
  metag: tz1090: select and instantiate pinctrl-tz1090
  metag: don't check for cache aliasing on smp cpu boot
  metag: panic if cache aliasing possible
  metag: *.dts: include using preprocessor
  metag: add <dt-bindings/> symlink
  metag/.gitignore: Extend the *.dtb pattern to match the dtb.S files
  metag/traps: include setup.h for the per_cpu_trap_init declaration
  metag/traps: Mark die() as __noreturn to match the declaration.
  metag/processor.h: Add missing cpuinfo_op declaration.
  metag/setup: Restrict scope for the capabilities variable
  metag/mm/cache: Restrict scope for metag_lnkget_probe
  metag/asm/irq.h: Declare init_IRQ
  metag/kernel/irq.c: Declare root_domain as static
  ...
* Meta Processor Binding
This binding specifies what properties must be available in the device tree
representation of a Meta Processor Core, which is the root node in the tree.
Required properties:
- compatible: Specifies the compatibility list for the Meta processor.
The type shall be <string> and the value shall include "img,meta".
Optional properties:
- clocks: Clock consumer specifiers as described in
Documentation/devicetree/bindings/clock/clock-bindings.txt
- clock-names: Clock consumer names as described in
Documentation/devicetree/bindings/clock/clock-bindings.txt.
Clocks are identified by name. Valid clocks are:
- "core": The Meta core clock from which the Meta timers are derived.
* Examples
/ {
compatible = "toumaz,tz1090", "img,meta";
clocks = <&meta_core_clk>;
clock-names = "core";
};
......@@ -58,6 +58,7 @@ snps Synopsys, Inc.
st STMicroelectronics
ste ST-Ericsson
stericsson ST-Ericsson
toumaz Toumaz
ti Texas Instruments
toshiba Toshiba Corporation
v3 V3 Semiconductor
......
......@@ -14,6 +14,18 @@ config META21_FPGA
help
This is a Meta 2.1 FPGA bitstream, just a bare CPU.
config SOC_TZ1090
bool "Toumaz Xenif TZ1090 SoC (Comet)"
select METAG_LNKGET_AROUND_CACHE
select METAG_META21
select METAG_SMP_WRITE_REORDERING
select PINCTRL
select PINCTRL_TZ1090
select PINCTRL_TZ1090_PDC
help
This is a Toumaz Technology Xenif TZ1090 (A.K.A. Comet) SoC containing
a 2-threaded HTP.
endchoice
menu "SoC configuration"
......
......@@ -20,7 +20,7 @@ checkflags-$(CONFIG_METAG_META12) += -DMETAC_1_2
checkflags-$(CONFIG_METAG_META21) += -DMETAC_2_1
CHECKFLAGS += -D__metag__ $(checkflags-y)
KBUILD_DEFCONFIG := meta2_defconfig
KBUILD_DEFCONFIG := tz1090_defconfig
sflags-$(CONFIG_METAG_META12) += -mmetac=1.2
ifeq ($(CONFIG_METAG_META12),y)
......
vmlinux*
uImage*
ramdisk.*
*.dtb
*.dtb*
dtb-y += skeleton.dtb
dtb-y += tz1090_generic.dtb
# Built-in dtb
builtindtb-y := skeleton
builtindtb-$(CONFIG_SOC_TZ1090) := tz1090_generic
ifneq ($(CONFIG_METAG_BUILTIN_DTB_NAME),"")
builtindtb-y := $(patsubst "%",%,$(CONFIG_METAG_BUILTIN_DTB_NAME))
......
../../../../../include/dt-bindings
\ No newline at end of file
......@@ -7,4 +7,4 @@
*/
/dts-v1/;
/include/ "skeleton.dtsi"
#include "skeleton.dtsi"
/*
* Copyright (C) 2012 Imagination Technologies Ltd.
*
* 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 "skeleton.dtsi"
/ {
compatible = "toumaz,tz1090", "img,meta";
interrupt-parent = <&intc>;
intc: interrupt-controller {
compatible = "img,meta-intc";
interrupt-controller;
#interrupt-cells = <2>;
num-banks = <2>;
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
pinctrl: pinctrl@02005800 {
#gpio-range-cells = <3>;
compatible = "img,tz1090-pinctrl";
reg = <0x02005800 0xe4>;
};
pdc_pinctrl: pinctrl@02006500 {
#gpio-range-cells = <3>;
compatible = "img,tz1090-pdc-pinctrl";
reg = <0x02006500 0x100>;
};
};
};
/*
* Copyright (C) 2012 Imagination Technologies Ltd.
*
* 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.
*/
/dts-v1/;
#include "tz1090.dtsi"
# CONFIG_LOCALVERSION_AUTO is not set
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_ELF_CORE is not set
CONFIG_SLAB=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_FLATMEM_MANUAL=y
CONFIG_SOC_TZ1090=y
CONFIG_METAG_HALT_ON_PANIC=y
# CONFIG_METAG_FPU is not set
CONFIG_METAG_DA=y
CONFIG_HZ_100=y
CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_DA_TTY=y
CONFIG_DA_CONSOLE=y
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
CONFIG_GPIOLIB=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_DNOTIFY is not set
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_SCHED_DEBUG is not set
CONFIG_DEBUG_INFO=y
......@@ -6,7 +6,7 @@
struct pt_regs;
extern const char *trap_name(int trapno);
extern void die(const char *str, struct pt_regs *regs, long err,
unsigned long addr) __attribute__ ((noreturn));
extern void __noreturn die(const char *str, struct pt_regs *regs, long err,
unsigned long addr);
#endif
......@@ -19,6 +19,8 @@
* core frequency will be determined like this:
* Meta 1: based on loops_per_jiffy.
* Meta 2: (EXPAND_TIMER_DIV + 1) MHz.
* If a "core" clock is provided by the device tree, it
* will override this function.
*/
struct meta_clock_desc {
unsigned long (*get_core_freq)(void);
......@@ -26,6 +28,12 @@ struct meta_clock_desc {
extern struct meta_clock_desc _meta_clock;
/*
* Perform platform clock initialisation, reading clocks from device tree etc.
* Only accessible during boot.
*/
void init_metag_clocks(void);
/*
* Set up the default clock, ensuring all callbacks are valid - only accessible
* during boot.
......
......@@ -17,6 +17,7 @@ struct pt_regs;
int tbisig_map(unsigned int hw);
extern void do_IRQ(int irq, struct pt_regs *regs);
extern void init_IRQ(void);
#ifdef CONFIG_METAG_SUSPEND_MEM
int traps_save_context(void);
......
......@@ -199,4 +199,6 @@ extern void (*soc_halt)(void);
extern void show_trace(struct task_struct *tsk, unsigned long *sp,
struct pt_regs *regs);
extern const struct seq_operations cpuinfo_op;
#endif
......@@ -100,22 +100,23 @@ void check_for_cache_aliasing(int thread_id)
thread_cache_size =
get_thread_cache_size(cache_type, thread_id);
if (thread_cache_size < 0)
pr_emerg("Can't read %s cache size", \
pr_emerg("Can't read %s cache size\n",
cache_type ? "DCACHE" : "ICACHE");
else if (thread_cache_size == 0)
/* Cache is off. No need to check for aliasing */
continue;
if (thread_cache_size / CACHE_ASSOCIATIVITY > PAGE_SIZE) {
pr_emerg("Cache aliasing detected in %s on Thread %d",
pr_emerg("Potential cache aliasing detected in %s on Thread %d\n",
cache_type ? "DCACHE" : "ICACHE", thread_id);
pr_warn("Total %s size: %u bytes",
cache_type ? "DCACHE" : "ICACHE ",
pr_warn("Total %s size: %u bytes\n",
cache_type ? "DCACHE" : "ICACHE",
cache_type ? get_dcache_size()
: get_icache_size());
pr_warn("Thread %s size: %d bytes",
pr_warn("Thread %s size: %d bytes\n",
cache_type ? "CACHE" : "ICACHE",
thread_cache_size);
pr_warn("Page Size: %lu bytes", PAGE_SIZE);
pr_warn("Page Size: %lu bytes\n", PAGE_SIZE);
panic("Potential cache aliasing detected");
}
}
}
......
......@@ -8,8 +8,10 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <asm/param.h>
#include <asm/clock.h>
......@@ -34,8 +36,63 @@ static unsigned long get_core_freq_default(void)
#endif
}
static struct clk *clk_core;
/* Clk based get_core_freq callback. */
static unsigned long get_core_freq_clk(void)
{
return clk_get_rate(clk_core);
}
/**
* init_metag_core_clock() - Set up core clock from devicetree.
*
* Checks to see if a "core" clock is provided in the device tree, and overrides
* the get_core_freq callback to use it.
*/
static void __init init_metag_core_clock(void)
{
/*
* See if a core clock is provided by the devicetree (and
* registered by the init callback above).
*/
struct device_node *node;
node = of_find_compatible_node(NULL, NULL, "img,meta");
if (!node) {
pr_warn("%s: no compatible img,meta DT node found\n",
__func__);
return;
}
clk_core = of_clk_get_by_name(node, "core");
if (IS_ERR(clk_core)) {
pr_warn("%s: no core clock found in DT\n",
__func__);
return;
}
/*
* Override the core frequency callback to use
* this clk.
*/
_meta_clock.get_core_freq = get_core_freq_clk;
}
/**
* init_metag_clocks() - Set up clocks from devicetree.
*
* Set up important clocks from device tree. In particular any needed for clock
* sources.
*/
void __init init_metag_clocks(void)
{
init_metag_core_clock();
pr_info("Core clock frequency: %lu Hz\n", get_coreclock());
}
/**
* setup_meta_clocks() - Set up the Meta clock.
* setup_meta_clocks() - Early set up of the Meta clock.
* @desc: Clock descriptor usually provided by machine description
*
* Ensures all callbacks are valid.
......
......@@ -25,7 +25,7 @@ static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
#endif
struct irq_domain *root_domain;
static struct irq_domain *root_domain;
static unsigned int startup_meta_irq(struct irq_data *data)
{
......@@ -279,11 +279,12 @@ static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_chip *chip = irq_data_get_irq_chip(data);
unsigned long flags;
raw_spin_lock_irq(&desc->lock);
raw_spin_lock_irqsave(&desc->lock, flags);
if (chip->irq_set_affinity)
chip->irq_set_affinity(data, cpumask_of(cpu), false);
raw_spin_unlock_irq(&desc->lock);
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
/*
......
......@@ -26,6 +26,8 @@
* pass it as an argument.
*/
#include <linux/export.h>
#include <linux/hardirq.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/types.h>
......@@ -66,6 +68,7 @@ EXPORT_SYMBOL(kick_unregister_func);
TBIRES
kick_handler(TBIRES State, int SigNum, int Triggers, int Inst, PTBI pTBI)
{
struct pt_regs *old_regs;
struct kick_irq_handler *kh;
struct list_head *lh;
int handled = 0;
......@@ -79,6 +82,9 @@ kick_handler(TBIRES State, int SigNum, int Triggers, int Inst, PTBI pTBI)
trace_hardirqs_off();
old_regs = set_irq_regs((struct pt_regs *)State.Sig.pCtx);
irq_enter();
/*
* There is no need to disable interrupts here because we
* can't nest KICK interrupts in a KICK interrupt handler.
......@@ -97,5 +103,8 @@ kick_handler(TBIRES State, int SigNum, int Triggers, int Inst, PTBI pTBI)
WARN_ON(!handled);
irq_exit();
set_irq_regs(old_regs);
return tail_end(ret);
}
#include <linux/export.h>
#include <linux/types.h>
#include <asm/checksum.h>
#include <asm/div64.h>
#include <asm/ftrace.h>
#include <asm/page.h>
......@@ -15,6 +17,9 @@ EXPORT_SYMBOL(max_pfn);
EXPORT_SYMBOL(min_low_pfn);
#endif
/* Network checksum functions */
EXPORT_SYMBOL(csum_partial);
/* TBI symbols */
EXPORT_SYMBOL(__TBI);
EXPORT_SYMBOL(__TBIFindSeg);
......
......@@ -20,6 +20,7 @@
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/pfn.h>
#include <linux/root_dev.h>
#include <linux/sched.h>
......@@ -424,6 +425,9 @@ static int __init customize_machine(void)
/* customizes platform devices, or adds new ones */
if (machine_desc->init_machine)
machine_desc->init_machine();
else
of_platform_populate(NULL, of_default_bus_match_table, NULL,
NULL);
return 0;
}
arch_initcall(customize_machine);
......@@ -587,20 +591,20 @@ PTBI pTBI_get(unsigned int cpu)
EXPORT_SYMBOL(pTBI_get);
#if defined(CONFIG_METAG_DSP) && defined(CONFIG_METAG_FPU)
char capabilites[] = "dsp fpu";
static char capabilities[] = "dsp fpu";
#elif defined(CONFIG_METAG_DSP)
char capabilites[] = "dsp";
static char capabilities[] = "dsp";
#elif defined(CONFIG_METAG_FPU)
char capabilites[] = "fpu";
static char capabilities[] = "fpu";
#else
char capabilites[] = "";
static char capabilities[] = "";
#endif
static struct ctl_table caps_kern_table[] = {
{
.procname = "capabilities",
.data = capabilites,
.maxlen = sizeof(capabilites),
.data = capabilities,
.maxlen = sizeof(capabilities),
.mode = 0444,
.proc_handler = proc_dostring,
},
......
......@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/atomic.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
......@@ -62,6 +63,8 @@ static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
static DEFINE_SPINLOCK(boot_lock);
static DECLARE_COMPLETION(cpu_running);
/*
* "thread" is assumed to be a valid Meta hardware thread ID.
*/
......@@ -235,20 +238,12 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
*/
ret = boot_secondary(thread, idle);
if (ret == 0) {
unsigned long timeout;
/*
* CPU was successfully started, wait for it
* to come online or time out.
*/
timeout = jiffies + HZ;
while (time_before(jiffies, timeout)) {
if (cpu_online(cpu))
break;
udelay(10);
barrier();
}
wait_for_completion_timeout(&cpu_running,
msecs_to_jiffies(1000));
if (!cpu_online(cpu))
ret = -EIO;
......@@ -276,7 +271,6 @@ static DECLARE_COMPLETION(cpu_killed);
int __cpuexit __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
struct task_struct *p;
/*
* Take this CPU offline. Once we clear this, we can't return,
......@@ -296,12 +290,7 @@ int __cpuexit __cpu_disable(void)
flush_cache_all();
local_flush_tlb_all();
read_lock(&tasklist_lock);
for_each_process(p) {
if (p->mm)
cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
}
read_unlock(&tasklist_lock);
clear_tasks_mm_cpumask(cpu);
return 0;
}
......@@ -385,12 +374,7 @@ asmlinkage void secondary_start_kernel(void)
setup_priv();
/*
* Enable local interrupts.
*/
tbi_startup_interrupt(TBID_SIGNUM_TRT);
notify_cpu_starting(cpu);
local_irq_enable();
pr_info("CPU%u (thread %u): Booted secondary processor\n",
cpu, cpu_2_hwthread_id[cpu]);
......@@ -402,12 +386,13 @@ asmlinkage void secondary_start_kernel(void)
* OK, now it's safe to let the boot CPU continue
*/
set_cpu_online(cpu, true);
complete(&cpu_running);
/*
* Check for cache aliasing.
* Preemption is disabled
* Enable local interrupts.
*/
check_for_cache_aliasing(cpu);
tbi_startup_interrupt(TBID_SIGNUM_TRT);
local_irq_enable();
/*
* OK, it's off to the idle thread for us
......
......@@ -5,11 +5,21 @@
*
*/
#include <linux/init.h>
#include <clocksource/metag_generic.h>
#include <linux/clk-provider.h>
#include <linux/init.h>
#include <asm/clock.h>
void __init time_init(void)
{
#ifdef CONFIG_COMMON_CLK
/* Init clocks from device tree */
of_clk_init(NULL);
#endif
/* Init meta clocks, particularly the core clock */
init_metag_clocks();
/* Set up the timer clock sources */
metag_generic_timer_init();
}
......@@ -33,6 +33,7 @@
#include <asm/siginfo.h>
#include <asm/traps.h>
#include <asm/hwthread.h>
#include <asm/setup.h>
#include <asm/switch.h>
#include <asm/user_gateway.h>
#include <asm/syscall.h>
......@@ -87,8 +88,8 @@ const char *trap_name(int trapno)
static DEFINE_SPINLOCK(die_lock);
void die(const char *str, struct pt_regs *regs, long err,
unsigned long addr)
void __noreturn die(const char *str, struct pt_regs *regs,
long err, unsigned long addr)
{
static int die_counter;
......
......@@ -124,7 +124,6 @@ __wsum csum_partial(const void *buff, int len, __wsum wsum)
result += 1;
return (__force __wsum)result;
}
EXPORT_SYMBOL(csum_partial);
/*
* this routine is used for miscellaneous IP-like checksums, mainly
......
......@@ -45,7 +45,7 @@ static volatile u32 lnkget_testdata[16] __initdata __aligned(64);
#define LNKGET_CONSTANT 0xdeadbeef
void __init metag_lnkget_probe(void)
static void __init metag_lnkget_probe(void)
{
int temp;
long flags;
......
......@@ -184,6 +184,8 @@ int __init metag_generic_timer_init(void)
#ifdef CONFIG_METAG_META21
hwtimer_freq = get_coreclock() / (metag_in32(EXPAND_TIMER_DIV) + 1);
#endif
pr_info("Timer frequency: %u Hz\n", hwtimer_freq);
clocksource_register_hz(&clocksource_metag, hwtimer_freq);
setup_irq(tbisig_map(TBID_SIGNUM_TRT), &metag_timer_irq);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册