Commit bd71c182 authored by Thomas Koeller's avatar Thomas Koeller Committed by Linus Torvalds

RM9000 serial driver

Add support for the integrated serial ports of the MIPS RM9122 processor
and its relatives.

The patch also does some whitespace cleanup.

[akpm@linux-foundation.org: cleanups]
Signed-off-by: default avatarThomas Koeller <thomas.koeller@baslerweb.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent beab697a
...@@ -1042,6 +1042,9 @@ config SOC_AU1X00 ...@@ -1042,6 +1042,9 @@ config SOC_AU1X00
select SYS_SUPPORTS_APM_EMULATION select SYS_SUPPORTS_APM_EMULATION
select SYS_SUPPORTS_KGDB select SYS_SUPPORTS_KGDB
config SERIAL_RM9000
bool
config PNX8550 config PNX8550
bool bool
select SOC_PNX8550 select SOC_PNX8550
......
...@@ -251,9 +251,16 @@ static const struct serial8250_config uart_config[] = { ...@@ -251,9 +251,16 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_UUE, .flags = UART_CAP_FIFO | UART_CAP_UUE,
}, },
[PORT_RM9000] = {
.name = "RM9000",
.fifo_size = 16,
.tx_loadsz = 16,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO,
},
}; };
#ifdef CONFIG_SERIAL_8250_AU1X00 #if defined (CONFIG_SERIAL_8250_AU1X00)
/* Au1x00 UART hardware has a weird register layout */ /* Au1x00 UART hardware has a weird register layout */
static const u8 au_io_in_map[] = { static const u8 au_io_in_map[] = {
...@@ -289,6 +296,44 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) ...@@ -289,6 +296,44 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
return au_io_out_map[offset]; return au_io_out_map[offset];
} }
#elif defined (CONFIG_SERIAL_8250_RM9K)
static const u8
regmap_in[8] = {
[UART_RX] = 0x00,
[UART_IER] = 0x0c,
[UART_IIR] = 0x14,
[UART_LCR] = 0x1c,
[UART_MCR] = 0x20,
[UART_LSR] = 0x24,
[UART_MSR] = 0x28,
[UART_SCR] = 0x2c
},
regmap_out[8] = {
[UART_TX] = 0x04,
[UART_IER] = 0x0c,
[UART_FCR] = 0x18,
[UART_LCR] = 0x1c,
[UART_MCR] = 0x20,
[UART_LSR] = 0x24,
[UART_MSR] = 0x28,
[UART_SCR] = 0x2c
};
static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
{
if (up->port.iotype != UPIO_RM9000)
return offset;
return regmap_in[offset];
}
static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
{
if (up->port.iotype != UPIO_RM9000)
return offset;
return regmap_out[offset];
}
#else #else
/* sane hardware needs no mapping */ /* sane hardware needs no mapping */
...@@ -311,6 +356,7 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) ...@@ -311,6 +356,7 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
case UPIO_DWAPB: case UPIO_DWAPB:
return readb(up->port.membase + offset); return readb(up->port.membase + offset);
case UPIO_RM9000:
case UPIO_MEM32: case UPIO_MEM32:
return readl(up->port.membase + offset); return readl(up->port.membase + offset);
...@@ -348,6 +394,7 @@ serial_out(struct uart_8250_port *up, int offset, int value) ...@@ -348,6 +394,7 @@ serial_out(struct uart_8250_port *up, int offset, int value)
writeb(value, up->port.membase + offset); writeb(value, up->port.membase + offset);
break; break;
case UPIO_RM9000:
case UPIO_MEM32: case UPIO_MEM32:
writel(value, up->port.membase + offset); writel(value, up->port.membase + offset);
break; break;
...@@ -419,7 +466,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value) ...@@ -419,7 +466,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value)
serial_outp(up, UART_DLM, value >> 8 & 0xff); serial_outp(up, UART_DLM, value >> 8 & 0xff);
} }
#ifdef CONFIG_SERIAL_8250_AU1X00 #if defined (CONFIG_SERIAL_8250_AU1X00)
/* Au1x00 haven't got a standard divisor latch */ /* Au1x00 haven't got a standard divisor latch */
static int serial_dl_read(struct uart_8250_port *up) static int serial_dl_read(struct uart_8250_port *up)
{ {
...@@ -436,6 +483,24 @@ static void serial_dl_write(struct uart_8250_port *up, int value) ...@@ -436,6 +483,24 @@ static void serial_dl_write(struct uart_8250_port *up, int value)
else else
_serial_dl_write(up, value); _serial_dl_write(up, value);
} }
#elif defined (CONFIG_SERIAL_8250_RM9K)
static int serial_dl_read(struct uart_8250_port *up)
{
return (up->port.iotype == UPIO_RM9000) ?
(((__raw_readl(up->port.membase + 0x10) << 8) |
(__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
_serial_dl_read(up);
}
static void serial_dl_write(struct uart_8250_port *up, int value)
{
if (up->port.iotype == UPIO_RM9000) {
__raw_writel(value, up->port.membase + 0x08);
__raw_writel(value >> 8, up->port.membase + 0x10);
} else {
_serial_dl_write(up, value);
}
}
#else #else
#define serial_dl_read(up) _serial_dl_read(up) #define serial_dl_read(up) _serial_dl_read(up)
#define serial_dl_write(up, value) _serial_dl_write(up, value) #define serial_dl_write(up, value) _serial_dl_write(up, value)
...@@ -1175,8 +1240,11 @@ static void serial8250_start_tx(struct uart_port *port) ...@@ -1175,8 +1240,11 @@ static void serial8250_start_tx(struct uart_port *port)
if (up->bugs & UART_BUG_TXEN) { if (up->bugs & UART_BUG_TXEN) {
unsigned char lsr, iir; unsigned char lsr, iir;
lsr = serial_in(up, UART_LSR); lsr = serial_in(up, UART_LSR);
iir = serial_in(up, UART_IIR); iir = serial_in(up, UART_IIR) & 0x0f;
if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) if ((up->port.type == PORT_RM9000) ?
(lsr & UART_LSR_THRE &&
(iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
(lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
transmit_chars(up); transmit_chars(up);
} }
} }
......
...@@ -254,6 +254,15 @@ config SERIAL_8250_AU1X00 ...@@ -254,6 +254,15 @@ config SERIAL_8250_AU1X00
to this option. The driver can handle 1 or 2 serial ports. to this option. The driver can handle 1 or 2 serial ports.
If unsure, say N. If unsure, say N.
config SERIAL_8250_RM9K
bool "Support for MIPS RM9xxx integrated serial port"
depends on SERIAL_8250 != n && SERIAL_RM9000
select SERIAL_8250_SHARE_IRQ
help
Selecting this option will add support for the integrated serial
port hardware found on MIPS RM9122 and similar processors.
If unsure, say N.
comment "Non-8250 serial port support" comment "Non-8250 serial port support"
config SERIAL_AMBA_PL010 config SERIAL_AMBA_PL010
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
#define PORT_RSA 13 #define PORT_RSA 13
#define PORT_NS16550A 14 #define PORT_NS16550A 14
#define PORT_XSCALE 15 #define PORT_XSCALE 15
#define PORT_MAX_8250 15 /* max port ID */ #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */
#define PORT_MAX_8250 16 /* max port ID */
/* /*
* ARM specific type numbers. These are not currently guaranteed * ARM specific type numbers. These are not currently guaranteed
...@@ -231,6 +232,7 @@ struct uart_port { ...@@ -231,6 +232,7 @@ struct uart_port {
#define UPIO_AU (4) /* Au1x00 type IO */ #define UPIO_AU (4) /* Au1x00 type IO */
#define UPIO_TSI (5) /* Tsi108/109 type IO */ #define UPIO_TSI (5) /* Tsi108/109 type IO */
#define UPIO_DWAPB (6) /* DesignWare APB UART */ #define UPIO_DWAPB (6) /* DesignWare APB UART */
#define UPIO_RM9000 (7) /* RM9000 type IO */
unsigned int read_status_mask; /* driver specific */ unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment