diff options
Diffstat (limited to 'arch/m68knommu/platform')
29 files changed, 458 insertions, 124 deletions
diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile index 113c3339006..b5db05625cf 100644 --- a/arch/m68knommu/platform/5206/Makefile +++ b/arch/m68knommu/platform/5206/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/5206e/Makefile b/arch/m68knommu/platform/5206e/Makefile index 113c3339006..b5db05625cf 100644 --- a/arch/m68knommu/platform/5206e/Makefile +++ b/arch/m68knommu/platform/5206e/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile index 435ab3483dc..ad3f4e5a57c 100644 --- a/arch/m68knommu/platform/520x/Makefile +++ b/arch/m68knommu/platform/520x/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile index b8f9b45440c..c04b8f71c88 100644 --- a/arch/m68knommu/platform/523x/Makefile +++ b/arch/m68knommu/platform/523x/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile index f56225d1582..4bed30fd007 100644 --- a/arch/m68knommu/platform/5249/Makefile +++ b/arch/m68knommu/platform/5249/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile index 93673ef8e2c..34110fc1430 100644 --- a/arch/m68knommu/platform/5272/Makefile +++ b/arch/m68knommu/platform/5272/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c index 59278c0887d..65bb582734e 100644 --- a/arch/m68knommu/platform/5272/config.c +++ b/arch/m68knommu/platform/5272/config.c @@ -13,6 +13,8 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/phy.h> +#include <linux/phy_fixed.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> @@ -148,9 +150,23 @@ void __init config_BSP(char *commandp, int size) /***************************************************************************/ +/* + * Some 5272 based boards have the FEC ethernet diectly connected to + * an ethernet switch. In this case we need to use the fixed phy type, + * and we need to declare it early in boot. + */ +static struct fixed_phy_status nettel_fixed_phy_status __initdata = { + .link = 1, + .speed = 100, + .duplex = 0, +}; + +/***************************************************************************/ + static int __init init_BSP(void) { m5272_uarts_init(); + fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status); platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices)); return 0; } diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c index 7081e0a9720..3cf681c177a 100644 --- a/arch/m68knommu/platform/5272/intc.c +++ b/arch/m68knommu/platform/5272/intc.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/interrupt.h> +#include <linux/kernel_stat.h> #include <linux/irq.h> #include <linux/io.h> #include <asm/coldfire.h> @@ -29,6 +30,10 @@ * via a set of 4 "Interrupt Controller Registers" (ICR). There is a * loose mapping of vector number to register and internal bits, but * a table is the easiest and quickest way to map them. + * + * Note that the external interrupts are edge triggered (unlike the + * internal interrupt sources which are level triggered). Which means + * they also need acknowledgeing via acknowledge bits. */ struct irqmap { unsigned char icr; @@ -68,6 +73,11 @@ static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = { /*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, }, }; +/* + * The act of masking the interrupt also has a side effect of 'ack'ing + * an interrupt on this irq (for the external irqs). So this mask function + * is also an ack_mask function. + */ static void intc_irq_mask(unsigned int irq) { if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { @@ -95,7 +105,9 @@ static void intc_irq_ack(unsigned int irq) irq -= MCFINT_VECBASE; if (intc_irqmap[irq].ack) { u32 v; - v = 0xd << intc_irqmap[irq].index; + v = readl(MCF_MBAR + intc_irqmap[irq].icr); + v &= (0x7 << intc_irqmap[irq].index); + v |= (0x8 << intc_irqmap[irq].index); writel(v, MCF_MBAR + intc_irqmap[irq].icr); } } @@ -103,21 +115,47 @@ static void intc_irq_ack(unsigned int irq) static int intc_irq_set_type(unsigned int irq, unsigned int type) { - /* We can set the edge type here for external interrupts */ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + irq -= MCFINT_VECBASE; + if (intc_irqmap[irq].ack) { + u32 v; + v = readl(MCF_MBAR + MCFSIM_PITR); + if (type == IRQ_TYPE_EDGE_FALLING) + v &= ~(0x1 << (32 - irq)); + else + v |= (0x1 << (32 - irq)); + writel(v, MCF_MBAR + MCFSIM_PITR); + } + } return 0; } +/* + * Simple flow handler to deal with the external edge triggered interrupts. + * We need to be careful with the masking/acking due to the side effects + * of masking an interrupt. + */ +static void intc_external_irq(unsigned int irq, struct irq_desc *desc) +{ + kstat_incr_irqs_this_cpu(irq, desc); + desc->status |= IRQ_INPROGRESS; + desc->chip->ack(irq); + handle_IRQ_event(irq, desc->action); + desc->status &= ~IRQ_INPROGRESS; +} + static struct irq_chip intc_irq_chip = { .name = "CF-INTC", .mask = intc_irq_mask, .unmask = intc_irq_unmask, + .mask_ack = intc_irq_mask, .ack = intc_irq_ack, .set_type = intc_irq_set_type, }; void __init init_IRQ(void) { - int irq; + int irq, edge; init_vectors(); @@ -128,11 +166,17 @@ void __init init_IRQ(void) writel(0x88888888, MCF_MBAR + MCFSIM_ICR4); for (irq = 0; (irq < NR_IRQS); irq++) { - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = NULL; - irq_desc[irq].depth = 1; - irq_desc[irq].chip = &intc_irq_chip; - intc_irq_set_type(irq, 0); + set_irq_chip(irq, &intc_irq_chip); + edge = 0; + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) + edge = intc_irqmap[irq - MCFINT_VECBASE].ack; + if (edge) { + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + set_irq_handler(irq, intc_external_irq); + } else { + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); + } } } diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68knommu/platform/527x/Makefile index 3d90e6d9245..6ac4b57370e 100644 --- a/arch/m68knommu/platform/527x/Makefile +++ b/arch/m68knommu/platform/527x/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68knommu/platform/528x/Makefile index 3d90e6d9245..6ac4b57370e 100644 --- a/arch/m68knommu/platform/528x/Makefile +++ b/arch/m68knommu/platform/528x/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile index 6de52697682..d4293b791f2 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68knommu/platform/5307/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile index 4cc23245bcd..ce01669399c 100644 --- a/arch/m68knommu/platform/532x/Makefile +++ b/arch/m68knommu/platform/532x/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile index dee62c5dbaa..e83fe148edd 100644 --- a/arch/m68knommu/platform/5407/Makefile +++ b/arch/m68knommu/platform/5407/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 diff --git a/arch/m68knommu/platform/548x/Makefile b/arch/m68knommu/platform/548x/Makefile new file mode 100644 index 00000000000..e6035e7a2d3 --- /dev/null +++ b/arch/m68knommu/platform/548x/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT +# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o + diff --git a/arch/m68knommu/platform/548x/config.c b/arch/m68knommu/platform/548x/config.c new file mode 100644 index 00000000000..9888846bd1c --- /dev/null +++ b/arch/m68knommu/platform/548x/config.c @@ -0,0 +1,115 @@ +/***************************************************************************/ + +/* + * linux/arch/m68knommu/platform/548x/config.c + * + * Copyright (C) 2010, Philippe De Muyter <phdm@macqel.be> + */ + +/***************************************************************************/ + +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <asm/machdep.h> +#include <asm/coldfire.h> +#include <asm/m548xsim.h> +#include <asm/mcfuart.h> +#include <asm/m548xgpt.h> + +/***************************************************************************/ + +static struct mcf_platform_uart m548x_uart_platform[] = { + { + .mapbase = MCF_MBAR + MCFUART_BASE1, + .irq = 64 + 35, + }, + { + .mapbase = MCF_MBAR + MCFUART_BASE2, + .irq = 64 + 34, + }, + { + .mapbase = MCF_MBAR + MCFUART_BASE3, + .irq = 64 + 33, + }, + { + .mapbase = MCF_MBAR + MCFUART_BASE4, + .irq = 64 + 32, + }, +}; + +static struct platform_device m548x_uart = { + .name = "mcfuart", + .id = 0, + .dev.platform_data = m548x_uart_platform, +}; + +static struct platform_device *m548x_devices[] __initdata = { + &m548x_uart, +}; + + +/***************************************************************************/ + +static void __init m548x_uart_init_line(int line, int irq) +{ + int rts_cts; + + /* enable io pins */ + switch (line) { + case 0: + rts_cts = 0; break; + case 1: + rts_cts = MCF_PAR_PSC_RTS_RTS; break; + case 2: + rts_cts = MCF_PAR_PSC_RTS_RTS | MCF_PAR_PSC_CTS_CTS; break; + case 3: + rts_cts = 0; break; + } + __raw_writeb(MCF_PAR_PSC_TXD | rts_cts | MCF_PAR_PSC_RXD, + MCF_MBAR + MCF_PAR_PSC(line)); +} + +static void __init m548x_uarts_init(void) +{ + const int nrlines = ARRAY_SIZE(m548x_uart_platform); + int line; + + for (line = 0; (line < nrlines); line++) + m548x_uart_init_line(line, m548x_uart_platform[line].irq); +} + +/***************************************************************************/ + +static void mcf548x_reset(void) +{ + /* disable interrupts and enable the watchdog */ + asm("movew #0x2700, %sr\n"); + __raw_writel(0, MCF_MBAR + MCF_GPT_GMS0); + __raw_writel(MCF_GPT_GCIR_CNT(1), MCF_MBAR + MCF_GPT_GCIR0); + __raw_writel(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4), + MCF_MBAR + MCF_GPT_GMS0); +} + +/***************************************************************************/ + +void __init config_BSP(char *commandp, int size) +{ + mach_reset = mcf548x_reset; + m548x_uarts_init(); +} + +/***************************************************************************/ + +static int __init init_BSP(void) +{ + + platform_add_devices(m548x_devices, ARRAY_SIZE(m548x_devices)); + return 0; +} + +arch_initcall(init_BSP); + +/***************************************************************************/ diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S index 9d80d2c4286..27241e16a52 100644 --- a/arch/m68knommu/platform/68328/entry.S +++ b/arch/m68knommu/platform/68328/entry.S @@ -43,10 +43,10 @@ badsys: jra ret_from_exception do_trace: - movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ + movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ subql #4,%sp SAVE_SWITCH_STACK - jbsr syscall_trace + jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp movel %sp@(PT_OFF_ORIG_D0),%d1 @@ -57,10 +57,10 @@ do_trace: lea sys_call_table, %a0 jbsr %a0@(%d1) -1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ +1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK - jbsr syscall_trace + jbsr syscall_trace_leave ret_from_signal: RESTORE_SWITCH_STACK @@ -71,16 +71,16 @@ ENTRY(system_call) SAVE_ALL /* save top of frame*/ - pea %sp@ - jbsr set_esp0 - addql #4,%sp + pea %sp@ + jbsr set_esp0 + addql #4,%sp movel %sp@(PT_OFF_ORIG_D0),%d0 movel %sp,%d1 /* get thread_info pointer */ andl #-THREAD_SIZE,%d1 movel %d1,%a2 - btst #TIF_SYSCALL_TRACE,%a2@(TI_FLAGS) + btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) jne do_trace cmpl #NR_syscalls,%d0 jcc badsys @@ -88,10 +88,10 @@ ENTRY(system_call) lea sys_call_table,%a0 movel %a0@(%d0), %a0 jbsr %a0@ - movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ + movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ ret_from_exception: - btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ + btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ jeq Luser_return /* if so, skip resched, signals*/ Lkernel_return: @@ -133,7 +133,7 @@ Lreturn: */ inthandler1: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -144,7 +144,7 @@ inthandler1: inthandler2: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -155,7 +155,7 @@ inthandler2: inthandler3: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -166,7 +166,7 @@ inthandler3: inthandler4: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -177,7 +177,7 @@ inthandler4: inthandler5: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -188,7 +188,7 @@ inthandler5: inthandler6: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -199,7 +199,7 @@ inthandler6: inthandler7: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- @@ -210,7 +210,7 @@ inthandler7: inthandler: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and #0x3ff, %d0 movel %sp,%sp@- diff --git a/arch/m68knommu/platform/68328/head-de2.S b/arch/m68knommu/platform/68328/head-de2.S index 92d96456d36..f632fdcb93e 100644 --- a/arch/m68knommu/platform/68328/head-de2.S +++ b/arch/m68knommu/platform/68328/head-de2.S @@ -1,11 +1,5 @@ -#if defined(CONFIG_RAM32MB) -#define MEM_END 0x02000000 /* Memory size 32Mb */ -#elif defined(CONFIG_RAM16MB) -#define MEM_END 0x01000000 /* Memory size 16Mb */ -#else #define MEM_END 0x00800000 /* Memory size 8Mb */ -#endif #undef CRT_DEBUG diff --git a/arch/m68knommu/platform/68328/head-ram.S b/arch/m68knommu/platform/68328/head-ram.S index 252b80b0203..7f1aeeacb21 100644 --- a/arch/m68knommu/platform/68328/head-ram.S +++ b/arch/m68knommu/platform/68328/head-ram.S @@ -67,33 +67,6 @@ pclp1: beq pclp1 #endif /* DEBUG */ -#ifdef CONFIG_RELOCATE - /* Copy me to RAM */ - moveal #__rom_start, %a0 - moveal #_stext, %a1 - moveal #_edata, %a2 - - /* Copy %a0 to %a1 until %a1 == %a2 */ -LD1: - movel %a0@+, %d0 - movel %d0, %a1@+ - cmpal %a1, %a2 - bhi LD1 - -#ifdef DEBUG - moveq #74, %d7 /* 'J' */ - moveb %d7,0xfffff907 /* No absolute addresses */ -pclp2: - movew 0xfffff906, %d7 - andw #0x2000, %d7 - beq pclp2 -#endif /* DEBUG */ - /* jump into the RAM copy */ - jmp ram_jump -ram_jump: - -#endif /* CONFIG_RELOCATE */ - #ifdef DEBUG moveq #82, %d7 /* 'R' */ moveb %d7,0xfffff907 /* No absolute addresses */ diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c index b91ee85d4b5..865852806a1 100644 --- a/arch/m68knommu/platform/68328/ints.c +++ b/arch/m68knommu/platform/68328/ints.c @@ -179,10 +179,8 @@ void __init init_IRQ(void) IMR = ~0; for (i = 0; (i < NR_IRQS); i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &intc_irq_chip; + set_irq_chip(irq, &intc_irq_chip); + set_irq_handler(irq, handle_level_irq); } } diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S index 6d3460a39ca..c131c6e1d92 100644 --- a/arch/m68knommu/platform/68360/entry.S +++ b/arch/m68knommu/platform/68360/entry.S @@ -42,7 +42,7 @@ do_trace: movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ subql #4,%sp SAVE_SWITCH_STACK - jbsr syscall_trace + jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp movel %sp@(PT_OFF_ORIG_D0),%d1 @@ -56,7 +56,7 @@ do_trace: 1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK - jbsr syscall_trace + jbsr syscall_trace_leave ret_from_signal: RESTORE_SWITCH_STACK @@ -71,7 +71,12 @@ ENTRY(system_call) jbsr set_esp0 addql #4,%sp - btst #PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF) + movel %sp@(PT_OFF_ORIG_D0),%d0 + + movel %sp,%d1 /* get thread_info pointer */ + andl #-THREAD_SIZE,%d1 + movel %d1,%a2 + btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) jne do_trace cmpl #NR_syscalls,%d0 jcc badsys @@ -124,7 +129,7 @@ Lreturn: */ inthandler: SAVE_ALL - movew %sp@(PT_OFF_VECTOR), %d0 + movew %sp@(PT_OFF_FORMATVEC), %d0 and.l #0x3ff, %d0 lsr.l #0x02, %d0 diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index 6f22970d8c2..ad96ab1051f 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c @@ -132,10 +132,8 @@ void init_IRQ(void) pquicc->intr_cimr = 0x00000000; for (i = 0; (i < NR_IRQS); i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &intc_irq_chip; + set_irq_chip(irq, &intc_irq_chip); + set_irq_handler(irq, handle_level_irq); } } diff --git a/arch/m68knommu/platform/68VZ328/config.c b/arch/m68knommu/platform/68VZ328/config.c index fc5c63054e9..eabaabe8af3 100644 --- a/arch/m68knommu/platform/68VZ328/config.c +++ b/arch/m68knommu/platform/68VZ328/config.c @@ -90,11 +90,6 @@ static void init_hardware(char *command, int size) PDIQEG &= ~PD(1); PDIRQEN |= PD(1); /* IRQ enabled */ -#ifdef CONFIG_68328_SERIAL_UART2 - /* Enable RXD TXD port bits to enable UART2 */ - PJSEL &= ~(PJ(5) | PJ(4)); -#endif - #ifdef CONFIG_INIT_LCD /* initialize LCD controller */ LSSA = (long) screen_bits; diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile index f72a0e5d999..45f501fa452 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68knommu/platform/coldfire/Makefile @@ -8,8 +8,8 @@ # on the console port whenever a DBG interrupt occurs. You have to # set up you HW breakpoints to trigger a DBG interrupt: # -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT # asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 @@ -26,6 +26,7 @@ obj-$(CONFIG_M528x) += pit.o intc-2.o obj-$(CONFIG_M5307) += timers.o intc.o obj-$(CONFIG_M532x) += timers.o intc-simr.o obj-$(CONFIG_M5407) += timers.o intc.o +obj-$(CONFIG_M548x) += sltimers.o intc-2.o obj-y += pinmux.o gpio.o extra-y := head.o diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S index dd7d591f70e..5e92bed94b7 100644 --- a/arch/m68knommu/platform/coldfire/entry.S +++ b/arch/m68knommu/platform/coldfire/entry.S @@ -88,7 +88,7 @@ ENTRY(system_call) movel %d2,PT_OFF_D0(%sp) /* on syscall entry */ subql #4,%sp SAVE_SWITCH_STACK - jbsr syscall_trace + jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp movel %d3,%a0 @@ -96,7 +96,7 @@ ENTRY(system_call) movel %d0,%sp@(PT_OFF_D0) /* save the return value */ subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK - jbsr syscall_trace + jbsr syscall_trace_leave ret_from_signal: RESTORE_SWITCH_STACK @@ -112,7 +112,7 @@ ret_from_exception: andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ movel %d1,%a0 movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ - andl #_TIF_NEED_RESCHED,%d1 + andl #(1<<TIF_NEED_RESCHED),%d1 jeq Lkernel_return movel %a0@(TI_PREEMPTCOUNT),%d1 @@ -136,7 +136,7 @@ Luser_return: andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ movel %d1,%a0 movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ - andl #_TIF_WORK_MASK,%d1 + andl #0xefff,%d1 jne Lwork_to_do /* still work to do */ Lreturn: diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68knommu/platform/coldfire/head.S index 4b91aa24eb0..0b2d7c7adf7 100644 --- a/arch/m68knommu/platform/coldfire/head.S +++ b/arch/m68knommu/platform/coldfire/head.S @@ -15,6 +15,7 @@ #include <asm/coldfire.h> #include <asm/mcfcache.h> #include <asm/mcfsim.h> +#include <asm/thread_info.h> /*****************************************************************************/ diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c index 5598c8b8661..85daa2b3001 100644 --- a/arch/m68knommu/platform/coldfire/intc-2.c +++ b/arch/m68knommu/platform/coldfire/intc-2.c @@ -1,5 +1,11 @@ /* - * intc-1.c + * intc-2.c + * + * General interrupt controller code for the many ColdFire cores that use + * interrupt controllers with 63 interrupt sources, organized as 56 fully- + * programmable + 7 fixed-level interrupt sources. This includes the 523x + * family, the 5270, 5271, 5274, 5275, and the 528x family which have two such + * controllers, and the 547x and 548x families which have only one of them. * * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> * @@ -19,21 +25,37 @@ #include <asm/traps.h> /* - * Each vector needs a unique priority and level asscoiated with it. + * Bit definitions for the ICR family of registers. + */ +#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */ +#define MCFSIM_ICR_PRI(p) (p) /* Priority p intr */ + +/* + * Each vector needs a unique priority and level associated with it. * We don't really care so much what they are, we don't rely on the - * tranditional priority interrupt scheme of the m68k/ColdFire. + * traditional priority interrupt scheme of the m68k/ColdFire. */ -static u8 intc_intpri = 0x36; +static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6); + +#ifdef MCFICM_INTC1 +#define NR_VECS 128 +#else +#define NR_VECS 64 +#endif static void intc_irq_mask(unsigned int irq) { - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) { + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + NR_VECS)) { unsigned long imraddr; u32 val, imrbit; irq -= MCFINT_VECBASE; imraddr = MCF_IPSBAR; +#ifdef MCFICM_INTC1 imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0; +#else + imraddr += MCFICM_INTC0; +#endif imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL; imrbit = 0x1 << (irq & 0x1f); @@ -44,13 +66,17 @@ static void intc_irq_mask(unsigned int irq) static void intc_irq_unmask(unsigned int irq) { - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) { + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + NR_VECS)) { unsigned long intaddr, imraddr, icraddr; u32 val, imrbit; irq -= MCFINT_VECBASE; intaddr = MCF_IPSBAR; +#ifdef MCFICM_INTC1 intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0; +#else + intaddr += MCFICM_INTC0; +#endif imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL); icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f); imrbit = 0x1 << (irq & 0x1f); @@ -67,10 +93,16 @@ static void intc_irq_unmask(unsigned int irq) } } +static int intc_irq_set_type(unsigned int irq, unsigned int type) +{ + return 0; +} + static struct irq_chip intc_irq_chip = { .name = "CF-INTC", .mask = intc_irq_mask, .unmask = intc_irq_unmask, + .set_type = intc_irq_set_type, }; void __init init_IRQ(void) @@ -81,13 +113,14 @@ void __init init_IRQ(void) /* Mask all interrupt sources */ __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL); +#ifdef MCFICM_INTC1 __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL); +#endif for (irq = 0; (irq < NR_IRQS); irq++) { - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = NULL; - irq_desc[irq].depth = 1; - irq_desc[irq].chip = &intc_irq_chip; + set_irq_chip(irq, &intc_irq_chip); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c index 1b01e79c2f6..bb704863614 100644 --- a/arch/m68knommu/platform/coldfire/intc-simr.c +++ b/arch/m68knommu/platform/coldfire/intc-simr.c @@ -1,6 +1,8 @@ /* * intc-simr.c * + * Interrupt controller code for the ColdFire 5208, 5207 & 532x parts. + * * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com> * * This file is subject to the terms and conditions of the GNU General Public @@ -68,11 +70,9 @@ void __init init_IRQ(void) __raw_writeb(0xff, MCFINTC1_SIMR); for (irq = 0; (irq < NR_IRQS); irq++) { - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = NULL; - irq_desc[irq].depth = 1; - irq_desc[irq].chip = &intc_irq_chip; - intc_irq_set_type(irq, 0); + set_irq_chip(irq, &intc_irq_chip); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c index a4560c86db7..60d2fcbe182 100644 --- a/arch/m68knommu/platform/coldfire/intc.c +++ b/arch/m68knommu/platform/coldfire/intc.c @@ -143,11 +143,9 @@ void __init init_IRQ(void) mcf_maskimr(0xffffffff); for (irq = 0; (irq < NR_IRQS); irq++) { - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = NULL; - irq_desc[irq].depth = 1; - irq_desc[irq].chip = &intc_irq_chip; - intc_irq_set_type(irq, 0); + set_irq_chip(irq, &intc_irq_chip); + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + set_irq_handler(irq, handle_level_irq); } } diff --git a/arch/m68knommu/platform/coldfire/sltimers.c b/arch/m68knommu/platform/coldfire/sltimers.c new file mode 100644 index 00000000000..0a1b937c3e1 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/sltimers.c @@ -0,0 +1,145 @@ +/***************************************************************************/ + +/* + * sltimers.c -- generic ColdFire slice timer support. + * + * Copyright (C) 2009-2010, Philippe De Muyter <phdm@macqel.be> + * based on + * timers.c -- generic ColdFire hardware timer support. + * Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com> + */ + +/***************************************************************************/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/profile.h> +#include <linux/clocksource.h> +#include <asm/io.h> +#include <asm/traps.h> +#include <asm/machdep.h> +#include <asm/coldfire.h> +#include <asm/mcfslt.h> +#include <asm/mcfsim.h> + +/***************************************************************************/ + +#ifdef CONFIG_HIGHPROFILE + +/* + * By default use Slice Timer 1 as the profiler clock timer. + */ +#define PA(a) (MCF_MBAR + MCFSLT_TIMER1 + (a)) + +/* + * Choose a reasonably fast profile timer. Make it an odd value to + * try and get good coverage of kernel operations. + */ +#define PROFILEHZ 1013 + +irqreturn_t mcfslt_profile_tick(int irq, void *dummy) +{ + /* Reset Slice Timer 1 */ + __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, PA(MCFSLT_SSR)); + if (current->pid) + profile_tick(CPU_PROFILING); + return IRQ_HANDLED; +} + +static struct irqaction mcfslt_profile_irq = { + .name = "profile timer", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = mcfslt_profile_tick, +}; + +void mcfslt_profile_init(void) +{ + printk(KERN_INFO "PROFILE: lodging TIMER 1 @ %dHz as profile timer\n", + PROFILEHZ); + + setup_irq(MCF_IRQ_PROFILER, &mcfslt_profile_irq); + + /* Set up TIMER 2 as high speed profile clock */ + __raw_writel(MCF_BUSCLK / PROFILEHZ - 1, PA(MCFSLT_STCNT)); + __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN, + PA(MCFSLT_SCR)); + +} + +#endif /* CONFIG_HIGHPROFILE */ + +/***************************************************************************/ + +/* + * By default use Slice Timer 0 as the system clock timer. + */ +#define TA(a) (MCF_MBAR + MCFSLT_TIMER0 + (a)) + +static u32 mcfslt_cycles_per_jiffy; +static u32 mcfslt_cnt; + +static irqreturn_t mcfslt_tick(int irq, void *dummy) +{ + /* Reset Slice Timer 0 */ + __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR)); + mcfslt_cnt += mcfslt_cycles_per_jiffy; + return arch_timer_interrupt(irq, dummy); +} + +static struct irqaction mcfslt_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = mcfslt_tick, +}; + +static cycle_t mcfslt_read_clk(struct clocksource *cs) +{ + unsigned long flags; + u32 cycles; + u16 scnt; + + local_irq_save(flags); + scnt = __raw_readl(TA(MCFSLT_SCNT)); + cycles = mcfslt_cnt; + local_irq_restore(flags); + + /* substract because slice timers count down */ + return cycles - scnt; +} + +static struct clocksource mcfslt_clk = { + .name = "slt", + .rating = 250, + .read = mcfslt_read_clk, + .shift = 20, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void hw_timer_init(void) +{ + mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ; + /* + * The coldfire slice timer (SLT) runs from STCNT to 0 included, + * then STCNT again and so on. It counts thus actually + * STCNT + 1 steps for 1 tick, not STCNT. So if you want + * n cycles, initialize STCNT with n - 1. + */ + __raw_writel(mcfslt_cycles_per_jiffy - 1, TA(MCFSLT_STCNT)); + __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN, + TA(MCFSLT_SCR)); + /* initialize mcfslt_cnt knowing that slice timers count down */ + mcfslt_cnt = mcfslt_cycles_per_jiffy; + + setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq); + + mcfslt_clk.mult = clocksource_hz2mult(MCF_BUSCLK, mcfslt_clk.shift); + clocksource_register(&mcfslt_clk); + +#ifdef CONFIG_HIGHPROFILE + mcfslt_profile_init(); +#endif +} |