diff options
80 files changed, 4495 insertions, 482 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index debde0128cd0..1e6b6bdf6340 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4448,7 +4448,7 @@ L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/panasonic-laptop.c -PANASONIC MN10300/AM33 PORT +PANASONIC MN10300/AM33/AM34 PORT M: David Howells <dhowells@redhat.com> M: Koichi Yasutake <yasutake.koichi@jp.panasonic.com> L: linux-am33-list@redhat.com (moderated for non-subscribers) diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index a0a16e6e4a4e..81e27816aaf8 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -48,7 +48,7 @@ config GENERIC_CALIBRATE_DELAY def_bool y config GENERIC_CMOS_UPDATE - def_bool y + def_bool n config GENERIC_FIND_NEXT_BIT def_bool y @@ -72,10 +72,6 @@ config GENERIC_HARDIRQS config HOTPLUG_CPU def_bool n -config HZ - int - default 1000 - mainmenu "Matsushita MN10300/AM33 Kernel Configuration" source "init/Kconfig" @@ -98,6 +94,9 @@ config MN10300_UNIT_ASB2303 config MN10300_UNIT_ASB2305 bool "ASB2305" +config MN10300_UNIT_ASB2364 + bool "ASB2364" + endchoice choice @@ -115,17 +114,13 @@ config MN10300_PROC_MN103E010 select MN10300_PROC_HAS_TTYSM1 select MN10300_PROC_HAS_TTYSM2 -endchoice - -choice - prompt "Processor core support" - default MN10300_CPU_AM33V2 - help - This option specifies the processor core for which the kernel will be - compiled. It affects the instruction set used. - -config MN10300_CPU_AM33V2 - bool "AM33v2" +config MN10300_PROC_MN2WS0050 + bool "MN2WS0050" + depends on MN10300_UNIT_ASB2364 + select AM34_2 + select MN10300_PROC_HAS_TTYSM0 + select MN10300_PROC_HAS_TTYSM1 + select MN10300_PROC_HAS_TTYSM2 endchoice @@ -138,7 +133,7 @@ config MN10300_HAS_ATOMIC_OPS_UNIT config FPU bool "FPU present" default y - depends on MN10300_PROC_MN103E010 + depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050 config LAZY_SAVE_FPU bool "Save FPU state lazily" @@ -179,24 +174,55 @@ config KERNEL_TEXT_ADDRESS config KERNEL_ZIMAGE_BASE_ADDRESS hex "Base address of compressed vmlinux image" - default "0x90700000" + default "0x50700000" + +config BOOT_STACK_OFFSET + hex + default "0xF00" if SMP + default "0xFF0" if !SMP +config BOOT_STACK_SIZE + hex + depends on SMP + default "0x100" endmenu -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. +config SMP + bool "Symmetric multi-processing support" + default y + depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050 + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + See also <file:Documentation/i386/IO-APIC.txt>, + <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at + <http://www.tldp.org/docs.html#howto>. - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. + If you don't know what to do here, say N. + +config NR_CPUS + int + depends on SMP + default "2" + +config USE_GENERIC_SMP_HELPERS + bool + depends on SMP + default y + +source "kernel/Kconfig.preempt" config MN10300_CURRENT_IN_E2 bool "Hold current task address in E2 register" + depends on !SMP default y help This option removes the E2/R2 register from the set available to gcc @@ -218,12 +244,14 @@ config MN10300_USING_JTAG suppresses the use of certain hardware debugging features, such as single-stepping, which are taken over completely by the JTAG unit. +source "kernel/Kconfig.hz" + config MN10300_RTC bool "Using MN10300 RTC" - depends on MN10300_PROC_MN103E010 + depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050 + select GENERIC_CMOS_UPDATE default n help - This option enables support for the RTC, thus enabling time to be tracked, even when system is powered down. This is available on-chip on the MN103E010. @@ -315,14 +343,23 @@ config MN10300_TTYSM1 choice prompt "Select the timer to supply the clock for SIF1" - default MN10300_TTYSM0_TIMER9 + default MN10300_TTYSM1_TIMER12 \ + if !(AM33_2 || AM33_3) + default MN10300_TTYSM1_TIMER9 \ + if AM33_2 || AM33_3 depends on MN10300_TTYSM1 +config MN10300_TTYSM1_TIMER12 + bool "Use timer 12 (16-bit)" + depends on !(AM33_2 || AM33_3) + config MN10300_TTYSM1_TIMER9 bool "Use timer 9 (16-bit)" + depends on AM33_2 || AM33_3 config MN10300_TTYSM1_TIMER3 bool "Use timer 3 (8-bit)" + depends on AM33_2 || AM33_3 endchoice @@ -337,17 +374,33 @@ config MN10300_TTYSM2 choice prompt "Select the timer to supply the clock for SIF2" - default MN10300_TTYSM0_TIMER10 + default MN10300_TTYSM2_TIMER3 \ + if !(AM33_2 || AM33_3) + default MN10300_TTYSM2_TIMER10 \ + if AM33_2 || AM33_3 depends on MN10300_TTYSM2 +config MN10300_TTYSM2_TIMER9 + bool "Use timer 9 (16-bit)" + depends on !(AM33_2 || AM33_3) + +config MN10300_TTYSM2_TIMER1 + bool "Use timer 1 (8-bit)" + depends on !(AM33_2 || AM33_3) + +config MN10300_TTYSM2_TIMER3 + bool "Use timer 3 (8-bit)" + depends on !(AM33_2 || AM33_3) + config MN10300_TTYSM2_TIMER10 bool "Use timer 10 (16-bit)" + depends on AM33_2 || AM33_3 endchoice config MN10300_TTYSM2_CTS bool "Enable the use of the CTS line /dev/ttySM2" - depends on MN10300_TTYSM2 + depends on MN10300_TTYSM2 && AM33_2 endmenu diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile index ac5c6bdb2f05..7120282bf0d8 100644 --- a/arch/mn10300/Makefile +++ b/arch/mn10300/Makefile @@ -36,6 +36,9 @@ endif ifeq ($(CONFIG_MN10300_PROC_MN103E010),y) PROCESSOR := mn103e010 endif +ifeq ($(CONFIG_MN10300_PROC_MN2WS0050),y) +PROCESSOR := mn2ws0050 +endif ifeq ($(CONFIG_MN10300_UNIT_ASB2303),y) UNIT := asb2303 @@ -43,6 +46,9 @@ endif ifeq ($(CONFIG_MN10300_UNIT_ASB2305),y) UNIT := asb2305 endif +ifeq ($(CONFIG_MN10300_UNIT_ASB2364),y) +UNIT := asb2364 +endif head-y := arch/mn10300/kernel/head.o arch/mn10300/kernel/init_task.o diff --git a/arch/mn10300/boot/compressed/head.S b/arch/mn10300/boot/compressed/head.S index 4ef608a62416..7b50345b9e84 100644 --- a/arch/mn10300/boot/compressed/head.S +++ b/arch/mn10300/boot/compressed/head.S @@ -15,10 +15,28 @@ #include <linux/linkage.h> #include <asm/cpu-regs.h> #include <asm/cache.h> +#ifdef CONFIG_SMP +#include <proc/smp-regs.h> +#endif .globl startup_32 startup_32: - # first save off parameters from bootloader +#ifdef CONFIG_SMP + # + # Secondary CPUs jump directly to the kernel entry point + # + # Must save primary CPU's D0-D2 registers as they hold boot parameters + # + mov (CPUID), d3 + and CPUID_MASK,d3 + beq startup_primary + mov CONFIG_KERNEL_TEXT_ADDRESS,a0 + jmp (a0) + +startup_primary: +#endif /* CONFIG_SMP */ + + # first save parameters from bootloader mov param_save_area,a0 mov d0,(a0) mov d1,(4,a0) diff --git a/arch/mn10300/include/asm/exceptions.h b/arch/mn10300/include/asm/exceptions.h index 7d8080bc6590..ca3e20508c77 100644 --- a/arch/mn10300/include/asm/exceptions.h +++ b/arch/mn10300/include/asm/exceptions.h @@ -114,6 +114,8 @@ extern void die(const char *, struct pt_regs *, enum exception_code) extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code); +#define NUM2EXCEP_IRQ_LEVEL(num) (EXCEP_IRQ_LEVEL0 + (num) * 8) + #endif /* __ASSEMBLY__ */ #endif /* _ASM_EXCEPTIONS_H */ diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc index 5b1949bdf039..406060e5e1c0 100644 --- a/arch/mn10300/include/asm/frame.inc +++ b/arch/mn10300/include/asm/frame.inc @@ -18,6 +18,9 @@ #ifndef __ASM_OFFSETS_H__ #include <asm/asm-offsets.h> #endif +#ifdef CONFIG_SMP +#include <proc/smp-regs.h> +#endif #define pi break @@ -37,9 +40,25 @@ movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) mov sp,fp # FRAME pointer in A3 add -12,sp # allow for calls to be made +#ifdef CONFIG_SMP +#ifdef CONFIG_PREEMPT /* FIXME */ + mov epsw,d2 + and ~EPSW_IE,epsw +#endif + mov (CPUID),a0 + add a0,a0 + add a0,a0 + mov (___frame,a0),a1 + mov a1,(REG_NEXT,fp) + mov fp,(___frame,a0) +#ifdef CONFIG_PREEMPT /* FIXME */ + mov d2,epsw +#endif +#else /* CONFIG_SMP */ mov (__frame),a1 mov a1,(REG_NEXT,fp) mov fp,(__frame) +#endif /* CONFIG_SMP */ and ~EPSW_FE,epsw # disable the FPU inside the kernel @@ -57,10 +76,27 @@ .macro RESTORE_ALL # peel back the stack to the calling frame # - this permits execve() to discard extra frames due to kernel syscalls +#ifdef CONFIG_SMP +#ifdef CONFIG_PREEMPT /* FIXME */ + mov epsw,d2 + and ~EPSW_IE,epsw +#endif + mov (CPUID),a0 + add a0,a0 + add a0,a0 + mov (___frame,a0),fp + mov fp,sp + mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 + mov d0,(___frame,a0) +#ifdef CONFIG_PREEMPT /* FIXME */ + mov d2,epsw +#endif +#else /* CONFIG_SMP */ mov (__frame),fp mov fp,sp mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 mov d0,(__frame) +#endif /* CONFIG_SMP */ #ifndef CONFIG_MN10300_USING_JTAG mov (REG_EPSW,fp),d0 diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h index 7bd9b7cc2451..0000d650b55f 100644 --- a/arch/mn10300/include/asm/hardirq.h +++ b/arch/mn10300/include/asm/hardirq.h @@ -19,8 +19,10 @@ /* assembly code in softirq.h is sensitive to the offsets of these fields */ typedef struct { unsigned int __softirq_pending; +#ifdef CONFIG_MN10300_WD_TIMER unsigned int __nmi_count; /* arch dependent */ unsigned int __irq_count; /* arch dependent */ +#endif } ____cacheline_aligned irq_cpustat_t; #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ diff --git a/arch/mn10300/include/asm/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h index ba544c796c5a..585b708c2bc0 100644 --- a/arch/mn10300/include/asm/intctl-regs.h +++ b/arch/mn10300/include/asm/intctl-regs.h @@ -15,24 +15,19 @@ #ifdef __KERNEL__ -/* interrupt controller registers */ -#define GxICR(X) __SYSREG(0xd4000000 + (X) * 4, u16) /* group irq ctrl regs */ - -#define IAGR __SYSREG(0xd4000100, u16) /* intr acceptance group reg */ -#define IAGR_GN 0x00fc /* group number register - * (documentation _has_ to be wrong) - */ +/* + * Interrupt controller registers + * - Registers 64-191 are at addresses offset from the main array + */ +#define GxICR(X) \ + __SYSREG(0xd4000000 + (X) * 4 + \ + (((X) >= 64) && ((X) < 192)) * 0xf00, u16) -#define EXTMD __SYSREG(0xd4000200, u16) /* external pin intr spec reg */ -#define GET_XIRQ_TRIGGER(X) ((EXTMD >> ((X) * 2)) & 3) +#define GxICR_u8(X) \ + __SYSREG(0xd4000000 + (X) * 4 + \ + (((X) >= 64) && ((X) < 192)) * 0xf00, u8) -#define SET_XIRQ_TRIGGER(X,Y) \ -do { \ - u16 x = EXTMD; \ - x &= ~(3 << ((X) * 2)); \ - x |= ((Y) & 3) << ((X) * 2); \ - EXTMD = x; \ -} while (0) +#include <proc/intctl-regs.h> #define XIRQ_TRIGGER_LOWLEVEL 0 #define XIRQ_TRIGGER_HILEVEL 1 @@ -59,10 +54,18 @@ do { \ #define GxICR_LEVEL_5 0x5000 /* - level 5 */ #define GxICR_LEVEL_6 0x6000 /* - level 6 */ #define GxICR_LEVEL_SHIFT 12 +#define GxICR_NMI 0x8000 /* nmi request flag */ + +#define NUM2GxICR_LEVEL(num) ((num) << GxICR_LEVEL_SHIFT) #ifndef __ASSEMBLY__ extern void set_intr_level(int irq, u16 level); -extern void set_intr_postackable(int irq); +extern void mn10300_intc_set_level(unsigned int irq, unsigned int level); +extern void mn10300_intc_clear(unsigned int irq); +extern void mn10300_intc_set(unsigned int irq); +extern void mn10300_intc_enable(unsigned int irq); +extern void mn10300_intc_disable(unsigned int irq); +extern void mn10300_set_lateack_irq_type(int irq); #endif /* external interrupts */ diff --git a/arch/mn10300/include/asm/irq.h b/arch/mn10300/include/asm/irq.h index 25c045d16d1c..b7b8e175b167 100644 --- a/arch/mn10300/include/asm/irq.h +++ b/arch/mn10300/include/asm/irq.h @@ -22,7 +22,11 @@ #define NO_IRQ INT_MAX /* hardware irq numbers */ +#ifdef CONFIG_SMP +#define NR_IRQS GxICR_NUM_EXT_IRQS +#else #define NR_IRQS GxICR_NUM_IRQS +#endif /* external hardware irq numbers */ #define NR_XIRQS GxICR_NUM_XIRQS diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h index b3ab2071354d..7a7ae12c7119 100644 --- a/arch/mn10300/include/asm/irqflags.h +++ b/arch/mn10300/include/asm/irqflags.h @@ -13,6 +13,9 @@ #define _ASM_IRQFLAGS_H #include <asm/cpu-regs.h> +#ifndef __ASSEMBLY__ +#include <linux/smp.h> +#endif /* * interrupt control @@ -60,11 +63,12 @@ static inline unsigned long arch_local_irq_save(void) /* * we make sure arch_irq_enable() doesn't cause priority inversion */ -extern unsigned long __mn10300_irq_enabled_epsw; +extern unsigned long __mn10300_irq_enabled_epsw[]; static inline void arch_local_irq_enable(void) { unsigned long tmp; + int cpu = raw_smp_processor_id(); asm volatile( " mov epsw,%0 \n" @@ -72,8 +76,8 @@ static inline void arch_local_irq_enable(void) " or %2,%0 \n" " mov %0,epsw \n" : "=&d"(tmp) - : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw) - : "memory"); + : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw[cpu]) + : "memory", "cc"); } static inline void arch_local_irq_restore(unsigned long flags) @@ -105,6 +109,9 @@ static inline bool arch_irqs_disabled(void) */ static inline void arch_safe_halt(void) { +#ifdef CONFIG_SMP + arch_local_irq_enable(); |