aboutsummaryrefslogtreecommitdiffstats
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.c106
1 files changed, 70 insertions, 36 deletions
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c
index 3e0b3fac6a0e..6f7eadc424a3 100644
--- a/drivers/tty/serial/arc_uart.c
+++ b/drivers/tty/serial/arc_uart.c
@@ -37,6 +37,8 @@
37#include <linux/tty_flip.h> 37#include <linux/tty_flip.h>
38#include <linux/serial_core.h> 38#include <linux/serial_core.h>
39#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/of.h>
41#include <linux/of_platform.h>
40 42
41/************************************* 43/*************************************
42 * ARC UART Hardware Specs 44 * ARC UART Hardware Specs
@@ -209,12 +211,8 @@ static void arc_serial_start_tx(struct uart_port *port)
209 211
210static void arc_serial_rx_chars(struct arc_uart_port *uart) 212static void arc_serial_rx_chars(struct arc_uart_port *uart)
211{ 213{
212 struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port);
213 unsigned int status, ch, flg = 0; 214 unsigned int status, ch, flg = 0;
214 215
215 if (!tty)
216 return;
217
218 /* 216 /*
219 * UART has 4 deep RX-FIFO. Driver's recongnition of this fact 217 * UART has 4 deep RX-FIFO. Driver's recongnition of this fact
220 * is very subtle. Here's how ... 218 * is very subtle. Here's how ...
@@ -250,10 +248,8 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart)
250 uart_insert_char(&uart->port, status, RXOERR, ch, flg); 248 uart_insert_char(&uart->port, status, RXOERR, ch, flg);
251 249
252done: 250done:
253 tty_flip_buffer_push(tty); 251 tty_flip_buffer_push(&uart->port.state->port);
254 } 252 }
255
256 tty_kref_put(tty);
257} 253}
258 254
259/* 255/*
@@ -526,18 +522,37 @@ static struct uart_ops arc_serial_pops = {
526}; 522};
527 523
528static int 524static int
529arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) 525arc_uart_init_one(struct platform_device *pdev, int dev_id)
530{ 526{
531 struct resource *res, *res2; 527 struct resource *res, *res2;
532 unsigned long *plat_data; 528 unsigned long *plat_data;
533 529 struct arc_uart_port *uart = &arc_uart_ports[dev_id];
534 if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) {
535 dev_err(&pdev->dev, "Wrong uart platform device id.\n");
536 return -ENOENT;
537 }
538 530
539 plat_data = ((unsigned long *)(pdev->dev.platform_data)); 531 plat_data = ((unsigned long *)(pdev->dev.platform_data));
540 uart->baud = plat_data[0]; 532 if (!plat_data)
533 return -ENODEV;
534
535 uart->is_emulated = !!plat_data[0]; /* workaround ISS bug */
536
537 if (is_early_platform_device(pdev)) {
538 uart->port.uartclk = plat_data[1];
539 uart->baud = plat_data[2];
540 } else {
541 struct device_node *np = pdev->dev.of_node;
542 u32 val;
543
544 if (of_property_read_u32(np, "clock-frequency", &val)) {
545 dev_err(&pdev->dev, "clock-frequency property NOTset\n");
546 return -EINVAL;
547 }
548 uart->port.uartclk = val;
549
550 if (of_property_read_u32(np, "baud", &val)) {
551 dev_err(&pdev->dev, "baud property NOT set\n");
552 return -EINVAL;
553 }
554 uart->baud = val;
555 }
541 556
542 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 557 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
543 if (!res) 558 if (!res)
@@ -557,10 +572,9 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart)
557 uart->port.dev = &pdev->dev; 572 uart->port.dev = &pdev->dev;
558 uart->port.iotype = UPIO_MEM; 573 uart->port.iotype = UPIO_MEM;
559 uart->port.flags = UPF_BOOT_AUTOCONF; 574 uart->port.flags = UPF_BOOT_AUTOCONF;
560 uart->port.line = pdev->id; 575 uart->port.line = dev_id;
561 uart->port.ops = &arc_serial_pops; 576 uart->port.ops = &arc_serial_pops;
562 577
563 uart->port.uartclk = plat_data[1];
564 uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; 578 uart->port.fifosize = ARC_UART_TX_FIFO_SIZE;
565 579
566 /* 580 /*
@@ -569,9 +583,6 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart)
569 */ 583 */
570 uart->port.ignore_status_mask = 0; 584 uart->port.ignore_status_mask = 0;
571 585
572 /* Real Hardware vs. emulated to work around a bug */
573 uart->is_emulated = !!plat_data[2];
574
575 return 0; 586 return 0;
576} 587}
577 588
@@ -648,45 +659,52 @@ static __init void early_serial_write(struct console *con, const char *s,
648 } 659 }
649} 660}
650 661
651static struct __initdata console arc_early_serial_console = { 662static struct console arc_early_serial_console __initdata = {
652 .name = "early_ARCuart", 663 .name = "early_ARCuart",
653 .write = early_serial_write, 664 .write = early_serial_write,
654 .flags = CON_PRINTBUFFER | CON_BOOT, 665 .flags = CON_PRINTBUFFER | CON_BOOT,
655 .index = -1 666 .index = -1
656}; 667};
657 668
658static int arc_serial_probe_earlyprintk(struct platform_device *pdev) 669static int __init arc_serial_probe_earlyprintk(struct platform_device *pdev)
659{ 670{
660 arc_early_serial_console.index = pdev->id; 671 int dev_id = pdev->id < 0 ? 0 : pdev->id;
672 int rc;
673
674 arc_early_serial_console.index = dev_id;
661 675
662 arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); 676 rc = arc_uart_init_one(pdev, dev_id);
677 if (rc)
678 panic("early console init failed\n");
663 679
664 arc_serial_console_setup(&arc_early_serial_console, NULL); 680 arc_serial_console_setup(&arc_early_serial_console, NULL);
665 681
666 register_console(&arc_early_serial_console); 682 register_console(&arc_early_serial_console);
667 return 0; 683 return 0;
668} 684}
669#else
670static int arc_serial_probe_earlyprintk(struct platform_device *pdev)
671{
672 return -ENODEV;
673}
674#endif /* CONFIG_SERIAL_ARC_CONSOLE */ 685#endif /* CONFIG_SERIAL_ARC_CONSOLE */
675 686
676static int arc_serial_probe(struct platform_device *pdev) 687static int arc_serial_probe(struct platform_device *pdev)
677{ 688{
678 struct arc_uart_port *uart; 689 int rc, dev_id;
679 int rc; 690 struct device_node *np = pdev->dev.of_node;
691
692 /* no device tree device */
693 if (!np)
694 return -ENODEV;
680 695
681 if (is_early_platform_device(pdev)) 696 dev_id = of_alias_get_id(np, "serial");
682 return arc_serial_probe_earlyprintk(pdev); 697 if (dev_id < 0) {
698 dev_err(&pdev->dev, "failed to get alias id: %d\n", dev_id);
699 return dev_id;
700 }
683 701
684 uart = &arc_uart_ports[pdev->id]; 702 rc = arc_uart_init_one(pdev, dev_id);
685 rc = arc_uart_init_one(pdev, uart);
686 if (rc) 703 if (rc)
687 return rc; 704 return rc;
688 705
689 return uart_add_one_port(&arc_uart_driver, &uart->port); 706 rc = uart_add_one_port(&arc_uart_driver, &arc_uart_ports[dev_id].port);
707 return rc;
690} 708}
691 709
692static int arc_serial_remove(struct platform_device *pdev) 710static int arc_serial_remove(struct platform_device *pdev)
@@ -695,16 +713,32 @@ static int arc_serial_remove(struct platform_device *pdev)
695 return 0; 713 return 0;
696} 714}
697 715
716static const struct of_device_id arc_uart_dt_ids[] = {
717 { .compatible = "snps,arc-uart" },
718 { /* Sentinel */ }
719};
720MODULE_DEVICE_TABLE(of, arc_uart_dt_ids);
721
698static struct platform_driver arc_platform_driver = { 722static struct platform_driver arc_platform_driver = {
699 .probe = arc_serial_probe, 723 .probe = arc_serial_probe,
700 .remove = arc_serial_remove, 724 .remove = arc_serial_remove,
701 .driver = { 725 .driver = {
702 .name = DRIVER_NAME, 726 .name = DRIVER_NAME,
703 .owner = THIS_MODULE, 727 .owner = THIS_MODULE,
728 .of_match_table = arc_uart_dt_ids,
704 }, 729 },
705}; 730};
706 731
707#ifdef CONFIG_SERIAL_ARC_CONSOLE 732#ifdef CONFIG_SERIAL_ARC_CONSOLE
733
734static struct platform_driver early_arc_platform_driver __initdata = {
735 .probe = arc_serial_probe_earlyprintk,
736 .remove = arc_serial_remove,
737 .driver = {
738 .name = DRIVER_NAME,
739 .owner = THIS_MODULE,
740 },
741};
708/* 742/*
709 * Register an early platform driver of "earlyprintk" class. 743 * Register an early platform driver of "earlyprintk" class.
710 * ARCH platform code installs the driver and probes the early devices 744 * ARCH platform code installs the driver and probes the early devices
@@ -712,7 +746,7 @@ static struct platform_driver arc_platform_driver = {
712 * or it could be done independently, for all "earlyprintk" class drivers. 746 * or it could be done independently, for all "earlyprintk" class drivers.
713 * [see arch/arc/plat-arcfpga/platform.c] 747 * [see arch/arc/plat-arcfpga/platform.c]
714 */ 748 */
715early_platform_init("earlyprintk", &arc_platform_driver); 749early_platform_init("earlyprintk", &early_arc_platform_driver);
716 750
717#endif /* CONFIG_SERIAL_ARC_CONSOLE */ 751#endif /* CONFIG_SERIAL_ARC_CONSOLE */
718 752