aboutsummaryrefslogtreecommitdiff
path: root/drivers/tty/serial/arc_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/arc_uart.c')
-rw-r--r--drivers/tty/serial/arc_uart.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c
index da734222e53..008c223eaf2 100644
--- a/drivers/tty/serial/arc_uart.c
+++ b/drivers/tty/serial/arc_uart.c
@@ -162,7 +162,7 @@ static unsigned int arc_serial_tx_empty(struct uart_port *port)
/*
* Driver internal routine, used by both tty(serial core) as well as tx-isr
* -Called under spinlock in either cases
- * -also tty->stopped / tty->hw_stopped has already been checked
+ * -also tty->stopped has already been checked
* = by uart_start( ) before calling us
* = tx_ist checks that too before calling
*/
@@ -177,7 +177,7 @@ static void arc_serial_tx_chars(struct arc_uart_port *uart)
uart->port.icount.tx++;
uart->port.x_char = 0;
sent = 1;
- } else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */
+ } else if (!uart_circ_empty(xmit)) {
ch = xmit->buf[xmit->tail];
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
uart->port.icount.tx++;
@@ -209,9 +209,9 @@ static void arc_serial_start_tx(struct uart_port *port)
arc_serial_tx_chars(uart);
}
-static void arc_serial_rx_chars(struct arc_uart_port *uart)
+static void arc_serial_rx_chars(struct arc_uart_port *uart, unsigned int status)
{
- unsigned int status, ch, flg = 0;
+ unsigned int ch, flg = 0;
/*
* UART has 4 deep RX-FIFO. Driver's recongnition of this fact
@@ -222,11 +222,11 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart)
* before RX-EMPTY=0, implies some sort of buffering going on in the
* controller, which is indeed the Rx-FIFO.
*/
- while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) {
-
- ch = UART_GET_DATA(uart);
- uart->port.icount.rx++;
-
+ do {
+ /*
+ * This could be an Rx Intr for err (no data),
+ * so check err and clear that Intr first
+ */
if (unlikely(status & (RXOERR | RXFERR))) {
if (status & RXOERR) {
uart->port.icount.overrun++;
@@ -242,14 +242,19 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart)
} else
flg = TTY_NORMAL;
- if (unlikely(uart_handle_sysrq_char(&uart->port, ch)))
- goto done;
+ if (status & RXEMPTY)
+ continue;
+
+ ch = UART_GET_DATA(uart);
+ uart->port.icount.rx++;
- uart_insert_char(&uart->port, status, RXOERR, ch, flg);
+ if (!(uart_handle_sysrq_char(&uart->port, ch)))
+ uart_insert_char(&uart->port, status, RXOERR, ch, flg);
-done:
+ spin_unlock(&uart->port.lock);
tty_flip_buffer_push(&uart->port.state->port);
- }
+ spin_lock(&uart->port.lock);
+ } while (!((status = UART_GET_STATUS(uart)) & RXEMPTY));
}
/*
@@ -292,11 +297,11 @@ static irqreturn_t arc_serial_isr(int irq, void *dev_id)
* notifications from the UART Controller.
* To demultiplex between the two, we check the relevant bits
*/
- if ((status & RXIENB) && !(status & RXEMPTY)) {
+ if (status & RXIENB) {
/* already in ISR, no need of xx_irqsave */
spin_lock(&uart->port.lock);
- arc_serial_rx_chars(uart);
+ arc_serial_rx_chars(uart, status);
spin_unlock(&uart->port.lock);
}
@@ -528,7 +533,7 @@ arc_uart_init_one(struct platform_device *pdev, int dev_id)
unsigned long *plat_data;
struct arc_uart_port *uart = &arc_uart_ports[dev_id];
- plat_data = ((unsigned long *)(pdev->dev.platform_data));
+ plat_data = dev_get_platdata(&pdev->dev);
if (!plat_data)
return -ENODEV;
@@ -547,8 +552,8 @@ arc_uart_init_one(struct platform_device *pdev, int dev_id)
}
uart->port.uartclk = val;
- if (of_property_read_u32(np, "baud", &val)) {
- dev_err(&pdev->dev, "baud property NOT set\n");
+ if (of_property_read_u32(np, "current-speed", &val)) {
+ dev_err(&pdev->dev, "current-speed property NOT set\n");
return -EINVAL;
}
uart->baud = val;
@@ -659,7 +664,7 @@ static __init void early_serial_write(struct console *con, const char *s,
}
}
-static struct __initdata console arc_early_serial_console = {
+static struct console arc_early_serial_console __initdata = {
.name = "early_ARCuart",
.write = early_serial_write,
.flags = CON_PRINTBUFFER | CON_BOOT,
@@ -694,10 +699,8 @@ static int arc_serial_probe(struct platform_device *pdev)
return -ENODEV;
dev_id = of_alias_get_id(np, "serial");
- if (dev_id < 0) {
- dev_err(&pdev->dev, "failed to get alias id: %d\n", dev_id);
- return dev_id;
- }
+ if (dev_id < 0)
+ dev_id = 0;
rc = arc_uart_init_one(pdev, dev_id);
if (rc)
@@ -731,7 +734,7 @@ static struct platform_driver arc_platform_driver = {
#ifdef CONFIG_SERIAL_ARC_CONSOLE
-static struct platform_driver early_arc_platform_driver = {
+static struct platform_driver early_arc_platform_driver __initdata = {
.probe = arc_serial_probe_earlyprintk,
.remove = arc_serial_remove,
.driver = {
@@ -775,6 +778,6 @@ module_init(arc_serial_init);
module_exit(arc_serial_exit);
MODULE_LICENSE("GPL");
-MODULE_ALIAS("plat-arcfpga/uart");
+MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_AUTHOR("Vineet Gupta");
MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");