aboutsummaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/serial/8250.c20
-rw-r--r--drivers/serial/8250.h1
-rw-r--r--drivers/serial/Kconfig1
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/atmel_serial.c38
-rw-r--r--drivers/serial/bfin_5xx.c4
-rw-r--r--drivers/serial/clps711x.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h11
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c66
-rw-r--r--drivers/serial/crisv10.c79
-rw-r--r--drivers/serial/crisv10.h3
-rw-r--r--drivers/serial/imx.c31
-rw-r--r--drivers/serial/netx-serial.c4
-rw-r--r--drivers/serial/pxa.c9
-rw-r--r--drivers/serial/s3c2400.c4
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/serial/s3c2412.c4
-rw-r--r--drivers/serial/s3c2440.c4
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/samsung.c4
-rw-r--r--drivers/serial/serial_ks8695.c65
-rw-r--r--drivers/serial/sh-sci.c17
-rw-r--r--drivers/serial/sh-sci.h40
-rw-r--r--drivers/serial/sunhv.c4
-rw-r--r--drivers/serial/sunsab.c4
-rw-r--r--drivers/serial/sunsu.c4
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/serial/v850e_uart.c548
29 files changed, 302 insertions, 678 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 6558a403780..f31c6698419 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -19,7 +19,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware/dec21285.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#define BAUD_BASE (mem_fclk_21285/64)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index a97f1ae11f7..9ccc563d873 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1885,7 +1885,7 @@ static int serial8250_startup(struct uart_port *port)
* the interrupt is enabled. Delays are necessary to
* allow register changes to become visible.
*/
- spin_lock(&up->port.lock);
+ spin_lock_irqsave(&up->port.lock, flags);
if (up->port.flags & UPF_SHARE_IRQ)
disable_irq_nosync(up->port.irq);
@@ -1901,22 +1901,30 @@ static int serial8250_startup(struct uart_port *port)
if (up->port.flags & UPF_SHARE_IRQ)
enable_irq(up->port.irq);
- spin_unlock(&up->port.lock);
+ spin_unlock_irqrestore(&up->port.lock, flags);
/*
* If the interrupt is not reasserted, setup a timer to
* kick the UART on a regular basis.
*/
if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
+ up->bugs |= UART_BUG_THRE;
pr_debug("ttyS%d - using backup timer\n", port->line);
- up->timer.function = serial8250_backup_timeout;
- up->timer.data = (unsigned long)up;
- mod_timer(&up->timer, jiffies +
- poll_timeout(up->port.timeout) + HZ / 5);
}
}
/*
+ * The above check will only give an accurate result the first time
+ * the port is opened so this value needs to be preserved.
+ */
+ if (up->bugs & UART_BUG_THRE) {
+ up->timer.function = serial8250_backup_timeout;
+ up->timer.data = (unsigned long)up;
+ mod_timer(&up->timer, jiffies +
+ poll_timeout(up->port.timeout) + HZ / 5);
+ }
+
+ /*
* If the "interrupt" for this port doesn't correspond with any
* hardware interrupt, we use a timer-based system. The original
* driver used to do this with IRQ0.
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 78c00162b04..520260326f3 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -47,6 +47,7 @@ struct serial8250_config {
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
+#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
#define PROBE_RSA (1 << 0)
#define PROBE_ANY (~0)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3b4a14e355c..77cb34270fc 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -449,6 +449,7 @@ config SERIAL_CLPS711X_CONSOLE
config SERIAL_SAMSUNG
tristate "Samsung SoC serial support"
depends on ARM && PLAT_S3C24XX
+ select SERIAL_CORE
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
providing /dev/ttySAC0, 1 and 2 (note, some machines may not
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 3a0bbbe17aa..7e7383e890d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -42,7 +42,6 @@ obj-$(CONFIG_SERIAL_68328) += 68328serial.o
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
obj-$(CONFIG_SERIAL_MCF) += mcf.o
-obj-$(CONFIG_V850E_UART) += v850e_uart.o
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
obj-$(CONFIG_SERIAL_DZ) += dz.o
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 1fee12c1f4f..61fb8b6d19a 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -42,11 +42,11 @@
#include <asm/io.h>
#include <asm/mach/serial_at91.h>
-#include <asm/arch/board.h>
+#include <mach/board.h>
#ifdef CONFIG_ARM
-#include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
+#include <mach/cpu.h>
+#include <mach/gpio.h>
#endif
#define PDC_BUFFER_SIZE 512
@@ -131,7 +131,8 @@ struct atmel_uart_char {
struct atmel_uart_port {
struct uart_port uart; /* uart */
struct clk *clk; /* uart clock */
- unsigned short suspended; /* is port suspended? */
+ int may_wakeup; /* cached value of device_may_wakeup for times we need to disable it */
+ u32 backup_imr; /* IMR saved during suspend */
int break_active; /* break being received */
short use_dma_rx; /* enable PDC receiver */
@@ -984,8 +985,15 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,
* This is called on uart_open() or a resume event.
*/
clk_enable(atmel_port->clk);
+
+ /* re-enable interrupts if we disabled some on suspend */
+ UART_PUT_IER(port, atmel_port->backup_imr);
break;
case 3:
+ /* Back up the interrupt mask and disable all interrupts */
+ atmel_port->backup_imr = UART_GET_IMR(port);
+ UART_PUT_IDR(port, -1);
+
/*
* Disable the peripheral clock for this serial port.
* This is called on uart_close() or a suspend event.
@@ -1475,13 +1483,12 @@ static int atmel_serial_suspend(struct platform_device *pdev,
cpu_relax();
}
- if (device_may_wakeup(&pdev->dev)
- && !atmel_serial_clk_will_stop())
- enable_irq_wake(port->irq);
- else {
- uart_suspend_port(&atmel_uart, port);
- atmel_port->suspended = 1;
- }
+ /* we can not wake up if we're running on slow clock */
+ atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
+ if (atmel_serial_clk_will_stop())
+ device_set_wakeup_enable(&pdev->dev, 0);
+
+ uart_suspend_port(&atmel_uart, port);
return 0;
}
@@ -1491,11 +1498,8 @@ static int atmel_serial_resume(struct platform_device *pdev)
struct uart_port *port = platform_get_drvdata(pdev);
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- if (atmel_port->suspended) {
- uart_resume_port(&atmel_uart, port);
- atmel_port->suspended = 0;
- } else
- disable_irq_wake(port->irq);
+ uart_resume_port(&atmel_uart, port);
+ device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup);
return 0;
}
@@ -1513,6 +1517,8 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE));
port = &atmel_ports[pdev->id];
+ port->backup_imr = 0;
+
atmel_init_port(port, pdev);
if (!atmel_use_dma_rx(&port->uart)) {
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 9d8543762a3..4a0d30bed9f 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -28,7 +28,7 @@
#endif
#include <asm/gpio.h>
-#include <asm/mach/bfin_serial_5xx.h>
+#include <mach/bfin_serial_5xx.h>
#ifdef CONFIG_SERIAL_BFIN_DMA
#include <linux/dma-mapping.h>
@@ -817,7 +817,7 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
if (line >= port->info->port.tty->driver->num)
return;
- switch (port->info->port.tty->ldisc.num) {
+ switch (port->info->port.tty->termios->c_line) {
case N_IRDA:
val = UART_GET_GCTL(&bfin_serial_ports[line]);
val |= (IREN | RPOLC);
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index fc1fa9267c5..459f3420a42 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -39,7 +39,7 @@
#include <linux/serial_core.h>
#include <linux/serial.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware/clps7111.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 5c76e0ae058..7274b527a3c 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -50,6 +50,15 @@
#define SCC_WAIT_CLOSING 100
+#define GPIO_CTS 0
+#define GPIO_RTS 1
+#define GPIO_DCD 2
+#define GPIO_DSR 3
+#define GPIO_DTR 4
+#define GPIO_RI 5
+
+#define NUM_GPIOS (GPIO_RI+1)
+
struct uart_cpm_port {
struct uart_port port;
u16 rx_nrfifos;
@@ -68,6 +77,7 @@ struct uart_cpm_port {
unsigned char *rx_buf;
u32 flags;
void (*set_lineif)(struct uart_cpm_port *);
+ struct clk *clk;
u8 brg;
uint dp_addr;
void *mem_addr;
@@ -82,6 +92,7 @@ struct uart_cpm_port {
int wait_closing;
/* value to combine with opcode to form cpm command */
u32 command;
+ int gpios[NUM_GPIOS];
};
extern int cpm_uart_nr;
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index a4f86927a74..25efca5a7a1 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -43,6 +43,9 @@
#include <linux/dma-mapping.h>
#include <linux/fs_uart_pd.h>
#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -96,13 +99,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port)
static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- /* Whee. Do nothing. */
+ struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+
+ if (pinfo->gpios[GPIO_RTS] >= 0)
+ gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
+
+ if (pinfo->gpios[GPIO_DTR] >= 0)
+ gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
}
static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
{
- /* Whee. Do nothing. */
- return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+ struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+ unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ if (pinfo->gpios[GPIO_CTS] >= 0) {
+ if (gpio_get_value(pinfo->gpios[GPIO_CTS]))
+ mctrl &= ~TIOCM_CTS;
+ }
+
+ if (pinfo->gpios[GPIO_DSR] >= 0) {
+ if (gpio_get_value(pinfo->gpios[GPIO_DSR]))
+ mctrl &= ~TIOCM_DSR;
+ }
+
+ if (pinfo->gpios[GPIO_DCD] >= 0) {
+ if (gpio_get_value(pinfo->gpios[GPIO_DCD]))
+ mctrl &= ~TIOCM_CAR;
+ }
+
+ if (pinfo->gpios[GPIO_RI] >= 0) {
+ if (!gpio_get_value(pinfo->gpios[GPIO_RI]))
+ mctrl |= TIOCM_RNG;
+ }
+
+ return mctrl;
}
/*
@@ -566,7 +597,10 @@ static void cpm_uart_set_termios(struct uart_port *port,
out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
}
- cpm_set_brg(pinfo->brg - 1, baud);
+ if (pinfo->clk)
+ clk_set_rate(pinfo->clk, baud);
+ else
+ cpm_set_brg(pinfo->brg - 1, baud);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -991,14 +1025,23 @@ static int cpm_uart_init_port(struct device_node *np,
void __iomem *mem, *pram;
int len;
int ret;
+ int i;
- data = of_get_property(np, "fsl,cpm-brg", &len);
- if (!data || len != 4) {
- printk(KERN_ERR "CPM UART %s has no/invalid "
- "fsl,cpm-brg property.\n", np->name);
- return -EINVAL;
+ data = of_get_property(np, "clock", NULL);
+ if (data) {
+ struct clk *clk = clk_get(NULL, (const char*)data);
+ if (!IS_ERR(clk))
+ pinfo->clk = clk;
+ }
+ if (!pinfo->clk) {
+ data = of_get_property(np, "fsl,cpm-brg", &len);
+ if (!data || len != 4) {
+ printk(KERN_ERR "CPM UART %s has no/invalid "
+ "fsl,cpm-brg property.\n", np->name);
+ return -EINVAL;
+ }
+ pinfo->brg = *data;
}
- pinfo->brg = *data;
data = of_get_property(np, "fsl,cpm-command", &len);
if (!data || len != 4) {
@@ -1050,6 +1093,9 @@ static int cpm_uart_init_port(struct device_node *np,
goto out_pram;
}
+ for (i = 0; i < NUM_GPIOS; i++)
+ pinfo->gpios[i] = of_get_gpio(np, i);
+
return cpm_uart_request_port(&pinfo->port);
out_pram:
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 8249ac49055..bf94a770bb4 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -234,7 +234,7 @@ unsigned long r_alt_ser_baudrate_shadow = 0;
static struct e100_serial rs_table[] = {
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL0_CTRL,
+ .ioport = (unsigned char *)R_SERIAL0_CTRL,
.irq = 1U << 12, /* uses DMA 6 and 7 */
.oclrintradr = R_DMA_CH6_CLR_INTR,
.ofirstadr = R_DMA_CH6_FIRST,
@@ -288,7 +288,7 @@ static struct e100_serial rs_table[] = {
}, /* ttyS0 */
#ifndef CONFIG_SVINTO_SIM
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL1_CTRL,
+ .ioport = (unsigned char *)R_SERIAL1_CTRL,
.irq = 1U << 16, /* uses DMA 8 and 9 */
.oclrintradr = R_DMA_CH8_CLR_INTR,
.ofirstadr = R_DMA_CH8_FIRST,
@@ -344,7 +344,7 @@ static struct e100_serial rs_table[] = {
}, /* ttyS1 */
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL2_CTRL,
+ .ioport = (unsigned char *)R_SERIAL2_CTRL,
.irq = 1U << 4, /* uses DMA 2 and 3 */
.oclrintradr = R_DMA_CH2_CLR_INTR,
.ofirstadr = R_DMA_CH2_FIRST,
@@ -398,7 +398,7 @@ static struct e100_serial rs_table[] = {
}, /* ttyS2 */
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL3_CTRL,
+ .ioport = (unsigned char *)R_SERIAL3_CTRL,
.irq = 1U << 8, /* uses DMA 4 and 5 */
.oclrintradr = R_DMA_CH4_CLR_INTR,
.ofirstadr = R_DMA_CH4_FIRST,
@@ -939,7 +939,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
/* Output */
#define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK)
/* Input */
-#define E100_CTS_GET(info) ((info)->port[REG_STATUS] & E100_CTS_MASK)
+#define E100_CTS_GET(info) ((info)->ioport[REG_STATUS] & E100_CTS_MASK)
/* These are typically PA or PB and 0 means 0V, 1 means 3.3V */
/* Is an output */
@@ -1092,7 +1092,7 @@ e100_rts(struct e100_serial *info, int set)
local_irq_save(flags);
info->rx_ctrl &= ~E100_RTS_MASK;
info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */
- info->port[REG_REC_CTRL] = info->rx_ctrl;
+ info->ioport[REG_REC_CTRL] = info->rx_ctrl;
local_irq_restore(flags);
#ifdef SERIAL_DEBUG_IO
printk("ser%i rts %i\n", info->line, set);
@@ -1142,7 +1142,7 @@ e100_disable_rx(struct e100_serial *info)
{
#ifndef CONFIG_SVINTO_SIM
/* disable the receiver */
- info->port[REG_REC_CTRL] =
+ info->ioport[REG_REC_CTRL] =
(info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
#endif
}
@@ -1152,7 +1152,7 @@ e100_enable_rx(struct e100_serial *info)
{
#ifndef CONFIG_SVINTO_SIM
/* enable the receiver */
- info->port[REG_REC_CTRL] =
+ info->ioport[REG_REC_CTRL] =
(info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
#endif
}
@@ -1490,7 +1490,7 @@ rs_stop(struct tty_struct *tty)
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
- *((unsigned long *)&info->port[REG_XOFF]) = xoff;
+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
local_irq_restore(flags);
}
}
@@ -1513,7 +1513,7 @@ rs_start(struct tty_struct *tty)
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
- *((unsigned long *)&info->port[REG_XOFF]) = xoff;
+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
if (!info->uses_dma_out &&
info->xmit.head != info->xmit.tail && info->xmit.buf)
e100_enable_serial_tx_ready_irq(info);
@@ -1888,7 +1888,7 @@ static void receive_chars_dma(struct e100_serial *info)
handle_all_descr_data(info);
/* Read the status register to detect errors */
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat));
}
@@ -1897,7 +1897,7 @@ static void receive_chars_dma(struct e100_serial *info)
/* If we got an error, we must reset it by reading the
* data_in field
*/
- unsigned char data = info->port[REG_DATA];
+ unsigned char data = info->ioport[REG_DATA];
PROCSTAT(ser_stat[info->line].errors_cnt++);
DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n",
@@ -2077,7 +2077,7 @@ static int force_eop_if_needed(struct e100_serial *info)
/* We check data_avail bit to determine if data has
* arrived since last time
*/
- unsigned char rstat = info->port[REG_STATUS];
+ unsigned char rstat = info->ioport[REG_STATUS];
/* error or datavail? */
if (rstat & SER_ERROR_MASK) {
@@ -2096,7 +2096,7 @@ static int force_eop_if_needed(struct e100_serial *info)
TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n",
rstat | (info->line << 8)));
/* Read data to clear status flags */
- (void)info->port[REG_DATA];
+ (void)info->ioport[REG_DATA];
info->forced_eop = 0;
START_FLUSH_FAST_TIMER(info, "magic");
@@ -2296,7 +2296,7 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
}
/* Read data and status at the same time */
- data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
+ data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
more_data:
if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) {
DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
@@ -2391,7 +2391,7 @@ more_data:
info->icount.rx++;
- data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
+ data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read));
goto more_data;
@@ -2413,7 +2413,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
return handle_ser_rx_interrupt_no_dma(info);
}
/* DMA is used */
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
}
@@ -2426,7 +2426,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
/* If we got an error, we must reset it by reading the
* data_in field
*/
- data = info->port[REG_DATA];
+ data = info->ioport[REG_DATA];
DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data));
DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat));
if (!data && (rstat & SER_FRAMING_ERR_MASK)) {
@@ -2528,10 +2528,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
unsigned char rstat;
DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char));
local_irq_save(flags);
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
- info->port[REG_TR_DATA] = info->x_char;
+ info->ioport[REG_TR_DATA] = info->x_char;
info->icount.tx++;
info->x_char = 0;
/* We must enable since it is disabled in ser_interrupt */
@@ -2545,7 +2545,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
/* We only use normal tx interrupt when sending x_char */
DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0));
local_irq_save(flags);
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
e100_disable_serial_tx_ready_irq(info);
if (info->port.tty->stopped)
@@ -2573,7 +2573,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail]));
/* Send a byte, rs485 timing is critical so turn of ints */
local_irq_save(flags);
- info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
+ info->ioport[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
info->icount.tx++;
if (info->xmit.head == info->xmit.tail) {
@@ -2848,7 +2848,7 @@ startup(struct e100_serial * info)
/* dummy read to reset any serial errors */
- (void)info->port[REG_DATA];
+ (void)info->ioport[REG_DATA];
/* enable the interrupts */
if (info->uses_dma_out)
@@ -2897,7 +2897,7 @@ shutdown(struct e100_serial * info)
/* shut down the transmitter and receiver */
DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line));
e100_disable_rx(info);
- info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
+ info->ioport[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
/* disable interrupts, reset dma channels */
if (info->uses_dma_in) {
@@ -2968,7 +2968,7 @@ change_speed(struct e100_serial *info)
if (!info->port.tty || !info->port.tty->termios)
return;
- if (!info->port)
+ if (!info->ioport)
return;
cflag = info->port.tty->termios->c_cflag;
@@ -3037,7 +3037,7 @@ change_speed(struct e100_serial *info)
info->baud = cflag_to_baud(cflag);
#ifndef CONFIG_SVINTO_SIM
- info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
+ info->ioport[REG_BAUD] = cflag_to_etrax_baud(cflag);
#endif /* CONFIG_SVINTO_SIM */
}
@@ -3097,8 +3097,8 @@ change_speed(struct e100_serial *info)
/* actually write the control regs to the hardware */
- info->port[REG_TR_CTRL] = info->tx_ctrl;
- info->port[REG_REC_CTRL] = info->rx_ctrl;
+ info->ioport[REG_TR_CTRL] = info->tx_ctrl;
+ info->ioport[REG_REC_CTRL] = info->rx_ctrl;
xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty));
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
if (info->port.tty->termios->c_iflag & IXON ) {
@@ -3107,7 +3107,7 @@ change_speed(struct e100_serial *info)
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
- *((unsigned long *)&info->port[REG_XOFF]) = xoff;
+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
local_irq_restore(flags);
#endif /* !CONFIG_SVINTO_SIM */
@@ -3156,7 +3156,7 @@ static int rs_raw_write(struct tty_struct *tty,
#ifdef SERIAL_DEBUG_DATA
if (info->line == SERIAL_DEBUG_LINE)
printk("rs_raw_write (%d), status %d\n",
- count, info->port[REG_STATUS]);
+ count, info->ioport[REG_STATUS]);
#endif
#ifdef CONFIG_SVINTO_SIM
@@ -3427,7 +3427,7 @@ get_serial_info(struct e100_serial * info,
memset(&tmp, 0, sizeof(tmp));
tmp.type = info->type;
tmp.line = info->line;
- tmp.port = (int)info->port;
+ tmp.port = (int)info->ioport;
tmp.irq = info->irq;
tmp.flags = info->flags;
tmp.baud_base = info->baud_base;
@@ -3557,14 +3557,14 @@ char *get_control_state_str(int MLines, char *s)
}
#endif
-static void
+static int
rs_break(struct tty_struct *tty, int break_state)
{
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
unsigned long flags;
- if (!info->port)
- return;
+ if (!info->ioport)
+ return -EIO;
local_irq_save(flags);
if (break_state == -1) {
@@ -3575,8 +3575,9 @@ rs_break(struct tty_struct *tty, int break_state)
/* Set bit 7 (txd) and 6 (tr_enable) */
info->tx_ctrl |= (0x80 | 0x40);
}
- info->port[REG_TR_CTRL] = info->tx_ctrl;
+ info->ioport[REG_TR_CTRL] = info->tx_ctrl;
local_irq_restore(flags);
+ return 0;
}
static int
@@ -4231,9 +4232,9 @@ static int line_info(char *buf, struct e100_serial *info)
unsigned long tmp;
ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d",
- info->line, (unsigned long)info->port, info->irq);
+ info->line, (unsigned long)info->ioport, info->irq);
- if (!info->port || (info->type == PORT_UNKNOWN)) {
+ if (!info->ioport || (info->type == PORT_UNKNOWN)) {
ret += sprintf(buf+ret, "\n");
return ret;
}
@@ -4281,7 +4282,7 @@ static int line_info(char *buf, struct e100_serial *info)
}
{
- unsigned char rstat = info->port[REG_STATUS];
+ unsigned char rstat = info->ioport[REG_STATUS];
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) )
ret += sprintf(buf+ret, " xoff_detect:1");
}
@@ -4502,7 +4503,7 @@ rs_init(void)
if (info->enabled) {
printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
- serial_driver->name, info->line, (unsigned int)info->port);
+ serial_driver->name, info->line, (unsigned int)info->ioport);
}
}
#ifdef CONFIG_ETRAX_FAST_TIMER
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h
index ccd0f32b737..e3c5c8c3c09 100644
--- a/drivers/serial/crisv10.h
+++ b/drivers/serial/crisv10.h
@@ -36,8 +36,9 @@ struct etrax_recv_buffer {
};
struct e100_serial {
+ struct tty_port port;
int baud;
- volatile u8 *port; /* R_SERIALx_CTRL */
+ volatile u8 *ioport; /* R_SERIALx_CTRL */
u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */
/* Output registers */
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index e0da4dc7bbf..3f90f1bbbbc 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -44,8 +44,8 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/arch/imx-uart.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
/* Register definitions */
#define URXD0 0x0 /* Receiver Register */
@@ -127,8 +127,13 @@
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
-#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
-#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
+#ifdef CONFIG_ARCH_IMX
+#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */
+#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */
+#endif
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+#define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */
+#endif
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
#define UCR3_BPEN (1<<0) /* Preset registers enable */
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
@@ -445,7 +450,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
imx_txint(irq, dev_id);
- if (sts & USR1_RTSS)
+ if (sts & USR1_RTSD)
imx_rtsint(irq, dev_id);
return IRQ_HANDLED;
@@ -598,6 +603,12 @@ static int imx_startup(struct uart_port *port)
temp |= (UCR2_RXEN | UCR2_TXEN);
writel(temp, sport->port.membase + UCR2);
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+ temp = readl(sport->port.membase + UCR3);
+ temp |= UCR3_RXDMUXSEL;
+ writel(temp, sport->port.membase + UCR3);
+#endif
+
/*
* Enable modem status interrupts
*/
@@ -1133,13 +1144,19 @@ static int serial_imx_probe(struct platform_device *pdev)
if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
sport->have_rtscts = 1;
- if (pdata->init)
- pdata->init(pdev);
+ if (pdata->init) {
+ ret = pdata->init(pdev);
+ if (ret)
+ goto clkput;
+ }
uart_add_one_port(&imx_reg, &sport->port);
platform_set_drvdata(pdev, &sport->port);
return 0;
+clkput:
+ clk_put(sport->clk);
+ clk_disable(sport->clk);
unmap:
iounmap(sport->port.membase);
free:
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 9f8ccb735c1..3f489329e8d 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -35,8 +35,8 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/arch/netx-regs.h>
+#include <mach/hardware.h>
+#include <mach/netx-regs.h>
/* We've been assigned a range on the "Low-density serial ports" major */
#define SERIAL_NX_MAJOR 204
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b9a93f326fb..abc00be5543 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -45,9 +45,9 @@
#include <linux/clk.h>
#include <asm/io.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/arch/pxa-regs.h>
+#include <mach/pxa-regs.h>
struct uart_pxa_port {
@@ -534,6 +534,11 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
serial_out(up, UART_IER, up->ier);
+ if (termios->c_cflag & CRTSCTS)
+ up->mcr |= UART_MCR_AFE;
+ else
+ up->mcr &= ~UART_MCR_AFE;
+
serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c
index a1102053e55..c8b4266ac35 100644
--- a/drivers/serial/s3c2400.c
+++ b/drivers/serial/s3c2400.c
@@ -17,10 +17,10 @@
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index c5f03f41686..40a2531b554 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -19,10 +19,10 @@
#include <linux/serial.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index ce0c220e3e9..d0170319c72 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -19,10 +19,10 @@
#include <linux/serial.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
index 38f954bd39c..d4a2b17b249 100644
--- a/drivers/serial/s3c2440.c
+++ b/drivers/serial/s3c2440.c
@@ -19,10 +19,10 @@
#include <linux/serial.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index a5e76cc1807..b24a25ea6bc 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -39,7 +39,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/mach/serial_sa1100.h>
/* We've been assigned a range on the "Low-density serial ports" major */
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index d852f83f890..5a88b3f9fe9 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -45,10 +45,10 @@
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 0edbc5dd378..998e89dc5aa 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -26,8 +26,8 @@
#include <asm/irq.h>
#include <asm/mach/irq.h>
-#include <asm/arch/regs-uart.h>
-#include <asm/arch/regs-irq.h>
+#include <mach/regs-uart.h>
+#include <mach/regs-irq.h>
#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -63,8 +63,44 @@
#define UART_DUMMY_LSR_RX 0x100
#define UART_PORT_SIZE (KS8695_USR - KS8695_URRB + 4)
-#define tx_enabled(port) ((port)->unused[0])
-#define rx_enabled(port) ((port)->unused[1])
+static inline int tx_enabled(struct uart_port *port)
+{
+ return port->unused[0] & 1;
+}
+
+static inline int rx_enabled(struct uart_port *port)
+{
+ return port->unused[0] & 2;
+}
+
+static inline int ms_enabled(struct uart_port *port)
+{
+ return port->unused[0] & 4;
+}
+
+static inline void ms_enable(struct uart_port *port, int enabled)
+{
+ if(enabled)
+ port->unused[0] |= 4;
+ else
+ port->unused[0] &= ~4;
+}
+
+static inline void rx_enable(struct uart_port *port, int enabled)
+{
+ if(enabled)
+ port->unused[0] |= 2;
+ else
+ port->unused[0] &= ~2;
+}
+
+static inline void tx_enable(struct uart_port *port, int enabled)
+{
+ if(enabled)
+ port->unused[0] |= 1;
+ else
+ port->unused[0] &= ~1;
+}
#ifdef SUPPORT_SYSRQ
@@ -75,7 +111,7 @@ static void ks8695uart_stop_tx(struct uart_port *port)
{
if (tx_enabled(port)) {
disable_irq(KS8695_IRQ_UART_TX);
- tx_enabled(port) = 0;
+ tx_enable(port, 0);
}
}
@@ -83,7 +119,7 @@ static void ks8695uart_start_tx(struct uart_port *port)
{
if (!tx_enabled(port)) {
enable_irq(KS8695_IRQ_UART_TX);
- tx_enabled(port) = 1;
+ tx_enable(port, 1);
}
}
@@ -91,18 +127,24 @@ static void ks8695uart_stop_rx(struct uart_port *port)
{
if (rx_enabled(port)) {
disable_irq(KS8695_IRQ_UART_RX);
- rx_enabled(port) = 0;
+ rx_enable(port, 0);
}
}
static void ks8695uart_enable_ms(struct uart_port *port)
{
- enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+ if (!ms_enabled(port)) {
+ enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+ ms_enable(port,1);
+ }
}
static void ks8695uart_disable_ms(struct uart_port *port)
{
- disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+ if (ms_enabled(port)) {
+ disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+ ms_enable(port,0);
+ }
}
static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
@@ -285,8 +327,9 @@ static int ks8695uart_startup(struct uart_port *port)
int retval;
set_irq_flags(KS8695_IRQ_UART_TX, IRQF_VALID | IRQF_NOAUTOEN);
- tx_enabled(port) = 0;
- rx_enabled(port) = 1;
+ tx_enable(port, 0);
+ rx_enable(port, 1);
+ ms_enable(port, 1);
/*
* Allocate the IRQ
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 208e42ba945..3df2aaec829 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -410,7 +410,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
static inline int scif_txroom(struct uart_port *port)
@@ -422,6 +421,22 @@ static inline int scif_rxroom(struct uart_port *port)
{
return sci_in(port, SCRFDR) & 0xff;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+static inline int scif_txroom(struct uart_port *port)
+{
+ if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
+ return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
+ else /* SCIF2 */
+ return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
+}
+
+static inline int scif_rxroom(struct uart_port *port)
+{
+ if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
+ return sci_in(port, SCRFDR) & 0xff;
+ else /* SCIF2 */
+ return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
+}
#else
static inline int scif_txroom(struct uart_port *port)
{
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index eb84833233f..8a0749e34ca 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -123,8 +123,9 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCSPTR1 0xffe08024 /* 16 bit SCIF */
+# define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */
# define SCIF_ORER 0x0001 /* overrun error bit */
-# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
# define SCSPTR0 0xff923020 /* 16 bit SCIF */
@@ -188,6 +189,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SHX3)
@@ -225,14 +227,21 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define SCIF_ORER 0x0200
-#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
-#define SCIF_RFDC_MASK 0x007f
-#define SCIF_TXROOM_MAX 64
+# define SCIF_ORER 0x0200
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
+# define SCIF_RFDC_MASK 0x007f
+# define SCIF_TXROOM_MAX 64
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK )
+# define SCIF_RFDC_MASK 0x007f
+# define SCIF_TXROOM_MAX 64
+/* SH7763 SCIF2 support */
+# define SCIF2_RFDC_MASK 0x001f
+# define SCIF2_TXROOM_MAX 16
#else
-#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
-#define SCIF_RFDC_MASK 0x001f
-#define SCIF_TXROOM_MAX 16
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
+# define SCIF_RFDC_MASK 0x001f
+# define SCIF_TXROOM_MAX 16
#endif
#if defined(SCI_ONLY)
@@ -442,7 +451,6 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
@@ -450,6 +458,14 @@ SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
+SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16)
+SCIF_FNS(SCLSR2, 0, 0, 0x24, 16)
+SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
+SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
+SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
+SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
#else
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
@@ -652,6 +668,9 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
if (port->mapbase == 0xffe08000)
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffe10000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */
+
return 1;
}
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
@@ -764,8 +783,7 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index aeeec5588af..a94a2ab4b57 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -17,11 +17,11 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/of_device.h>
#include <asm/hypervisor.h>
#include <asm/spitfire.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#include <asm/irq.h>
#if defined(CONFIG_MAGIC_SYSRQ)
@@ -616,7 +616,7 @@ static int __devexit hv_remove(struct of_device *dev)
return 0;
}
-static struct of_device_id hv_match[] = {
+static const struct of_device_id hv_match[] = {
{
.name = "console",
.compatible = "qcn",
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 15ee497e1c7..0355efe115d 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -32,11 +32,11 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#if defined(CONFIG_SERIAL_SUNSAB_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -1078,7 +1078,7 @@ static int __devexit sab_remove(struct of_device *op)
return 0;
}
-static struct of_device_id sab_match[] = {
+static const struct of_device_id sab_match[] = {
{
.name = "se",
},
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index e24e6823508..a4dc79b1d7a 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -35,11 +35,11 @@
#include <linux/serial_reg.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -1506,7 +1506,7 @@ static int __devexit su_remove(struct of_device *op)
return 0;
}
-static struct of_device_id su_match[] = {
+static const struct of_device_id su_match[] = {
{
.name = "su",
},
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 0f3d69b86d6..45a299f3561 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -32,11 +32,11 @@
#include <linux/serio.h>
#endif
#include <linux/init.h>
+#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -1480,7 +1480,7 @@ static int __devexit zs_remove(struct of_device *op)
return 0;
}
-static struct of_device_id zs_match[] = {
+static const struct of_device_id zs_match[] = {
{
.name = "zs",
},
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c
deleted file mode 100644
index 5acf061b6cd..00000000000
--- a/drivers/serial/v850e_uart.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * drivers/serial/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
- *
- * Copyright (C) 2001,02,03 NEC Electronics Corporation
- * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
- *
- * 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.
- *
- * Written by Miles Bader <miles@gnu.org>
- */
-
-/* This driver supports both the original V850E UART interface (called
- merely `UART' in the docs) and the newer `UARTB' interface, which is
- roughly a superset of the first one. The selection is made at
- configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
- presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
- can never have both.
-
- The UARTB interface also has a 16-entry FIFO mode, which is not
- yet supported by this driver. */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/console.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-
-#include <asm/v850e_uart.h>
-
-/* Initial UART state. This may be overridden by machine-dependent headers. */
-#ifndef V850E_UART_INIT_BAUD
-#define V850E_UART_INIT_BAUD 115200
-#endif
-#ifndef V850E_UART_INIT_CFLAGS
-#define V850E_UART_INIT_CFLAGS (B115200 | CS8 | CREAD)
-#endif
-
-/* A string used for prefixing printed descriptions; since the same UART
- macro is actually used on other chips than the V850E. This must be a
- constant string. */
-#ifndef V850E_UART_CHIP_NAME
-#define V850E_UART_CHIP_NAME "V850E"
-#endif
-
-#define V850E_UART_MINOR_BASE 64 /* First tty minor number */
-
-
-/* Low-level UART functions. */
-
-/* Configure and turn on uart channel CHAN, using the termios `control
- modes' bits in CFLAGS, and a baud-rate of BAUD. */
-void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
-{
- int flags;
- v850e_uart_speed_t old_speed;
- v850e_uart_config_t old_config;
- v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
- v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);
-
- /* Disable interrupts while we're twiddling the hardware. */
- local_irq_save (flags);
-
-#ifdef V850E_UART_PRE_CONFIGURE
- V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
-#endif
-
- old_config = V850E_UART_CONFIG (chan);
- old_speed = v850e_uart_speed (chan);
-
- if (! v850e_uart_speed_eq (old_speed, new_speed)) {
- /* The baud rate has changed. First, disable the UART. */
- V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
- old_config = 0; /* Force the uart to be re-initialized. */
-
- /* Reprogram the baud-rate generator. */
- v850e_uart_set_speed (chan, new_speed);
- }
-
- if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
- /* If we are using the uart for the first time, start by
- enabling it, which must be done before turning on any
- other bits. */
- V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
- /* See the initial state. */
- old_config = V850E_UART_CONFIG (chan);
- }
-
- if (new_config != old_config) {
- /* Which of the TXE/RXE bits we'll temporarily turn off
- before changing other control bits. */
- unsigned temp_disable = 0;
- /* Which of the TXE/RXE bits will be enabled. */
- unsigned enable = 0;
- unsigned changed_bits = new_config ^ old_config;
-
- /* Which of RX/TX will be enabled in the new configuration. */
- if (new_config & V850E_UART_CONFIG_RX_BITS)
- enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
- if (new_config & V850E_UART_CONFIG_TX_BITS)
- enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);
-
- /* Figure out which of RX/TX needs to be disabled; note
- that this will only happen if they're not already
- disabled. */
- if (changed_bits & V850E_UART_CONFIG_RX_BITS)
- temp_disable
- |= (old_config & V850E_UART_CONFIG_RX_ENABLE);
- if (changed_bits & V850E_UART_CONFIG_TX_BITS)
- temp_disable
- |= (old_config & V850E_UART_CONFIG_TX_ENABLE);
-
- /* We have to turn off RX and/or TX mode before changing
- any associated control bits. */
- if (temp_disable)
- V850E_UART_CONFIG (chan) = old_config & ~temp_disable;
-
- /* Write the new control bits, while RX/TX are disabled. */
- if (changed_bits & ~enable)
- V850E_UART_CONFIG (chan) = new_config & ~enable;
-
- v850e_uart_config_delay (new_config, new_speed);
-
- /* Write the final version, with enable bits turned on. */
- V850E_UART_CONFIG (chan) = new_config;
- }
-
- local_irq_restore (flags);
-}
-
-
-/* Low-level console. */
-
-#ifdef CONFIG_V850E_UART_CONSOLE
-
-static void v850e_uart_cons_write (struct console *co,
- const char *s, unsigned count)
-{
- if (count > 0) {
- unsigned chan = co->index;
- unsigned irq = V850E_UART_TX_IRQ (chan);
- int irq_was_enabled, irq_was_pending, flags;
-
- /* We don't want to get `transmission completed'
- interrupts, since we're busy-waiting, so we disable them
- while sending (we don't disable interrupts entirely
- because sending over a serial line is really slow). We
- save the status of the tx interrupt and restore it when
- we're done so that using printk doesn't interfere with
- normal serial transmission (other than interleaving the
- output, of course!). This should work correctly even if
- this function is interrupted and the interrupt printks
- something. */
-
- /* Disable interrupts while fiddling with tx interrupt. */
- local_irq_save (flags);
- /* Get current tx interrupt status. */
- irq_was_enabled = v850e_intc_irq_enabled (irq);
- irq_was_pending = v850e_intc_irq_pending (irq);
- /* Disable tx interrupt if necessary. */
- if (irq_was_enabled)
- v850e_intc_disable_irq (irq);
- /* Turn interrupts back on. */
- local_irq_restore (flags);
-
- /* Send characters. */
- while (count > 0) {
- int ch = *s++;
-
- if (ch == '\n') {
- /* We don't have the benefit of a tty
- driver, so translate NL into CR LF. */
- v850e_uart_wait_for_xmit_ok (chan);
- v850e_uart_putc (chan, '\r');
- }
-
- v850e_uart_wait_for_xmit_ok (chan);
- v850e_uart_putc (chan, ch);
-
- count--;
- }
-
- /* Restore saved tx interrupt status. */
- if (irq_was_enabled) {
- /* Wait for the last character we sent to be
- completely transmitted (as we'll get an
- interrupt interrupt at that point). */
- v850e_uart_wait_for_xmit_done (chan);
- /* Clear pending interrupts received due
- to our transmission, unless there was already
- one pending, in which case we want the
- handler to be called. */
- if (! irq_was_pending)
- v850e_intc_clear_pending_irq (irq);
- /* ... and then turn back on handling. */
- v850e_intc_enable_irq (irq);
- }
- }
-}
-
-extern struct uart_driver v850e_uart_driver;
-static struct console v850e_uart_cons =
-{
- .name = "ttyS",
- .write = v850e_uart_cons_write,
- .device = uart_console_device,
- .flags = CON_PRINTBUFFER,
- .cflag = V850E_UART_INIT_CFLAGS,
- .index = -1,
- .data = &v850e_uart_driver,
-};
-
-void v850e_uart_cons_init (unsigned chan)
-{
- v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
- V850E_UART_INIT_BAUD);
- v850e_uart_cons.index = chan;
- register_console (&v850e_uart_cons);
- printk ("Console: %s on-chip UART channel %d\n",
- V850E_UART_CHIP_NAME, chan);
-}
-
-/* This is what the init code actually calls. */
-static int v850e_uart_console_init (void)
-{
- v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
- return 0;
-}
-console_initcall(v850e_uart_console_init);
-
-#define V850E_UART_CONSOLE &v850e_uart_cons
-
-#else /* !CONFIG_V850E_UART_CONSOLE */
-#define V850E_UART_CONSOLE 0
-#endif /* CONFIG_V850E_UART_CONSOLE */
-
-/* TX/RX interrupt handlers. */
-
-static void v850e_uart_stop_tx (struct uart_port *port);
-
-void v850e_uart_tx (struct uart_port *port)
-{
- struct circ_buf *xmit = &port->info->xmit;
- int stopped = uart_tx_stopped (port);
-
- if (v850e_uart_xmit_ok (port->line)) {
- int tx_ch;
-
- if (port->x_char) {
- tx_ch = port->x_char;
- port->x_char = 0;
- } else if (!uart_circ_empty (xmit) && !stopped) {
- tx_ch = xmit->buf[xmit->tail];
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- } else
- goto no_xmit;
-
- v850e_uart_putc (port->line, tx_ch);
- port->icount.tx++;
-
- if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
- uart_write_wakeup (port);
- }
-
- no_xmit:
- if (uart_circ_empty (xmit) || stopped)
- v850e_uart_stop_tx (port, stopped);
-}
-
-static irqreturn_t v850e_uart_tx_irq(int irq, void *data)
-{
- struct uart_port *port = data;
- v850e_uart_tx (port);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t v850e_uart_rx_irq(int irq, void *data)
-{
- struct uart_port *port = data;
- unsigned ch_stat = TTY_NORMAL;
- unsigned ch = v850e_uart_getc (port->line);
- unsigned err = v850e_uart_err (port->line);
-
- if (err) {
- if (err & V850E_UART_ERR_OVERRUN) {
- ch_stat = TTY_OVERRUN;
- port->icount.overrun++;
- } else if (err & V850E_UART_ERR_FRAME) {
- ch_stat = TTY_FRAME;
- port->icount.frame++;
- } else if (err & V850E_UART_ERR_PARITY) {
- ch_stat = TTY_PARITY;
- port->icount.parity++;
- }
- }
-
- port->icount.rx++;
-
- tty_insert_flip_char (port->info->port.tty, ch, ch_stat);
- tty_schedule_flip (port->info->port.tty);
-
- return IRQ_HANDLED;
-}
-
-
-/* Control functions for the serial framework. */
-
-static void v850e_uart_nop (struct uart_port *port) { }
-static int v850e_uart_success (struct uart_port *port) { return 0; }
-
-static unsigned v850e_uart_tx_empty (struct uart_port *port)
-{
- return TIOCSER_TEMT; /* Can't detect. */
-}
-
-static void v850e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
-{
-#ifdef V850E_UART_SET_RTS
- V850E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
-#endif
-}
-
-static unsigned v850e_uart_get_mctrl (struct uart_port *port)
-{
- /* We don't support DCD or DSR, so consider them permanently active. */
- int mctrl = TIOCM_CAR | TIOCM_DSR;
-
- /* We may support CTS. */
-#ifdef V850E_UART_CTS
- mctrl |= V850E_UART_CTS(port->line) ? TIOCM_CTS : 0;
-#else
- mctrl |= TIOCM_CTS;
-#endif
-
- return mctrl;
-}
-
-static void v850e_uart_start_tx (struct uart_port *port)
-{
- v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
- v850e_uart_tx (port);
- v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
-}
-
-static void v850e_uart_stop_tx (struct uart_port *port)
-{
- v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
-}
-
-static void v850e_uart_start_rx (struct uart_port *port)
-{
- v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->line));
-}
-
-static void v850e_uart_stop_rx (struct uart_port *port)
-{
- v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->line));
-}
-
-static void v850e_uart_break_ctl (struct uart_port *port, int break_ctl)
-{
- /* Umm, do this later. */
-}
-
-static int v850e_uart_startup (struct uart_port *port)
-{
- int err;
-
- /* Alloc RX irq. */
- err = request_irq (V850E_UART_RX_IRQ (port->line), v850e_uart_rx_irq,
- IRQF_DISABLED, "v850e_uart", port);
- if (err)
- return err;
-
- /* Alloc TX irq. */
- err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
- IRQF_DISABLED, "v850e_uart", port);
- if (err) {
- free_irq (V850E_UART_RX_IRQ (port->line), port);
- return err;
- }
-
- v850e_uart_start_rx (port);
-
- return 0;
-}
-
-static void v850e_uart_shutdown (struct uart_port *port)
-{
- /* Disable port interrupts. */
- free_irq (V850E_UART_TX_IRQ (port->line), port);
- free_irq (V850E_UART_RX_IRQ (port->line), port);
-
- /* Turn off xmit/recv enable bits. */
- V850E_UART_CONFIG (port->line)
- &= ~(V850E_UART_CONFIG_TX_ENABLE
- | V850E_UART_CONFIG_RX_ENABLE);
- /* Then reset the channel. */
- V850E_UART_CONFIG (port->line) = 0;
-}
-
-static void
-v850e_uart_set_termios (struct uart_port *port, struct ktermios *termios,
- struct ktermios *old)
-{
- unsigned cflags = termios->c_cflag;
-
- /* Restrict flags to legal values. */
- if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
- /* The new value of CSIZE is invalid, use the old value. */
- cflags = (cflags & ~CSIZE)
- | (old ? (old->c_cflag & CSIZE) : CS8);
-
- termios->c_cflag = cflags;
-
- v850e_uart_configure (port->line, cflags,
- uart_get_baud_rate (port, termios, old,
- v850e_uart_min_baud(),
- v850e_uart_max_baud()));
-}
-
-static const char *v850e_uart_type (struct uart_port *port)
-{
- return port->type == PORT_V850E_UART ? "v850e_uart" : 0;
-}
-
-static void v850e_uart_config_port (struct uart_port *port, int flags)
-{
- if (flags & UART_CONFIG_TYPE)
- port->type = PORT_V850E_UART;
-}
-
-static int
-v850e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
-{
- if (ser->type != PORT_UNKNOWN && ser->type != PORT_V850E_UART)
- return -EINVAL;
- if (ser->irq != V850E_UART_TX_IRQ (port->line))
- return -EINVAL;
- return 0;
-}
-
-static struct uart_ops v850e_uart_ops = {
- .tx_empty = v850e_uart_tx_empty,
- .get_mctrl = v850e_uart_get_mctrl,
- .set_mctrl = v850e_uart_set_mctrl,
- .start_tx = v850e_uart_start_tx,
- .stop_tx = v850e_uart_stop_tx,
- .stop_rx = v850e_uart_stop_rx,
- .enable_ms = v850e_uart_nop,
- .break_ctl = v850e_uart_break_ctl,
- .startup = v850e_uart_startup,
- .shutdown = v850e_uart_shutdown,
- .set_termios = v850e_uart_set_termios,
- .type = v850e_uart_type,
- .release_port = v850e_uart_nop,
- .request_port = v850e_uart_success,
- .config_port = v850e_uart_config_port,
- .verify_port = v850e_uart_verify_port,
-};
-
-/* Initialization and cleanup. */
-
-static struct uart_driver v850e_uart_driver = {
- .owner = THIS_MODULE,
- .driver_name = "v850e_uart",
- .dev_name = "ttyS",
- .major = TTY_MAJOR,
- .minor = V850E_UART_MINOR_BASE,
- .nr = V850E_UART_NUM_CHANNELS,
- .cons = V850E_UART_CONSOLE,
-};
-
-
-static struct uart_port v850e_uart_ports[V850E_UART_NUM_CHANNELS];
-
-static int __init v850e_uart_init (void)
-{
- int rval;
-
- printk (KERN_INFO "%s on-chip UART\n", V850E_UART_CHIP_NAME);
-
- rval = uart_register_driver (&v850e_uart_driver);
- if (rval == 0) {
- unsigned chan;
-
- for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
- struct uart_port *port = &v850e_uart_ports[chan];
-
- memset (port, 0, sizeof *port);
-
- port->ops = &v850e_uart_ops;
- port->line = chan;
- port->iotype = UPIO_MEM;
- port->flags = UPF_BOOT_AUTOCONF;
-
- /* We actually use multiple IRQs, but the serial
- framework seems to mainly use this for
- informational purposes anyway. Here we use the TX
- irq. */
- port->irq = V850E_UART_TX_IRQ (chan);
-
- /* The serial framework doesn't really use these
- membase/mapbase fields for anything useful, but
- it requires that they be something non-zero to
- consider the port `valid', and also uses them
- for informational purposes. */
- port->membase = (void *)V850E_UART_BASE_ADDR (chan);
- port->mapbase = V850E_UART_BASE_ADDR (chan);
-
- /* The framework insists on knowing the uart's master
- clock freq, though it doesn't seem to do anything
- useful for us with it. We must make it at least
- higher than (the maximum baud rate * 16), otherwise
- the framework will puke during its internal
- calculations, and force the baud rate to be 9600.
- To be accurate though, just repeat the calculation
- we use when actually setting the speed. */
- port->uartclk = v850e_uart_max_clock() * 16;
-
- uart_add_one_port (&v850e_uart_driver, port);
- }
- }
-
- return rval;
-}
-
-static void __exit v850e_uart_exit (void)
-{
- unsigned chan;
-
- for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++)
- uart_remove_one_port (&v850e_uart_driver,
- &v850e_uart_ports[chan]);
-
- uart_unregister_driver (&v850e_uart_driver);
-}
-
-module_init (v850e_uart_init);
-module_exit (v850e_uart_exit);
-
-MODULE_AUTHOR ("Miles Bader");
-MODULE_DESCRIPTION ("NEC " V850E_UART_CHIP_NAME " on-chip UART");
-MODULE_LICENSE ("GPL");