diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/lantiq.c | 83 | ||||
-rw-r--r-- | drivers/tty/serial/sb1250-duart.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/zs.c | 1 |
3 files changed, 53 insertions, 32 deletions
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 96c1cacc7360..02da071fe1e7 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c | |||
@@ -31,16 +31,19 @@ | |||
31 | #include <linux/tty_flip.h> | 31 | #include <linux/tty_flip.h> |
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/of_platform.h> |
35 | #include <linux/of_address.h> | ||
36 | #include <linux/of_irq.h> | ||
35 | #include <linux/io.h> | 37 | #include <linux/io.h> |
36 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/gpio.h> | ||
37 | 40 | ||
38 | #include <lantiq_soc.h> | 41 | #include <lantiq_soc.h> |
39 | 42 | ||
40 | #define PORT_LTQ_ASC 111 | 43 | #define PORT_LTQ_ASC 111 |
41 | #define MAXPORTS 2 | 44 | #define MAXPORTS 2 |
42 | #define UART_DUMMY_UER_RX 1 | 45 | #define UART_DUMMY_UER_RX 1 |
43 | #define DRVNAME "ltq_asc" | 46 | #define DRVNAME "lantiq,asc" |
44 | #ifdef __BIG_ENDIAN | 47 | #ifdef __BIG_ENDIAN |
45 | #define LTQ_ASC_TBUF (0x0020 + 3) | 48 | #define LTQ_ASC_TBUF (0x0020 + 3) |
46 | #define LTQ_ASC_RBUF (0x0024 + 3) | 49 | #define LTQ_ASC_RBUF (0x0024 + 3) |
@@ -114,6 +117,9 @@ static DEFINE_SPINLOCK(ltq_asc_lock); | |||
114 | 117 | ||
115 | struct ltq_uart_port { | 118 | struct ltq_uart_port { |
116 | struct uart_port port; | 119 | struct uart_port port; |
120 | /* clock used to derive divider */ | ||
121 | struct clk *fpiclk; | ||
122 | /* clock gating of the ASC core */ | ||
117 | struct clk *clk; | 123 | struct clk *clk; |
118 | unsigned int tx_irq; | 124 | unsigned int tx_irq; |
119 | unsigned int rx_irq; | 125 | unsigned int rx_irq; |
@@ -316,7 +322,9 @@ lqasc_startup(struct uart_port *port) | |||
316 | struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); | 322 | struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); |
317 | int retval; | 323 | int retval; |
318 | 324 | ||
319 | port->uartclk = clk_get_rate(ltq_port->clk); | 325 | if (ltq_port->clk) |
326 | clk_enable(ltq_port->clk); | ||
327 | port->uartclk = clk_get_rate(ltq_port->fpiclk); | ||
320 | 328 | ||
321 | ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), | 329 | ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), |
322 | port->membase + LTQ_ASC_CLC); | 330 | port->membase + LTQ_ASC_CLC); |
@@ -382,6 +390,8 @@ lqasc_shutdown(struct uart_port *port) | |||
382 | port->membase + LTQ_ASC_RXFCON); | 390 | port->membase + LTQ_ASC_RXFCON); |
383 | ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU, | 391 | ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU, |
384 | port->membase + LTQ_ASC_TXFCON); | 392 | port->membase + LTQ_ASC_TXFCON); |
393 | if (ltq_port->clk) | ||
394 | clk_disable(ltq_port->clk); | ||
385 | } | 395 | } |
386 | 396 | ||
387 | static void | 397 | static void |
@@ -630,7 +640,7 @@ lqasc_console_setup(struct console *co, char *options) | |||
630 | 640 | ||
631 | port = <q_port->port; | 641 | port = <q_port->port; |
632 | 642 | ||
633 | port->uartclk = clk_get_rate(ltq_port->clk); | 643 | port->uartclk = clk_get_rate(ltq_port->fpiclk); |
634 | 644 | ||
635 | if (options) | 645 | if (options) |
636 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 646 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
@@ -668,37 +678,32 @@ static struct uart_driver lqasc_reg = { | |||
668 | static int __init | 678 | static int __init |
669 | lqasc_probe(struct platform_device *pdev) | 679 | lqasc_probe(struct platform_device *pdev) |
670 | { | 680 | { |
681 | struct device_node *node = pdev->dev.of_node; | ||
671 | struct ltq_uart_port *ltq_port; | 682 | struct ltq_uart_port *ltq_port; |
672 | struct uart_port *port; | 683 | struct uart_port *port; |
673 | struct resource *mmres, *irqres; | 684 | struct resource *mmres, irqres[3]; |
674 | int tx_irq, rx_irq, err_irq; | 685 | int line = 0; |
675 | struct clk *clk; | ||
676 | int ret; | 686 | int ret; |
677 | 687 | ||
678 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 688 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
679 | irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 689 | ret = of_irq_to_resource_table(node, irqres, 3); |
680 | if (!mmres || !irqres) | 690 | if (!mmres || (ret != 3)) { |
691 | dev_err(&pdev->dev, | ||
692 | "failed to get memory/irq for serial port\n"); | ||
681 | return -ENODEV; | 693 | return -ENODEV; |
694 | } | ||
682 | 695 | ||
683 | if (pdev->id >= MAXPORTS) | 696 | /* check if this is the console port */ |
684 | return -EBUSY; | 697 | if (mmres->start != CPHYSADDR(LTQ_EARLY_ASC)) |
698 | line = 1; | ||
685 | 699 | ||
686 | if (lqasc_port[pdev->id] != NULL) | 700 | if (lqasc_port[line]) { |
701 | dev_err(&pdev->dev, "port %d already allocated\n", line); | ||
687 | return -EBUSY; | 702 | return -EBUSY; |
688 | |||
689 | clk = clk_get(&pdev->dev, "fpi"); | ||
690 | if (IS_ERR(clk)) { | ||
691 | pr_err("failed to get fpi clk\n"); | ||
692 | return -ENOENT; | ||
693 | } | 703 | } |
694 | 704 | ||
695 | tx_irq = platform_get_irq_byname(pdev, "tx"); | 705 | ltq_port = devm_kzalloc(&pdev->dev, sizeof(struct ltq_uart_port), |
696 | rx_irq = platform_get_irq_byname(pdev, "rx"); | 706 | GFP_KERNEL); |
697 | err_irq = platform_get_irq_byname(pdev, "err"); | ||
698 | if ((tx_irq < 0) | (rx_irq < 0) | (err_irq < 0)) | ||
699 | return -ENODEV; | ||
700 | |||
701 | ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL); | ||
702 | if (!ltq_port) | 707 | if (!ltq_port) |
703 | return -ENOMEM; | 708 | return -ENOMEM; |
704 | 709 | ||
@@ -709,19 +714,26 @@ lqasc_probe(struct platform_device *pdev) | |||
709 | port->ops = &lqasc_pops; | 714 | port->ops = &lqasc_pops; |
710 | port->fifosize = 16; | 715 | port->fifosize = 16; |
711 | port->type = PORT_LTQ_ASC, | 716 | port->type = PORT_LTQ_ASC, |
712 | port->line = pdev->id; | 717 | port->line = line; |
713 | port->dev = &pdev->dev; | 718 | port->dev = &pdev->dev; |
714 | 719 | /* unused, just to be backward-compatible */ | |
715 | port->irq = tx_irq; /* unused, just to be backward-compatibe */ | 720 | port->irq = irqres[0].start; |
716 | port->mapbase = mmres->start; | 721 | port->mapbase = mmres->start; |
717 | 722 | ||
718 | ltq_port->clk = clk; | 723 | ltq_port->fpiclk = clk_get_fpi(); |
724 | if (IS_ERR(ltq_port->fpiclk)) { | ||
725 | pr_err("failed to get fpi clk\n"); | ||
726 | return -ENOENT; | ||
727 | } | ||
719 | 728 | ||
720 | ltq_port->tx_irq = tx_irq; | 729 | /* not all asc ports have clock gates, lets ignore the return code */ |
721 | ltq_port->rx_irq = rx_irq; | 730 | ltq_port->clk = clk_get(&pdev->dev, NULL); |
722 | ltq_port->err_irq = err_irq; | ||
723 | 731 | ||
724 | lqasc_port[pdev->id] = ltq_port; | 732 | ltq_port->tx_irq = irqres[0].start; |
733 | ltq_port->rx_irq = irqres[1].start; | ||
734 | ltq_port->err_irq = irqres[2].start; | ||
735 | |||
736 | lqasc_port[line] = ltq_port; | ||
725 | platform_set_drvdata(pdev, ltq_port); | 737 | platform_set_drvdata(pdev, ltq_port); |
726 | 738 | ||
727 | ret = uart_add_one_port(&lqasc_reg, port); | 739 | ret = uart_add_one_port(&lqasc_reg, port); |
@@ -729,10 +741,17 @@ lqasc_probe(struct platform_device *pdev) | |||
729 | return ret; | 741 | return ret; |
730 | } | 742 | } |
731 | 743 | ||
744 | static const struct of_device_id ltq_asc_match[] = { | ||
745 | { .compatible = DRVNAME }, | ||
746 | {}, | ||
747 | }; | ||
748 | MODULE_DEVICE_TABLE(of, ltq_asc_match); | ||
749 | |||
732 | static struct platform_driver lqasc_driver = { | 750 | static struct platform_driver lqasc_driver = { |
733 | .driver = { | 751 | .driver = { |
734 | .name = DRVNAME, | 752 | .name = DRVNAME, |
735 | .owner = THIS_MODULE, | 753 | .owner = THIS_MODULE, |
754 | .of_match_table = ltq_asc_match, | ||
736 | }, | 755 | }, |
737 | }; | 756 | }; |
738 | 757 | ||
diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index 0be8a2f00d0b..f76b1688c5c8 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/ioport.h> | 32 | #include <linux/ioport.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | ||
34 | #include <linux/major.h> | 35 | #include <linux/major.h> |
35 | #include <linux/serial.h> | 36 | #include <linux/serial.h> |
36 | #include <linux/serial_core.h> | 37 | #include <linux/serial_core.h> |
diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 4001eee6c08d..92c00b24d0df 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/ioport.h> | 57 | #include <linux/ioport.h> |
58 | #include <linux/irqflags.h> | 58 | #include <linux/irqflags.h> |
59 | #include <linux/kernel.h> | 59 | #include <linux/kernel.h> |
60 | #include <linux/module.h> | ||
60 | #include <linux/major.h> | 61 | #include <linux/major.h> |
61 | #include <linux/serial.h> | 62 | #include <linux/serial.h> |
62 | #include <linux/serial_core.h> | 63 | #include <linux/serial_core.h> |