aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 21:28:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 21:28:06 -0400
commit2a2bf85f05e42b12ea6bfe821e2d19221cf93555 (patch)
tree11abcdaef6e4f8307574056998d306d21558b6ed /drivers/tty
parent11801e9de26992d37cb869cc74f389b6a7677e0e (diff)
parent99261fbad0a16f105b262d7525801697588ba526 (diff)
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM soc device tree updates from Olof Johansson: "Device tree conversion and enablement branch. Mostly a bunch of new bindings and setup for various platforms, but the Via/Winchip VT8500 platform is also converted over from being 100% legacy to now use device tree for probing. More of that will come for 3.8." Trivial conflicts due to removal of vt8500 files, and one documentation file that was added with slightly different contents both here and in the USb tree. * tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (212 commits) arm: vt8500: Fixup for missing gpio.h ARM: LPC32xx: LED fix in PHY3250 DTS file ARM: dt: mmp-dma: add binding file arm: vt8500: Update arch-vt8500 to devicetree support. arm: vt8500: gpio: Devicetree support for arch-vt8500 arm: vt8500: doc: Add device tree bindings for arch-vt8500 devices arm: vt8500: clk: Add Common Clock Framework support video: vt8500: Add devicetree support for vt8500-fb and wm8505-fb serial: vt8500: Add devicetree support for vt8500-serial rtc: vt8500: Add devicetree support for vt8500-rtc arm: vt8500: Add device tree files for VIA/Wondermedia SoC's ARM: tegra: Add Avionic Design Tamonten Evaluation Carrier support ARM: tegra: Add Avionic Design Medcom-Wide support ARM: tegra: Add Avionic Design Plutux support ARM: tegra: Add Avionic Design Tamonten support ARM: tegra: dts: Add pwm label ARM: ux500: Fix SSP register address format ARM: ux500: Apply tc3589x's GPIO/IRQ properties to HREF's DT ARM: ux500: Remove redundant #gpio-cell properties from Snowball DT ARM: ux500: Add all encompassing sound node to the HREF Device Tree ...
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/vt8500_serial.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 2be006fb3da..205d4cf4a06 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/of.h>
37 38
38/* 39/*
39 * UART Register offsets 40 * UART Register offsets
@@ -76,6 +77,8 @@
76#define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) 77#define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT)
77#define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) 78#define TX_FIFO_INTS (TXFAE | TXFE | TXUDR)
78 79
80#define VT8500_MAX_PORTS 6
81
79struct vt8500_port { 82struct vt8500_port {
80 struct uart_port uart; 83 struct uart_port uart;
81 char name[16]; 84 char name[16];
@@ -83,6 +86,13 @@ struct vt8500_port {
83 unsigned int ier; 86 unsigned int ier;
84}; 87};
85 88
89/*
90 * we use this variable to keep track of which ports
91 * have been allocated as we can't use pdev->id in
92 * devicetree
93 */
94static unsigned long vt8500_ports_in_use;
95
86static inline void vt8500_write(struct uart_port *port, unsigned int val, 96static inline void vt8500_write(struct uart_port *port, unsigned int val,
87 unsigned int off) 97 unsigned int off)
88{ 98{
@@ -431,7 +441,7 @@ static int vt8500_verify_port(struct uart_port *port,
431 return 0; 441 return 0;
432} 442}
433 443
434static struct vt8500_port *vt8500_uart_ports[4]; 444static struct vt8500_port *vt8500_uart_ports[VT8500_MAX_PORTS];
435static struct uart_driver vt8500_uart_driver; 445static struct uart_driver vt8500_uart_driver;
436 446
437#ifdef CONFIG_SERIAL_VT8500_CONSOLE 447#ifdef CONFIG_SERIAL_VT8500_CONSOLE
@@ -548,7 +558,9 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
548{ 558{
549 struct vt8500_port *vt8500_port; 559 struct vt8500_port *vt8500_port;
550 struct resource *mmres, *irqres; 560 struct resource *mmres, *irqres;
561 struct device_node *np = pdev->dev.of_node;
551 int ret; 562 int ret;
563 int port;
552 564
553 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); 565 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
554 irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 566 irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -559,16 +571,46 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
559 if (!vt8500_port) 571 if (!vt8500_port)
560 return -ENOMEM; 572 return -ENOMEM;
561 573
574 if (np)
575 port = of_alias_get_id(np, "serial");
576 if (port > VT8500_MAX_PORTS)
577 port = -1;
578 else
579 port = -1;
580
581 if (port < 0) {
582 /* calculate the port id */
583 port = find_first_zero_bit(&vt8500_ports_in_use,
584 sizeof(vt8500_ports_in_use));
585 }
586
587 if (port > VT8500_MAX_PORTS)
588 return -ENODEV;
589
590 /* reserve the port id */
591 if (test_and_set_bit(port, &vt8500_ports_in_use)) {
592 /* port already in use - shouldn't really happen */
593 return -EBUSY;
594 }
595
562 vt8500_port->uart.type = PORT_VT8500; 596 vt8500_port->uart.type = PORT_VT8500;
563 vt8500_port->uart.iotype = UPIO_MEM; 597 vt8500_port->uart.iotype = UPIO_MEM;
564 vt8500_port->uart.mapbase = mmres->start; 598 vt8500_port->uart.mapbase = mmres->start;
565 vt8500_port->uart.irq = irqres->start; 599 vt8500_port->uart.irq = irqres->start;
566 vt8500_port->uart.fifosize = 16; 600 vt8500_port->uart.fifosize = 16;
567 vt8500_port->uart.ops = &vt8500_uart_pops; 601 vt8500_port->uart.ops = &vt8500_uart_pops;
568 vt8500_port->uart.line = pdev->id; 602 vt8500_port->uart.line = port;
569 vt8500_port->uart.dev = &pdev->dev; 603 vt8500_port->uart.dev = &pdev->dev;
570 vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; 604 vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
571 vt8500_port->uart.uartclk = 24000000; 605
606 vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
607 if (vt8500_port->clk) {
608 vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
609 } else {
610 /* use the default of 24Mhz if not specified and warn */
611 pr_warn("%s: serial clock source not specified\n", __func__);
612 vt8500_port->uart.uartclk = 24000000;
613 }
572 614
573 snprintf(vt8500_port->name, sizeof(vt8500_port->name), 615 snprintf(vt8500_port->name, sizeof(vt8500_port->name),
574 "VT8500 UART%d", pdev->id); 616 "VT8500 UART%d", pdev->id);
@@ -579,7 +621,7 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
579 goto err; 621 goto err;
580 } 622 }
581 623
582 vt8500_uart_ports[pdev->id] = vt8500_port; 624 vt8500_uart_ports[port] = vt8500_port;
583 625
584 uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); 626 uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
585 627
@@ -603,12 +645,18 @@ static int __devexit vt8500_serial_remove(struct platform_device *pdev)
603 return 0; 645 return 0;
604} 646}
605 647
648static const struct of_device_id wmt_dt_ids[] = {
649 { .compatible = "via,vt8500-uart", },
650 {}
651};
652
606static struct platform_driver vt8500_platform_driver = { 653static struct platform_driver vt8500_platform_driver = {
607 .probe = vt8500_serial_probe, 654 .probe = vt8500_serial_probe,
608 .remove = __devexit_p(vt8500_serial_remove), 655 .remove = __devexit_p(vt8500_serial_remove),
609 .driver = { 656 .driver = {
610 .name = "vt8500_serial", 657 .name = "vt8500_serial",
611 .owner = THIS_MODULE, 658 .owner = THIS_MODULE,
659 .of_match_table = of_match_ptr(wmt_dt_ids),
612 }, 660 },
613}; 661};
614 662
@@ -642,4 +690,4 @@ module_exit(vt8500_serial_exit);
642 690
643MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); 691MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
644MODULE_DESCRIPTION("Driver for vt8500 serial device"); 692MODULE_DESCRIPTION("Driver for vt8500 serial device");
645MODULE_LICENSE("GPL"); 693MODULE_LICENSE("GPL v2");