From af39bb8b07af83b579c90c09ba3943123cdb4132 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:00 -0700 Subject: core generic GPIO support for Freescale Coldfire processors. This adds the basic infrastructure used by all of the different Coldfire CPUs. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/gpio.h | 238 ++++++++++++++++++++++++++++++++++++++++ arch/m68k/include/asm/mcfgpio.h | 40 +++++++ arch/m68k/include/asm/pinmux.h | 30 +++++ 3 files changed, 308 insertions(+) create mode 100644 arch/m68k/include/asm/gpio.h create mode 100644 arch/m68k/include/asm/mcfgpio.h create mode 100644 arch/m68k/include/asm/pinmux.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h new file mode 100644 index 00000000000..283214dc65a --- /dev/null +++ b/arch/m68k/include/asm/gpio.h @@ -0,0 +1,238 @@ +/* + * 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. +*/ + +#ifndef coldfire_gpio_h +#define coldfire_gpio_h + +#include +#include +#include +#include + +/* + * The Freescale Coldfire family is quite varied in how they implement GPIO. + * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have + * only one port, others have multiple ports; some have a single data latch + * for both input and output, others have a separate pin data register to read + * input; some require a read-modify-write access to change an output, others + * have set and clear registers for some of the outputs; Some have all the + * GPIOs in a single control area, others have some GPIOs implemented in + * different modules. + * + * This implementation attempts accomodate the differences while presenting + * a generic interface that will optimize to as few instructions as possible. + */ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + +/* These parts have GPIO organized by 8 bit ports */ + +#define MCFGPIO_PORTTYPE u8 +#define MCFGPIO_PORTSIZE 8 +#define mcfgpio_read(port) __raw_readb(port) +#define mcfgpio_write(data, port) __raw_writeb(data, port) + +#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) + +/* These parts have GPIO organized by 16 bit ports */ + +#define MCFGPIO_PORTTYPE u16 +#define MCFGPIO_PORTSIZE 16 +#define mcfgpio_read(port) __raw_readw(port) +#define mcfgpio_write(data, port) __raw_writew(data, port) + +#elif defined(CONFIG_M5249) + +/* These parts have GPIO organized by 32 bit ports */ + +#define MCFGPIO_PORTTYPE u32 +#define MCFGPIO_PORTSIZE 32 +#define mcfgpio_read(port) __raw_readl(port) +#define mcfgpio_write(data, port) __raw_writel(data, port) + +#endif + +#define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) +#define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) + +#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) +/* + * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses + * read-modify-write to change an output and a GPIO module which has separate + * set/clr registers to directly change outputs with a single write access. + */ +#if defined(CONFIG_M528x) +/* + * The 528x also has GPIOs in other modules (GPT, QADC) which use + * read-modify-write as well as those controlled by the EPORT and GPIO modules. + */ +#define MCFGPIO_SCR_START 40 +#else +#define MCFGPIO_SCR_START 8 +#endif + +#define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ + mcfgpio_port(gpio - MCFGPIO_SCR_START)) + +#define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ + mcfgpio_port(gpio - MCFGPIO_SCR_START)) +#else + +#define MCFGPIO_SCR_START MCFGPIO_PIN_MAX +/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ +#define MCFGPIO_SETR_PORT(gpio) 0 +#define MCFGPIO_CLRR_PORT(gpio) 0 + +#endif +/* + * Coldfire specific helper functions + */ + +/* return the port pin data register for a gpio */ +static inline u32 __mcf_gpio_ppdr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADAT; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADAT; + else if (gpio < 32) + return MCFSIM_PBDAT; + else + return MCFSIM_PCDAT; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOREAD; + else + return MCFSIM2_GPIO1READ; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPPDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTPORT; + else if (gpio < 24) + return MCFGPTB_GPTPORT; + else if (gpio < 32) + return MCFQADC_PORTQA; + else if (gpio < 40) + return MCFQADC_PORTQB; +#endif + else + return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#endif +} + +/* return the port output data register for a gpio */ +static inline u32 __mcf_gpio_podr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADAT; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADAT; + else if (gpio < 32) + return MCFSIM_PBDAT; + else + return MCFSIM_PCDAT; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOWRITE; + else + return MCFSIM2_GPIO1WRITE; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTPORT; + else if (gpio < 24) + return MCFGPTB_GPTPORT; + else if (gpio < 32) + return MCFQADC_PORTQA; + else if (gpio < 40) + return MCFQADC_PORTQB; +#endif + else + return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#endif +} + +/* + * The Generic GPIO functions + * + * If the gpio is a compile time constant and is one of the Coldfire gpios, + * use the inline version, otherwise dispatch thru gpiolib. + */ + +static inline int gpio_get_value(unsigned gpio) +{ + if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) + return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio); + else + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) { + if (gpio < MCFGPIO_SCR_START) { + unsigned long flags; + MCFGPIO_PORTTYPE data; + + local_irq_save(flags); + data = mcfgpio_read(__mcf_gpio_podr(gpio)); + if (value) + data |= mcfgpio_bit(gpio); + else + data &= ~mcfgpio_bit(gpio); + mcfgpio_write(data, __mcf_gpio_podr(gpio)); + local_irq_restore(flags); + } else { + if (value) + mcfgpio_write(mcfgpio_bit(gpio), + MCFGPIO_SETR_PORT(gpio)); + else + mcfgpio_write(~mcfgpio_bit(gpio), + MCFGPIO_CLRR_PORT(gpio)); + } + } else + __gpio_set_value(gpio, value); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return (irq >= MCFGPIO_IRQ_VECBASE && + irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ? + irq - MCFGPIO_IRQ_VECBASE : -ENXIO; +} + +static inline int gpio_cansleep(unsigned gpio) +{ + return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); +} + +#endif diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h new file mode 100644 index 00000000000..ee5e4ccce89 --- /dev/null +++ b/arch/m68k/include/asm/mcfgpio.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef mcfgpio_h +#define mcfgpio_h + +#include +#include + +struct mcf_gpio_chip { + struct gpio_chip gpio_chip; + void __iomem *pddr; + void __iomem *podr; + void __iomem *ppdr; + void __iomem *setr; + void __iomem *clrr; + const u8 *gpio_to_pinmux; +}; + +int mcf_gpio_direction_input(struct gpio_chip *, unsigned); +int mcf_gpio_get_value(struct gpio_chip *, unsigned); +int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int); +void mcf_gpio_set_value(struct gpio_chip *, unsigned, int); +void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int); +int mcf_gpio_request(struct gpio_chip *, unsigned); +void mcf_gpio_free(struct gpio_chip *, unsigned); + +#endif diff --git a/arch/m68k/include/asm/pinmux.h b/arch/m68k/include/asm/pinmux.h new file mode 100644 index 00000000000..119ee686dbd --- /dev/null +++ b/arch/m68k/include/asm/pinmux.h @@ -0,0 +1,30 @@ +/* + * Coldfire generic GPIO pinmux 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. + */ + +#ifndef pinmux_h +#define pinmux_h + +#define MCFPINMUX_NONE -1 + +extern int mcf_pinmux_request(unsigned, unsigned); +extern void mcf_pinmux_release(unsigned, unsigned); + +static inline int mcf_pinmux_is_valid(unsigned pinmux) +{ + return pinmux != MCFPINMUX_NONE; +} + +#endif + -- cgit v1.2.3-70-g09d2 From bc25b057fa0a0e4754b7e2524c509874649d11ae Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:01 -0700 Subject: generic GPIO support for the Freescale Coldfire 5206. Add support for the 5206. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m5206sim.h | 10 +++++-- arch/m68knommu/platform/5206/Makefile | 2 +- arch/m68knommu/platform/5206/gpio.c | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 arch/m68knommu/platform/5206/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h index 7e3594dea88..7be8a2d3e65 100644 --- a/arch/m68k/include/asm/m5206sim.h +++ b/arch/m68k/include/asm/m5206sim.h @@ -85,9 +85,15 @@ #define MCFSIM_PAR 0xcb /* Pin Assignment reg (r/w) */ #endif -#define MCFSIM_PADDR 0x1c5 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x1c9 /* Parallel Port Value (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */ +#define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */ +/* + * Generic GPIO + */ +#define MCFGPIO_PIN_MAX 8 +#define MCFGPIO_IRQ_VECBASE -1 +#define MCFGPIO_IRQ_MAX -1 /* * Some symbol defines for the Parallel Port Pin Assignment Register */ diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile index a439d9ab3f2..113c3339006 100644 --- a/arch/m68knommu/platform/5206/Makefile +++ b/arch/m68knommu/platform/5206/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/5206/gpio.c b/arch/m68knommu/platform/5206/gpio.c new file mode 100644 index 00000000000..60f779ce165 --- /dev/null +++ b/arch/m68knommu/platform/5206/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 = 8, + }, + .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-70-g09d2 From afde8560b4217338c17b7dbc9e9d7676c1b3a5ff Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:03 -0700 Subject: generic GPIO support for the Freescale Coldfire 520x. Add support for the 520x. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 56 +++++++++ arch/m68knommu/platform/520x/Makefile | 2 +- arch/m68knommu/platform/520x/gpio.c | 211 ++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 arch/m68knommu/platform/520x/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 83bbcfd6e8f..e80b6a54ea9 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -41,6 +41,62 @@ #define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */ #define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */ +#define MCFEPORT_EPDDR 0xFC088002 +#define MCFEPORT_EPDR 0xFC088004 +#define MCFEPORT_EPPDR 0xFC088005 + +#define MCFGPIO_PODR_BUSCTL 0xFC0A4000 +#define MCFGPIO_PODR_BE 0xFC0A4001 +#define MCFGPIO_PODR_CS 0xFC0A4002 +#define MCFGPIO_PODR_FECI2C 0xFC0A4003 +#define MCFGPIO_PODR_QSPI 0xFC0A4004 +#define MCFGPIO_PODR_TIMER 0xFC0A4005 +#define MCFGPIO_PODR_UART 0xFC0A4006 +#define MCFGPIO_PODR_FECH 0xFC0A4007 +#define MCFGPIO_PODR_FECL 0xFC0A4008 + +#define MCFGPIO_PDDR_BUSCTL 0xFC0A400C +#define MCFGPIO_PDDR_BE 0xFC0A400D +#define MCFGPIO_PDDR_CS 0xFC0A400E +#define MCFGPIO_PDDR_FECI2C 0xFC0A400F +#define MCFGPIO_PDDR_QSPI 0xFC0A4010 +#define MCFGPIO_PDDR_TIMER 0xFC0A4011 +#define MCFGPIO_PDDR_UART 0xFC0A4012 +#define MCFGPIO_PDDR_FECH 0xFC0A4013 +#define MCFGPIO_PDDR_FECL 0xFC0A4014 + +#define MCFGPIO_PPDSDR_BUSCTL 0xFC0A401A +#define MCFGPIO_PPDSDR_BE 0xFC0A401B +#define MCFGPIO_PPDSDR_CS 0xFC0A401C +#define MCFGPIO_PPDSDR_FECI2C 0xFC0A401D +#define MCFGPIO_PPDSDR_QSPI 0xFC0A401E +#define MCFGPIO_PPDSDR_TIMER 0xFC0A401F +#define MCFGPIO_PPDSDR_UART 0xFC0A4021 +#define MCFGPIO_PPDSDR_FECH 0xFC0A4021 +#define MCFGPIO_PPDSDR_FECL 0xFC0A4022 + +#define MCFGPIO_PCLRR_BUSCTL 0xFC0A4024 +#define MCFGPIO_PCLRR_BE 0xFC0A4025 +#define MCFGPIO_PCLRR_CS 0xFC0A4026 +#define MCFGPIO_PCLRR_FECI2C 0xFC0A4027 +#define MCFGPIO_PCLRR_QSPI 0xFC0A4028 +#define MCFGPIO_PCLRR_TIMER 0xFC0A4029 +#define MCFGPIO_PCLRR_UART 0xFC0A402A +#define MCFGPIO_PCLRR_FECH 0xFC0A402B +#define MCFGPIO_PCLRR_FECL 0xFC0A402C +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL +#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL + +#define MCFGPIO_PIN_MAX 80 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +/****************************************************************************/ #define MCF_GPIO_PAR_UART (0xA4036) #define MCF_GPIO_PAR_FECI2C (0xA4033) diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile index a50e76acc8f..435ab3483dc 100644 --- a/arch/m68knommu/platform/520x/Makefile +++ b/arch/m68knommu/platform/520x/Makefile @@ -14,4 +14,4 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/520x/gpio.c b/arch/m68knommu/platform/520x/gpio.c new file mode 100644 index 00000000000..15b5bb62a69 --- /dev/null +++ b/arch/m68knommu/platform/520x/gpio.c @@ -0,0 +1,211 @@ +/* + * 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 = "PIRQ", + .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 = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .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_fast, + .base = 8, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BE", + .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_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BE, + .podr = MCFGPIO_PODR_BE, + .ppdr = MCFGPIO_PPDSDR_BE, + .setr = MCFGPIO_PPDSDR_BE, + .clrr = MCFGPIO_PCLRR_BE, + }, + { + .gpio_chip = { + .label = "CS", + .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_fast, + .base = 25, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "FECI2C", + .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_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "QSPI", + .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_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .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_fast, + .base = 48, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "UART", + .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_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UART, + .podr = MCFGPIO_PODR_UART, + .ppdr = MCFGPIO_PPDSDR_UART, + .setr = MCFGPIO_PPDSDR_UART, + .clrr = MCFGPIO_PCLRR_UART, + }, + { + .gpio_chip = { + .label = "FECH", + .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_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECH, + .podr = MCFGPIO_PODR_FECH, + .ppdr = MCFGPIO_PPDSDR_FECH, + .setr = MCFGPIO_PPDSDR_FECH, + .clrr = MCFGPIO_PCLRR_FECH, + }, + { + .gpio_chip = { + .label = "FECL", + .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_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECL, + .podr = MCFGPIO_PODR_FECL, + .ppdr = MCFGPIO_PPDSDR_FECL, + .setr = MCFGPIO_PPDSDR_FECL, + .clrr = MCFGPIO_PCLRR_FECL, + }, +}; + +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-70-g09d2 From a03ce7d9ef05e145ef706f99e68d5ffacf0ad325 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:04 -0700 Subject: generic GPIO support for the Freescale Coldfire 523x. Add support for the 523x. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m523xsim.h | 77 +++++++++ arch/m68knommu/platform/523x/Makefile | 2 +- arch/m68knommu/platform/523x/gpio.c | 283 ++++++++++++++++++++++++++++++++++ 3 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 arch/m68knommu/platform/523x/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index 55183b5df1b..a34894cf8e6 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -50,5 +50,82 @@ #define MCF_RCR_SWRESET 0x80 /* Software reset bit */ #define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ +#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000) +#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001) +#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002) +#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100003) +#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100004) +#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100005) +#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x100006) +#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x100007) +#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100008) +#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100009) +#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000A) +#define MCFGPIO_PODR_TIMER (MCF_IPSBAR + 0x10000B) +#define MCFGPIO_PODR_ETPU (MCF_IPSBAR + 0x10000C) + +#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100010) +#define MCFGPIO_PDDR_DATAH (MCF_IPSBAR + 0x100011) +#define MCFGPIO_PDDR_DATAL (MCF_IPSBAR + 0x100012) +#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100013) +#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100014) +#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100015) +#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x100016) +#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100017) +#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100018) +#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x100019) +#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x10001A) +#define MCFGPIO_PDDR_TIMER (MCF_IPSBAR + 0x10001B) +#define MCFGPIO_PDDR_ETPU (MCF_IPSBAR + 0x10001C) + +#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x100020) +#define MCFGPIO_PPDSDR_DATAH (MCF_IPSBAR + 0x100021) +#define MCFGPIO_PPDSDR_DATAL (MCF_IPSBAR + 0x100022) +#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x100023) +#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x100024) +#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100025) +#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100026) +#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100027) +#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100028) +#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100029) +#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x10002A) +#define MCFGPIO_PPDSDR_TIMER (MCF_IPSBAR + 0x10002B) +#define MCFGPIO_PPDSDR_ETPU (MCF_IPSBAR + 0x10002C) + +#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100030) +#define MCFGPIO_PCLRR_DATAH (MCF_IPSBAR + 0x100031) +#define MCFGPIO_PCLRR_DATAL (MCF_IPSBAR + 0x100032) +#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100033) +#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100034) +#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x100035) +#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100036) +#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100037) +#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x100038) +#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100039) +#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x10003A) +#define MCFGPIO_PCLRR_TIMER (MCF_IPSBAR + 0x10003B) +#define MCFGPIO_PCLRR_ETPU (MCF_IPSBAR + 0x10003C) + +/* + * EPort + */ + +#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x130002) +#define MCFEPORT_EPDR (MCF_IPSBAR + 0x130004) +#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005) + +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_ADDR +#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR + +#define MCFGPIO_PIN_MAX 107 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE + /****************************************************************************/ #endif /* m523xsim_h */ diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile index 5694d593f02..b8f9b45440c 100644 --- a/arch/m68knommu/platform/523x/Makefile +++ b/arch/m68knommu/platform/523x/Makefile @@ -14,4 +14,4 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/523x/gpio.c b/arch/m68knommu/platform/523x/gpio.c new file mode 100644 index 00000000000..f02840d54d3 --- /dev/null +++ b/arch/m68knommu/platform/523x/gpio.c @@ -0,0 +1,283 @@ +/* + * 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 = "PIRQ", + .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 = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "ADDR", + .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_fast, + .base = 13, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ADDR, + .podr = MCFGPIO_PODR_ADDR, + .ppdr = MCFGPIO_PPDSDR_ADDR, + .setr = MCFGPIO_PPDSDR_ADDR, + .clrr = MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "DATAH", + .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_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAH, + .podr = MCFGPIO_PODR_DATAH, + .ppdr = MCFGPIO_PPDSDR_DATAH, + .setr = MCFGPIO_PPDSDR_DATAH, + .clrr = MCFGPIO_PCLRR_DATAH, + }, + { + .gpio_chip = { + .label = "DATAL", + .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_fast, + .base = 24, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAL, + .podr = MCFGPIO_PODR_DATAL, + .ppdr = MCFGPIO_PPDSDR_DATAL, + .setr = MCFGPIO_PPDSDR_DATAL, + .clrr = MCFGPIO_PCLRR_DATAL, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .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_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BS", + .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_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BS, + .podr = MCFGPIO_PODR_BS, + .ppdr = MCFGPIO_PPDSDR_BS, + .setr = MCFGPIO_PPDSDR_BS, + .clrr = MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "CS", + .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_fast, + .base = 49, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "SDRAM", + .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_fast, + .base = 56, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_SDRAM, + .podr = MCFGPIO_PODR_SDRAM, + .ppdr = MCFGPIO_PPDSDR_SDRAM, + .setr = MCFGPIO_PPDSDR_SDRAM, + .clrr = MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .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_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UARTH", + .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_fast, + .base = 72, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_UARTH, + .podr = MCFGPIO_PODR_UARTH, + .ppdr = MCFGPIO_PPDSDR_UARTH, + .setr = MCFGPIO_PPDSDR_UARTH, + .clrr = MCFGPIO_PCLRR_UARTH, + }, + { + .gpio_chip = { + .label = "UARTL", + .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_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UARTL, + .podr = MCFGPIO_PODR_UARTL, + .ppdr = MCFGPIO_PPDSDR_UARTL, + .setr = MCFGPIO_PPDSDR_UARTL, + .clrr = MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "QSPI", + .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_fast, + .base = 88, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .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_fast, + .base = 96, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "ETPU", + .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_fast, + .base = 104, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ETPU, + .podr = MCFGPIO_PODR_ETPU, + .ppdr = MCFGPIO_PPDSDR_ETPU, + .setr = MCFGPIO_PPDSDR_ETPU, + .clrr = MCFGPIO_PCLRR_ETPU, + }, +}; + +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-70-g09d2 From 9e8ded166dcc7831ee6f31f8a0937cd9b58e83b0 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:05 -0700 Subject: generic GPIO support for the Freescale Coldfire 5249. Add support for the 5249. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m5249sim.h | 23 ++++++++----- arch/m68knommu/platform/5249/Makefile | 2 +- arch/m68knommu/platform/5249/gpio.c | 65 +++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 arch/m68knommu/platform/5249/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h index 366eb8602d2..2c23a83512a 100644 --- a/arch/m68k/include/asm/m5249sim.h +++ b/arch/m68k/include/asm/m5249sim.h @@ -73,14 +73,14 @@ /* * General purpose IO registers (in MBAR2). */ -#define MCFSIM2_GPIOREAD 0x0 /* GPIO read values */ -#define MCFSIM2_GPIOWRITE 0x4 /* GPIO write values */ -#define MCFSIM2_GPIOENABLE 0x8 /* GPIO enabled */ -#define MCFSIM2_GPIOFUNC 0xc /* GPIO function */ -#define MCFSIM2_GPIO1READ 0xb0 /* GPIO1 read values */ -#define MCFSIM2_GPIO1WRITE 0xb4 /* GPIO1 write values */ -#define MCFSIM2_GPIO1ENABLE 0xb8 /* GPIO1 enabled */ -#define MCFSIM2_GPIO1FUNC 0xbc /* GPIO1 function */ +#define MCFSIM2_GPIOREAD (MCF_MBAR2 + 0x000) /* GPIO read values */ +#define MCFSIM2_GPIOWRITE (MCF_MBAR2 + 0x004) /* GPIO write values */ +#define MCFSIM2_GPIOENABLE (MCF_MBAR2 + 0x008) /* GPIO enabled */ +#define MCFSIM2_GPIOFUNC (MCF_MBAR2 + 0x00C) /* GPIO function */ +#define MCFSIM2_GPIO1READ (MCF_MBAR2 + 0x0B0) /* GPIO1 read values */ +#define MCFSIM2_GPIO1WRITE (MCF_MBAR2 + 0x0B4) /* GPIO1 write values */ +#define MCFSIM2_GPIO1ENABLE (MCF_MBAR2 + 0x0B8) /* GPIO1 enabled */ +#define MCFSIM2_GPIO1FUNC (MCF_MBAR2 + 0x0BC) /* GPIO1 function */ #define MCFSIM2_GPIOINTSTAT 0xc0 /* GPIO interrupt status */ #define MCFSIM2_GPIOINTCLEAR 0xc0 /* GPIO interrupt clear */ @@ -100,7 +100,12 @@ #define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */ #define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */ - +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 64 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /* * Macro to set IMR register. It is 32 bits on the 5249. */ diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile index a439d9ab3f2..113c3339006 100644 --- a/arch/m68knommu/platform/5249/Makefile +++ b/arch/m68knommu/platform/5249/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/5249/gpio.c b/arch/m68knommu/platform/5249/gpio.c new file mode 100644 index 00000000000..c611eab8b3b --- /dev/null +++ b/arch/m68knommu/platform/5249/gpio.c @@ -0,0 +1,65 @@ +/* + * 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 = "GPIO0", + .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 = 32, + }, + .pddr = MCFSIM2_GPIOENABLE, + .podr = MCFSIM2_GPIOWRITE, + .ppdr = MCFSIM2_GPIOREAD, + }, + { + .gpio_chip = { + .label = "GPIO1", + .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, + .base = 32, + .ngpio = 32, + }, + .pddr = MCFSIM2_GPIO1ENABLE, + .podr = MCFSIM2_GPIO1WRITE, + .ppdr = MCFSIM2_GPIO1READ, + }, +}; + +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-70-g09d2 From f1554da34f11518bde33776c292c1b58fc20f073 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:06 -0700 Subject: generic GPIO support for the Freescale Coldfire 527x. Add support for the 5271 & 5275. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m527xsim.h | 169 ++++++++++ arch/m68knommu/platform/527x/Makefile | 2 +- arch/m68knommu/platform/527x/gpio.c | 607 ++++++++++++++++++++++++++++++++++ 3 files changed, 777 insertions(+), 1 deletion(-) create mode 100644 arch/m68knommu/platform/527x/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 95f4f8ee8f7..453356d72d8 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -54,6 +54,175 @@ #define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */ #endif + +#ifdef CONFIG_M5271 +#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000) +#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001) +#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002) +#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100003) +#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100004) +#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100005) +#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x100006) +#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x100007) +#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100008) +#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100009) +#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000A) +#define MCFGPIO_PODR_TIMER (MCF_IPSBAR + 0x10000B) + +#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100010) +#define MCFGPIO_PDDR_DATAH (MCF_IPSBAR + 0x100011) +#define MCFGPIO_PDDR_DATAL (MCF_IPSBAR + 0x100012) +#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100013) +#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100014) +#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100015) +#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x100016) +#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100017) +#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100018) +#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x100019) +#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x10001A) +#define MCFGPIO_PDDR_TIMER (MCF_IPSBAR + 0x10001B) + +#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x100020) +#define MCFGPIO_PPDSDR_DATAH (MCF_IPSBAR + 0x100021) +#define MCFGPIO_PPDSDR_DATAL (MCF_IPSBAR + 0x100022) +#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x100023) +#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x100024) +#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100025) +#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100026) +#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100027) +#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100028) +#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100029) +#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x10002A) +#define MCFGPIO_PPDSDR_TIMER (MCF_IPSBAR + 0x10002B) + +#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100030) +#define MCFGPIO_PCLRR_DATAH (MCF_IPSBAR + 0x100031) +#define MCFGPIO_PCLRR_DATAL (MCF_IPSBAR + 0x100032) +#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100033) +#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100034) +#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x100035) +#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100036) +#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100037) +#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x100038) +#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100039) +#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x10003A) +#define MCFGPIO_PCLRR_TIMER (MCF_IPSBAR + 0x10003B) + +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_ADDR +#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR +#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR + +#define MCFGPIO_PIN_MAX 100 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +#endif + +#ifdef CONFIG_M5275 +#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100004) +#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100005) +#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100008) +#define MCFGPIO_PODR_FEC0H (MCF_IPSBAR + 0x10000A) +#define MCFGPIO_PODR_FEC0L (MCF_IPSBAR + 0x10000B) +#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x10000C) +#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000D) +#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x10000E) +#define MCFGPIO_PODR_TIMERH (MCF_IPSBAR + 0x10000F) +#define MCFGPIO_PODR_TIMERL (MCF_IPSBAR + 0x100010) +#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100011) +#define MCFGPIO_PODR_FEC1H (MCF_IPSBAR + 0x100012) +#define MCFGPIO_PODR_FEC1L (MCF_IPSBAR + 0x100013) +#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100014) +#define MCFGPIO_PODR_IRQ (MCF_IPSBAR + 0x100015) +#define MCFGPIO_PODR_USBH (MCF_IPSBAR + 0x100016) +#define MCFGPIO_PODR_USBL (MCF_IPSBAR + 0x100017) +#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100018) + +#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100020) +#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100021) +#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100024) +#define MCFGPIO_PDDR_FEC0H (MCF_IPSBAR + 0x100026) +#define MCFGPIO_PDDR_FEC0L (MCF_IPSBAR + 0x100027) +#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100028) +#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x100029) +#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x10002A) +#define MCFGPIO_PDDR_TIMERH (MCF_IPSBAR + 0x10002B) +#define MCFGPIO_PDDR_TIMERL (MCF_IPSBAR + 0x10002C) +#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x10002D) +#define MCFGPIO_PDDR_FEC1H (MCF_IPSBAR + 0x10002E) +#define MCFGPIO_PDDR_FEC1L (MCF_IPSBAR + 0x10002F) +#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100030) +#define MCFGPIO_PDDR_IRQ (MCF_IPSBAR + 0x100031) +#define MCFGPIO_PDDR_USBH (MCF_IPSBAR + 0x100032) +#define MCFGPIO_PDDR_USBL (MCF_IPSBAR + 0x100033) +#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100034) + +#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x10003C) +#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x10003D) +#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100040) +#define MCFGPIO_PPDSDR_FEC0H (MCF_IPSBAR + 0x100042) +#define MCFGPIO_PPDSDR_FEC0L (MCF_IPSBAR + 0x100043) +#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100044) +#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x100045) +#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100046) +#define MCFGPIO_PPDSDR_TIMERH (MCF_IPSBAR + 0x100047) +#define MCFGPIO_PPDSDR_TIMERL (MCF_IPSBAR + 0x100048) +#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100049) +#define MCFGPIO_PPDSDR_FEC1H (MCF_IPSBAR + 0x10004A) +#define MCFGPIO_PPDSDR_FEC1L (MCF_IPSBAR + 0x10004B) +#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x10004C) +#define MCFGPIO_PPDSDR_IRQ (MCF_IPSBAR + 0x10004D) +#define MCFGPIO_PPDSDR_USBH (MCF_IPSBAR + 0x10004E) +#define MCFGPIO_PPDSDR_USBL (MCF_IPSBAR + 0x10004F) +#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100050) + +#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100058) +#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100059) +#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x10005C) +#define MCFGPIO_PCLRR_FEC0H (MCF_IPSBAR + 0x10005E) +#define MCFGPIO_PCLRR_FEC0L (MCF_IPSBAR + 0x10005F) +#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100060) +#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x100061) +#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100062) +#define MCFGPIO_PCLRR_TIMERH (MCF_IPSBAR + 0x100063) +#define MCFGPIO_PCLRR_TIMERL (MCF_IPSBAR + 0x100064) +#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100065) +#define MCFGPIO_PCLRR_FEC1H (MCF_IPSBAR + 0x100066) +#define MCFGPIO_PCLRR_FEC1L (MCF_IPSBAR + 0x100067) +#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100068) +#define MCFGPIO_PCLRR_IRQ (MCF_IPSBAR + 0x100069) +#define MCFGPIO_PCLRR_USBH (MCF_IPSBAR + 0x10006A) +#define MCFGPIO_PCLRR_USBL (MCF_IPSBAR + 0x10006B) +#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x10006C) + + +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL +#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL +#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL + +#define MCFGPIO_PIN_MAX 148 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +#endif + +/* + * EPort + */ + +#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x130002) +#define MCFEPORT_EPDR (MCF_IPSBAR + 0x130004) +#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005) + + /* * GPIO pins setups to enable the UARTs. */ diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68knommu/platform/527x/Makefile index 26135d92b34..3d90e6d9245 100644 --- a/arch/m68knommu/platform/527x/Makefile +++ b/arch/m68knommu/platform/527x/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/527x/gpio.c b/arch/m68knommu/platform/527x/gpio.c new file mode 100644 index 00000000000..1028142851a --- /dev/null +++ b/arch/m68knommu/platform/527x/gpio.c @@ -0,0 +1,607 @@ +/* + * 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[] = { +#if defined(CONFIG_M5271) + { + .gpio_chip = { + .label = "PIRQ", + .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 = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "ADDR", + .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_fast, + .base = 13, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ADDR, + .podr = MCFGPIO_PODR_ADDR, + .ppdr = MCFGPIO_PPDSDR_ADDR, + .setr = MCFGPIO_PPDSDR_ADDR, + .clrr = MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "DATAH", + .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_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAH, + .podr = MCFGPIO_PODR_DATAH, + .ppdr = MCFGPIO_PPDSDR_DATAH, + .setr = MCFGPIO_PPDSDR_DATAH, + .clrr = MCFGPIO_PCLRR_DATAH, + }, + { + .gpio_chip = { + .label = "DATAL", + .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_fast, + .base = 24, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_DATAL, + .podr = MCFGPIO_PODR_DATAL, + .ppdr = MCFGPIO_PPDSDR_DATAL, + .setr = MCFGPIO_PPDSDR_DATAL, + .clrr = MCFGPIO_PCLRR_DATAL, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .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_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BS", + .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_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BS, + .podr = MCFGPIO_PODR_BS, + .ppdr = MCFGPIO_PPDSDR_BS, + .setr = MCFGPIO_PPDSDR_BS, + .clrr = MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "CS", + .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_fast, + .base = 49, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "SDRAM", + .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_fast, + .base = 56, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_SDRAM, + .podr = MCFGPIO_PODR_SDRAM, + .ppdr = MCFGPIO_PPDSDR_SDRAM, + .setr = MCFGPIO_PPDSDR_SDRAM, + .clrr = MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .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_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UARTH", + .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_fast, + .base = 72, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_UARTH, + .podr = MCFGPIO_PODR_UARTH, + .ppdr = MCFGPIO_PPDSDR_UARTH, + .setr = MCFGPIO_PPDSDR_UARTH, + .clrr = MCFGPIO_PCLRR_UARTH, + }, + { + .gpio_chip = { + .label = "UARTL", + .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_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UARTL, + .podr = MCFGPIO_PODR_UARTL, + .ppdr = MCFGPIO_PPDSDR_UARTL, + .setr = MCFGPIO_PPDSDR_UARTL, + .clrr = MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "QSPI", + .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_fast, + .base = 88, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .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_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, +#elif defined(CONFIG_M5275) + { + .gpio_chip = { + .label = "PIRQ", + .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 = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .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_fast, + .base = 8, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "ADDR", + .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_fast, + .base = 21, + .ngpio = 3, + }, + .pddr = MCFGPIO_PDDR_ADDR, + .podr = MCFGPIO_PODR_ADDR, + .ppdr = MCFGPIO_PPDSDR_ADDR, + .setr = MCFGPIO_PPDSDR_ADDR, + .clrr = MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "CS", + .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_fast, + .base = 25, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "FEC0H", + .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_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC0H, + .podr = MCFGPIO_PODR_FEC0H, + .ppdr = MCFGPIO_PPDSDR_FEC0H, + .setr = MCFGPIO_PPDSDR_FEC0H, + .clrr = MCFGPIO_PCLRR_FEC0H, + }, + { + .gpio_chip = { + .label = "FEC0L", + .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_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC0L, + .podr = MCFGPIO_PODR_FEC0L, + .ppdr = MCFGPIO_PPDSDR_FEC0L, + .setr = MCFGPIO_PPDSDR_FEC0L, + .clrr = MCFGPIO_PCLRR_FEC0L, + }, + { + .gpio_chip = { + .label = "FECI2C", + .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_fast, + .base = 48, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "QSPI", + .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_fast, + .base = 56, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "SDRAM", + .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_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_SDRAM, + .podr = MCFGPIO_PODR_SDRAM, + .ppdr = MCFGPIO_PPDSDR_SDRAM, + .setr = MCFGPIO_PPDSDR_SDRAM, + .clrr = MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "TIMERH", + .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_fast, + .base = 72, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMERH, + .podr = MCFGPIO_PODR_TIMERH, + .ppdr = MCFGPIO_PPDSDR_TIMERH, + .setr = MCFGPIO_PPDSDR_TIMERH, + .clrr = MCFGPIO_PCLRR_TIMERH, + }, + { + .gpio_chip = { + .label = "TIMERL", + .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_fast, + .base = 80, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMERL, + .podr = MCFGPIO_PODR_TIMERL, + .ppdr = MCFGPIO_PPDSDR_TIMERL, + .setr = MCFGPIO_PPDSDR_TIMERL, + .clrr = MCFGPIO_PCLRR_TIMERL, + }, + { + .gpio_chip = { + .label = "UARTL", + .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_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UARTL, + .podr = MCFGPIO_PODR_UARTL, + .ppdr = MCFGPIO_PPDSDR_UARTL, + .setr = MCFGPIO_PPDSDR_UARTL, + .clrr = MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "FEC1H", + .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_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC1H, + .podr = MCFGPIO_PODR_FEC1H, + .ppdr = MCFGPIO_PPDSDR_FEC1H, + .setr = MCFGPIO_PPDSDR_FEC1H, + .clrr = MCFGPIO_PCLRR_FEC1H, + }, + { + .gpio_chip = { + .label = "FEC1L", + .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_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FEC1L, + .podr = MCFGPIO_PODR_FEC1L, + .ppdr = MCFGPIO_PPDSDR_FEC1L, + .setr = MCFGPIO_PPDSDR_FEC1L, + .clrr = MCFGPIO_PCLRR_FEC1L, + }, + { + .gpio_chip = { + .label = "BS", + .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_fast, + .base = 114, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_BS, + .podr = MCFGPIO_PODR_BS, + .ppdr = MCFGPIO_PPDSDR_BS, + .setr = MCFGPIO_PPDSDR_BS, + .clrr = MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "IRQ", + .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_fast, + .base = 121, + .ngpio = 7, + }, + .pddr = MCFGPIO_PDDR_IRQ, + .podr = MCFGPIO_PODR_IRQ, + .ppdr = MCFGPIO_PPDSDR_IRQ, + .setr = MCFGPIO_PPDSDR_IRQ, + .clrr = MCFGPIO_PCLRR_IRQ, + }, + { + .gpio_chip = { + .label = "USBH", + .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_fast, + .base = 128, + .ngpio = 1, + }, + .pddr = MCFGPIO_PDDR_USBH, + .podr = MCFGPIO_PODR_USBH, + .ppdr = MCFGPIO_PPDSDR_USBH, + .setr = MCFGPIO_PPDSDR_USBH, + .clrr = MCFGPIO_PCLRR_USBH, + }, + { + .gpio_chip = { + .label = "USBL", + .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_fast, + .base = 136, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_USBL, + .podr = MCFGPIO_PODR_USBL, + .ppdr = MCFGPIO_PPDSDR_USBL, + .setr = MCFGPIO_PPDSDR_USBL, + .clrr = MCFGPIO_PCLRR_USBL, + }, + { + .gpio_chip = { + .label = "UARTH", + .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_fast, + .base = 144, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_UARTH, + .podr = MCFGPIO_PODR_UARTH, + .ppdr = MCFGPIO_PPDSDR_UARTH, + .setr = MCFGPIO_PPDSDR_UARTH, + .clrr = MCFGPIO_PCLRR_UARTH, + }, +#endif +}; + +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-70-g09d2 From 316f2c483c32e9385329303258d12e6e33892af5 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:07 -0700 Subject: generic GPIO support for the Freescale Coldfire 5272. Add support for the 5272. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m5272sim.h | 24 +++++++---- arch/m68knommu/platform/5272/Makefile | 2 +- arch/m68knommu/platform/5272/gpio.c | 81 +++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 arch/m68knommu/platform/5272/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h index 6217edc2113..0665ba1a5d3 100644 --- a/arch/m68k/include/asm/m5272sim.h +++ b/arch/m68k/include/asm/m5272sim.h @@ -63,16 +63,22 @@ #define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */ #define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */ -#define MCFSIM_PACNT 0x80 /* Port A Control (r/w) */ -#define MCFSIM_PADDR 0x84 /* Port A Direction (r/w) */ -#define MCFSIM_PADAT 0x86 /* Port A Data (r/w) */ -#define MCFSIM_PBCNT 0x88 /* Port B Control (r/w) */ -#define MCFSIM_PBDDR 0x8c /* Port B Direction (r/w) */ -#define MCFSIM_PBDAT 0x8e /* Port B Data (r/w) */ -#define MCFSIM_PCDDR 0x94 /* Port C Direction (r/w) */ -#define MCFSIM_PCDAT 0x96 /* Port C Data (r/w) */ -#define MCFSIM_PDCNT 0x98 /* Port D Control (r/w) */ +#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */ +#define MCFSIM_PADAT (MCF_MBAR + 0x86) /* Port A Data (r/w) */ +#define MCFSIM_PBCNT (MCF_MBAR + 0x88) /* Port B Control (r/w) */ +#define MCFSIM_PBDDR (MCF_MBAR + 0x8c) /* Port B Direction (r/w) */ +#define MCFSIM_PBDAT (MCF_MBAR + 0x8e) /* Port B Data (r/w) */ +#define MCFSIM_PCDDR (MCF_MBAR + 0x94) /* Port C Direction (r/w) */ +#define MCFSIM_PCDAT (MCF_MBAR + 0x96) /* Port C Data (r/w) */ +#define MCFSIM_PDCNT (MCF_MBAR + 0x98) /* Port D Control (r/w) */ +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 48 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /****************************************************************************/ #endif /* m5272sim_h */ diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile index 26135d92b34..3d90e6d9245 100644 --- a/arch/m68knommu/platform/5272/Makefile +++ b/arch/m68knommu/platform/5272/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/5272/gpio.c b/arch/m68knommu/platform/5272/gpio.c new file mode 100644 index 00000000000..459db89a89c --- /dev/null +++ b/arch/m68knommu/platform/5272/gpio.c @@ -0,0 +1,81 @@ +/* + * 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 = "PA", + .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, + }, + { + .gpio_chip = { + .label = "PB", + .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, + .base = 16, + .ngpio = 16, + }, + .pddr = MCFSIM_PBDDR, + .podr = MCFSIM_PBDAT, + .ppdr = MCFSIM_PBDAT, + }, + { + .gpio_chip = { + .label = "PC", + .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, + .base = 32, + .ngpio = 16, + }, + .pddr = MCFSIM_PCDDR, + .podr = MCFSIM_PCDAT, + .ppdr = MCFSIM_PCDAT, + }, +}; + +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-70-g09d2 From 6da6e63c96f5fc8a92b6d1d6f12c2bf998588ffe Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:08 -0700 Subject: generic GPIO support for the Freescale Coldfire 528x. Add support for the 528x. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m528xsim.h | 151 ++++++++++++ arch/m68knommu/platform/528x/Makefile | 2 +- arch/m68knommu/platform/528x/gpio.c | 438 ++++++++++++++++++++++++++++++++++ 3 files changed, 590 insertions(+), 1 deletion(-) create mode 100644 arch/m68knommu/platform/528x/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h index d79c49f8134..e2ad1f42b65 100644 --- a/arch/m68k/include/asm/m528xsim.h +++ b/arch/m68k/include/asm/m528xsim.h @@ -40,6 +40,157 @@ #define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ #define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ +/* + * GPIO registers + */ +#define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000) +#define MCFGPIO_PORTB (MCF_IPSBAR + 0x00100001) +#define MCFGPIO_PORTC (MCF_IPSBAR + 0x00100002) +#define MCFGPIO_PORTD (MCF_IPSBAR + 0x00100003) +#define MCFGPIO_PORTE (MCF_IPSBAR + 0x00100004) +#define MCFGPIO_PORTF (MCF_IPSBAR + 0x00100005) +#define MCFGPIO_PORTG (MCF_IPSBAR + 0x00100006) +#define MCFGPIO_PORTH (MCF_IPSBAR + 0x00100007) +#define MCFGPIO_PORTJ (MCF_IPSBAR + 0x00100008) +#define MCFGPIO_PORTDD (MCF_IPSBAR + 0x00100009) +#define MCFGPIO_PORTEH (MCF_IPSBAR + 0x0010000A) +#define MCFGPIO_PORTEL (MCF_IPSBAR + 0x0010000B) +#define MCFGPIO_PORTAS (MCF_IPSBAR + 0x0010000C) +#define MCFGPIO_PORTQS (MCF_IPSBAR + 0x0010000D) +#define MCFGPIO_PORTSD (MCF_IPSBAR + 0x0010000E) +#define MCFGPIO_PORTTC (MCF_IPSBAR + 0x0010000F) +#define MCFGPIO_PORTTD (MCF_IPSBAR + 0x00100010) +#define MCFGPIO_PORTUA (MCF_IPSBAR + 0x00100011) + +#define MCFGPIO_DDRA (MCF_IPSBAR + 0x00100014) +#define MCFGPIO_DDRB (MCF_IPSBAR + 0x00100015) +#define MCFGPIO_DDRC (MCF_IPSBAR + 0x00100016) +#define MCFGPIO_DDRD (MCF_IPSBAR + 0x00100017) +#define MCFGPIO_DDRE (MCF_IPSBAR + 0x00100018) +#define MCFGPIO_DDRF (MCF_IPSBAR + 0x00100019) +#define MCFGPIO_DDRG (MCF_IPSBAR + 0x0010001A) +#define MCFGPIO_DDRH (MCF_IPSBAR + 0x0010001B) +#define MCFGPIO_DDRJ (MCF_IPSBAR + 0x0010001C) +#define MCFGPIO_DDRDD (MCF_IPSBAR + 0x0010001D) +#define MCFGPIO_DDREH (MCF_IPSBAR + 0x0010001E) +#define MCFGPIO_DDREL (MCF_IPSBAR + 0x0010001F) +#define MCFGPIO_DDRAS (MCF_IPSBAR + 0x00100020) +#define MCFGPIO_DDRQS (MCF_IPSBAR + 0x00100021) +#define MCFGPIO_DDRSD (MCF_IPSBAR + 0x00100022) +#define MCFGPIO_DDRTC (MCF_IPSBAR + 0x00100023) +#define MCFGPIO_DDRTD (MCF_IPSBAR + 0x00100024) +#define MCFGPIO_DDRUA (MCF_IPSBAR + 0x00100025) + +#define MCFGPIO_PORTAP (MCF_IPSBAR + 0x00100028) +#define MCFGPIO_PORTBP (MCF_IPSBAR + 0x00100029) +#define MCFGPIO_PORTCP (MCF_IPSBAR + 0x0010002A) +#define MCFGPIO_PORTDP (MCF_IPSBAR + 0x0010002B) +#define MCFGPIO_PORTEP (MCF_IPSBAR + 0x0010002C) +#define MCFGPIO_PORTFP (MCF_IPSBAR + 0x0010002D) +#define MCFGPIO_PORTGP (MCF_IPSBAR + 0x0010002E) +#define MCFGPIO_PORTHP (MCF_IPSBAR + 0x0010002F) +#define MCFGPIO_PORTJP (MCF_IPSBAR + 0x00100030) +#define MCFGPIO_PORTDDP (MCF_IPSBAR + 0x00100031) +#define MCFGPIO_PORTEHP (MCF_IPSBAR + 0x00100032) +#define MCFGPIO_PORTELP (MCF_IPSBAR + 0x00100033) +#define MCFGPIO_PORTASP (MCF_IPSBAR + 0x00100034) +#define MCFGPIO_PORTQSP (MCF_IPSBAR + 0x00100035) +#define MCFGPIO_PORTSDP (MCF_IPSBAR + 0x00100036) +#define MCFGPIO_PORTTCP (MCF_IPSBAR + 0x00100037) +#define MCFGPIO_PORTTDP (MCF_IPSBAR + 0x00100038) +#define MCFGPIO_PORTUAP (MCF_IPSBAR + 0x00100039) + +#define MCFGPIO_SETA (MCF_IPSBAR + 0x00100028) +#define MCFGPIO_SETB (MCF_IPSBAR + 0x00100029) +#define MCFGPIO_SETC (MCF_IPSBAR + 0x0010002A) +#define MCFGPIO_SETD (MCF_IPSBAR + 0x0010002B) +#define MCFGPIO_SETE (MCF_IPSBAR + 0x0010002C) +#define MCFGPIO_SETF (MCF_IPSBAR + 0x0010002D) +#define MCFGPIO_SETG (MCF_IPSBAR + 0x0010002E) +#define MCFGPIO_SETH (MCF_IPSBAR + 0x0010002F) +#define MCFGPIO_SETJ (MCF_IPSBAR + 0x00100030) +#define MCFGPIO_SETDD (MCF_IPSBAR + 0x00100031) +#define MCFGPIO_SETEH (MCF_IPSBAR + 0x00100032) +#define MCFGPIO_SETEL (MCF_IPSBAR + 0x00100033) +#define MCFGPIO_SETAS (MCF_IPSBAR + 0x00100034) +#define MCFGPIO_SETQS (MCF_IPSBAR + 0x00100035) +#define MCFGPIO_SETSD (MCF_IPSBAR + 0x00100036) +#define MCFGPIO_SETTC (MCF_IPSBAR + 0x00100037) +#define MCFGPIO_SETTD (MCF_IPSBAR + 0x00100038) +#define MCFGPIO_SETUA (MCF_IPSBAR + 0x00100039) + +#define MCFGPIO_CLRA (MCF_IPSBAR + 0x0010003C) +#define MCFGPIO_CLRB (MCF_IPSBAR + 0x0010003D) +#define MCFGPIO_CLRC (MCF_IPSBAR + 0x0010003E) +#define MCFGPIO_CLRD (MCF_IPSBAR + 0x0010003F) +#define MCFGPIO_CLRE (MCF_IPSBAR + 0x00100040) +#define MCFGPIO_CLRF (MCF_IPSBAR + 0x00100041) +#define MCFGPIO_CLRG (MCF_IPSBAR + 0x00100042) +#define MCFGPIO_CLRH (MCF_IPSBAR + 0x00100043) +#define MCFGPIO_CLRJ (MCF_IPSBAR + 0x00100044) +#define MCFGPIO_CLRDD (MCF_IPSBAR + 0x00100045) +#define MCFGPIO_CLREH (MCF_IPSBAR + 0x00100046) +#define MCFGPIO_CLREL (MCF_IPSBAR + 0x00100047) +#define MCFGPIO_CLRAS (MCF_IPSBAR + 0x00100048) +#define MCFGPIO_CLRQS (MCF_IPSBAR + 0x00100049) +#define MCFGPIO_CLRSD (MCF_IPSBAR + 0x0010004A) +#define MCFGPIO_CLRTC (MCF_IPSBAR + 0x0010004B) +#define MCFGPIO_CLRTD (MCF_IPSBAR + 0x0010004C) +#define MCFGPIO_CLRUA (MCF_IPSBAR + 0x0010004D) + +#define MCFGPIO_PBCDPAR (MCF_IPSBAR + 0x00100050) +#define MCFGPIO_PFPAR (MCF_IPSBAR + 0x00100051) +#define MCFGPIO_PEPAR (MCF_IPSBAR + 0x00100052) +#define MCFGPIO_PJPAR (MCF_IPSBAR + 0x00100054) +#define MCFGPIO_PSDPAR (MCF_IPSBAR + 0x00100055) +#define MCFGPIO_PASPAR (MCF_IPSBAR + 0x00100056) +#define MCFGPIO_PEHLPAR (MCF_IPSBAR + 0x00100058) +#define MCFGPIO_PQSPAR (MCF_IPSBAR + 0x00100059) +#define MCFGPIO_PTCPAR (MCF_IPSBAR + 0x0010005A) +#define MCFGPIO_PTDPAR (MCF_IPSBAR + 0x0010005B) +#define MCFGPIO_PUAPAR (MCF_IPSBAR + 0x0010005C) + +/* + * Edge Port registers + */ +#define MCFEPORT_EPPAR (MCF_IPSBAR + 0x00130000) +#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x00130002) +#define MCFEPORT_EPIER (MCF_IPSBAR + 0x00130003) +#define MCFEPORT_EPDR (MCF_IPSBAR + 0x00130004) +#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x00130005) +#define MCFEPORT_EPFR (MCF_IPSBAR + 0x00130006) + +/* + * Queued ADC registers + */ +#define MCFQADC_PORTQA (MCF_IPSBAR + 0x00190006) +#define MCFQADC_PORTQB (MCF_IPSBAR + 0x00190007) +#define MCFQADC_DDRQA (MCF_IPSBAR + 0x00190008) +#define MCFQADC_DDRQB (MCF_IPSBAR + 0x00190009) + +/* + * General Purpose Timers registers + */ +#define MCFGPTA_GPTPORT (MCF_IPSBAR + 0x001A001D) +#define MCFGPTA_GPTDDR (MCF_IPSBAR + 0x001A001E) +#define MCFGPTB_GPTPORT (MCF_IPSBAR + 0x001B001D) +#define MCFGPTB_GPTDDR (MCF_IPSBAR + 0x001B001E) +/* + * + * definitions for generic gpio support + * + */ +#define MCFGPIO_PODR MCFGPIO_PORTA /* port output data */ +#define MCFGPIO_PDDR MCFGPIO_DDRA /* port data direction */ +#define MCFGPIO_PPDR MCFGPIO_PORTAP /* port pin data */ +#define MCFGPIO_SETR MCFGPIO_SETA /* set output */ +#define MCFGPIO_CLRR MCFGPIO_CLRA /* clr output */ + +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE +#define MCFGPIO_PIN_MAX 180 + + /* * Derek Cheung - 6 Feb 2005 * add I2C and QSPI register definition using Freescale's MCF5282 diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68knommu/platform/528x/Makefile index 26135d92b34..3d90e6d9245 100644 --- a/arch/m68knommu/platform/528x/Makefile +++ b/arch/m68knommu/platform/528x/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/528x/gpio.c b/arch/m68knommu/platform/528x/gpio.c new file mode 100644 index 00000000000..ec593950696 --- /dev/null +++ b/arch/m68knommu/platform/528x/gpio.c @@ -0,0 +1,438 @@ +/* + * 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 = "NQ", + .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, + .base = 1, + .ngpio = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "TA", + .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_fast, + .base = 8, + .ngpio = 4, + }, + .pddr = MCFGPTA_GPTDDR, + .podr = MCFGPTA_GPTPORT, + .ppdr = MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "TB", + .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_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = MCFGPTB_GPTDDR, + .podr = MCFGPTB_GPTPORT, + .ppdr = MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "QA", + .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_fast, + .base = 24, + .ngpio = 4, + }, + .pddr = MCFQADC_DDRQA, + .podr = MCFQADC_PORTQA, + .ppdr = MCFQADC_PORTQA, + }, + { + .gpio_chip = { + .label = "QB", + .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_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = MCFQADC_DDRQB, + .podr = MCFQADC_PORTQB, + .ppdr = MCFQADC_PORTQB, + }, + { + .gpio_chip = { + .label = "A", + .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_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRA, + .podr = MCFGPIO_PORTA, + .ppdr = MCFGPIO_PORTAP, + .setr = MCFGPIO_SETA, + .clrr = MCFGPIO_CLRA, + }, + { + .gpio_chip = { + .label = "B", + .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_fast, + .base = 48, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRB, + .podr = MCFGPIO_PORTB, + .ppdr = MCFGPIO_PORTBP, + .setr = MCFGPIO_SETB, + .clrr = MCFGPIO_CLRB, + }, + { + .gpio_chip = { + .label = "C", + .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_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRC, + .podr = MCFGPIO_PORTC, + .ppdr = MCFGPIO_PORTCP, + .setr = MCFGPIO_SETC, + .clrr = MCFGPIO_CLRC, + }, + { + .gpio_chip = { + .label = "D", + .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_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRD, + .podr = MCFGPIO_PORTD, + .ppdr = MCFGPIO_PORTDP, + .setr = MCFGPIO_SETD, + .clrr = MCFGPIO_CLRD, + }, + { + .gpio_chip = { + .label = "E", + .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_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRE, + .podr = MCFGPIO_PORTE, + .ppdr = MCFGPIO_PORTEP, + .setr = MCFGPIO_SETE, + .clrr = MCFGPIO_CLRE, + }, + { + .gpio_chip = { + .label = "F", + .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_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRF, + .podr = MCFGPIO_PORTF, + .ppdr = MCFGPIO_PORTFP, + .setr = MCFGPIO_SETF, + .clrr = MCFGPIO_CLRF, + }, + { + .gpio_chip = { + .label = "G", + .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_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRG, + .podr = MCFGPIO_PORTG, + .ppdr = MCFGPIO_PORTGP, + .setr = MCFGPIO_SETG, + .clrr = MCFGPIO_CLRG, + }, + { + .gpio_chip = { + .label = "H", + .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_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRH, + .podr = MCFGPIO_PORTH, + .ppdr = MCFGPIO_PORTHP, + .setr = MCFGPIO_SETH, + .clrr = MCFGPIO_CLRH, + }, + { + .gpio_chip = { + .label = "J", + .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_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRJ, + .podr = MCFGPIO_PORTJ, + .ppdr = MCFGPIO_PORTJP, + .setr = MCFGPIO_SETJ, + .clrr = MCFGPIO_CLRJ, + }, + { + .gpio_chip = { + .label = "DD", + .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_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDRDD, + .podr = MCFGPIO_PORTDD, + .ppdr = MCFGPIO_PORTDDP, + .setr = MCFGPIO_SETDD, + .clrr = MCFGPIO_CLRDD, + }, + { + .gpio_chip = { + .label = "EH", + .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_fast, + .base = 120, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDREH, + .podr = MCFGPIO_PORTEH, + .ppdr = MCFGPIO_PORTEHP, + .setr = MCFGPIO_SETEH, + .clrr = MCFGPIO_CLREH, + }, + { + .gpio_chip = { + .label = "EL", + .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_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = MCFGPIO_DDREL, + .podr = MCFGPIO_PORTEL, + .ppdr = MCFGPIO_PORTELP, + .setr = MCFGPIO_SETEL, + .clrr = MCFGPIO_CLREL, + }, + { + .gpio_chip = { + .label = "AS", + .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_fast, + .base = 136, + .ngpio = 6, + }, + .pddr = MCFGPIO_DDRAS, + .podr = MCFGPIO_PORTAS, + .ppdr = MCFGPIO_PORTASP, + .setr = MCFGPIO_SETAS, + .clrr = MCFGPIO_CLRAS, + }, + { + .gpio_chip = { + .label = "QS", + .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_fast, + .base = 144, + .ngpio = 7, + }, + .pddr = MCFGPIO_DDRQS, + .podr = MCFGPIO_PORTQS, + .ppdr = MCFGPIO_PORTQSP, + .setr = MCFGPIO_SETQS, + .clrr = MCFGPIO_CLRQS, + }, + { + .gpio_chip = { + .label = "SD", + .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_fast, + .base = 152, + .ngpio = 6, + }, + .pddr = MCFGPIO_DDRSD, + .podr = MCFGPIO_PORTSD, + .ppdr = MCFGPIO_PORTSDP, + .setr = MCFGPIO_SETSD, + .clrr = MCFGPIO_CLRSD, + }, + { + .gpio_chip = { + .label = "TC", + .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_fast, + .base = 160, + .ngpio = 4, + }, + .pddr = MCFGPIO_DDRTC, + .podr = MCFGPIO_PORTTC, + .ppdr = MCFGPIO_PORTTCP, + .setr = MCFGPIO_SETTC, + .clrr = MCFGPIO_CLRTC, + }, + { + .gpio_chip = { + .label = "TD", + .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_fast, + .base = 168, + .ngpio = 4, + }, + .pddr = MCFGPIO_DDRTD, + .podr = MCFGPIO_PORTTD, + .ppdr = MCFGPIO_PORTTDP, + .setr = MCFGPIO_SETTD, + .clrr = MCFGPIO_CLRTD, + }, + { + .gpio_chip = { + .label = "UA", + .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_fast, + .base = 176, + .ngpio = 4, + }, + .pddr = MCFGPIO_DDRUA, + .podr = MCFGPIO_PORTUA, + .ppdr = MCFGPIO_PORTUAP, + .setr = MCFGPIO_SETUA, + .clrr = MCFGPIO_CLRUA, + }, +}; + +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-70-g09d2 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/m68k/include/asm/m5307sim.h | 11 ++++++-- arch/m68knommu/platform/5307/Makefile | 2 +- arch/m68knommu/platform/5307/gpio.c | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 arch/m68knommu/platform/5307/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index 5886728409c..6a1870c925a 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -90,8 +90,15 @@ #define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ #define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ -#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x244) +#define MCFSIM_PADAT (MCF_MBAR + 0x248) + +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 16 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /* Definition offset address for CS2-7 -- old mask 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-70-g09d2 From 7846fe800a81adae1e28d9d035b5226f75358280 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:10 -0700 Subject: generic GPIO support for the Freescale Coldfire 532x. Add support for the 532x. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m532xsim.h | 154 +++++++++------- arch/m68knommu/platform/532x/Makefile | 2 +- arch/m68knommu/platform/532x/config.c | 4 +- arch/m68knommu/platform/532x/gpio.c | 337 ++++++++++++++++++++++++++++++++++ 4 files changed, 424 insertions(+), 73 deletions(-) create mode 100644 arch/m68knommu/platform/532x/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index eb7fd444894..3e80810b378 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -422,70 +422,70 @@ *********************************************************************/ /* Register read/write macros */ -#define MCF_GPIO_PODR_FECH MCF_REG08(0xFC0A4000) -#define MCF_GPIO_PODR_FECL MCF_REG08(0xFC0A4001) -#define MCF_GPIO_PODR_SSI MCF_REG08(0xFC0A4002) -#define MCF_GPIO_PODR_BUSCTL MCF_REG08(0xFC0A4003) -#define MCF_GPIO_PODR_BE MCF_REG08(0xFC0A4004) -#define MCF_GPIO_PODR_CS MCF_REG08(0xFC0A4005) -#define MCF_GPIO_PODR_PWM MCF_REG08(0xFC0A4006) -#define MCF_GPIO_PODR_FECI2C MCF_REG08(0xFC0A4007) -#define MCF_GPIO_PODR_UART MCF_REG08(0xFC0A4009) -#define MCF_GPIO_PODR_QSPI MCF_REG08(0xFC0A400A) -#define MCF_GPIO_PODR_TIMER MCF_REG08(0xFC0A400B) -#define MCF_GPIO_PODR_LCDDATAH MCF_REG08(0xFC0A400D) -#define MCF_GPIO_PODR_LCDDATAM MCF_REG08(0xFC0A400E) -#define MCF_GPIO_PODR_LCDDATAL MCF_REG08(0xFC0A400F) -#define MCF_GPIO_PODR_LCDCTLH MCF_REG08(0xFC0A4010) -#define MCF_GPIO_PODR_LCDCTLL MCF_REG08(0xFC0A4011) -#define MCF_GPIO_PDDR_FECH MCF_REG08(0xFC0A4014) -#define MCF_GPIO_PDDR_FECL MCF_REG08(0xFC0A4015) -#define MCF_GPIO_PDDR_SSI MCF_REG08(0xFC0A4016) -#define MCF_GPIO_PDDR_BUSCTL MCF_REG08(0xFC0A4017) -#define MCF_GPIO_PDDR_BE MCF_REG08(0xFC0A4018) -#define MCF_GPIO_PDDR_CS MCF_REG08(0xFC0A4019) -#define MCF_GPIO_PDDR_PWM MCF_REG08(0xFC0A401A) -#define MCF_GPIO_PDDR_FECI2C MCF_REG08(0xFC0A401B) -#define MCF_GPIO_PDDR_UART MCF_REG08(0xFC0A401C) -#define MCF_GPIO_PDDR_QSPI MCF_REG08(0xFC0A401E) -#define MCF_GPIO_PDDR_TIMER MCF_REG08(0xFC0A401F) -#define MCF_GPIO_PDDR_LCDDATAH MCF_REG08(0xFC0A4021) -#define MCF_GPIO_PDDR_LCDDATAM MCF_REG08(0xFC0A4022) -#define MCF_GPIO_PDDR_LCDDATAL MCF_REG08(0xFC0A4023) -#define MCF_GPIO_PDDR_LCDCTLH MCF_REG08(0xFC0A4024) -#define MCF_GPIO_PDDR_LCDCTLL MCF_REG08(0xFC0A4025) -#define MCF_GPIO_PPDSDR_FECH MCF_REG08(0xFC0A4028) -#define MCF_GPIO_PPDSDR_FECL MCF_REG08(0xFC0A4029) -#define MCF_GPIO_PPDSDR_SSI MCF_REG08(0xFC0A402A) -#define MCF_GPIO_PPDSDR_BUSCTL MCF_REG08(0xFC0A402B) -#define MCF_GPIO_PPDSDR_BE MCF_REG08(0xFC0A402C) -#define MCF_GPIO_PPDSDR_CS MCF_REG08(0xFC0A402D) -#define MCF_GPIO_PPDSDR_PWM MCF_REG08(0xFC0A402E) -#define MCF_GPIO_PPDSDR_FECI2C MCF_REG08(0xFC0A402F) -#define MCF_GPIO_PPDSDR_UART MCF_REG08(0xFC0A4031) -#define MCF_GPIO_PPDSDR_QSPI MCF_REG08(0xFC0A4032) -#define MCF_GPIO_PPDSDR_TIMER MCF_REG08(0xFC0A4033) -#define MCF_GPIO_PPDSDR_LCDDATAH MCF_REG08(0xFC0A4035) -#define MCF_GPIO_PPDSDR_LCDDATAM MCF_REG08(0xFC0A4036) -#define MCF_GPIO_PPDSDR_LCDDATAL MCF_REG08(0xFC0A4037) -#define MCF_GPIO_PPDSDR_LCDCTLH MCF_REG08(0xFC0A4038) -#define MCF_GPIO_PPDSDR_LCDCTLL MCF_REG08(0xFC0A4039) -#define MCF_GPIO_PCLRR_FECH MCF_REG08(0xFC0A403C) -#define MCF_GPIO_PCLRR_FECL MCF_REG08(0xFC0A403D) -#define MCF_GPIO_PCLRR_SSI MCF_REG08(0xFC0A403E) -#define MCF_GPIO_PCLRR_BUSCTL MCF_REG08(0xFC0A403F) -#define MCF_GPIO_PCLRR_BE MCF_REG08(0xFC0A4040) -#define MCF_GPIO_PCLRR_CS MCF_REG08(0xFC0A4041) -#define MCF_GPIO_PCLRR_PWM MCF_REG08(0xFC0A4042) -#define MCF_GPIO_PCLRR_FECI2C MCF_REG08(0xFC0A4043) -#define MCF_GPIO_PCLRR_UART MCF_REG08(0xFC0A4045) -#define MCF_GPIO_PCLRR_QSPI MCF_REG08(0xFC0A4046) -#define MCF_GPIO_PCLRR_TIMER MCF_REG08(0xFC0A4047) -#define MCF_GPIO_PCLRR_LCDDATAH MCF_REG08(0xFC0A4049) -#define MCF_GPIO_PCLRR_LCDDATAM MCF_REG08(0xFC0A404A) -#define MCF_GPIO_PCLRR_LCDDATAL MCF_REG08(0xFC0A404B) -#define MCF_GPIO_PCLRR_LCDCTLH MCF_REG08(0xFC0A404C) -#define MCF_GPIO_PCLRR_LCDCTLL MCF_REG08(0xFC0A404D) +#define MCFGPIO_PODR_FECH (0xFC0A4000) +#define MCFGPIO_PODR_FECL (0xFC0A4001) +#define MCFGPIO_PODR_SSI (0xFC0A4002) +#define MCFGPIO_PODR_BUSCTL (0xFC0A4003) +#define MCFGPIO_PODR_BE (0xFC0A4004) +#define MCFGPIO_PODR_CS (0xFC0A4005) +#define MCFGPIO_PODR_PWM (0xFC0A4006) +#define MCFGPIO_PODR_FECI2C (0xFC0A4007) +#define MCFGPIO_PODR_UART (0xFC0A4009) +#define MCFGPIO_PODR_QSPI (0xFC0A400A) +#define MCFGPIO_PODR_TIMER (0xFC0A400B) +#define MCFGPIO_PODR_LCDDATAH (0xFC0A400D) +#define MCFGPIO_PODR_LCDDATAM (0xFC0A400E) +#define MCFGPIO_PODR_LCDDATAL (0xFC0A400F) +#define MCFGPIO_PODR_LCDCTLH (0xFC0A4010) +#define MCFGPIO_PODR_LCDCTLL (0xFC0A4011) +#define MCFGPIO_PDDR_FECH (0xFC0A4014) +#define MCFGPIO_PDDR_FECL (0xFC0A4015) +#define MCFGPIO_PDDR_SSI (0xFC0A4016) +#define MCFGPIO_PDDR_BUSCTL (0xFC0A4017) +#define MCFGPIO_PDDR_BE (0xFC0A4018) +#define MCFGPIO_PDDR_CS (0xFC0A4019) +#define MCFGPIO_PDDR_PWM (0xFC0A401A) +#define MCFGPIO_PDDR_FECI2C (0xFC0A401B) +#define MCFGPIO_PDDR_UART (0xFC0A401C) +#define MCFGPIO_PDDR_QSPI (0xFC0A401E) +#define MCFGPIO_PDDR_TIMER (0xFC0A401F) +#define MCFGPIO_PDDR_LCDDATAH (0xFC0A4021) +#define MCFGPIO_PDDR_LCDDATAM (0xFC0A4022) +#define MCFGPIO_PDDR_LCDDATAL (0xFC0A4023) +#define MCFGPIO_PDDR_LCDCTLH (0xFC0A4024) +#define MCFGPIO_PDDR_LCDCTLL (0xFC0A4025) +#define MCFGPIO_PPDSDR_FECH (0xFC0A4028) +#define MCFGPIO_PPDSDR_FECL (0xFC0A4029) +#define MCFGPIO_PPDSDR_SSI (0xFC0A402A) +#define MCFGPIO_PPDSDR_BUSCTL (0xFC0A402B) +#define MCFGPIO_PPDSDR_BE (0xFC0A402C) +#define MCFGPIO_PPDSDR_CS (0xFC0A402D) +#define MCFGPIO_PPDSDR_PWM (0xFC0A402E) +#define MCFGPIO_PPDSDR_FECI2C (0xFC0A402F) +#define MCFGPIO_PPDSDR_UART (0xFC0A4031) +#define MCFGPIO_PPDSDR_QSPI (0xFC0A4032) +#define MCFGPIO_PPDSDR_TIMER (0xFC0A4033) +#define MCFGPIO_PPDSDR_LCDDATAH (0xFC0A4035) +#define MCFGPIO_PPDSDR_LCDDATAM (0xFC0A4036) +#define MCFGPIO_PPDSDR_LCDDATAL (0xFC0A4037) +#define MCFGPIO_PPDSDR_LCDCTLH (0xFC0A4038) +#define MCFGPIO_PPDSDR_LCDCTLL (0xFC0A4039) +#define MCFGPIO_PCLRR_FECH (0xFC0A403C) +#define MCFGPIO_PCLRR_FECL (0xFC0A403D) +#define MCFGPIO_PCLRR_SSI (0xFC0A403E) +#define MCFGPIO_PCLRR_BUSCTL (0xFC0A403F) +#define MCFGPIO_PCLRR_BE (0xFC0A4040) +#define MCFGPIO_PCLRR_CS (0xFC0A4041) +#define MCFGPIO_PCLRR_PWM (0xFC0A4042) +#define MCFGPIO_PCLRR_FECI2C (0xFC0A4043) +#define MCFGPIO_PCLRR_UART (0xFC0A4045) +#define MCFGPIO_PCLRR_QSPI (0xFC0A4046) +#define MCFGPIO_PCLRR_TIMER (0xFC0A4047) +#define MCFGPIO_PCLRR_LCDDATAH (0xFC0A4049) +#define MCFGPIO_PCLRR_LCDDATAM (0xFC0A404A) +#define MCFGPIO_PCLRR_LCDDATAL (0xFC0A404B) +#define MCFGPIO_PCLRR_LCDCTLH (0xFC0A404C) +#define MCFGPIO_PCLRR_LCDCTLL (0xFC0A404D) #define MCF_GPIO_PAR_FEC MCF_REG08(0xFC0A4050) #define MCF_GPIO_PAR_PWM MCF_REG08(0xFC0A4051) #define MCF_GPIO_PAR_BUSCTL MCF_REG08(0xFC0A4052) @@ -1187,6 +1187,20 @@ /* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */ #define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x) (((x)&0x03)<<0) +/* + * Generic GPIO support + */ +#define MCFGPIO_PODR MCFGPIO_PODR_FECH +#define MCFGPIO_PDDR MCFGPIO_PDDR_FECH +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_FECH +#define MCFGPIO_SETR MCFGPIO_PPDSDR_FECH +#define MCFGPIO_CLRR MCFGPIO_PCLRR_FECH + +#define MCFGPIO_PIN_MAX 136 +#define MCFGPIO_IRQ_MAX 8 +#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE + + /********************************************************************* * * Interrupt Controller (INTC) @@ -2154,12 +2168,12 @@ *********************************************************************/ /* Register read/write macros */ -#define MCF_EPORT_EPPAR MCF_REG16(0xFC094000) -#define MCF_EPORT_EPDDR MCF_REG08(0xFC094002) -#define MCF_EPORT_EPIER MCF_REG08(0xFC094003) -#define MCF_EPORT_EPDR MCF_REG08(0xFC094004) -#define MCF_EPORT_EPPDR MCF_REG08(0xFC094005) -#define MCF_EPORT_EPFR MCF_REG08(0xFC094006) +#define MCFEPORT_EPPAR (0xFC094000) +#define MCFEPORT_EPDDR (0xFC094002) +#define MCFEPORT_EPIER (0xFC094003) +#define MCFEPORT_EPDR (0xFC094004) +#define MCFEPORT_EPPDR (0xFC094005) +#define MCFEPORT_EPFR (0xFC094006) /* Bit definitions and macros for MCF_EPORT_EPPAR */ #define MCF_EPORT_EPPAR_EPPA1(x) (((x)&0x0003)<<2) diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile index e431912f562..4cc23245bcd 100644 --- a/arch/m68knommu/platform/532x/Makefile +++ b/arch/m68knommu/platform/532x/Makefile @@ -15,4 +15,4 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 #obj-y := config.o usb-mcf532x.o spi-mcf532x.o -obj-y := config.o +obj-y := config.o gpio.o diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c index cdb761971f7..28eb9ea55f4 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68knommu/platform/532x/config.c @@ -438,8 +438,8 @@ void gpio_init(void) /* Initialize TIN3 as a GPIO output to enable the write half of the latch */ MCF_GPIO_PAR_TIMER = 0x00; - MCF_GPIO_PDDR_TIMER = 0x08; - MCF_GPIO_PCLRR_TIMER = 0x0; + __raw_writeb(0x08, MCFGPIO_PDDR_TIMER); + __raw_writeb(0x00, MCFGPIO_PCLRR_TIMER); } diff --git a/arch/m68knommu/platform/532x/gpio.c b/arch/m68knommu/platform/532x/gpio.c new file mode 100644 index 00000000000..184b77382c3 --- /dev/null +++ b/arch/m68knommu/platform/532x/gpio.c @@ -0,0 +1,337 @@ +/* + * 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 = "PIRQ", + .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 = 8, + }, + .pddr = MCFEPORT_EPDDR, + .podr = MCFEPORT_EPDR, + .ppdr = MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "FECH", + .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_fast, + .base = 8, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECH, + .podr = MCFGPIO_PODR_FECH, + .ppdr = MCFGPIO_PPDSDR_FECH, + .setr = MCFGPIO_PPDSDR_FECH, + .clrr = MCFGPIO_PCLRR_FECH, + }, + { + .gpio_chip = { + .label = "FECL", + .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_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_FECL, + .podr = MCFGPIO_PODR_FECL, + .ppdr = MCFGPIO_PPDSDR_FECL, + .setr = MCFGPIO_PPDSDR_FECL, + .clrr = MCFGPIO_PCLRR_FECL, + }, + { + .gpio_chip = { + .label = "SSI", + .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_fast, + .base = 24, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_SSI, + .podr = MCFGPIO_PODR_SSI, + .ppdr = MCFGPIO_PPDSDR_SSI, + .setr = MCFGPIO_PPDSDR_SSI, + .clrr = MCFGPIO_PCLRR_SSI, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .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_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BUSCTL, + .podr = MCFGPIO_PODR_BUSCTL, + .ppdr = MCFGPIO_PPDSDR_BUSCTL, + .setr = MCFGPIO_PPDSDR_BUSCTL, + .clrr = MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BE", + .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_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_BE, + .podr = MCFGPIO_PODR_BE, + .ppdr = MCFGPIO_PPDSDR_BE, + .setr = MCFGPIO_PPDSDR_BE, + .clrr = MCFGPIO_PCLRR_BE, + }, + { + .gpio_chip = { + .label = "CS", + .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_fast, + .base = 49, + .ngpio = 5, + }, + .pddr = MCFGPIO_PDDR_CS, + .podr = MCFGPIO_PODR_CS, + .ppdr = MCFGPIO_PPDSDR_CS, + .setr = MCFGPIO_PPDSDR_CS, + .clrr = MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "PWM", + .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_fast, + .base = 58, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_PWM, + .podr = MCFGPIO_PODR_PWM, + .ppdr = MCFGPIO_PPDSDR_PWM, + .setr = MCFGPIO_PPDSDR_PWM, + .clrr = MCFGPIO_PCLRR_PWM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .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_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_FECI2C, + .podr = MCFGPIO_PODR_FECI2C, + .ppdr = MCFGPIO_PPDSDR_FECI2C, + .setr = MCFGPIO_PPDSDR_FECI2C, + .clrr = MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UART", + .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_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_UART, + .podr = MCFGPIO_PODR_UART, + .ppdr = MCFGPIO_PPDSDR_UART, + .setr = MCFGPIO_PPDSDR_UART, + .clrr = MCFGPIO_PCLRR_UART, + }, + { + .gpio_chip = { + .label = "QSPI", + .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_fast, + .base = 80, + .ngpio = 6, + }, + .pddr = MCFGPIO_PDDR_QSPI, + .podr = MCFGPIO_PODR_QSPI, + .ppdr = MCFGPIO_PPDSDR_QSPI, + .setr = MCFGPIO_PPDSDR_QSPI, + .clrr = MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .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_fast, + .base = 88, + .ngpio = 4, + }, + .pddr = MCFGPIO_PDDR_TIMER, + .podr = MCFGPIO_PODR_TIMER, + .ppdr = MCFGPIO_PPDSDR_TIMER, + .setr = MCFGPIO_PPDSDR_TIMER, + .clrr = MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "LCDDATAH", + .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_fast, + .base = 96, + .ngpio = 2, + }, + .pddr = MCFGPIO_PDDR_LCDDATAH, + .podr = MCFGPIO_PODR_LCDDATAH, + .ppdr = MCFGPIO_PPDSDR_LCDDATAH, + .setr = MCFGPIO_PPDSDR_LCDDATAH, + .clrr = MCFGPIO_PCLRR_LCDDATAH, + }, + { + .gpio_chip = { + .label = "LCDDATAM", + .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_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_LCDDATAM, + .podr = MCFGPIO_PODR_LCDDATAM, + .ppdr = MCFGPIO_PPDSDR_LCDDATAM, + .setr = MCFGPIO_PPDSDR_LCDDATAM, + .clrr = MCFGPIO_PCLRR_LCDDATAM, + }, + { + .gpio_chip = { + .label = "LCDDATAL", + .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_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_LCDDATAL, + .podr = MCFGPIO_PODR_LCDDATAL, + .ppdr = MCFGPIO_PPDSDR_LCDDATAL, + .setr = MCFGPIO_PPDSDR_LCDDATAL, + .clrr = MCFGPIO_PCLRR_LCDDATAL, + }, + { + .gpio_chip = { + .label = "LCDCTLH", + .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_fast, + .base = 120, + .ngpio = 1, + }, + .pddr = MCFGPIO_PDDR_LCDCTLH, + .podr = MCFGPIO_PODR_LCDCTLH, + .ppdr = MCFGPIO_PPDSDR_LCDCTLH, + .setr = MCFGPIO_PPDSDR_LCDCTLH, + .clrr = MCFGPIO_PCLRR_LCDCTLH, + }, + { + .gpio_chip = { + .label = "LCDCTLL", + .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_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = MCFGPIO_PDDR_LCDCTLL, + .podr = MCFGPIO_PODR_LCDCTLL, + .ppdr = MCFGPIO_PPDSDR_LCDCTLL, + .setr = MCFGPIO_PPDSDR_LCDCTLL, + .clrr = MCFGPIO_PCLRR_LCDCTLL, + }, +}; + +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-70-g09d2 From dca7cf33bb5c98187ffcc849652b1b2c4c8a0c25 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:11 -0700 Subject: generic GPIO support for the Freescale Coldfire 5407. Add support for the 5407. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m5407sim.h | 10 +++++-- arch/m68knommu/platform/5407/Makefile | 2 +- arch/m68knommu/platform/5407/gpio.c | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 arch/m68knommu/platform/5407/gpio.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index cc22c4a5300..25194756b43 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -73,9 +73,15 @@ #define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ #define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ -#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ +#define MCFSIM_PADDR (MCF_MBAR + 0x244) +#define MCFSIM_PADAT (MCF_MBAR + 0x248) +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 16 +#define MCFGPIO_IRQ_MAX -1 +#define MCFGPIO_IRQ_VECBASE -1 /* * Some symbol defines for the above... diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile index e6035e7a2d3..dee62c5dbaa 100644 --- a/arch/m68knommu/platform/5407/Makefile +++ b/arch/m68knommu/platform/5407/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/5407/gpio.c b/arch/m68knommu/platform/5407/gpio.c new file mode 100644 index 00000000000..8da5880e406 --- /dev/null +++ b/arch/m68knommu/platform/5407/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-70-g09d2 From 732c611e5bbb76201397297f834dddd5ab684b05 Mon Sep 17 00:00:00 2001 From: "sfking@fdwdc.com" Date: Fri, 19 Jun 2009 18:11:12 -0700 Subject: generic GPIO support misc files. The definition of MCFSIM_PADDR and MCFSIM_PADAT now has MCF_BAR already added in. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/mcfsmc.h | 6 +++--- arch/m68k/include/asm/nettel.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/mcfsmc.h b/arch/m68k/include/asm/mcfsmc.h index 2d7a4dbd968..527bea5d678 100644 --- a/arch/m68k/include/asm/mcfsmc.h +++ b/arch/m68k/include/asm/mcfsmc.h @@ -167,15 +167,15 @@ void smc_remap(unsigned int ioaddr) static int once = 0; extern unsigned short ppdata; if (once++ == 0) { - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec; + *((volatile unsigned short *)MCFSIM_PADDR) = 0x00ec; ppdata |= 0x0080; - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; + *((volatile unsigned short *)MCFSIM_PADAT) = ppdata; outw(0x0001, ioaddr + BANK_SELECT); outw(0x0001, ioaddr + BANK_SELECT); outw(0x0067, ioaddr + BASE); ppdata &= ~0x0080; - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; + *((volatile unsigned short *)MCFSIM_PADAT) = ppdata; } *((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180; diff --git a/arch/m68k/include/asm/nettel.h b/arch/m68k/include/asm/nettel.h index 0299f6a2dee..4dec2d9fb99 100644 --- a/arch/m68k/include/asm/nettel.h +++ b/arch/m68k/include/asm/nettel.h @@ -48,14 +48,14 @@ extern volatile unsigned short ppdata; static __inline__ unsigned int mcf_getppdata(void) { volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); + pp = (volatile unsigned short *) MCFSIM_PADAT; return((unsigned int) *pp); } static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits) { volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); + pp = (volatile unsigned short *) MCFSIM_PADAT; ppdata = (ppdata & ~mask) | bits; *pp = ppdata; } -- cgit v1.2.3-70-g09d2 From f3aa42c6b26f502f6502ea2e07908d5768a3dd35 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Sat, 4 Jul 2009 00:13:57 +1000 Subject: m68k: remove unused elia.h include file Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/elia.h | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 arch/m68k/include/asm/elia.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/elia.h b/arch/m68k/include/asm/elia.h deleted file mode 100644 index e037d4e2de3..00000000000 --- a/arch/m68k/include/asm/elia.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************/ - -/* - * elia.h -- Lineo (formerly Moreton Bay) eLIA platform support. - * - * (C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au) - * (C) Copyright 1999-2000, Lineo (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef elia_h -#define elia_h -/****************************************************************************/ - -#include - -#ifdef CONFIG_eLIA - -/* - * The serial port DTR and DCD lines are also on the Parallel I/O - * as well, so define those too. - */ - -#define eLIA_DCD1 0x0001 -#define eLIA_DCD0 0x0002 -#define eLIA_DTR1 0x0004 -#define eLIA_DTR0 0x0008 - -#define eLIA_PCIRESET 0x0020 - -/* - * Kernel macros to set and unset the LEDs. - */ -#ifndef __ASSEMBLY__ -extern unsigned short ppdata; -#endif /* __ASSEMBLY__ */ - -#endif /* CONFIG_eLIA */ - -/****************************************************************************/ -#endif /* elia_h */ -- cgit v1.2.3-70-g09d2 From d668bf0a0d73daea4eaaf748435752f52cc077aa Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 4 Aug 2009 16:52:44 +0200 Subject: m68knommu: convert to asm-generic/hardirq.h Signed-off-by: Christoph Hellwig Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/hardirq_no.h | 10 +--------- arch/m68knommu/kernel/irq.c | 5 ----- 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/hardirq_no.h b/arch/m68k/include/asm/hardirq_no.h index bfad28149a4..b44b14be87d 100644 --- a/arch/m68k/include/asm/hardirq_no.h +++ b/arch/m68k/include/asm/hardirq_no.h @@ -1,16 +1,8 @@ #ifndef __M68K_HARDIRQ_H #define __M68K_HARDIRQ_H -#include -#include #include -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include /* Standard mappings for irq_cpustat_t above */ - #define HARDIRQ_BITS 8 /* @@ -22,6 +14,6 @@ typedef struct { # error HARDIRQ_BITS is too low! #endif -void ack_bad_irq(unsigned int irq); +#include #endif /* __M68K_HARDIRQ_H */ diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c index 56e0f4c55a6..9e0c100447c 100644 --- a/arch/m68knommu/kernel/irq.c +++ b/arch/m68knommu/kernel/irq.c @@ -29,11 +29,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) set_irq_regs(oldregs); } -void ack_bad_irq(unsigned int irq) -{ - printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq); -} - static struct irq_chip m_irq_chip = { .name = "M68K-INTC", .enable = enable_vector, -- cgit v1.2.3-70-g09d2 From 633ea5d78b8b01ba903aeaae10297033830a52dd Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 23 Apr 2009 11:03:20 +1000 Subject: m68k: merge mmu and non-mmu versions of processor.h The mmu and non-mmu versions of processor.h have a lot of common code. This is a strait forward merge. start_thread() could be improved, but that is not quite as strait forward, leaving for a follow on change. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/processor.h | 171 ++++++++++++++++++++++++++++++++++- arch/m68k/include/asm/processor_mm.h | 130 -------------------------- arch/m68k/include/asm/processor_no.h | 143 ----------------------------- 3 files changed, 168 insertions(+), 276 deletions(-) delete mode 100644 arch/m68k/include/asm/processor_mm.h delete mode 100644 arch/m68k/include/asm/processor_no.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index fc3f2c22f2b..74fd674b15a 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -1,5 +1,170 @@ -#ifdef __uClinux__ -#include "processor_no.h" +/* + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include +#include +#include +#include + +static inline unsigned long rdusp(void) +{ +#ifdef CONFIG_COLDFIRE + extern unsigned int sw_usp; + return sw_usp; #else -#include "processor_mm.h" + unsigned long usp; + __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); + return usp; +#endif +} + +static inline void wrusp(unsigned long usp) +{ +#ifdef CONFIG_COLDFIRE + extern unsigned int sw_usp; + sw_usp = usp; +#else + __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); +#endif +} + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#ifndef CONFIG_SUN3 +#define TASK_SIZE (0xF0000000UL) +#else +#define TASK_SIZE (0x0E000000UL) +#endif + +#ifdef __KERNEL__ +#define STACK_TOP TASK_SIZE +#define STACK_TOP_MAX STACK_TOP +#endif + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#ifdef CONFIG_MMU +#ifndef CONFIG_SUN3 +#define TASK_UNMAPPED_BASE 0xC0000000UL +#else +#define TASK_UNMAPPED_BASE 0x0A000000UL +#endif +#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) +#else +#define TASK_UNMAPPED_BASE 0 +#endif + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ + unsigned short fs; /* saved fs (sfc, dfc) */ + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long faddr; /* info about last fault */ + int signo, code; + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ + struct thread_info info; +}; + +#define INIT_THREAD { \ + .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ + .sr = PS_S, \ + .fs = __KERNEL_DS, \ + .info = INIT_THREAD_INFO(init_task), \ +} + +#ifdef CONFIG_MMU +/* + * Do necessary setup to start up a newly executed thread. + */ +static inline void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long usp) +{ + /* reads from user space */ + set_fs(USER_DS); + + regs->pc = pc; + regs->sr &= ~0x2000; + wrusp(usp); +} + +#else + +/* + * Coldfire stacks need to be re-aligned on trap exit, conventional + * 68k can handle this case cleanly. + */ +#ifdef CONFIG_COLDFIRE +#define reformat(_regs) do { (_regs)->format = 0x4; } while(0) +#else +#define reformat(_regs) do { } while (0) +#endif + +#define start_thread(_regs, _pc, _usp) \ +do { \ + set_fs(USER_DS); /* reads from user space */ \ + (_regs)->pc = (_pc); \ + ((struct switch_stack *)(_regs))[-1].a6 = 0; \ + reformat(_regs); \ + if (current->mm) \ + (_regs)->d5 = current->mm->start_data; \ + (_regs)->sr &= ~0x2000; \ + wrusp(_usp); \ +} while(0) + +#endif + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + (virt_addr_valid((tsk)->thread.esp0))) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() barrier() + #endif diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h deleted file mode 100644 index 1f61ef53f0e..00000000000 --- a/arch/m68k/include/asm/processor_mm.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * include/asm-m68k/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_M68K_PROCESSOR_H -#define __ASM_M68K_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include -#include -#include -#include - -static inline unsigned long rdusp(void) -{ - unsigned long usp; - - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); - return usp; -} - -static inline void wrusp(unsigned long usp) -{ - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#ifndef CONFIG_SUN3 -#define TASK_SIZE (0xF0000000UL) -#else -#define TASK_SIZE (0x0E000000UL) -#endif - -#ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX STACK_TOP -#endif - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#ifndef CONFIG_SUN3 -#define TASK_UNMAPPED_BASE 0xC0000000UL -#else -#define TASK_UNMAPPED_BASE 0x0A000000UL -#endif -#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned short sr; /* saved status register */ - unsigned short fs; /* saved fs (sfc, dfc) */ - unsigned long crp[2]; /* cpu root pointer */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long faddr; /* info about last fault */ - int signo, code; - unsigned long fp[8*3]; - unsigned long fpcntl[3]; /* fp control regs */ - unsigned char fpstate[FPSTATESIZE]; /* floating point state */ - struct thread_info info; -}; - -#define INIT_THREAD { \ - .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ - .sr = PS_S, \ - .fs = __KERNEL_DS, \ - .info = INIT_THREAD_INFO(init_task), \ -} - -/* - * Do necessary setup to start up a newly executed thread. - */ -static inline void start_thread(struct pt_regs * regs, unsigned long pc, - unsigned long usp) -{ - /* reads from user space */ - set_fs(USER_DS); - - regs->pc = pc; - regs->sr &= ~0x2000; - wrusp(usp); -} - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -extern unsigned long thread_saved_pc(struct task_struct *tsk); - -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - (virt_addr_valid((tsk)->thread.esp0))) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#endif diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h deleted file mode 100644 index 7a1e0ba35f5..00000000000 --- a/arch/m68k/include/asm/processor_no.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * include/asm-m68knommu/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_M68K_PROCESSOR_H -#define __ASM_M68K_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include -#include -#include -#include -#include -#include -#include - -static inline unsigned long rdusp(void) -{ -#ifdef CONFIG_COLDFIRE - extern unsigned int sw_usp; - return(sw_usp); -#else - unsigned long usp; - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); - return usp; -#endif -} - -static inline void wrusp(unsigned long usp) -{ -#ifdef CONFIG_COLDFIRE - extern unsigned int sw_usp; - sw_usp = usp; -#else - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); -#endif -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#define TASK_SIZE (0xF0000000UL) - -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. We won't be using it - */ -#define TASK_UNMAPPED_BASE 0 - -/* - * if you change this structure, you must change the code and offsets - * in m68k/machasm.S - */ - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned short sr; /* saved status register */ - unsigned short fs; /* saved fs (sfc, dfc) */ - unsigned long crp[2]; /* cpu root pointer */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long fp[8*3]; - unsigned long fpcntl[3]; /* fp control regs */ - unsigned char fpstate[FPSTATESIZE]; /* floating point state */ -}; - -#define INIT_THREAD { \ - .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ - .sr = PS_S, \ - .fs = __KERNEL_DS, \ -} - -/* - * Coldfire stacks need to be re-aligned on trap exit, conventional - * 68k can handle this case cleanly. - */ -#if defined(CONFIG_COLDFIRE) -#define reformat(_regs) do { (_regs)->format = 0x4; } while(0) -#else -#define reformat(_regs) do { } while (0) -#endif - -/* - * Do necessary setup to start up a newly executed thread. - * - * pass the data segment into user programs if it exists, - * it can't hurt anything as far as I can tell - */ -#define start_thread(_regs, _pc, _usp) \ -do { \ - set_fs(USER_DS); /* reads from user space */ \ - (_regs)->pc = (_pc); \ - ((struct switch_stack *)(_regs))[-1].a6 = 0; \ - reformat(_regs); \ - if (current->mm) \ - (_regs)->d5 = current->mm->start_data; \ - (_regs)->sr &= ~0x2000; \ - wrusp(_usp); \ -} while(0) - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -unsigned long thread_saved_pc(struct task_struct *tsk); -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - (virt_addr_valid((tsk)->thread.esp0))) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#endif -- cgit v1.2.3-70-g09d2 From 3ddc7e261a990d03fa4e78e37e6623ca45b18d77 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 26 Jun 2009 16:51:05 +1000 Subject: m68k: merge mmu and non-mmu versions of irq.h It is reasonably strait forward to merge the mmu and non-mmu versions of irq.h. Most of the defines and structs are not needed on non-mmu. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/irq.h | 135 ++++++++++++++++++++++++++++++++++++++++- arch/m68k/include/asm/irq_mm.h | 126 -------------------------------------- arch/m68k/include/asm/irq_no.h | 26 -------- 3 files changed, 132 insertions(+), 155 deletions(-) delete mode 100644 arch/m68k/include/asm/irq_mm.h delete mode 100644 arch/m68k/include/asm/irq_no.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index d031416595b..907eff1edd2 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -1,5 +1,134 @@ -#ifdef __uClinux__ -#include "irq_no.h" +#ifndef _M68K_IRQ_H_ +#define _M68K_IRQ_H_ + +/* + * This should be the same as the max(NUM_X_SOURCES) for all the + * different m68k hosts compiled into the kernel. + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +#if defined(CONFIG_COLDFIRE) +#define NR_IRQS 256 +#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) +#define NR_IRQS 200 +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) +#define NR_IRQS 72 +#elif defined(CONFIG_Q40) +#define NR_IRQS 43 +#elif defined(CONFIG_AMIGA) || !defined(CONFIG_MMU) +#define NR_IRQS 32 +#elif defined(CONFIG_APOLLO) +#define NR_IRQS 24 +#elif defined(CONFIG_HP300) +#define NR_IRQS 8 #else -#include "irq_mm.h" +#define NR_IRQS 0 #endif + +#ifdef CONFIG_MMU + +#include +#include +#include +#include + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +/* + * Interrupt source definitions + * General interrupt sources are the level 1-7. + * Adding an interrupt service routine for one of these sources + * results in the addition of that routine to a chain of routines. + * Each one is called in succession. Each individual interrupt + * service routine should determine if the device associated with + * that routine requires service. + */ + +#define IRQ_SPURIOUS 0 + +#define IRQ_AUTO_1 1 /* level 1 interrupt */ +#define IRQ_AUTO_2 2 /* level 2 interrupt */ +#define IRQ_AUTO_3 3 /* level 3 interrupt */ +#define IRQ_AUTO_4 4 /* level 4 interrupt */ +#define IRQ_AUTO_5 5 /* level 5 interrupt */ +#define IRQ_AUTO_6 6 /* level 6 interrupt */ +#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ + +#define IRQ_USER 8 + +extern unsigned int irq_canonicalize(unsigned int irq); + +struct pt_regs; + +/* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - IRQF_DISABLED and + * IRQF_SHARED are your friends. + */ +#ifndef MACH_AMIGA_ONLY +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ +#endif + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + irqreturn_t (*handler)(int, void *); + void *dev_id; + struct irq_node *next; + unsigned long flags; + const char *devname; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +struct irq_handler { + int (*handler)(int, void *); + unsigned long flags; + void *dev_id; + const char *devname; +}; + +struct irq_controller { + const char *name; + spinlock_t lock; + int (*startup)(unsigned int irq); + void (*shutdown)(unsigned int irq); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); +}; + +extern int m68k_irq_startup(unsigned int); +extern void m68k_irq_shutdown(unsigned int); + +/* + * This function returns a new irq_node_t + */ +extern irq_node_t *new_irq_node(void); + +extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); +extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, + void (*handler)(unsigned int, struct pt_regs *)); +extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); + +asmlinkage void m68k_handle_int(unsigned int); +asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); + +#else +#define irq_canonicalize(irq) (irq) +#endif /* CONFIG_MMU */ + +#endif /* _M68K_IRQ_H_ */ diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h deleted file mode 100644 index 0cab42cad79..00000000000 --- a/arch/m68k/include/asm/irq_mm.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef _M68K_IRQ_H_ -#define _M68K_IRQ_H_ - -#include -#include -#include -#include - -/* - * This should be the same as the max(NUM_X_SOURCES) for all the - * different m68k hosts compiled into the kernel. - * Currently the Atari has 72 and the Amiga 24, but if both are - * supported in the kernel it is better to make room for 72. - */ -#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) -#define NR_IRQS 200 -#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) -#define NR_IRQS 72 -#elif defined(CONFIG_Q40) -#define NR_IRQS 43 -#elif defined(CONFIG_AMIGA) -#define NR_IRQS 32 -#elif defined(CONFIG_APOLLO) -#define NR_IRQS 24 -#elif defined(CONFIG_HP300) -#define NR_IRQS 8 -#else -#define NR_IRQS 0 -#endif - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - -/* - * Interrupt source definitions - * General interrupt sources are the level 1-7. - * Adding an interrupt service routine for one of these sources - * results in the addition of that routine to a chain of routines. - * Each one is called in succession. Each individual interrupt - * service routine should determine if the device associated with - * that routine requires service. - */ - -#define IRQ_SPURIOUS 0 - -#define IRQ_AUTO_1 1 /* level 1 interrupt */ -#define IRQ_AUTO_2 2 /* level 2 interrupt */ -#define IRQ_AUTO_3 3 /* level 3 interrupt */ -#define IRQ_AUTO_4 4 /* level 4 interrupt */ -#define IRQ_AUTO_5 5 /* level 5 interrupt */ -#define IRQ_AUTO_6 6 /* level 6 interrupt */ -#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ - -#define IRQ_USER 8 - -extern unsigned int irq_canonicalize(unsigned int irq); - -struct pt_regs; - -/* - * various flags for request_irq() - the Amiga now uses the standard - * mechanism like all other architectures - IRQF_DISABLED and - * IRQF_SHARED are your friends. - */ -#ifndef MACH_AMIGA_ONLY -#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ -#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ -#define IRQ_FLG_FAST (0x0004) -#define IRQ_FLG_SLOW (0x0008) -#define IRQ_FLG_STD (0x8000) /* internally used */ -#endif - -/* - * This structure is used to chain together the ISRs for a particular - * interrupt source (if it supports chaining). - */ -typedef struct irq_node { - irqreturn_t (*handler)(int, void *); - void *dev_id; - struct irq_node *next; - unsigned long flags; - const char *devname; -} irq_node_t; - -/* - * This structure has only 4 elements for speed reasons - */ -struct irq_handler { - int (*handler)(int, void *); - unsigned long flags; - void *dev_id; - const char *devname; -}; - -struct irq_controller { - const char *name; - spinlock_t lock; - int (*startup)(unsigned int irq); - void (*shutdown)(unsigned int irq); - void (*enable)(unsigned int irq); - void (*disable)(unsigned int irq); -}; - -extern int m68k_irq_startup(unsigned int); -extern void m68k_irq_shutdown(unsigned int); - -/* - * This function returns a new irq_node_t - */ -extern irq_node_t *new_irq_node(void); - -extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); - -asmlinkage void m68k_handle_int(unsigned int); -asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); - -#endif /* _M68K_IRQ_H_ */ diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h deleted file mode 100644 index 9373c31ac87..00000000000 --- a/arch/m68k/include/asm/irq_no.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _M68KNOMMU_IRQ_H_ -#define _M68KNOMMU_IRQ_H_ - -#ifdef CONFIG_COLDFIRE -/* - * On the ColdFire we keep track of all vectors. That way drivers - * can register whatever vector number they wish, and we can deal - * with it. - */ -#define SYS_IRQS 256 -#define NR_IRQS SYS_IRQS - -#else - -/* - * # of m68k interrupts - */ -#define SYS_IRQS 8 -#define NR_IRQS (24 + SYS_IRQS) - -#endif /* CONFIG_COLDFIRE */ - - -#define irq_canonicalize(irq) (irq) - -#endif /* _M68KNOMMU_IRQ_H_ */ -- cgit v1.2.3-70-g09d2 From 6192c1ea0ac5806592c5c9cc2b2b94b0298df02b Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 2 Jul 2009 16:11:58 +1000 Subject: m68k: merge the mmu and non-mmu versions of checksum.h The mmu and non-mmu versions of checksum.h are mostly the same, merge them. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/checksum.h | 173 +++++++++++++++++++++++++++++++++++- arch/m68k/include/asm/checksum_mm.h | 148 ------------------------------ arch/m68k/include/asm/checksum_no.h | 132 --------------------------- arch/m68knommu/lib/checksum.c | 11 +-- 4 files changed, 171 insertions(+), 293 deletions(-) delete mode 100644 arch/m68k/include/asm/checksum_mm.h delete mode 100644 arch/m68k/include/asm/checksum_no.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 1cf54476745..ec514485c8b 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -1,5 +1,170 @@ -#ifdef __uClinux__ -#include "checksum_no.h" +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +#include + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern __wsum csum_partial_copy_from_user(const void __user *src, + void *dst, + int len, __wsum sum, + int *csum_err); + +extern __wsum csum_partial_copy_nocheck(const void *src, + void *dst, int len, + __wsum sum); + + +#ifdef CONFIG_COLDFIRE + +/* + * The ColdFire cores don't support all the 68k instructions used + * in the optimized checksum code below. So it reverts back to using + * more standard C coded checksums. The fast checksum code is + * significantly larger than the optimized version, so it is not + * inlined here. + */ +__sum16 ip_fast_csum(const void *iph, unsigned int ihl); + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp = (__force u32)sum; + + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + + return (__force __sum16)~tmp; +} + #else -#include "checksum_mm.h" -#endif + +/* + * This is a version of ip_fast_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum = 0; + unsigned long tmp; + + __asm__ ("subqw #1,%2\n" + "1:\t" + "movel %1@+,%3\n\t" + "addxl %3,%0\n\t" + "dbra %2,1b\n\t" + "movel %0,%3\n\t" + "swap %3\n\t" + "addxw %3,%0\n\t" + "clrw %3\n\t" + "addxw %3,%0\n\t" + : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) + : "0" (sum), "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)~sum; +} + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp = (__force u32)sum; + + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" + "addxw %1, %0" + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (tmp)); + + return (__force __sum16)~sum; +} + +#endif /* CONFIG_COLDFIRE */ + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__ ("addl %2,%0\n\t" + "addxl %3,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=d" (saddr) + : "g" (daddr), "1" (saddr), "d" (len + proto), + "0" (sum)); + return sum; +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) +{ + register unsigned long tmp; + __asm__("addl %2@,%0\n\t" + "movel %2@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(12),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@,%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(12),%1\n\t" + "addxl %1,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (tmp) + : "a" (saddr), "a" (daddr), "d" (len + proto), + "0" (sum)); + + return csum_fold(sum); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h deleted file mode 100644 index 494f9aec37e..00000000000 --- a/arch/m68k/include/asm/checksum_mm.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _M68K_CHECKSUM_H -#define _M68K_CHECKSUM_H - -#include - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, - void *dst, - int len, __wsum sum, - int *csum_err); - -extern __wsum csum_partial_copy_nocheck(const void *src, - void *dst, int len, - __wsum sum); - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum = 0; - unsigned long tmp; - - __asm__ ("subqw #1,%2\n" - "1:\t" - "movel %1@+,%3\n\t" - "addxl %3,%0\n\t" - "dbra %2,1b\n\t" - "movel %0,%3\n\t" - "swap %3\n\t" - "addxw %3,%0\n\t" - "clrw %3\n\t" - "addxw %3,%0\n\t" - : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) - : "0" (sum), "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)~sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; - __asm__("swap %1\n\t" - "addw %1, %0\n\t" - "clrw %1\n\t" - "addxw %1, %0" - : "=&d" (sum), "=&d" (tmp) - : "0" (sum), "1" (tmp)); - return (__force __sum16)~sum; -} - - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("addl %2,%0\n\t" - "addxl %3,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=d" (saddr) - : "g" (daddr), "1" (saddr), "d" (len + proto), - "0" (sum)); - return sum; -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) -{ - register unsigned long tmp; - __asm__("addl %2@,%0\n\t" - "movel %2@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(12),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@,%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(12),%1\n\t" - "addxl %1,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (tmp) - : "a" (saddr), "a" (daddr), "d" (len + proto), - "0" (sum)); - - return csum_fold(sum); -} - -#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h deleted file mode 100644 index 81883482ffb..00000000000 --- a/arch/m68k/include/asm/checksum_no.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _M68K_CHECKSUM_H -#define _M68K_CHECKSUM_H - -#include - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - - -/* - * the same as csum_partial_copy, but copies from user space. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, int *csum_err); - -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; -#ifdef CONFIG_COLDFIRE - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - return (__force __sum16)~tmp; -#else - __asm__("swap %1\n\t" - "addw %1, %0\n\t" - "clrw %1\n\t" - "addxw %1, %0" - : "=&d" (sum), "=&d" (tmp) - : "0" (sum), "1" (sum)); - return (__force __sum16)~sum; -#endif -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("addl %1,%0\n\t" - "addxl %4,%0\n\t" - "addxl %5,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (saddr) - : "0" (daddr), "1" (saddr), "d" (len + proto), - "d"(sum)); - return sum; -} - -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) -{ - register unsigned long tmp; - __asm__("addl %2@,%0\n\t" - "movel %2@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(12),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@,%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(12),%1\n\t" - "addxl %1,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (tmp) - : "a" (saddr), "a" (daddr), "d" (len + proto), - "0" (sum)); - - return csum_fold(sum); -} - -#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c index 269d83bfbbe..eccf25d3d73 100644 --- a/arch/m68knommu/lib/checksum.c +++ b/arch/m68knommu/lib/checksum.c @@ -92,6 +92,7 @@ out: return result; } +#ifdef CONFIG_COLDFIRE /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -100,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { return (__force __sum16)~do_csum(iph,ihl*4); } +#endif /* * computes the checksum of a memory block at buff, length len, @@ -126,15 +128,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum) EXPORT_SYMBOL(csum_partial); -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -__sum16 ip_compute_csum(const void *buff, int len) -{ - return (__force __sum16)~do_csum(buff,len); -} - /* * copy from fs while checksumming, otherwise like csum_partial */ -- cgit v1.2.3-70-g09d2 From cba89e231f97139dc6013030210624efd1087f68 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 12 Jun 2009 15:11:17 +1000 Subject: m68k: merge mmu and non-mmu versions of dma.h The non-mmu version of dma.h contains a lot of ColdFire specific DMA support, but also all of the base m68k support. So use the non-mmu version of dma.h for all. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/dma.h | 492 +++++++++++++++++++++++++++++++++++++++- arch/m68k/include/asm/dma_mm.h | 16 -- arch/m68k/include/asm/dma_no.h | 494 ----------------------------------------- 3 files changed, 489 insertions(+), 513 deletions(-) delete mode 100644 arch/m68k/include/asm/dma_mm.h delete mode 100644 arch/m68k/include/asm/dma_no.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index b82e660cf1c..3b85f6e6c09 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -1,5 +1,491 @@ -#ifdef __uClinux__ -#include "dma_no.h" +#ifndef _M68K_DMA_H +#define _M68K_DMA_H 1 + +#ifdef CONFIG_COLDFIRE +/* + * ColdFire DMA Model: + * ColdFire DMA supports two forms of DMA: Single and Dual address. Single + * address mode emits a source address, and expects that the device will either + * pick up the data (DMA READ) or source data (DMA WRITE). This implies that + * the device will place data on the correct byte(s) of the data bus, as the + * memory transactions are always 32 bits. This implies that only 32 bit + * devices will find single mode transfers useful. Dual address DMA mode + * performs two cycles: source read and destination write. ColdFire will + * align the data so that the device will always get the correct bytes, thus + * is useful for 8 and 16 bit devices. This is the mode that is supported + * below. + * + * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 + * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) + * + * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000 + * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) + * + * APR/18/2002 : added proper support for MCF5272 DMA controller. + * Arthur Shipkowski (art@videon-central.com) + */ + +#include +#include +#include + +/* + * Set number of channels of DMA on ColdFire for different implementations. + */ +#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ + defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +#define MAX_M68K_DMA_CHANNELS 4 +#elif defined(CONFIG_M5272) +#define MAX_M68K_DMA_CHANNELS 1 +#elif defined(CONFIG_M532x) +#define MAX_M68K_DMA_CHANNELS 0 #else -#include "dma_mm.h" +#define MAX_M68K_DMA_CHANNELS 2 #endif + +extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; +extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; + +#if !defined(CONFIG_M5272) +#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */ +#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */ +#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */ +#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */ + +/* I/O to memory, 8 bits, mode */ +#define DMA_MODE_READ 0 +/* memory to I/O, 8 bits, mode */ +#define DMA_MODE_WRITE 1 +/* I/O to memory, 16 bits, mode */ +#define DMA_MODE_READ_WORD 2 +/* memory to I/O, 16 bits, mode */ +#define DMA_MODE_WRITE_WORD 3 +/* I/O to memory, 32 bits, mode */ +#define DMA_MODE_READ_LONG 4 +/* memory to I/O, 32 bits, mode */ +#define DMA_MODE_WRITE_LONG 5 +/* I/O to memory, 8 bits, single-address-mode */ +#define DMA_MODE_READ_SINGLE 8 +/* memory to I/O, 8 bits, single-address-mode */ +#define DMA_MODE_WRITE_SINGLE 9 +/* I/O to memory, 16 bits, single-address-mode */ +#define DMA_MODE_READ_WORD_SINGLE 10 +/* memory to I/O, 16 bits, single-address-mode */ +#define DMA_MODE_WRITE_WORD_SINGLE 11 +/* I/O to memory, 32 bits, single-address-mode */ +#define DMA_MODE_READ_LONG_SINGLE 12 +/* memory to I/O, 32 bits, single-address-mode */ +#define DMA_MODE_WRITE_LONG_SINGLE 13 + +#else /* CONFIG_M5272 is defined */ + +/* Source static-address mode */ +#define DMA_MODE_SRC_SA_BIT 0x01 +/* Two bits to select between all four modes */ +#define DMA_MODE_SSIZE_MASK 0x06 +/* Offset to shift bits in */ +#define DMA_MODE_SSIZE_OFF 0x01 +/* Destination static-address mode */ +#define DMA_MODE_DES_SA_BIT 0x10 +/* Two bits to select between all four modes */ +#define DMA_MODE_DSIZE_MASK 0x60 +/* Offset to shift bits in */ +#define DMA_MODE_DSIZE_OFF 0x05 +/* Size modifiers */ +#define DMA_MODE_SIZE_LONG 0x00 +#define DMA_MODE_SIZE_BYTE 0x01 +#define DMA_MODE_SIZE_WORD 0x02 +#define DMA_MODE_SIZE_LINE 0x03 + +/* + * Aliases to help speed quick ports; these may be suboptimal, however. They + * do not include the SINGLE mode modifiers since the MCF5272 does not have a + * mode where the device is in control of its addressing. + */ + +/* I/O to memory, 8 bits, mode */ +#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 8 bits, mode */ +#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) +/* I/O to memory, 16 bits, mode */ +#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 16 bits, mode */ +#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) +/* I/O to memory, 32 bits, mode */ +#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 32 bits, mode */ +#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) + +#endif /* !defined(CONFIG_M5272) */ + +#if !defined(CONFIG_M5272) +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("enable_dma(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT; +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + volatile unsigned char *dmapb; + +#ifdef DMA_DEBUG + printk("disable_dma(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmapb = (unsigned char *) dma_base_addr[dmanr]; + + /* Turn off external requests, and stop any DMA in progress */ + dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT; + dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE; +} + +/* + * Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + * + * This is a NOP for ColdFire. Provide a stub for compatibility. + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + + volatile unsigned char *dmabp; + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); +#endif + + dmabp = (unsigned char *) dma_base_addr[dmanr]; + dmawp = (unsigned short *) dma_base_addr[dmanr]; + + // Clear config errors + dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; + + // Set command register + dmawp[MCFDMA_DCR] = + MCFDMA_DCR_INT | // Enable completion irq + MCFDMA_DCR_CS | // Force one xfer per request + MCFDMA_DCR_AA | // Enable auto alignment + // single-address-mode + ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | + // sets s_rw (-> r/w) high if Memory to I/0 + ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | + // Memory to I/O or I/O to Memory + ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | + // 32 bit, 16 bit or 8 bit transfers + ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : + ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : + MCFDMA_DCR_SSIZE_BYTE)) | + ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD : + ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG : + MCFDMA_DCR_DSIZE_BYTE)); + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__, + dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR], + (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]); +#endif +} + +/* Set transfer address for specific DMA channel */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + volatile unsigned short *dmawp; + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + // Determine which address registers are used for memory/device accesses + if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { + // Source incrementing, must be memory + dmalp[MCFDMA_SAR] = a; + // Set dest address, must be device + dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; + } else { + // Destination incrementing, must be memory + dmalp[MCFDMA_DAR] = a; + // Set source address, must be device + dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; + } + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", + __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR], + (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR], + (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]); +#endif +} + +/* + * Specific for Coldfire - sets device address. + * Should be called after the mode set call, and before set DMA address. + */ +static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) +{ +#ifdef DMA_DEBUG + printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dma_device_address[dmanr] = a; +} + +/* + * NOTE 2: "count" represents _bytes_. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmawp[MCFDMA_BCR] = (unsigned short)count; +} + +/* + * Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + unsigned short count; + +#ifdef DMA_DEBUG + printk("get_dma_residue(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + count = dmawp[MCFDMA_BCR]; + return((int) count); +} +#else /* CONFIG_M5272 is defined */ + +/* + * The MCF5272 DMA controller is very different than the controller defined above + * in terms of register mapping. For instance, with the exception of the 16-bit + * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. + * + * The big difference, however, is the lack of device-requested DMA. All modes + * are dual address transfer, and there is no 'device' setup or direction bit. + * You can DMA between a device and memory, between memory and memory, or even between + * two devices directly, with any combination of incrementing and non-incrementing + * addresses you choose. This puts a crimp in distinguishing between the 'device + * address' set up by set_dma_device_addr. + * + * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, + * which will act exactly as above in -- it will look to see if the source is set to + * autoincrement, and if so it will make the source use the set_dma_addr value and the + * destination the set_dma_device_addr value. Otherwise the source will be set to the + * set_dma_device_addr value and the destination will get the set_dma_addr value. + * + * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions + * and make it explicit. Depending on what you're doing, one of these two should work + * for you, but don't mix them in the same transfer setup. + */ + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("enable_dma(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN; +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("disable_dma(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + /* Turn off external requests, and stop any DMA in progress */ + dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; +} + +/* + * Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + * + * This is a NOP for ColdFire. Provide a stub for compatibility. + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + + volatile unsigned int *dmalp; + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); +#endif + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmawp = (unsigned short *) dma_base_addr[dmanr]; + + // Clear config errors + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; + + // Set command register + dmalp[MCFDMA_DMR] = + MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting + MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. + MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. + // source static-address-mode + ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | + // dest static-address-mode + ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | + // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 + (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | + (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); + + dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, + dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], + (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]); +#endif +} + +/* Set transfer address for specific DMA channel */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + // Determine which address registers are used for memory/device accesses + if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { + // Source incrementing, must be memory + dmalp[MCFDMA_DSAR] = a; + // Set dest address, must be device + dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; + } else { + // Destination incrementing, must be memory + dmalp[MCFDMA_DDAR] = a; + // Set source address, must be device + dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; + } + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", + __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], + (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], + (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]); +#endif +} + +/* + * Specific for Coldfire - sets device address. + * Should be called after the mode set call, and before set DMA address. + */ +static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) +{ +#ifdef DMA_DEBUG + printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dma_device_address[dmanr] = a; +} + +/* + * NOTE 2: "count" represents _bytes_. + * + * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmalp[MCFDMA_DBCR] = count; +} + +/* + * Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + unsigned int count; + +#ifdef DMA_DEBUG + printk("get_dma_residue(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + count = dmalp[MCFDMA_DBCR]; + return(count); +} + +#endif /* !defined(CONFIG_M5272) */ +#endif /* CONFIG_COLDFIRE */ + +/* it's useless on the m68k, but unfortunately needed by the new + bootmem allocator (but this should do it for this) */ +#define MAX_DMA_ADDRESS PAGE_OFFSET + +#define MAX_DMA_CHANNELS 8 + +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +#define isa_dma_bridge_buggy (0) + +#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h deleted file mode 100644 index 4240fbc946f..00000000000 --- a/arch/m68k/include/asm/dma_mm.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _M68K_DMA_H -#define _M68K_DMA_H 1 - - -/* it's useless on the m68k, but unfortunately needed by the new - bootmem allocator (but this should do it for this) */ -#define MAX_DMA_ADDRESS PAGE_OFFSET - -#define MAX_DMA_CHANNELS 8 - -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#define isa_dma_bridge_buggy (0) - -#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h deleted file mode 100644 index 939a0205621..00000000000 --- a/arch/m68k/include/asm/dma_no.h +++ /dev/null @@ -1,494 +0,0 @@ -#ifndef _M68K_DMA_H -#define _M68K_DMA_H 1 - -//#define DMA_DEBUG 1 - - -#ifdef CONFIG_COLDFIRE -/* - * ColdFire DMA Model: - * ColdFire DMA supports two forms of DMA: Single and Dual address. Single - * address mode emits a source address, and expects that the device will either - * pick up the data (DMA READ) or source data (DMA WRITE). This implies that - * the device will place data on the correct byte(s) of the data bus, as the - * memory transactions are always 32 bits. This implies that only 32 bit - * devices will find single mode transfers useful. Dual address DMA mode - * performs two cycles: source read and destination write. ColdFire will - * align the data so that the device will always get the correct bytes, thus - * is useful for 8 and 16 bit devices. This is the mode that is supported - * below. - * - * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 - * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) - * - * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000 - * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) - * - * APR/18/2002 : added proper support for MCF5272 DMA controller. - * Arthur Shipkowski (art@videon-central.com) - */ - -#include -#include -#include - -/* - * Set number of channels of DMA on ColdFire for different implementations. - */ -#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ - defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) -#define MAX_M68K_DMA_CHANNELS 4 -#elif defined(CONFIG_M5272) -#define MAX_M68K_DMA_CHANNELS 1 -#elif defined(CONFIG_M532x) -#define MAX_M68K_DMA_CHANNELS 0 -#else -#define MAX_M68K_DMA_CHANNELS 2 -#endif - -extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; -extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; - -#if !defined(CONFIG_M5272) -#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */ -#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */ -#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */ -#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */ - -/* I/O to memory, 8 bits, mode */ -#define DMA_MODE_READ 0 -/* memory to I/O, 8 bits, mode */ -#define DMA_MODE_WRITE 1 -/* I/O to memory, 16 bits, mode */ -#define DMA_MODE_READ_WORD 2 -/* memory to I/O, 16 bits, mode */ -#define DMA_MODE_WRITE_WORD 3 -/* I/O to memory, 32 bits, mode */ -#define DMA_MODE_READ_LONG 4 -/* memory to I/O, 32 bits, mode */ -#define DMA_MODE_WRITE_LONG 5 -/* I/O to memory, 8 bits, single-address-mode */ -#define DMA_MODE_READ_SINGLE 8 -/* memory to I/O, 8 bits, single-address-mode */ -#define DMA_MODE_WRITE_SINGLE 9 -/* I/O to memory, 16 bits, single-address-mode */ -#define DMA_MODE_READ_WORD_SINGLE 10 -/* memory to I/O, 16 bits, single-address-mode */ -#define DMA_MODE_WRITE_WORD_SINGLE 11 -/* I/O to memory, 32 bits, single-address-mode */ -#define DMA_MODE_READ_LONG_SINGLE 12 -/* memory to I/O, 32 bits, single-address-mode */ -#define DMA_MODE_WRITE_LONG_SINGLE 13 - -#else /* CONFIG_M5272 is defined */ - -/* Source static-address mode */ -#define DMA_MODE_SRC_SA_BIT 0x01 -/* Two bits to select between all four modes */ -#define DMA_MODE_SSIZE_MASK 0x06 -/* Offset to shift bits in */ -#define DMA_MODE_SSIZE_OFF 0x01 -/* Destination static-address mode */ -#define DMA_MODE_DES_SA_BIT 0x10 -/* Two bits to select between all four modes */ -#define DMA_MODE_DSIZE_MASK 0x60 -/* Offset to shift bits in */ -#define DMA_MODE_DSIZE_OFF 0x05 -/* Size modifiers */ -#define DMA_MODE_SIZE_LONG 0x00 -#define DMA_MODE_SIZE_BYTE 0x01 -#define DMA_MODE_SIZE_WORD 0x02 -#define DMA_MODE_SIZE_LINE 0x03 - -/* - * Aliases to help speed quick ports; these may be suboptimal, however. They - * do not include the SINGLE mode modifiers since the MCF5272 does not have a - * mode where the device is in control of its addressing. - */ - -/* I/O to memory, 8 bits, mode */ -#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 8 bits, mode */ -#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) -/* I/O to memory, 16 bits, mode */ -#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 16 bits, mode */ -#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) -/* I/O to memory, 32 bits, mode */ -#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 32 bits, mode */ -#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) - -#endif /* !defined(CONFIG_M5272) */ - -#if !defined(CONFIG_M5272) -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("enable_dma(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT; -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - volatile unsigned char *dmapb; - -#ifdef DMA_DEBUG - printk("disable_dma(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmapb = (unsigned char *) dma_base_addr[dmanr]; - - /* Turn off external requests, and stop any DMA in progress */ - dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT; - dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE; -} - -/* - * Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - * - * This is a NOP for ColdFire. Provide a stub for compatibility. - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - - volatile unsigned char *dmabp; - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); -#endif - - dmabp = (unsigned char *) dma_base_addr[dmanr]; - dmawp = (unsigned short *) dma_base_addr[dmanr]; - - // Clear config errors - dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; - - // Set command register - dmawp[MCFDMA_DCR] = - MCFDMA_DCR_INT | // Enable completion irq - MCFDMA_DCR_CS | // Force one xfer per request - MCFDMA_DCR_AA | // Enable auto alignment - // single-address-mode - ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | - // sets s_rw (-> r/w) high if Memory to I/0 - ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | - // Memory to I/O or I/O to Memory - ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | - // 32 bit, 16 bit or 8 bit transfers - ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : - ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : - MCFDMA_DCR_SSIZE_BYTE)) | - ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD : - ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG : - MCFDMA_DCR_DSIZE_BYTE)); - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__, - dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR], - (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]); -#endif -} - -/* Set transfer address for specific DMA channel */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - volatile unsigned short *dmawp; - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - // Determine which address registers are used for memory/device accesses - if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { - // Source incrementing, must be memory - dmalp[MCFDMA_SAR] = a; - // Set dest address, must be device - dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; - } else { - // Destination incrementing, must be memory - dmalp[MCFDMA_DAR] = a; - // Set source address, must be device - dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; - } - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", - __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR], - (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR], - (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]); -#endif -} - -/* - * Specific for Coldfire - sets device address. - * Should be called after the mode set call, and before set DMA address. - */ -static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) -{ -#ifdef DMA_DEBUG - printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dma_device_address[dmanr] = a; -} - -/* - * NOTE 2: "count" represents _bytes_. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmawp[MCFDMA_BCR] = (unsigned short)count; -} - -/* - * Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * Otherwise, it returns the number of _bytes_ left to transfer. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - unsigned short count; - -#ifdef DMA_DEBUG - printk("get_dma_residue(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - count = dmawp[MCFDMA_BCR]; - return((int) count); -} -#else /* CONFIG_M5272 is defined */ - -/* - * The MCF5272 DMA controller is very different than the controller defined above - * in terms of register mapping. For instance, with the exception of the 16-bit - * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. - * - * The big difference, however, is the lack of device-requested DMA. All modes - * are dual address transfer, and there is no 'device' setup or direction bit. - * You can DMA between a device and memory, between memory and memory, or even between - * two devices directly, with any combination of incrementing and non-incrementing - * addresses you choose. This puts a crimp in distinguishing between the 'device - * address' set up by set_dma_device_addr. - * - * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, - * which will act exactly as above in -- it will look to see if the source is set to - * autoincrement, and if so it will make the source use the set_dma_addr value and the - * destination the set_dma_device_addr value. Otherwise the source will be set to the - * set_dma_device_addr value and the destination will get the set_dma_addr value. - * - * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions - * and make it explicit. Depending on what you're doing, one of these two should work - * for you, but don't mix them in the same transfer setup. - */ - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("enable_dma(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN; -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("disable_dma(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - /* Turn off external requests, and stop any DMA in progress */ - dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; -} - -/* - * Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - * - * This is a NOP for ColdFire. Provide a stub for compatibility. - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - - volatile unsigned int *dmalp; - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); -#endif - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmawp = (unsigned short *) dma_base_addr[dmanr]; - - // Clear config errors - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; - - // Set command register - dmalp[MCFDMA_DMR] = - MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting - MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. - MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. - // source static-address-mode - ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | - // dest static-address-mode - ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | - // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 - (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | - (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); - - dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, - dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], - (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]); -#endif -} - -/* Set transfer address for specific DMA channel */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - // Determine which address registers are used for memory/device accesses - if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { - // Source incrementing, must be memory - dmalp[MCFDMA_DSAR] = a; - // Set dest address, must be device - dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; - } else { - // Destination incrementing, must be memory - dmalp[MCFDMA_DDAR] = a; - // Set source address, must be device - dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; - } - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", - __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], - (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], - (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]); -#endif -} - -/* - * Specific for Coldfire - sets device address. - * Should be called after the mode set call, and before set DMA address. - */ -static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) -{ -#ifdef DMA_DEBUG - printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dma_device_address[dmanr] = a; -} - -/* - * NOTE 2: "count" represents _bytes_. - * - * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmalp[MCFDMA_DBCR] = count; -} - -/* - * Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * Otherwise, it returns the number of _bytes_ left to transfer. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - unsigned int count; - -#ifdef DMA_DEBUG - printk("get_dma_residue(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - count = dmalp[MCFDMA_DBCR]; - return(count); -} - -#endif /* !defined(CONFIG_M5272) */ -#endif /* CONFIG_COLDFIRE */ - -#define MAX_DMA_CHANNELS 8 - -/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any - occurrence should be flagged as an error. */ -/* under 2.4 it is actually needed by the new bootmem allocator */ -#define MAX_DMA_ADDRESS PAGE_OFFSET - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#endif /* _M68K_DMA_H */ -- cgit v1.2.3-70-g09d2 From 584320156b7e42e74105ca78bdf895d2b0269251 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 5 Aug 2009 14:02:48 +1000 Subject: m68k: clean up comment delimiters in dma.h Change C99 style comments to traditional K&R style. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/dma.h | 54 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index 3b85f6e6c09..6fbdfe89510 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -177,21 +177,21 @@ static __inline__ void set_dma_mode(unsigned int dmanr, char mode) dmabp = (unsigned char *) dma_base_addr[dmanr]; dmawp = (unsigned short *) dma_base_addr[dmanr]; - // Clear config errors + /* Clear config errors */ dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; - // Set command register + /* Set command register */ dmawp[MCFDMA_DCR] = - MCFDMA_DCR_INT | // Enable completion irq - MCFDMA_DCR_CS | // Force one xfer per request - MCFDMA_DCR_AA | // Enable auto alignment - // single-address-mode + MCFDMA_DCR_INT | /* Enable completion irq */ + MCFDMA_DCR_CS | /* Force one xfer per request */ + MCFDMA_DCR_AA | /* Enable auto alignment */ + /* single-address-mode */ ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | - // sets s_rw (-> r/w) high if Memory to I/0 + /* sets s_rw (-> r/w) high if Memory to I/0 */ ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | - // Memory to I/O or I/O to Memory + /* Memory to I/O or I/O to Memory */ ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | - // 32 bit, 16 bit or 8 bit transfers + /* 32 bit, 16 bit or 8 bit transfers */ ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : MCFDMA_DCR_SSIZE_BYTE)) | @@ -219,16 +219,16 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) dmawp = (unsigned short *) dma_base_addr[dmanr]; dmalp = (unsigned int *) dma_base_addr[dmanr]; - // Determine which address registers are used for memory/device accesses + /* Determine which address registers are used for memory/device accesses */ if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { - // Source incrementing, must be memory + /* Source incrementing, must be memory */ dmalp[MCFDMA_SAR] = a; - // Set dest address, must be device + /* Set dest address, must be device */ dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; } else { - // Destination incrementing, must be memory + /* Destination incrementing, must be memory */ dmalp[MCFDMA_DAR] = a; - // Set source address, must be device + /* Set source address, must be device */ dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; } @@ -367,19 +367,19 @@ static __inline__ void set_dma_mode(unsigned int dmanr, char mode) dmalp = (unsigned int *) dma_base_addr[dmanr]; dmawp = (unsigned short *) dma_base_addr[dmanr]; - // Clear config errors + /* Clear config errors */ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; - // Set command register + /* Set command register */ dmalp[MCFDMA_DMR] = - MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting - MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. - MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. - // source static-address-mode + MCFDMA_DMR_RQM_DUAL | /* Mandatory Request Mode setting */ + MCFDMA_DMR_DSTT_SD | /* Set up addressing types; set to supervisor-data. */ + MCFDMA_DMR_SRCT_SD | /* Set up addressing types; set to supervisor-data. */ + /* source static-address-mode */ ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | - // dest static-address-mode + /* dest static-address-mode */ ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | - // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 + /* burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 */ (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); @@ -403,16 +403,16 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) dmalp = (unsigned int *) dma_base_addr[dmanr]; - // Determine which address registers are used for memory/device accesses + /* Determine which address registers are used for memory/device accesses */ if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { - // Source incrementing, must be memory + /* Source incrementing, must be memory */ dmalp[MCFDMA_DSAR] = a; - // Set dest address, must be device + /* Set dest address, must be device */ dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; } else { - // Destination incrementing, must be memory + /* Destination incrementing, must be memory */ dmalp[MCFDMA_DDAR] = a; - // Set source address, must be device + /* Set source address, must be device */ dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; } -- cgit v1.2.3-70-g09d2 From cd3dd4068db5e1258a14b63e0feaf0332640d896 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 27 Apr 2009 15:09:29 +1000 Subject: m68knommu: use general interrupt controller for ColdFire 520x family Create general interrupt controller code for the ColdFire 520x family, that does proper masking and unmasking of interrupts. With this in place some of the driver hacks in place to support ColdFire interrupts can finally go away. Within the ColdFire family there is a variety of different interrupt controllers in use. Some are used on multiple parts, some on only one. There is quite some differences in some varients, so much so that common code for all ColdFire parts would be impossible. This commit introduces code to support one of the newer interrupt controllers in the ColdFire 5208 and 5207 parts. It has very simple mask and unmask operations, so is one of the easiest to support. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 2 + arch/m68knommu/kernel/irq.c | 4 ++ arch/m68knommu/platform/coldfire/Makefile | 2 +- arch/m68knommu/platform/coldfire/intc-simr.c | 61 ++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 arch/m68knommu/platform/coldfire/intc-simr.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index e80b6a54ea9..e79b9bc76a1 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -22,6 +22,8 @@ #define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ #define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ #define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ +#define MCFINTC_SIMR 0x1c /* Set interrupt mask 0-63 */ +#define MCFINTC_CIMR 0x1d /* Clear interrupt mask 0-63 */ #define MCFINTC_ICR0 0x40 /* Base ICR register */ #define MCFINT_VECBASE 64 diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c index 9e0c100447c..47f6af57e18 100644 --- a/arch/m68knommu/kernel/irq.c +++ b/arch/m68knommu/kernel/irq.c @@ -29,6 +29,8 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) set_irq_regs(oldregs); } +#if !defined(CONFIG_M520x) + static struct irq_chip m_irq_chip = { .name = "M68K-INTC", .enable = enable_vector, @@ -50,6 +52,8 @@ void __init init_IRQ(void) } } +#endif + int show_interrupts(struct seq_file *p, void *v) { struct irqaction *ap; diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile index 2667323c7fe..dd242db7daa 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68knommu/platform/coldfire/Makefile @@ -17,7 +17,7 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o obj-$(CONFIG_M5206) += timers.o obj-$(CONFIG_M5206e) += timers.o -obj-$(CONFIG_M520x) += pit.o +obj-$(CONFIG_M520x) += pit.o intc-simr.o obj-$(CONFIG_M523x) += pit.o dma_timer.o obj-$(CONFIG_M5249) += timers.o obj-$(CONFIG_M527x) += pit.o diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c new file mode 100644 index 00000000000..3b614a3508f --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc-simr.c @@ -0,0 +1,61 @@ +/* + * intc-simr.c + * + * (C) Copyright 2009, Greg Ungerer + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +static void intc_irq_mask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 63)) + __raw_writeb(irq - MCFINT_VECBASE, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR); +} + +static void intc_irq_unmask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 63)) + __raw_writeb(irq - MCFINT_VECBASE, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR); +} + +static int intc_irq_set_type(unsigned int irq, unsigned int type) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 63)) + __raw_writeb(5, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + irq - MCFINT_VECBASE); + 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) +{ + int irq; + + init_vectors(); + + 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); + } +} + -- cgit v1.2.3-70-g09d2 From 277c5e3e26cac45010f57a581c56476639b2cfa0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 29 Apr 2009 12:07:13 +1000 Subject: m68knommu: general interrupt controller for ColdFire 532x parts The ColdFire 532x family of parts uses 2 of the same INTC interrupt controlers used in the ColdFire 520x family. So modify the code to support both parts. The extra code for the second INTC controler in the case of the 520x is easily optimized away to nothing. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 15 +++++++++++++-- arch/m68k/include/asm/m532xsim.h | 18 ++++++++++-------- arch/m68knommu/kernel/irq.c | 3 ++- arch/m68knommu/platform/coldfire/Makefile | 2 +- arch/m68knommu/platform/coldfire/intc-simr.c | 24 ++++++++++++++++++------ 5 files changed, 44 insertions(+), 18 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index e79b9bc76a1..91de39c8d86 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -11,9 +11,8 @@ #define m520xsim_h /****************************************************************************/ - /* - * Define the 5282 SIM register set addresses. + * Define the 520x SIM register set addresses. */ #define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */ #define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ @@ -26,6 +25,18 @@ #define MCFINTC_CIMR 0x1d /* Clear interrupt mask 0-63 */ #define MCFINTC_ICR0 0x40 /* Base ICR register */ +/* + * The common interrupt controller code just wants to know the absolute + * address to the SIMR and CIMR registers (not offsets into IPSBAR). + * The 520x family only has a single INTC unit. + */ +#define MCFINTC0_SIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR) +#define MCFINTC0_CIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR) +#define MCFINTC0_ICR0 (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0) +#define MCFINTC1_SIMR (0) +#define MCFINTC1_CIMR (0) +#define MCFINTC1_ICR0 (0) + #define MCFINT_VECBASE 64 #define MCFINT_UART0 26 /* Interrupt number for UART0 */ #define MCFINT_UART1 27 /* Interrupt number for UART1 */ diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index 3e80810b378..41c57e0f445 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -58,10 +58,12 @@ #define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */ -#define MCFSIM_IMR_SIMR0 0xFC04801C -#define MCFSIM_IMR_SIMR1 0xFC04C01C -#define MCFSIM_IMR_CIMR0 0xFC04801D -#define MCFSIM_IMR_CIMR1 0xFC04C01D +#define MCFINTC0_SIMR 0xFC04801C +#define MCFINTC0_CIMR 0xFC04801D +#define MCFINTC0_ICR0 0xFC048040 +#define MCFINTC1_SIMR 0xFC04C01C +#define MCFINTC1_CIMR 0xFC04C01D +#define MCFINTC1_ICR0 0xFC04C040 #define MCFSIM_ICR_TIMER1 (0xFC048040+32) #define MCFSIM_ICR_TIMER2 (0xFC048040+33) @@ -87,16 +89,16 @@ #define mcf_enable_irq0(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq); + *((volatile unsigned char *) (MCFINTC0_CIMR)) = (irq); #define mcf_enable_irq1(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq); + *((volatile unsigned char *) (MCFINTC1_CIMR)) = (irq); #define mcf_disable_irq0(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq); + *((volatile unsigned char *) (MCFINTC0_SIMR)) = (irq); #define mcf_disable_irq1(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq); + *((volatile unsigned char *) (MCFINTC1_SIMR)) = (irq); /* * Define the Cache register flags. diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c index f9965d7ee7c..93d567bbf33 100644 --- a/arch/m68knommu/kernel/irq.c +++ b/arch/m68knommu/kernel/irq.c @@ -30,7 +30,8 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) } #if !defined(CONFIG_M520x) && !defined(CONFIG_M523x) && \ - !defined(CONFIG_M527x) && !defined(CONFIG_M528x) + !defined(CONFIG_M527x) && !defined(CONFIG_M528x) && \ + !defined(CONFIG_M532x) static struct irq_chip m_irq_chip = { .name = "M68K-INTC", diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile index bce9a62d3a1..6c5f699cf14 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68knommu/platform/coldfire/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_M527x) += pit.o intc-2.o obj-$(CONFIG_M5272) += timers.o obj-$(CONFIG_M528x) += pit.o intc-2.o obj-$(CONFIG_M5307) += timers.o -obj-$(CONFIG_M532x) += timers.o +obj-$(CONFIG_M532x) += timers.o intc-simr.o obj-$(CONFIG_M5407) += timers.o obj-y += pinmux.o gpio.o diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c index 3b614a3508f..86fc2047d7a 100644 --- a/arch/m68knommu/platform/coldfire/intc-simr.c +++ b/arch/m68knommu/platform/coldfire/intc-simr.c @@ -20,20 +20,32 @@ static void intc_irq_mask(unsigned int irq) { - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 63)) - __raw_writeb(irq - MCFINT_VECBASE, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR); + if (irq >= MCFINT_VECBASE) { + if (irq < MCFINT_VECBASE + 64) + __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR); + else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR) + __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR); + } } static void intc_irq_unmask(unsigned int irq) { - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 63)) - __raw_writeb(irq - MCFINT_VECBASE, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR); + if (irq >= MCFINT_VECBASE) { + if (irq < MCFINT_VECBASE + 64) + __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR); + else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR) + __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR); + } } static int intc_irq_set_type(unsigned int irq, unsigned int type) { - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 63)) - __raw_writeb(5, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + irq - MCFINT_VECBASE); + if (irq >= MCFINT_VECBASE) { + if (irq < MCFINT_VECBASE + 64) + __raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE); + else if ((irq < MCFINT_VECBASE) && MCFINTC1_ICR0) + __raw_writeb(5, MCFINTC1_ICR0 + irq - MCFINT_VECBASE - 64); + } return 0; } -- cgit v1.2.3-70-g09d2 From f1a59d244abd8d7b94b90f45ee5e0988e5a154cb Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 6 May 2009 11:36:00 +1000 Subject: m68knommu: remove interrupt masking from ColdFire pit timer With proper interrupt controller code in place there is no need for devices like the timers to have custom interrupt masking code. Remove it (and the defines that go along with it). Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 4 ---- arch/m68k/include/asm/mcfsim.h | 14 -------------- arch/m68knommu/platform/coldfire/pit.c | 8 -------- 3 files changed, 26 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 91de39c8d86..ed2b69b9680 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -124,10 +124,6 @@ #define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02) #define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) -#define ICR_INTRCONF 0x05 -#define MCFPIT_IMR MCFINTC_IMRL -#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1) - /* * Reset Controll Unit. */ diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index da3f2ceff3a..b90425fb50f 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -101,20 +101,6 @@ #endif -/* - * PIT interrupt settings, if not found in mXXXXsim.h file. - */ -#ifndef ICR_INTRCONF -#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */ -#endif -#ifndef MCFPIT_IMR -#define MCFPIT_IMR MCFINTC_IMRH -#endif -#ifndef MCFPIT_IMR_IBIT -#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32)) -#endif - - #ifndef __ASSEMBLY__ /* * Definition for the interrupt auto-vectoring support. diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68knommu/platform/coldfire/pit.c index 61b96211f8f..d8720ee3451 100644 --- a/arch/m68knommu/platform/coldfire/pit.c +++ b/arch/m68knommu/platform/coldfire/pit.c @@ -32,7 +32,6 @@ */ #define FREQ ((MCF_CLK / 2) / 64) #define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a)) -#define INTC0 (MCF_IPSBAR + MCFICM_INTC0) #define PIT_CYCLES_PER_JIFFY (FREQ / HZ) static u32 pit_cnt; @@ -154,8 +153,6 @@ static struct clocksource pit_clk = { void hw_timer_init(void) { - u32 imr; - cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id()); cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32); cf_pit_clockevent.max_delta_ns = @@ -166,11 +163,6 @@ void hw_timer_init(void) setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq); - __raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1); - imr = __raw_readl(INTC0 + MCFPIT_IMR); - imr &= ~MCFPIT_IMR_IBIT; - __raw_writel(imr, INTC0 + MCFPIT_IMR); - pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift); clocksource_register(&pit_clk); } -- cgit v1.2.3-70-g09d2 From e47cc3d6acacffdc673779a44c21a4a12b20db23 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 6 May 2009 14:28:25 +1000 Subject: m68knommu: mask off all interrupts in ColdFire intc-simr controller The ColdFire intc-simr interrupt controller should mask off all interrupt sources at init time. Doing it here instead of separately in each platform setup. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m532xsim.h | 33 ---------------------------- arch/m68knommu/platform/coldfire/intc-simr.c | 5 +++++ 2 files changed, 5 insertions(+), 33 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index 41c57e0f445..021a0e15527 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -56,8 +56,6 @@ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ -#define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */ - #define MCFINTC0_SIMR 0xFC04801C #define MCFINTC0_CIMR 0xFC04801D #define MCFINTC0_ICR0 0xFC048040 @@ -69,37 +67,6 @@ #define MCFSIM_ICR_TIMER2 (0xFC048040+33) -/* - * Macro to set IMR register. It is 32 bits on the 5307. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - -#define mcf_getiprl() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL)) - -#define mcf_getiprh() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH)) - - -#define mcf_enable_irq0(irq) \ - *((volatile unsigned char *) (MCFINTC0_CIMR)) = (irq); - -#define mcf_enable_irq1(irq) \ - *((volatile unsigned char *) (MCFINTC1_CIMR)) = (irq); - -#define mcf_disable_irq0(irq) \ - *((volatile unsigned char *) (MCFINTC0_SIMR)) = (irq); - -#define mcf_disable_irq1(irq) \ - *((volatile unsigned char *) (MCFINTC1_SIMR)) = (irq); - /* * Define the Cache register flags. */ diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c index 86fc2047d7a..1b01e79c2f6 100644 --- a/arch/m68knommu/platform/coldfire/intc-simr.c +++ b/arch/m68knommu/platform/coldfire/intc-simr.c @@ -62,6 +62,11 @@ void __init init_IRQ(void) init_vectors(); + /* Mask all interrupt sources */ + __raw_writeb(0xff, MCFINTC0_SIMR); + if (MCFINTC1_SIMR) + __raw_writeb(0xff, MCFINTC1_SIMR); + for (irq = 0; (irq < NR_IRQS); irq++) { irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = NULL; -- cgit v1.2.3-70-g09d2 From 5938084bd8843490a4493d19fb108df70d87df2d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 19 May 2009 13:56:44 +1000 Subject: m68knommu: move ColdFire INTC definitions to new include file Create an mcfintc.h include file with the definitions for the old style ColdFire interrupt controller. They are only needed on CPU's that use this old controller - so isolate them on their own. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/mcfintc.h | 106 ++++++++++++++++++++++++++++++++++++++++ arch/m68k/include/asm/mcfsim.h | 81 +++--------------------------- 2 files changed, 114 insertions(+), 73 deletions(-) create mode 100644 arch/m68k/include/asm/mcfintc.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h new file mode 100644 index 00000000000..a75a001e773 --- /dev/null +++ b/arch/m68k/include/asm/mcfintc.h @@ -0,0 +1,106 @@ +/****************************************************************************/ + +/* + * mcfintc.h -- support definitions for the simple ColdFire + * Interrupt Controller + * + * (C) Copyright 2009, Greg Ungerer + */ + +/****************************************************************************/ +#ifndef mcfintc_h +#define mcfintc_h +/****************************************************************************/ + +/* + * Most of the older ColdFire parts use the same simple interrupt + * controller. This is currently used on the 5206, 5206e, 5249, 5307 + * and 5407 parts. + * + * The builtin peripherals are masked through dedicated bits in the + * Interrupt Mask register (IMR) - and this is not indexed (or in any way + * related to) the actual interrupt number they use. So knowing the IRQ + * number doesn't explicitly map to a certain internal device for + * interrupt control purposes. + */ + +/* + * Define the base address of the SIM within the MBAR address space. + */ +#define MCFSIM_BASE 0x0 /* Base address within SIM */ + +/* + * Bit definitions for the ICR family of registers. + */ +#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ +#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ +#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ +#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ +#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ +#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ +#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ +#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ +#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ + +#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ +#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ +#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ +#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ + +/* + * Bit definitions for the ICR family of registers. + */ +#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ +#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ +#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ +#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ +#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ +#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ +#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ +#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ +#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ + +#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ +#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ +#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ +#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ + +/* + * Bit definitions for the Interrupt Mask register (IMR). + */ +#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */ +#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */ +#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */ +#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */ +#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */ +#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */ +#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */ + +#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */ +#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */ +#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */ +#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */ +#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */ +#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */ + +#if defined(CONFIG_M5206e) +#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */ +#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */ +#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) +#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */ +#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */ +#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */ +#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */ +#endif + +/* + * Mask for all of the SIM devices. Some parts have more or less + * SIM devices. This is a catchall for the sandard set. + */ +#ifndef MCFSIM_IMR_MASKALL +#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */ +#endif + + +/****************************************************************************/ +#endif /* mcfintc_h */ diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index b90425fb50f..9c70a67bf85 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -4,7 +4,7 @@ * mcfsim.h -- ColdFire System Integration Module support. * * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) */ /****************************************************************************/ @@ -12,19 +12,21 @@ #define mcfsim_h /****************************************************************************/ - /* - * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282, - * 5307 or 5407 specific addresses. + * Include the appropriate ColdFire CPU specific System Integration Module + * (SIM) definitions. */ #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) #include +#include #elif defined(CONFIG_M520x) #include #elif defined(CONFIG_M523x) #include +#include #elif defined(CONFIG_M5249) #include +#include #elif defined(CONFIG_M527x) #include #elif defined(CONFIG_M5272) @@ -33,80 +35,13 @@ #include #elif defined(CONFIG_M5307) #include +#include #elif defined(CONFIG_M532x) #include #elif defined(CONFIG_M5407) #include +#include #endif - -/* - * Define the base address of the SIM within the MBAR address space. - */ -#define MCFSIM_BASE 0x0 /* Base address of SIM */ - - -/* - * Bit definitions for the ICR family of registers. - */ -#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ -#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ -#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ -#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ -#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ -#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ -#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ -#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ -#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ - -#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ -#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ -#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ -#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ - -/* - * Bit definitions for the Interrupt Mask register (IMR). - */ -#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */ -#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */ -#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */ -#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */ -#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */ -#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */ -#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */ - -#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */ -#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */ -#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */ -#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */ -#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */ -#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */ - -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) -#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */ -#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */ -#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */ -#endif - -/* - * Mask for all of the SIM devices. Some parts have more or less - * SIM devices. This is a catchall for the sandard set. - */ -#ifndef MCFSIM_IMR_MASKALL -#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */ -#endif - - -#ifndef __ASSEMBLY__ -/* - * Definition for the interrupt auto-vectoring support. - */ -extern void mcf_autovector(unsigned int vec); -#endif /* __ASSEMBLY__ */ - /****************************************************************************/ #endif /* mcfsim_h */ -- cgit v1.2.3-70-g09d2 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/m68k/include/asm/m5206sim.h | 16 ++------ arch/m68k/include/asm/m5249sim.h | 13 ------ arch/m68k/include/asm/m5307sim.h | 17 -------- arch/m68k/include/asm/m5407sim.h | 13 ------ arch/m68k/include/asm/mcfintc.h | 73 +++++++++++---------------------- arch/m68knommu/platform/5206/config.c | 11 +++-- arch/m68knommu/platform/5206e/config.c | 12 +++--- arch/m68knommu/platform/5249/config.c | 11 +++-- arch/m68knommu/platform/5307/config.c | 12 +++--- arch/m68knommu/platform/5407/config.c | 12 +++--- arch/m68knommu/platform/coldfire/intc.c | 59 +++++++++++++++++++++++++- 11 files changed, 109 insertions(+), 140 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h index 7be8a2d3e65..b50061aaf8f 100644 --- a/arch/m68k/include/asm/m5206sim.h +++ b/arch/m68k/include/asm/m5206sim.h @@ -117,21 +117,11 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR15 /* DMA 2 ICR */ #endif -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_MASKALL 0xfffe /* All SIM intr sources */ -#endif - /* - * Macro to get and set IMR register. It is 16 bits on the 5206. + * Let the common interrupt handler code know that the ColdFire 5206* + * family of CPU's only has a 16bit sized IMR register. */ -#define mcf_getimr() \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr) - -#define mcf_getipr() \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR)) +#define MCFSIM_IMR_IS_16BITS /****************************************************************************/ #endif /* m5206sim_h */ diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h index 2c23a83512a..36ed31bbf6c 100644 --- a/arch/m68k/include/asm/m5249sim.h +++ b/arch/m68k/include/asm/m5249sim.h @@ -106,19 +106,6 @@ #define MCFGPIO_PIN_MAX 64 #define MCFGPIO_IRQ_MAX -1 #define MCFGPIO_IRQ_VECBASE -1 -/* - * Macro to set IMR register. It is 32 bits on the 5249. - */ -#define MCFSIM_IMR_MASKALL 0x7fffe /* All SIM intr sources */ - -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) /****************************************************************************/ diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index 6a1870c925a..60946225699 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -124,23 +124,6 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ -#if defined(CONFIG_M5307) -#define MCFSIM_IMR_MASKALL 0x3fffe /* All SIM intr sources */ -#endif - -/* - * Macro to set IMR register. It is 32 bits on the 5307. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - - /* * Some symbol defines for the Parallel Port Pin Assignment Register */ diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index 25194756b43..3c4bd5f08cd 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -96,19 +96,6 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ -/* - * Macro to set IMR register. It is 32 bits on the 5407. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - - /* * Some symbol defines for the Parallel Port Pin Assignment Register */ diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h index a75a001e773..213aa6c68ab 100644 --- a/arch/m68k/include/asm/mcfintc.h +++ b/arch/m68k/include/asm/mcfintc.h @@ -48,59 +48,32 @@ #define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ /* - * Bit definitions for the ICR family of registers. + * IMR bit position definitions. */ -#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ -#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ -#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ -#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ -#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ -#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ -#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ -#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ -#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ +#define MCFINTC_EINT1 1 /* External int #1 */ +#define MCFINTC_EINT2 2 /* External int #2 */ +#define MCFINTC_EINT3 3 /* External int #3 */ +#define MCFINTC_EINT4 4 /* External int #4 */ +#define MCFINTC_EINT5 5 /* External int #5 */ +#define MCFINTC_EINT6 6 /* External int #6 */ +#define MCFINTC_EINT7 7 /* External int #7 */ +#define MCFINTC_SWT 8 /* Software Watchdog */ +#define MCFINTC_TIMER1 9 +#define MCFINTC_TIMER2 10 +#define MCFINTC_I2C 11 /* I2C / MBUS */ +#define MCFINTC_UART0 12 +#define MCFINTC_UART1 13 +#define MCFINTC_DMA0 14 +#define MCFINTC_DMA1 15 +#define MCFINTC_DMA2 16 +#define MCFINTC_DMA3 17 +#define MCFINTC_QSPI 18 -#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ -#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ -#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ -#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ - -/* - * Bit definitions for the Interrupt Mask register (IMR). - */ -#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */ -#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */ -#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */ -#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */ -#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */ -#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */ -#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */ - -#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */ -#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */ -#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */ -#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */ -#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */ -#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */ - -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) -#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */ -#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */ -#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */ +#ifndef __ASSEMBLER__ +void mcf_autovector(int irq); +void mcf_setimr(int index); +void mcf_clrimr(int index); #endif -/* - * Mask for all of the SIM devices. Some parts have more or less - * SIM devices. This is a catchall for the sandard set. - */ -#ifndef MCFSIM_IMR_MASKALL -#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */ -#endif - - /****************************************************************************/ #endif /* mcfintc_h */ diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c index 481617a23d0..0dce2383320 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68knommu/platform/5206/config.c @@ -49,11 +49,11 @@ static void __init m5206_uart_init_line(int line, int irq) if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_clrimr(MCFINTC_UART0); } else if (line == 1) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_clrimr(MCFINTC_UART1); } } @@ -75,13 +75,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); } } @@ -100,7 +100,6 @@ void m5206_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); mach_reset = m5206_cpu_reset; } diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index 29e565a4443..08ef7e26898 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c @@ -50,11 +50,11 @@ static void __init m5206e_uart_init_line(int line, int irq) if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + mcf_clrimr(MCFINTC_UART0); } else if (line == 1) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + mcf_clrimr(MCFINTC_UART1); } } @@ -76,13 +76,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); } } @@ -101,8 +101,6 @@ void m5206e_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - #if defined(CONFIG_NETtel) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index 365fb6c5270..7261a3d28ad 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -48,11 +48,11 @@ static void __init m5249_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); } } @@ -75,13 +75,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); } } @@ -100,7 +100,6 @@ void m5249_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); mach_reset = m5249_cpu_reset; } 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... */ diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c index 1e8ef74ea15..8aa94837bbc 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68knommu/platform/5407/config.c @@ -55,11 +55,11 @@ static void __init m5407_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); } } @@ -81,13 +81,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); } } @@ -106,8 +106,6 @@ void m5407_cpu_reset(void) void __init config_BSP(char *commandp, int size) { - mcf_setimr(MCFSIM_IMR_MASKALL); - #if defined(CONFIG_CLEOPATRA) /* Different timer setup - to prevent device clash */ mcf_timervector = 30; diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c index f7a61346ee2..88bffac50c6 100644 --- a/arch/m68knommu/platform/coldfire/intc.c +++ b/arch/m68knommu/platform/coldfire/intc.c @@ -1,5 +1,5 @@ /* - * intc.c + * intc.c -- support for the old ColdFire interrupt controller * * (C) Copyright 2009, Greg Ungerer * @@ -26,6 +26,62 @@ #define EIRQ1 25 #define EIRQ7 31 +/* + * In the early version 2 core ColdFire parts the IMR register was 16 bits + * in size. Version 3 (and later version 2) core parts have a 32 bit + * sized IMR register. Provide some size independant methods to access the + * IMR register. + */ +#ifdef MCFSIM_IMR_IS_16BITS + +void mcf_setimr(int index) +{ + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_clrimr(int index) +{ + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_maskimr(unsigned int mask) +{ + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + imr |= mask; + __raw_writew(imr, MCF_MBAR + MCFSIM_IMR); +} + +#else + +void mcf_setimr(int index) +{ + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_clrimr(int index) +{ + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); +} + +void mcf_maskimr(unsigned int mask) +{ + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + imr |= mask; + __raw_writel(imr, MCF_MBAR + MCFSIM_IMR); +} + +#endif + /* * Interrupts can be "vectored" on the ColdFire cores that support this old * interrupt controller. That is, the device raising the interrupt can also @@ -70,6 +126,7 @@ void __init init_IRQ(void) int irq; init_vectors(); + mcf_maskimr(0xffffffff); for (irq = 0; (irq < NR_IRQS); irq++) { irq_desc[irq].status = IRQ_DISABLED; -- cgit v1.2.3-70-g09d2 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/m68k/include/asm/m5206sim.h | 13 ++++++----- arch/m68k/include/asm/m5249sim.h | 6 +++++ arch/m68k/include/asm/m5272sim.h | 5 ++++ arch/m68k/include/asm/m5307sim.h | 6 +++++ arch/m68k/include/asm/m5407sim.h | 5 ++++ arch/m68knommu/platform/5206/config.c | 25 +++++++++----------- arch/m68knommu/platform/5206e/config.c | 25 +++++++++----------- arch/m68knommu/platform/5249/config.c | 26 +++++++++------------ arch/m68knommu/platform/5272/config.c | 22 +++++++---------- arch/m68knommu/platform/5307/config.c | 35 +++++++++------------------ arch/m68knommu/platform/5407/config.c | 39 ++++++++++--------------------- arch/m68knommu/platform/coldfire/timers.c | 17 ++++---------- 12 files changed, 97 insertions(+), 127 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h index b50061aaf8f..9c384e294af 100644 --- a/arch/m68k/include/asm/m5206sim.h +++ b/arch/m68k/include/asm/m5206sim.h @@ -88,12 +88,19 @@ #define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */ #define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */ +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ + /* * Generic GPIO */ #define MCFGPIO_PIN_MAX 8 #define MCFGPIO_IRQ_VECBASE -1 #define MCFGPIO_IRQ_MAX -1 + /* * Some symbol defines for the Parallel Port Pin Assignment Register */ @@ -117,11 +124,5 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR15 /* DMA 2 ICR */ #endif -/* - * Let the common interrupt handler code know that the ColdFire 5206* - * family of CPU's only has a 16bit sized IMR register. - */ -#define MCFSIM_IMR_IS_16BITS - /****************************************************************************/ #endif /* m5206sim_h */ diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h index 36ed31bbf6c..8d76a193071 100644 --- a/arch/m68k/include/asm/m5249sim.h +++ b/arch/m68k/include/asm/m5249sim.h @@ -70,6 +70,12 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ + /* * General purpose IO registers (in MBAR2). */ diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h index 0665ba1a5d3..469686ffc4a 100644 --- a/arch/m68k/include/asm/m5272sim.h +++ b/arch/m68k/include/asm/m5272sim.h @@ -73,6 +73,11 @@ #define MCFSIM_PCDAT (MCF_MBAR + 0x96) /* Port C Data (r/w) */ #define MCFSIM_PDCNT (MCF_MBAR + 0x98) /* Port D Control (r/w) */ +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 69 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 70 /* Timer1, Level 7 */ /* * Generic GPIO support diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index 60946225699..c6830e5b54c 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -124,6 +124,7 @@ #define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ + /* * Some symbol defines for the Parallel Port Pin Assignment Register */ @@ -139,6 +140,11 @@ #define IRQ3_LEVEL6 0x40 #define IRQ1_LEVEL2 0x20 +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ /* * Define the Cache register flags. diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index 3c4bd5f08cd..c399abbf953 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -111,6 +111,11 @@ #define IRQ3_LEVEL6 0x40 #define IRQ1_LEVEL2 0x20 +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ /* * Define the Cache register flags. diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c index 0dce2383320..c1d24796ef2 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68knommu/platform/5206/config.c @@ -68,21 +68,17 @@ static void __init m5206_uarts_init(void) /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5206_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 } /***************************************************************************/ @@ -101,6 +97,7 @@ void m5206_cpu_reset(void) void __init config_BSP(char *commandp, int size) { mach_reset = m5206_cpu_reset; + m5206_timers_init(); } /***************************************************************************/ diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index 08ef7e26898..363296af2ee 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c @@ -69,21 +69,17 @@ static void __init m5206e_uarts_init(void) /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5206e_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 } /***************************************************************************/ @@ -108,6 +104,7 @@ void __init config_BSP(char *commandp, int size) #endif /* CONFIG_NETtel */ mach_reset = m5206e_cpu_reset; + m5206e_timers_init(); } /***************************************************************************/ diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index 7261a3d28ad..51202b1096c 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -65,24 +65,19 @@ static void __init m5249_uarts_init(void) m5249_uart_init_line(line, m5249_uart_platform[line].irq); } - /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5249_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 } /***************************************************************************/ @@ -101,6 +96,7 @@ void m5249_cpu_reset(void) void __init config_BSP(char *commandp, int size) { mach_reset = m5249_cpu_reset; + m5249_timers_init(); } /***************************************************************************/ diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c index 94a66c12c96..b16add9aa4e 100644 --- a/arch/m68knommu/platform/5272/config.c +++ b/arch/m68knommu/platform/5272/config.c @@ -20,12 +20,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. */ @@ -148,14 +142,15 @@ void mcf_disableall(void) /***************************************************************************/ -void mcf_settimericr(int timer, int level) +static void __init m5272_timers_init(void) { - volatile unsigned long *icrp; + /* Timer1 @ level6 is always used as system timer */ + writel((0x8 | 0x6) << ((4 - 1) * 4), MCF_MBAR + MCFSIM_ICR1); - if ((timer >= 1 ) && (timer <= 4)) { - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (0x8 | level) << ((4 - timer) * 4); - } +#ifdef CONFIG_HIGHPROFILE + /* Timer2 @ level7 is to be used as a high speed profile timer */ + writel((0x8 | 0x7) << ((4 - 2) * 4), MCF_MBAR + MCFSIM_ICR1); +#endif } /***************************************************************************/ @@ -195,9 +190,8 @@ void __init config_BSP(char *commandp, int size) commandp[size-1] = 0; #endif - mcf_timervector = 69; - mcf_profilevector = 70; mach_reset = m5272_cpu_reset; + m5272_timers_init(); } /***************************************************************************/ 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 /* diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c index 8aa94837bbc..cc80029a4a0 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68knommu/platform/5407/config.c @@ -20,12 +20,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - static struct mcf_platform_uart m5407_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -59,6 +53,7 @@ static void __init m5407_uart_init_line(int line, int irq) } 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); } } @@ -74,21 +69,17 @@ static void __init m5407_uarts_init(void) /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) +static void __init m5407_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 } /***************************************************************************/ @@ -106,14 +97,8 @@ void m5407_cpu_reset(void) void __init config_BSP(char *commandp, int size) { -#if defined(CONFIG_CLEOPATRA) - /* Different timer setup - to prevent device clash */ - mcf_timervector = 30; - mcf_profilevector = 31; - mcf_timerlevel = 6; -#endif - mach_reset = m5407_cpu_reset; + m5407_timers_init(); } /***************************************************************************/ diff --git a/arch/m68knommu/platform/coldfire/timers.c b/arch/m68knommu/platform/coldfire/timers.c index 1ba8a373165..77b0c17ce6b 100644 --- a/arch/m68knommu/platform/coldfire/timers.c +++ b/arch/m68knommu/platform/coldfire/timers.c @@ -30,15 +30,6 @@ #define FREQ (MCF_BUSCLK / 16) #define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a)) -/* - * Default the timer and vector to use for ColdFire. Some ColdFire - * CPU's and some boards may want different. Their sub-architecture - * startup code (in config.c) can change these if they want. - */ -unsigned int mcf_timervector = 29; -unsigned int mcf_profilevector = 31; -unsigned int mcf_timerlevel = 5; - /* * These provide the underlying interrupt vector support. * Unfortunately it is a little different on each ColdFire. @@ -107,7 +98,7 @@ static struct clocksource mcftmr_clk = { void hw_timer_init(void) { - setup_irq(mcf_timervector, &mcftmr_timer_irq); + setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq); __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); mcftmr_cycles_per_jiffy = FREQ / HZ; @@ -124,7 +115,7 @@ void hw_timer_init(void) mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift); clocksource_register(&mcftmr_clk); - mcf_settimericr(1, mcf_timerlevel); + mcf_clrimr(MCFINTC_TIMER1); #ifdef CONFIG_HIGHPROFILE coldfire_profile_init(); @@ -171,7 +162,7 @@ void coldfire_profile_init(void) printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); - setup_irq(mcf_profilevector, &coldfire_profile_irq); + setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq); /* Set up TIMER 2 as high speed profile clock */ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); @@ -180,7 +171,7 @@ void coldfire_profile_init(void) __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); - mcf_settimericr(2, 7); + mcf_clrimr(MCFINTC_TIMER2); } /***************************************************************************/ -- cgit v1.2.3-70-g09d2 From f6a66276f5fdc018d2a9378c71de3bae13c588d7 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 19 May 2009 15:00:01 +1000 Subject: m68knommu: clean up ColdFire 532x CPU timer setup The newer ColdFire 532x family of CPU's uses the old timer, but has a newer interrupt controller. It doesn't need the special timer setup that was required when using the older interrupt controller. Remove the dead timer irq and level setting code, and define the hard coded vector. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m532xsim.h | 5 +++++ arch/m68knommu/platform/532x/config.c | 17 +---------------- 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index 021a0e15527..36bf15aec9a 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -66,6 +66,11 @@ #define MCFSIM_ICR_TIMER1 (0xFC048040+32) #define MCFSIM_ICR_TIMER2 (0xFC048040+33) +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_TIMER (64 + 32) /* Timer0 */ +#define MCF_IRQ_PROFILER (64 + 33) /* Timer1 */ /* * Define the Cache register flags. diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c index 66e212b58b8..d632948e64e 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68knommu/platform/532x/config.c @@ -30,12 +30,6 @@ /***************************************************************************/ -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - static struct mcf_platform_uart m532x_uart_platform[] = { { .mapbase = MCFUART_BASE1, @@ -87,6 +81,7 @@ static struct platform_device m532x_fec = { .num_resources = ARRAY_SIZE(m532x_fec_resources), .resource = m532x_fec_resources, }; + static struct platform_device *m532x_devices[] __initdata = { &m532x_uart, &m532x_fec, @@ -126,12 +121,6 @@ static void __init m532x_fec_init(void) /***************************************************************************/ -void mcf_settimericr(unsigned int timer, unsigned int level) -{ -} - -/***************************************************************************/ - static void m532x_cpu_reset(void) { local_irq_disable(); @@ -153,10 +142,6 @@ void __init config_BSP(char *commandp, int size) } #endif - mcf_timervector = 64+32; - mcf_profilevector = 64+33; - mach_reset = m532x_cpu_reset; - #ifdef CONFIG_BDM_DISABLE /* * Disable the BDM clocking. This also turns off most of the rest of -- cgit v1.2.3-70-g09d2 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/m68k/include/asm/mcfintc.h | 22 ++++++++++++----- arch/m68knommu/platform/5206/config.c | 13 +++++++--- arch/m68knommu/platform/5206e/config.c | 13 +++++++--- arch/m68knommu/platform/5249/config.c | 8 +++--- arch/m68knommu/platform/5307/config.c | 14 ++++++++--- arch/m68knommu/platform/5407/config.c | 15 ++++++++--- arch/m68knommu/platform/coldfire/intc.c | 44 ++++++++++++++++++++------------- 7 files changed, 90 insertions(+), 39 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h index 213aa6c68ab..4183320a381 100644 --- a/arch/m68k/include/asm/mcfintc.h +++ b/arch/m68k/include/asm/mcfintc.h @@ -24,11 +24,6 @@ * interrupt control purposes. */ -/* - * Define the base address of the SIM within the MBAR address space. - */ -#define MCFSIM_BASE 0x0 /* Base address within SIM */ - /* * Bit definitions for the ICR family of registers. */ @@ -48,7 +43,9 @@ #define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ /* - * IMR bit position definitions. + * IMR bit position definitions. Not all ColdFire parts with this interrupt + * controller actually support all of these interrupt sources. But the bit + * numbers are the same in all cores. */ #define MCFINTC_EINT1 1 /* External int #1 */ #define MCFINTC_EINT2 2 /* External int #2 */ @@ -70,6 +67,19 @@ #define MCFINTC_QSPI 18 #ifndef __ASSEMBLER__ + +/* + * There is no one-is-one correspondance between the interrupt number (irq) + * and the bit fields on the mask register. So we create a per-cpu type + * mapping of irq to mask bit. The CPU platform code needs to register + * its supported irq's at init time, using this function. + */ +extern unsigned char mcf_irq2imr[]; +static inline void mcf_mapirq2imr(int irq, int imr) +{ + mcf_irq2imr[irq] = imr; +} + void mcf_autovector(int irq); void mcf_setimr(int index); void mcf_clrimr(int index); diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c index c1d24796ef2..9c335465e66 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68knommu/platform/5206/config.c @@ -49,11 +49,11 @@ static void __init m5206_uart_init_line(int line, int irq) if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); - mcf_clrimr(MCFINTC_UART0); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); - mcf_clrimr(MCFINTC_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -73,11 +73,13 @@ static void __init m5206_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 } @@ -98,13 +100,18 @@ void __init config_BSP(char *commandp, int size) { mach_reset = m5206_cpu_reset; m5206_timers_init(); + m5206_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(28, MCFINTC_EINT4); + mcf_mapirq2imr(31, MCFINTC_EINT7); } /***************************************************************************/ static int __init init_BSP(void) { - m5206_uarts_init(); platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices)); return 0; } diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index 363296af2ee..0f41ba82a3b 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c @@ -50,11 +50,11 @@ static void __init m5206e_uart_init_line(int line, int irq) if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); - mcf_clrimr(MCFINTC_UART0); + mcf_mapirq2imr(irq, MCFINTC_UART0); } else if (line == 1) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); - mcf_clrimr(MCFINTC_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -74,11 +74,13 @@ static void __init m5206e_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 } @@ -105,13 +107,18 @@ void __init config_BSP(char *commandp, int size) mach_reset = m5206e_cpu_reset; m5206e_timers_init(); + m5206e_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(28, MCFINTC_EINT4); + mcf_mapirq2imr(31, MCFINTC_EINT7); } /***************************************************************************/ static int __init init_BSP(void) { - m5206e_uarts_init(); platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices)); return 0; } diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index 51202b1096c..646f5ba462f 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -48,11 +48,11 @@ static void __init m5249_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); } } @@ -72,11 +72,13 @@ static void __init m5249_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 } @@ -97,13 +99,13 @@ void __init config_BSP(char *commandp, int size) { mach_reset = m5249_cpu_reset; m5249_timers_init(); + m5249_uarts_init(); } /***************************************************************************/ static int __init init_BSP(void) { - m5249_uarts_init(); platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices)); return 0; } 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; } diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c index cc80029a4a0..70ea789a400 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68knommu/platform/5407/config.c @@ -49,12 +49,11 @@ static void __init m5407_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_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); - mcf_clrimr(MCFINTC_UART1); + mcf_mapirq2imr(irq, MCFINTC_UART1); } } @@ -74,11 +73,13 @@ static void __init m5407_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 } @@ -99,13 +100,19 @@ void __init config_BSP(char *commandp, int size) { mach_reset = m5407_cpu_reset; m5407_timers_init(); + m5407_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); } /***************************************************************************/ static int __init init_BSP(void) { - m5407_uarts_init(); platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices)); return 0; } diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c index 14db26bf6e2..a4560c86db7 100644 --- a/arch/m68knommu/platform/coldfire/intc.c +++ b/arch/m68knommu/platform/coldfire/intc.c @@ -19,9 +19,17 @@ #include /* - * Define the vector numbers for the basic 7 interrupt sources. - * These are often referred to as the "external" interrupts in - * the ColdFire documentation (for the early ColdFire cores at least). + * The mapping of irq number to a mask register bit is not one-to-one. + * The irq numbers are either based on "level" of interrupt or fixed + * for an autovector-able interrupt. So we keep a local data structure + * that maps from irq to mask register. Not all interrupts will have + * an IMR bit. + */ +unsigned char mcf_irq2imr[NR_IRQS]; + +/* + * Define the miniumun and maximum external interrupt numbers. + * This is also used as the "level" interrupt numbers. */ #define EIRQ1 25 #define EIRQ7 31 @@ -36,22 +44,22 @@ void mcf_setimr(int index) { - u16 imr; - imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); } void mcf_clrimr(int index) { - u16 imr; - imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + u16 imr; + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); } void mcf_maskimr(unsigned int mask) { u16 imr; - imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); + imr = __raw_readw(MCF_MBAR + MCFSIM_IMR); imr |= mask; __raw_writew(imr, MCF_MBAR + MCFSIM_IMR); } @@ -60,22 +68,22 @@ void mcf_maskimr(unsigned int mask) void mcf_setimr(int index) { - u32 imr; - imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR); } void mcf_clrimr(int index) { - u32 imr; - imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + u32 imr; + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR); } void mcf_maskimr(unsigned int mask) { u32 imr; - imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); + imr = __raw_readl(MCF_MBAR + MCFSIM_IMR); imr |= mask; __raw_writel(imr, MCF_MBAR + MCFSIM_IMR); } @@ -93,24 +101,26 @@ void mcf_maskimr(unsigned int mask) */ void mcf_autovector(int irq) { +#ifdef MCFSIM_AVR if ((irq >= EIRQ1) && (irq <= EIRQ7)) { u8 avec; avec = __raw_readb(MCF_MBAR + MCFSIM_AVR); avec |= (0x1 << (irq - EIRQ1 + 1)); __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR); } +#endif } static void intc_irq_mask(unsigned int irq) { - if ((irq >= EIRQ1) && (irq <= EIRQ7)) - mcf_setimr(irq - EIRQ1 + 1); + if (mcf_irq2imr[irq]) + mcf_setimr(mcf_irq2imr[irq]); } static void intc_irq_unmask(unsigned int irq) { - if ((irq >= EIRQ1) && (irq <= EIRQ7)) - mcf_clrimr(irq - EIRQ1 + 1); + if (mcf_irq2imr[irq]) + mcf_clrimr(mcf_irq2imr[irq]); } static int intc_irq_set_type(unsigned int irq, unsigned int type) -- cgit v1.2.3-70-g09d2 From da3601a5fa664c8d51383fe916d96bd4fbce84b8 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 22 May 2009 14:16:39 +1000 Subject: m68knommu: add support for second interrupt controller of ColdFire 5249 The ColdFire 5249 CPU has a second (compleletly different) interrupt controller. It is the only ColdFire CPU that has this type. It controlls GPIO interrupts amongst a number of interrupts from other internal peripherals. Add support code for it. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m5249sim.h | 20 ++++++++++-- arch/m68knommu/platform/5249/Makefile | 2 +- arch/m68knommu/platform/5249/intc2.c | 59 +++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 arch/m68knommu/platform/5249/intc2.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h index 8d76a193071..14bce877ed8 100644 --- a/arch/m68k/include/asm/m5249sim.h +++ b/arch/m68k/include/asm/m5249sim.h @@ -106,6 +106,22 @@ #define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */ #define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */ +/* + * Define the base interrupt for the second interrupt controller. + * We set it to 128, out of the way of the base interrupts, and plenty + * of room for its 64 interrupts. + */ +#define MCFINTC2_VECBASE 128 + +#define MCFINTC2_GPIOIRQ0 (MCFINTC2_VECBASE + 32) +#define MCFINTC2_GPIOIRQ1 (MCFINTC2_VECBASE + 33) +#define MCFINTC2_GPIOIRQ2 (MCFINTC2_VECBASE + 34) +#define MCFINTC2_GPIOIRQ3 (MCFINTC2_VECBASE + 35) +#define MCFINTC2_GPIOIRQ4 (MCFINTC2_VECBASE + 36) +#define MCFINTC2_GPIOIRQ5 (MCFINTC2_VECBASE + 37) +#define MCFINTC2_GPIOIRQ6 (MCFINTC2_VECBASE + 38) +#define MCFINTC2_GPIOIRQ7 (MCFINTC2_VECBASE + 39) + /* * Generic GPIO support */ @@ -135,9 +151,9 @@ subql #1,%a1 /* get MBAR2 address in a1 */ /* - * Move secondary interrupts to base at 128. + * Move secondary interrupts to their base (128). */ - moveb #0x80,%d0 + moveb #MCFINTC2_VECBASE,%d0 moveb %d0,0x16b(%a1) /* interrupt base register */ /* diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile index 113c3339006..f56225d1582 100644 --- a/arch/m68knommu/platform/5249/Makefile +++ b/arch/m68knommu/platform/5249/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o gpio.o +obj-y := config.o gpio.o intc2.o diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c new file mode 100644 index 00000000000..d09d9da0453 --- /dev/null +++ b/arch/m68knommu/platform/5249/intc2.c @@ -0,0 +1,59 @@ +/* + * intc2.c -- support for the 2nd INTC controller of the 5249 + * + * (C) Copyright 2009, Greg Ungerer + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +static void intc2_irq_gpio_mask(unsigned int irq) +{ + u32 imr; + imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); + imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0)); + writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); +} + +static void intc2_irq_gpio_unmask(unsigned int irq) +{ + u32 imr; + imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); + imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0)); + writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); +} + +static void intc2_irq_gpio_ack(unsigned int irq) +{ + writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR); +} + +static struct irq_chip intc2_irq_gpio_chip = { + .name = "CF-INTC2", + .mask = intc2_irq_gpio_mask, + .unmask = intc2_irq_gpio_unmask, + .ack = intc2_irq_gpio_ack, +}; + +static int __init mcf_intc2_init(void) +{ + int irq; + + /* GPIO interrupt sources */ + for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) + irq_desc[irq].chip = &intc2_irq_gpio_chip; + + return 0; +} + +arch_initcall(mcf_intc2_init); -- cgit v1.2.3-70-g09d2 From 9075216d2c8761c91dc268125f6580af3ffc58b5 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 7 Jul 2009 09:39:11 +1000 Subject: m68knommu: create a speciailized ColdFire 5272 interrupt controller The ColdFire 5272 CPU has a very different interrupt controller than any of the other ColdFire parts. It needs its own controller code to correctly setup and ack interrupts. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m5272sim.h | 37 +++++++- arch/m68knommu/platform/5272/Makefile | 2 +- arch/m68knommu/platform/5272/intc.c | 138 ++++++++++++++++++++++++++++++ arch/m68knommu/platform/coldfire/Makefile | 2 +- 4 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 arch/m68knommu/platform/5272/intc.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h index 469686ffc4a..df3332c2317 100644 --- a/arch/m68k/include/asm/m5272sim.h +++ b/arch/m68k/include/asm/m5272sim.h @@ -12,7 +12,6 @@ #define m5272sim_h /****************************************************************************/ - /* * Define the 5272 SIM register set addresses. */ @@ -76,8 +75,40 @@ /* * Define system peripheral IRQ usage. */ -#define MCF_IRQ_TIMER 69 /* Timer0, Level 6 */ -#define MCF_IRQ_PROFILER 70 /* Timer1, Level 7 */ +#define MCFINT_VECBASE 64 /* Base of interrupts */ +#define MCF_IRQ_SPURIOUS 64 /* User Spurious */ +#define MCF_IRQ_EINT1 65 /* External Interrupt 1 */ +#define MCF_IRQ_EINT2 66 /* External Interrupt 2 */ +#define MCF_IRQ_EINT3 67 /* External Interrupt 3 */ +#define MCF_IRQ_EINT4 68 /* External Interrupt 4 */ +#define MCF_IRQ_TIMER1 69 /* Timer 1 */ +#define MCF_IRQ_TIMER2 70 /* Timer 2 */ +#define MCF_IRQ_TIMER3 71 /* Timer 3 */ +#define MCF_IRQ_TIMER4 72 /* Timer 4 */ +#define MCF_IRQ_UART1 73 /* UART 1 */ +#define MCF_IRQ_UART2 74 /* UART 2 */ +#define MCF_IRQ_PLIP 75 /* PLIC 2Khz Periodic */ +#define MCF_IRQ_PLIA 76 /* PLIC Asynchronous */ +#define MCF_IRQ_USB0 77 /* USB Endpoint 0 */ +#define MCF_IRQ_USB1 78 /* USB Endpoint 1 */ +#define MCF_IRQ_USB2 79 /* USB Endpoint 2 */ +#define MCF_IRQ_USB3 80 /* USB Endpoint 3 */ +#define MCF_IRQ_USB4 81 /* USB Endpoint 4 */ +#define MCF_IRQ_USB5 82 /* USB Endpoint 5 */ +#define MCF_IRQ_USB6 83 /* USB Endpoint 6 */ +#define MCF_IRQ_USB7 84 /* USB Endpoint 7 */ +#define MCF_IRQ_DMA 85 /* DMA Controller */ +#define MCF_IRQ_ERX 86 /* Ethernet Receiver */ +#define MCF_IRQ_ETX 87 /* Ethernet Transmitter */ +#define MCF_IRQ_ENTC 88 /* Ethernet Non-Time Critical */ +#define MCF_IRQ_QSPI 89 /* Queued Serial Interface */ +#define MCF_IRQ_EINT5 90 /* External Interrupt 5 */ +#define MCF_IRQ_EINT6 91 /* External Interrupt 6 */ +#define MCF_IRQ_SWTO 92 /* Software Watchdog */ +#define MCFINT_VECMAX 95 /* Maxmum interrupt */ + +#define MCF_IRQ_TIMER MCF_IRQ_TIMER1 +#define MCF_IRQ_PROFILER MCF_IRQ_TIMER2 /* * Generic GPIO support diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile index 3d90e6d9245..93673ef8e2c 100644 --- a/arch/m68knommu/platform/5272/Makefile +++ b/arch/m68knommu/platform/5272/Makefile @@ -14,5 +14,5 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y := config.o gpio.o +obj-y := config.o gpio.o intc.o diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c new file mode 100644 index 00000000000..7081e0a9720 --- /dev/null +++ b/arch/m68knommu/platform/5272/intc.c @@ -0,0 +1,138 @@ +/* + * intc.c -- interrupt controller or ColdFire 5272 SoC + * + * (C) Copyright 2009, Greg Ungerer + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The 5272 ColdFire interrupt controller is nothing like any other + * ColdFire interrupt controller - it truly is completely different. + * Given its age it is unlikely to be used on any other ColdFire CPU. + */ + +/* + * The masking and priproty setting of interrupts on the 5272 is done + * 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. + */ +struct irqmap { + unsigned char icr; + unsigned char index; + unsigned char ack; +}; + +static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = { + /*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, }, + /*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, }, + /*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, }, + /*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, }, + /*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, }, + /*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, }, + /*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, }, + /*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, }, + /*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, }, + /*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, }, + /*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, }, + /*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, }, + /*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, }, + /*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, }, + /*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, }, + /*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, }, + /*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, }, + /*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, }, + /*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, }, + /*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, }, + /*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, }, + /*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, }, + /*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, }, + /*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, }, + /*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, }, + /*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, }, + /*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, }, + /*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, }, + /*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, }, +}; + +static void intc_irq_mask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + u32 v; + irq -= MCFINT_VECBASE; + v = 0x8 << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } +} + +static void intc_irq_unmask(unsigned int irq) +{ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + u32 v; + irq -= MCFINT_VECBASE; + v = 0xd << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } +} + +static void intc_irq_ack(unsigned int irq) +{ + /* Only external interrupts are acked */ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + irq -= MCFINT_VECBASE; + if (intc_irqmap[irq].ack) { + u32 v; + v = 0xd << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } + } +} + +static int intc_irq_set_type(unsigned int irq, unsigned int type) +{ + /* We can set the edge type here for external interrupts */ + return 0; +} + +static struct irq_chip intc_irq_chip = { + .name = "CF-INTC", + .mask = intc_irq_mask, + .unmask = intc_irq_unmask, + .ack = intc_irq_ack, + .set_type = intc_irq_set_type, +}; + +void __init init_IRQ(void) +{ + int irq; + + init_vectors(); + + /* Mask all interrupt sources */ + writel(0x88888888, MCF_MBAR + MCFSIM_ICR1); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR2); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR3); + 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); + } +} + diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile index 24ea95a2312..f72a0e5d999 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68knommu/platform/coldfire/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_M520x) += pit.o intc-simr.o obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o obj-$(CONFIG_M5249) += timers.o intc.o obj-$(CONFIG_M527x) += pit.o intc-2.o -obj-$(CONFIG_M5272) += timers.o intc.o +obj-$(CONFIG_M5272) += timers.o obj-$(CONFIG_M528x) += pit.o intc-2.o obj-$(CONFIG_M5307) += timers.o intc.o obj-$(CONFIG_M532x) += timers.o intc-simr.o -- cgit v1.2.3-70-g09d2 From fe84c1087a6e2e76396cd4003a525c3110354ad0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 11 Aug 2009 16:33:51 +1000 Subject: m68knommu: relax IO_SPACE_LIMIT setting There is really no limit to the addresses which can be used by the in*() and out*() family of IO space calls in m68k non-MMU environments. So don't impose an artificial address limit, allow the full 32bit range. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/io_no.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 6adef1ee208..7f57436ec18 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -134,7 +134,7 @@ static inline void io_insl(unsigned int addr, void *buf, int len) #define insw(a,b,l) io_insw(a,b,l) #define insl(a,b,l) io_insl(a,b,l) -#define IO_SPACE_LIMIT 0xffff +#define IO_SPACE_LIMIT 0xffffffff /* Values for nocacheflag and cmode */ -- cgit v1.2.3-70-g09d2 From d89395babbe811811e70c6ee3465e3b60c0cdc11 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 12 Aug 2009 11:35:49 +1000 Subject: m68knommu: remove special interrupt handling code for ne2k support The improved interrupt support for ColdFire CPU cores means we no longer need all the interrupt setup and ack hacks to support the NE2000 driver on ColdFire platforms. Remove all that code. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/mcfne.h | 83 ------------------------------------------- 1 file changed, 83 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/mcfne.h b/arch/m68k/include/asm/mcfne.h index 431f63aadd0..bf638be0958 100644 --- a/arch/m68k/include/asm/mcfne.h +++ b/arch/m68k/include/asm/mcfne.h @@ -238,88 +238,5 @@ void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len) #endif /* COLDFIRE_NE2000_FUNCS */ #endif /* NE2000_OFFOFFSET */ -/****************************************************************************/ - -#ifdef COLDFIRE_NE2000_FUNCS - -/* - * Lastly the interrupt set up code... - * Minor differences between the different board types. - */ - -#if defined(CONFIG_ARN5206) -void ne2000_irqsetup(int irq) -{ - volatile unsigned char *icrp; - - icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); - *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2; - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); -} -#endif - -#if defined(CONFIG_M5206eC3) -void ne2000_irqsetup(int irq) -{ - volatile unsigned char *icrp; - - icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); - *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC; - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); -} -#endif - -#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) -void ne2000_irqsetup(int irq) -{ - mcf_autovector(irq); -} -#endif - -#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) -void ne2000_irqsetup(int irq) -{ - volatile unsigned long *icrp; - volatile unsigned long *pitr; - - /* The NE2000 device uses external IRQ3 */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77077777) | 0x00d00000; - - pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR); - *pitr = *pitr | 0x20000000; -} - -void ne2000_irqack(int irq) -{ - volatile unsigned long *icrp; - - /* The NE2000 device uses external IRQ3 */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77777777) | 0x00800000; -} -#endif - -#if defined(CONFIG_M5307) || defined(CONFIG_M5407) -#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) - -void ne2000_irqsetup(int irq) -{ - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); - mcf_autovector(irq); -} - -#else - -void ne2000_irqsetup(int irq) -{ - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); -} - -#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */ -#endif /* CONFIG_M5307 || CONFIG_M5407 */ - -#endif /* COLDFIRE_NE2000_FUNCS */ - /****************************************************************************/ #endif /* mcfne_h */ -- cgit v1.2.3-70-g09d2 From 2756730b798e4f1f8343cf034c33cc730ae3a5d4 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Wed, 12 Aug 2009 16:35:28 +1000 Subject: m68knommu: fix ColdFire definition of CLOCK_TICK_RATE The good definition of CLOCK_TICK_RATE for coldfires has been lost in the merge of m68k and m68knommu include files. Restore it. Culprit : commit ebafc17468d58bd903c886175ca84a4edc69ae1d Signed-off-by: Philippe De Muyter Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/timex.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h index b87f2f278f6..6759dad954f 100644 --- a/arch/m68k/include/asm/timex.h +++ b/arch/m68k/include/asm/timex.h @@ -3,10 +3,23 @@ * * m68k architecture timex specifications */ -#ifndef _ASMm68k_TIMEX_H -#define _ASMm68k_TIMEX_H +#ifndef _ASMm68K_TIMEX_H +#define _ASMm68K_TIMEX_H +#ifdef CONFIG_COLDFIRE +/* + * CLOCK_TICK_RATE should give the underlying frequency of the tick timer + * to make ntp work best. For Coldfires, that's the main clock. + */ +#include +#define CLOCK_TICK_RATE MCF_CLK +#else +/* + * This default CLOCK_TICK_RATE is probably wrong for many 68k boards + * Users of those boards will need to check and modify accordingly + */ #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#endif typedef unsigned long cycles_t; -- cgit v1.2.3-70-g09d2 From 2985709d7f3078c7609ae7f16affc0fb478d7d7a Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Mon, 7 Sep 2009 17:26:49 +1000 Subject: m68knommu: Make PAGE_SIZE available to assembly files. Signed-off-by: Tim Abbott Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/page_no.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h index 9aa3f90f485..1f31b060cc8 100644 --- a/arch/m68k/include/asm/page_no.h +++ b/arch/m68k/include/asm/page_no.h @@ -1,10 +1,12 @@ #ifndef _M68KNOMMU_PAGE_H #define _M68KNOMMU_PAGE_H +#include + /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT (12) -#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #include -- cgit v1.2.3-70-g09d2