summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/imx.c111
-rw-r--r--drivers/serial/sh-sci.c7
-rw-r--r--drivers/serial/sh-sci.h60
3 files changed, 104 insertions, 74 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 16ba9ac7a56..5a375bf0ebf 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -166,15 +166,6 @@
#define SERIAL_IMX_MAJOR 204
#define MINOR_START 41
-#define NR_PORTS 2
-
-#define IMX_ISR_PASS_LIMIT 256
-
-/*
- * This is the size of our serial port register set.
- */
-#define UART_PORT_SIZE 0x100
-
/*
* This determines how often we check the modem status signals
* for any change. They generally aren't connected to an IRQ
@@ -358,66 +349,60 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
struct tty_struct *tty = sport->port.info->tty;
unsigned long flags, temp;
- rx = readl(sport->port.membase + URXD0);
spin_lock_irqsave(&sport->port.lock,flags);
- do {
+ while (readl(sport->port.membase + USR2) & USR2_RDR) {
flg = TTY_NORMAL;
sport->port.icount.rx++;
+ rx = readl(sport->port.membase + URXD0);
+
temp = readl(sport->port.membase + USR2);
- if( temp & USR2_BRCD ) {
+ if (temp & USR2_BRCD) {
writel(temp | USR2_BRCD, sport->port.membase + USR2);
- if(uart_handle_break(&sport->port))
- goto ignore_char;
+ if (uart_handle_break(&sport->port))
+ continue;
}
if (uart_handle_sysrq_char
(&sport->port, (unsigned char)rx))
- goto ignore_char;
+ continue;
+
+ if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
+ if (rx & URXD_PRERR)
+ sport->port.icount.parity++;
+ else if (rx & URXD_FRMERR)
+ sport->port.icount.frame++;
+ if (rx & URXD_OVRRUN)
+ sport->port.icount.overrun++;
+
+ if (rx & sport->port.ignore_status_mask) {
+ if (++ignored > 100)
+ goto out;
+ continue;
+ }
+
+ rx &= sport->port.read_status_mask;
+
+ if (rx & URXD_PRERR)
+ flg = TTY_PARITY;
+ else if (rx & URXD_FRMERR)
+ flg = TTY_FRAME;
+ if (rx & URXD_OVRRUN)
+ flg = TTY_OVERRUN;
- if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) )
- goto handle_error;
+#ifdef SUPPORT_SYSRQ
+ sport->port.sysrq = 0;
+#endif
+ }
- error_return:
tty_insert_flip_char(tty, rx, flg);
-
- ignore_char:
- rx = readl(sport->port.membase + URXD0);
- } while(rx & URXD_CHARRDY);
+ }
out:
spin_unlock_irqrestore(&sport->port.lock,flags);
tty_flip_buffer_push(tty);
return IRQ_HANDLED;
-
-handle_error:
- if (rx & URXD_PRERR)
- sport->port.icount.parity++;
- else if (rx & URXD_FRMERR)
- sport->port.icount.frame++;
- if (rx & URXD_OVRRUN)
- sport->port.icount.overrun++;
-
- if (rx & sport->port.ignore_status_mask) {
- if (++ignored > 100)
- goto out;
- goto ignore_char;
- }
-
- rx &= sport->port.read_status_mask;
-
- if (rx & URXD_PRERR)
- flg = TTY_PARITY;
- else if (rx & URXD_FRMERR)
- flg = TTY_FRAME;
- if (rx & URXD_OVRRUN)
- flg = TTY_OVERRUN;
-
-#ifdef SUPPORT_SYSRQ
- sport->port.sysrq = 0;
-#endif
- goto error_return;
}
/*
@@ -546,7 +531,7 @@ static int imx_startup(struct uart_port *port)
writel(USR1_RTSD, sport->port.membase + USR1);
temp = readl(sport->port.membase + UCR1);
- temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+ temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR2);
@@ -731,9 +716,11 @@ static const char *imx_type(struct uart_port *port)
*/
static void imx_release_port(struct uart_port *port)
{
- struct imx_port *sport = (struct imx_port *)port;
+ struct platform_device *pdev = to_platform_device(port->dev);
+ struct resource *mmres;
- release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mmres->start, mmres->end - mmres->start + 1);
}
/*
@@ -741,10 +728,18 @@ static void imx_release_port(struct uart_port *port)
*/
static int imx_request_port(struct uart_port *port)
{
- struct imx_port *sport = (struct imx_port *)port;
+ struct platform_device *pdev = to_platform_device(port->dev);
+ struct resource *mmres;
+ void *ret;
+
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mmres)
+ return -ENODEV;
+
+ ret = request_mem_region(mmres->start, mmres->end - mmres->start + 1,
+ "imx-uart");
- return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
- "imx-uart") != NULL ? 0 : -EBUSY;
+ return ret ? 0 : -EBUSY;
}
/*
@@ -815,7 +810,7 @@ static struct imx_port imx_ports[] = {
.type = PORT_IMX,
.iotype = UPIO_MEM,
.membase = (void *)IMX_UART1_BASE,
- .mapbase = IMX_UART1_BASE, /* FIXME */
+ .mapbase = 0x00206000,
.irq = UART1_MINT_RX,
.uartclk = 16000000,
.fifosize = 32,
@@ -831,7 +826,7 @@ static struct imx_port imx_ports[] = {
.type = PORT_IMX,
.iotype = UPIO_MEM,
.membase = (void *)IMX_UART2_BASE,
- .mapbase = IMX_UART2_BASE, /* FIXME */
+ .mapbase = 0x00207000,
.irq = UART2_MINT_RX,
.uartclk = 16000000,
.fifosize = 32,
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index eff593080d4..c2ea5d4df44 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -333,7 +333,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
}
sci_out(port, SCFCR, fcr_val);
}
-
#elif defined(CONFIG_CPU_SH3)
/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
@@ -384,6 +383,12 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
sci_out(port, SCFCR, fcr_val);
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
+{
+ /* Nothing to do here.. */
+ sci_out(port, SCFCR, 0);
+}
#else
/* For SH7750 */
static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 01a9dd715f5..fa8700a968f 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -1,20 +1,5 @@
-/* $Id: sh-sci.h,v 1.4 2004/02/19 16:43:56 lethal Exp $
- *
- * linux/drivers/serial/sh-sci.h
- *
- * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
- * Copyright (C) 1999, 2000 Niibe Yutaka
- * Copyright (C) 2000 Greg Banks
- * Copyright (C) 2002, 2003 Paul Mundt
- * Modified to support multiple serial ports. Stuart Menefy (May 2000).
- * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003).
- * Modified to support H8/300 Series Yoshinori Sato (Feb 2004).
- * Removed SH7300 support (Jul 2007).
- * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Aug 2007).
- */
#include <linux/serial_core.h>
#include <asm/io.h>
-
#include <asm/gpio.h>
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
@@ -102,6 +87,15 @@
# define SCSPTR0 SCPDR0
# define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+# define SCSPTR0 0xa4050160
+# define SCSPTR1 0xa405013e
+# define SCSPTR2 0xa4050160
+# define SCSPTR3 0xa405013e
+# define SCSPTR4 0xa4050128
+# define SCSPTR5 0xa4050128
+# define SCIF_ORER 0x0001 /* overrun error bit */
+# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
@@ -395,6 +389,11 @@
h8_sci_offset, h8_sci_size) \
CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size)
#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+ #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size)
+ #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
#else
#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
@@ -419,6 +418,18 @@ SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
SCIF_FNS(SCLSR, 0x24, 16)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
+SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8)
+SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
+SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8)
+SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16)
+SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8)
+SCIF_FNS(SCTDSR, 0x0c, 8)
+SCIF_FNS(SCFER, 0x10, 16)
+SCIF_FNS(SCFCR, 0x18, 16)
+SCIF_FNS(SCFDR, 0x1c, 16)
+SCIF_FNS(SCLSR, 0x24, 16)
#else
/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/
/* name off sz off sz off sz off sz off sz*/
@@ -589,6 +600,23 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
return 1;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+ if (port->mapbase == 0xffe00000)
+ return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */
+ if (port->mapbase == 0xffe10000)
+ return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */
+ if (port->mapbase == 0xffe20000)
+ return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */
+ if (port->mapbase == 0xa4e30000)
+ return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */
+ if (port->mapbase == 0xa4e40000)
+ return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */
+ if (port->mapbase == 0xa4e50000)
+ return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */
+ return 1;
+}
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
static inline int sci_rxd_in(struct uart_port *port)
{
@@ -727,6 +755,8 @@ static inline int sci_rxd_in(struct uart_port *port)
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1)
#elif defined(__H8300H__) || defined(__H8300S__)
#define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1)
#elif defined(CONFIG_SUPERH64)