From b497549a035c2a81b71c7a27f2b00c8a16c09423 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 3 Jul 2008 12:32:51 +0100 Subject: [ARM] S3C24XX: Split serial driver into core and per-cpu drivers The S3C2410 serial driver in drivers/serial/s3c2410.c has been growing bigger with the addition of more variants of this hardware with the growing Samsung SoCs range. As such, it would be easier to split this code up into a core and per-cpu drivers to make driver addition easier, and the core smaller. Signed-off-by: Ben Dooks --- drivers/serial/Kconfig | 54 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'drivers/serial/Kconfig') diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9bc42763623..5a9754455ee 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -448,22 +448,27 @@ config SERIAL_CLPS711X_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_S3C2410 - tristate "Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support" - depends on ARM && ARCH_S3C2410 - select SERIAL_CORE +config SERIAL_SAMSUNG + tristate "Samsung SoC serial support" + depends on ARM && PLAT_S3C24XX help Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, providing /dev/ttySAC0, 1 and 2 (note, some machines may not provide all of these ports, depending on how the serial port pins are configured. - Currently this driver supports the UARTS on the S3C2410, S3C2440, - S3C2442, S3C2412 and S3C2413 CPUs. +config SERIAL_SAMSUNG_DEBUG + bool "Samsung SoC serial debug" + depends on SERIAL_SAMSUNG + help + Add support for debugging the serial driver. Since this is + generally being used as a console, we use our own output + routines that go via the low-level debug printascii() + function. -config SERIAL_S3C2410_CONSOLE - bool "Support for console on S3C2410 serial port" - depends on SERIAL_S3C2410=y +config SERIAL_SAMSUNG_CONSOLE + bool "Support for console on Samsung SoC serial port" + depends on SERIAL_SAMSUNG=y select SERIAL_CORE_CONSOLE help Allow selection of the S3C24XX on-board serial ports for use as @@ -476,6 +481,37 @@ config SERIAL_S3C2410_CONSOLE your boot loader about how to pass options to the kernel at boot time.) +config SERIAL_S3C2400 + tristate "Samsung S3C2410 Serial port support" + depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400 + default y if CPU_S3C2400 + help + Serial port support for the Samsung S3C2400 SoC + +config SERIAL_S3C2410 + tristate "Samsung S3C2410 Serial port support" + depends on SERIAL_SAMSUNG && CPU_S3C2410 + default y if CPU_S3C2410 + help + Serial port support for the Samsung S3C2410 SoC + +config SERIAL_S3C2412 + tristate "Samsung S3C2412/S3C2413 Serial port support" + depends on SERIAL_SAMSUNG && CPU_S3C2412 + default y if CPU_S3C2412 + help + Serial port support for the Samsung S3C2412 and S3C2413 SoC + +config SERIAL_S3C2440 + tristate "Samsung S3C2440/S3C2442 Serial port support" + depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442) + default y if CPU_S3C2440 + default y if CPU_S3C2442 + help + Serial port support for the Samsung S3C2440 and S3C2442 SoC + + + config SERIAL_DZ bool "DECstation DZ serial driver" depends on MACH_DECSTATION && 32BIT -- cgit v1.2.3-70-g09d2 From e3d13ff4b9d3b05d7a969153e2c049548e25deea Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: mxc: add MX3 support for i.MX internal UART driver This patch adds MX3 support for the i.MX internal uart driver. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/devices.c | 153 ++++++++++++++++++++++++++++++++++++ drivers/serial/Kconfig | 2 +- drivers/serial/imx.c | 100 ++++++++++++++++++----- include/asm-arm/arch-mxc/imx-uart.h | 32 ++++++++ 5 files changed, 267 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mach-mx3/devices.c create mode 100644 include/asm-arm/arch-mxc/imx-uart.h (limited to 'drivers/serial/Kconfig') diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index febb37f2393..a788cb0b793 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o +obj-y := mm.o time.o clock.o devices.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c new file mode 100644 index 00000000000..1bc6d23a1d5 --- /dev/null +++ b/arch/arm/mach-mx3/devices.c @@ -0,0 +1,153 @@ +/* + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Sascha Hauer, kernel@pengutronix.de + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +static struct resource uart0[] = { + { + .start = UART1_BASE_ADDR, + .end = UART1_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART1, + .end = MXC_INT_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device0 = { + .name = "imx-uart", + .id = 0, + .resource = uart0, + .num_resources = ARRAY_SIZE(uart0), +}; + +static struct resource uart1[] = { + { + .start = UART2_BASE_ADDR, + .end = UART2_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART2, + .end = MXC_INT_UART2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device1 = { + .name = "imx-uart", + .id = 1, + .resource = uart1, + .num_resources = ARRAY_SIZE(uart1), +}; + +static struct resource uart2[] = { + { + .start = UART3_BASE_ADDR, + .end = UART3_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART3, + .end = MXC_INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "imx-uart", + .id = 2, + .resource = uart2, + .num_resources = ARRAY_SIZE(uart2), +}; + +static struct resource uart3[] = { + { + .start = UART4_BASE_ADDR, + .end = UART4_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART4, + .end = MXC_INT_UART4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device3 = { + .name = "imx-uart", + .id = 3, + .resource = uart3, + .num_resources = ARRAY_SIZE(uart3), +}; + +static struct resource uart4[] = { + { + .start = UART5_BASE_ADDR, + .end = UART5_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART5, + .end = MXC_INT_UART5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device4 = { + .name = "imx-uart", + .id = 4, + .resource = uart4, + .num_resources = ARRAY_SIZE(uart4), +}; + +/* + * Register only those UARTs that physically exist + */ +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata) +{ + switch (uart_no) { + case 0: + mxc_uart_device0.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device0); + break; + case 1: + mxc_uart_device1.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device1); + break; + case 2: + mxc_uart_device2.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device2); + break; + case 3: + mxc_uart_device3.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device3); + break; + case 4: + mxc_uart_device4.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device4); + break; + default: + return -ENODEV; + } + + return 0; +} + diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9bc42763623..0843c540068 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -753,7 +753,7 @@ config BFIN_UART3_CTSRTS config SERIAL_IMX bool "IMX serial port support" - depends on ARM && ARCH_IMX + depends on ARM && (ARCH_IMX || ARCH_MXC) select SERIAL_CORE help If you have a machine based on a Motorola IMX CPU you diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 9e2162ebf1b..549440b098b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -62,6 +62,11 @@ #define UBIR 0xa4 /* BRM Incremental Register */ #define UBMR 0xa8 /* BRM Modulator Register */ #define UBRC 0xac /* Baud Rate Count Register */ +#ifdef CONFIG_ARCH_MX3 +#define ONEMS 0xb0 /* One Millisecond register */ +#define UTS 0xb4 /* UART Test Register */ +#endif +#ifdef CONFIG_ARCH_IMX #define BIPR1 0xb0 /* Incremental Preset Register 1 */ #define BIPR2 0xb4 /* Incremental Preset Register 2 */ #define BIPR3 0xb8 /* Incremental Preset Register 3 */ @@ -71,6 +76,7 @@ #define BMPR3 0xc8 /* BRM Modulator Register 3 */ #define BMPR4 0xcc /* BRM Modulator Register 4 */ #define UTS 0xd0 /* UART Test Register */ +#endif /* UART Control Register Bit Fields.*/ #define URXD_CHARRDY (1<<15) @@ -90,7 +96,12 @@ #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ #define UCR1_SNDBRK (1<<4) /* Send break */ #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ +#ifdef CONFIG_ARCH_IMX #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ +#endif +#ifdef CONFIG_ARCH_MX3 +#define UCR1_UARTCLKEN (0) /* not present on mx2/mx3 */ +#endif #define UCR1_DOZE (1<<1) /* Doze */ #define UCR1_UARTEN (1<<0) /* UART enabled */ #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ @@ -164,8 +175,19 @@ #define UTS_SOFTRST (1<<0) /* Software reset */ /* We've been assigned a range on the "Low-density serial ports" major */ +#ifdef CONFIG_ARCH_IMX #define SERIAL_IMX_MAJOR 204 #define MINOR_START 41 +#define DEV_NAME "ttySMX" +#define MAX_INTERNAL_IRQ IMX_IRQS +#endif + +#ifdef CONFIG_ARCH_MX3 +#define SERIAL_IMX_MAJOR 207 +#define MINOR_START 16 +#define DEV_NAME "ttymxc" +#define MAX_INTERNAL_IRQ MXC_MAX_INT_LINES +#endif /* * This determines how often we check the modem status signals @@ -409,6 +431,26 @@ out: return IRQ_HANDLED; } +static irqreturn_t imx_int(int irq, void *dev_id) +{ + struct imx_port *sport = dev_id; + unsigned int sts; + + sts = readl(sport->port.membase + USR1); + + if (sts & USR1_RRDY) + imx_rxint(irq, dev_id); + + if (sts & USR1_TRDY && + readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) + imx_txint(irq, dev_id); + + if (sts & USR1_RTSS) + imx_rtsint(irq, dev_id); + + return IRQ_HANDLED; +} + /* * Return TIOCSER_TEMT when transmitter is not busy. */ @@ -514,21 +556,34 @@ static int imx_startup(struct uart_port *port) writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); /* - * Allocate the IRQ + * Allocate the IRQ(s) i.MX1 has three interrupts whereas later + * chips only have one interrupt. */ - retval = request_irq(sport->rxirq, imx_rxint, 0, - DRIVER_NAME, sport); - if (retval) goto error_out1; - - retval = request_irq(sport->txirq, imx_txint, 0, - DRIVER_NAME, sport); - if (retval) goto error_out2; - - retval = request_irq(sport->rtsirq, imx_rtsint, - (sport->rtsirq < IMX_IRQS) ? 0 : + if (sport->txirq > 0) { + retval = request_irq(sport->rxirq, imx_rxint, 0, + DRIVER_NAME, sport); + if (retval) + goto error_out1; + + retval = request_irq(sport->txirq, imx_txint, 0, + DRIVER_NAME, sport); + if (retval) + goto error_out2; + + retval = request_irq(sport->rtsirq, imx_rtsint, + (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 : IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - DRIVER_NAME, sport); - if (retval) goto error_out3; + DRIVER_NAME, sport); + if (retval) + goto error_out3; + } else { + retval = request_irq(sport->port.irq, imx_int, 0, + DRIVER_NAME, sport); + if (retval) { + free_irq(sport->port.irq, sport); + goto error_out1; + } + } /* * Finally, clear and enable interrupts @@ -553,9 +608,11 @@ static int imx_startup(struct uart_port *port) return 0; error_out3: - free_irq(sport->txirq, sport); + if (sport->txirq) + free_irq(sport->txirq, sport); error_out2: - free_irq(sport->rxirq, sport); + if (sport->rxirq) + free_irq(sport->rxirq, sport); error_out1: return retval; } @@ -573,9 +630,12 @@ static void imx_shutdown(struct uart_port *port) /* * Free the interrupts */ - free_irq(sport->rtsirq, sport); - free_irq(sport->txirq, sport); - free_irq(sport->rxirq, sport); + if (sport->txirq > 0) { + free_irq(sport->rtsirq, sport); + free_irq(sport->txirq, sport); + free_irq(sport->rxirq, sport); + } else + free_irq(sport->port.irq, sport); /* * Disable all interrupts, port and break condition. @@ -973,7 +1033,7 @@ imx_console_setup(struct console *co, char *options) static struct uart_driver imx_reg; static struct console imx_console = { - .name = "ttySMX", + .name = DEV_NAME, .write = imx_console_write, .device = uart_console_device, .setup = imx_console_setup, @@ -990,7 +1050,7 @@ static struct console imx_console = { static struct uart_driver imx_reg = { .owner = THIS_MODULE, .driver_name = DRIVER_NAME, - .dev_name = "ttySMX", + .dev_name = DEV_NAME, .major = SERIAL_IMX_MAJOR, .minor = MINOR_START, .nr = ARRAY_SIZE(imx_ports), diff --git a/include/asm-arm/arch-mxc/imx-uart.h b/include/asm-arm/arch-mxc/imx-uart.h new file mode 100644 index 00000000000..83fb72c4048 --- /dev/null +++ b/include/asm-arm/arch-mxc/imx-uart.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef ASMARM_ARCH_UART_H +#define ASMARM_ARCH_UART_H + +#define IMXUART_HAVE_RTSCTS (1<<0) + +struct imxuart_platform_data { + int (*init)(struct platform_device *pdev); + int (*exit)(struct platform_device *pdev); + unsigned int flags; +}; + +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata); + +#endif -- cgit v1.2.3-70-g09d2