From f7a20ba06435d067247bd50a15a1d550b9b3fc7d Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:09 -0700 Subject: generic GPIO support for the Freescale Coldfire 5307. Add support for the 5307. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68knommu/platform/5307/Makefile | 2 +- arch/m68knommu/platform/5307/gpio.c | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 arch/m68knommu/platform/5307/gpio.c (limited to 'arch/m68knommu/platform/5307') diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile index cfd586860fd..667db659845 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68knommu/platform/5307/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y += config.o +obj-y += config.o gpio.o diff --git a/arch/m68knommu/platform/5307/gpio.c b/arch/m68knommu/platform/5307/gpio.c new file mode 100644 index 00000000000..8da5880e406 --- /dev/null +++ b/arch/m68knommu/platform/5307/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = MCFSIM_PADDR, + .podr = MCFSIM_PADAT, + .ppdr = MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); -- cgit v1.2.3 From 5187995f0a9253e915dfee83684eae7b692213e6 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 19 May 2009 14:08:47 +1000 Subject: m68knommu: remove duplicate ColdFire mcf_autovector() code Each of the ColdFire CPU platform code that used the old style interrupt controller had its own copy of the mcf_autovector() function. They are all the same, remove them all and create a single function in the common coldfire/intc.c code. Signed-off-by: Greg Ungerer --- arch/m68knommu/platform/5307/config.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch/m68knommu/platform/5307') diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index 39da9e9ff67..60fe45d5139 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -83,20 +83,6 @@ static void __init m5307_uarts_init(void) /***************************************************************************/ -void mcf_autovector(unsigned int vec) -{ - volatile unsigned char *mbar; - - if ((vec >= 25) && (vec <= 31)) { - mbar = (volatile unsigned char *) MCF_MBAR; - vec = 0x1 << (vec - 24); - *(mbar + MCFSIM_AVR) |= vec; - mcf_setimr(mcf_getimr() & ~vec); - } -} - -/***************************************************************************/ - void mcf_settimericr(unsigned int timer, unsigned int level) { volatile unsigned char *icrp; -- cgit v1.2.3 From f2154bef817ac3d0ea67b52526fd8e88898b66f9 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 19 May 2009 14:38:08 +1000 Subject: m68knommu: merge old ColdFire interrupt controller masking macros Currently the code that supports setting the old style ColdFire interrupt controller mask registers is macros in the include files of each of the CPU types. Merge all these into a set of real masking functions in the old Coldfire interrupt controller code proper. All the macros are basically the same (excepting a register size difference on really early parts). Signed-off-by: Greg Ungerer --- arch/m68knommu/platform/5307/config.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'arch/m68knommu/platform/5307') diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index 60fe45d5139..3e27d2ec03f 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -64,11 +64,11 @@ static void __init m5307_uart_init_line(int line, int irq) if (line == 0) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_clrimr(MCFINTC_UART0); } else if (line == 1) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_clrimr(MCFINTC_UART1); } } @@ -90,13 +90,13 @@ void mcf_settimericr(unsigned int timer, unsigned int level) if (timer <= 2) { switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break; + case 2: icr = MCFSIM_TIMER2ICR; imr = MCFINTC_TIMER2; break; + default: icr = MCFSIM_TIMER1ICR; imr = MCFINTC_TIMER1; break; } icrp = (volatile unsigned char *) (MCF_MBAR + icr); *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_setimr(mcf_getimr() & ~imr); + mcf_clrimr(imr); } } @@ -115,8 +115,6 @@ void m5307_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - #if defined(CONFIG_NETtel) || \ defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) /* Copy command line from FLASH to local buffer... */ -- cgit v1.2.3 From 04b75b10dceadf937e3707ecc3dfccf6a076fd29 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 19 May 2009 14:52:40 +1000 Subject: m68knommu: simplify ColdFire "timers" clock initialization The ColdFire "timers" clock setup can be simplified. There is really no need for the flexible per-platform setup code. The clock interrupt can be hard defined per CPU platform (in CPU include files). This makes the actual timer code simpler. Signed-off-by: Greg Ungerer --- arch/m68knommu/platform/5307/config.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) (limited to 'arch/m68knommu/platform/5307') diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index 3e27d2ec03f..b711597ac8e 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -21,12 +21,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - /* * Some platforms need software versions of the GPIO data registers. */ @@ -83,21 +77,17 @@ static void __init m5307_uarts_init(void) /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5307_timers_init(void) { - volatile unsigned char *icrp; - unsigned int icr, imr; - - if (timer <= 2) { - switch (timer) { - case 2: icr = MCFSIM_TIMER2ICR; imr = MCFINTC_TIMER2; break; - default: icr = MCFSIM_TIMER1ICR; imr = MCFINTC_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3; - mcf_clrimr(imr); - } + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); +#endif } /***************************************************************************/ @@ -120,13 +110,10 @@ void __init config_BSP(char *commandp, int size) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); commandp[size-1] = 0; - /* Different timer setup - to prevent device clash */ - mcf_timervector = 30; - mcf_profilevector = 31; - mcf_timerlevel = 6; #endif mach_reset = m5307_cpu_reset; + m5307_timers_init(); #ifdef CONFIG_BDM_DISABLE /* -- cgit v1.2.3 From 39f0fb6a3448cfc316e0d5295ed1b121db50037e Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 22 May 2009 13:33:35 +1000 Subject: m68knommu: map ColdFire interrupts to correct masking bits The older simple ColdFire interrupt controller has no one-to-one mapping of interrupt numbers to bits in the interrupt mask register. Create a mapping array that each ColdFire CPU type can populate with its available interrupts and the bits that each use in the interrupt mask register. Signed-off-by: Greg Ungerer --- arch/m68knommu/platform/5307/config.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'arch/m68knommu/platform/5307') diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index b711597ac8e..00900ac06a9 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -58,11 +58,11 @@ static void __init m5307_uart_init_line(int line, int irq) if (line == 0) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR); - mcf_clrimr(MCFINTC_UART0); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR); - mcf_clrimr(MCFINTC_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -82,11 +82,13 @@ static void __init m5307_timers_init(void) /* Timer1 is always used as system timer */ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); #ifdef CONFIG_HIGHPROFILE /* Timer2 is to be used as a high speed profile timer */ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); #endif } @@ -114,6 +116,13 @@ void __init config_BSP(char *commandp, int size) mach_reset = m5307_cpu_reset; m5307_timers_init(); + m5307_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(27, MCFINTC_EINT3); + mcf_mapirq2imr(29, MCFINTC_EINT5); + mcf_mapirq2imr(31, MCFINTC_EINT7); #ifdef CONFIG_BDM_DISABLE /* @@ -129,7 +138,6 @@ void __init config_BSP(char *commandp, int size) static int __init init_BSP(void) { - m5307_uarts_init(); platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices)); return 0; } -- cgit v1.2.3