aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/vt8500_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/vt8500_serial.c')
-rw-r--r--drivers/tty/serial/vt8500_serial.c70
1 files changed, 56 insertions, 14 deletions
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 15ad6fcda88b..f22571915185 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -33,8 +33,8 @@
33#include <linux/serial.h> 33#include <linux/serial.h>
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>
37#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/of_device.h>
38#include <linux/err.h> 38#include <linux/err.h>
39 39
40/* 40/*
@@ -78,6 +78,29 @@
78#define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) 78#define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT)
79#define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) 79#define TX_FIFO_INTS (TXFAE | TXFE | TXUDR)
80 80
81/*
82 * Line control bits
83 */
84
85#define VT8500_TXEN (1 << 0) /* Enable transmit logic */
86#define VT8500_RXEN (1 << 1) /* Enable receive logic */
87#define VT8500_CS8 (1 << 2) /* 8-bit data length (vs. 7-bit) */
88#define VT8500_CSTOPB (1 << 3) /* 2 stop bits (vs. 1) */
89#define VT8500_PARENB (1 << 4) /* Enable parity */
90#define VT8500_PARODD (1 << 5) /* Odd parity (vs. even) */
91#define VT8500_RTS (1 << 6) /* Ready to send */
92#define VT8500_LOOPBK (1 << 7) /* Enable internal loopback */
93#define VT8500_DMA (1 << 8) /* Enable DMA mode (needs FIFO) */
94#define VT8500_BREAK (1 << 9) /* Initiate break signal */
95#define VT8500_PSLVERR (1 << 10) /* APB error upon empty RX FIFO read */
96#define VT8500_SWRTSCTS (1 << 11) /* Software-controlled RTS/CTS */
97
98/*
99 * Capability flags (driver-internal)
100 */
101
102#define VT8500_HAS_SWRTSCTS_SWITCH (1 << 1)
103
81#define VT8500_MAX_PORTS 6 104#define VT8500_MAX_PORTS 6
82 105
83struct vt8500_port { 106struct vt8500_port {
@@ -85,6 +108,7 @@ struct vt8500_port {
85 char name[16]; 108 char name[16];
86 struct clk *clk; 109 struct clk *clk;
87 unsigned int ier; 110 unsigned int ier;
111 unsigned int vt8500_uart_flags;
88}; 112};
89 113
90/* 114/*
@@ -272,7 +296,8 @@ static void vt8500_set_mctrl(struct uart_port *port, unsigned int mctrl)
272static void vt8500_break_ctl(struct uart_port *port, int break_ctl) 296static void vt8500_break_ctl(struct uart_port *port, int break_ctl)
273{ 297{
274 if (break_ctl) 298 if (break_ctl)
275 vt8500_write(port, vt8500_read(port, VT8500_URLCR) | (1 << 9), 299 vt8500_write(port,
300 vt8500_read(port, VT8500_URLCR) | VT8500_BREAK,
276 VT8500_URLCR); 301 VT8500_URLCR);
277} 302}
278 303
@@ -347,31 +372,35 @@ static void vt8500_set_termios(struct uart_port *port,
347 372
348 /* calculate parity */ 373 /* calculate parity */
349 lcr = vt8500_read(&vt8500_port->uart, VT8500_URLCR); 374 lcr = vt8500_read(&vt8500_port->uart, VT8500_URLCR);
350 lcr &= ~((1 << 5) | (1 << 4)); 375 lcr &= ~(VT8500_PARENB | VT8500_PARODD);
351 if (termios->c_cflag & PARENB) { 376 if (termios->c_cflag & PARENB) {
352 lcr |= (1 << 4); 377 lcr |= VT8500_PARENB;
353 termios->c_cflag &= ~CMSPAR; 378 termios->c_cflag &= ~CMSPAR;
354 if (termios->c_cflag & PARODD) 379 if (termios->c_cflag & PARODD)
355 lcr |= (1 << 5); 380 lcr |= VT8500_PARODD;
356 } 381 }
357 382
358 /* calculate bits per char */ 383 /* calculate bits per char */
359 lcr &= ~(1 << 2); 384 lcr &= ~VT8500_CS8;
360 switch (termios->c_cflag & CSIZE) { 385 switch (termios->c_cflag & CSIZE) {
361 case CS7: 386 case CS7:
362 break; 387 break;
363 case CS8: 388 case CS8:
364 default: 389 default:
365 lcr |= (1 << 2); 390 lcr |= VT8500_CS8;
366 termios->c_cflag &= ~CSIZE; 391 termios->c_cflag &= ~CSIZE;
367 termios->c_cflag |= CS8; 392 termios->c_cflag |= CS8;
368 break; 393 break;
369 } 394 }
370 395
371 /* calculate stop bits */ 396 /* calculate stop bits */
372 lcr &= ~(1 << 3); 397 lcr &= ~VT8500_CSTOPB;
373 if (termios->c_cflag & CSTOPB) 398 if (termios->c_cflag & CSTOPB)
374 lcr |= (1 << 3); 399 lcr |= VT8500_CSTOPB;
400
401 lcr &= ~VT8500_SWRTSCTS;
402 if (vt8500_port->vt8500_uart_flags & VT8500_HAS_SWRTSCTS_SWITCH)
403 lcr |= VT8500_SWRTSCTS;
375 404
376 /* set parity, bits per char, and stop bit */ 405 /* set parity, bits per char, and stop bit */
377 vt8500_write(&vt8500_port->uart, lcr, VT8500_URLCR); 406 vt8500_write(&vt8500_port->uart, lcr, VT8500_URLCR);
@@ -548,14 +577,31 @@ static struct uart_driver vt8500_uart_driver = {
548 .cons = VT8500_CONSOLE, 577 .cons = VT8500_CONSOLE,
549}; 578};
550 579
580static unsigned int vt8500_flags; /* none required so far */
581static unsigned int wm8880_flags = VT8500_HAS_SWRTSCTS_SWITCH;
582
583static const struct of_device_id wmt_dt_ids[] = {
584 { .compatible = "via,vt8500-uart", .data = &vt8500_flags},
585 { .compatible = "wm,wm8880-uart", .data = &wm8880_flags},
586 {}
587};
588
551static int vt8500_serial_probe(struct platform_device *pdev) 589static int vt8500_serial_probe(struct platform_device *pdev)
552{ 590{
553 struct vt8500_port *vt8500_port; 591 struct vt8500_port *vt8500_port;
554 struct resource *mmres, *irqres; 592 struct resource *mmres, *irqres;
555 struct device_node *np = pdev->dev.of_node; 593 struct device_node *np = pdev->dev.of_node;
594 const struct of_device_id *match;
595 const unsigned int *flags;
556 int ret; 596 int ret;
557 int port; 597 int port;
558 598
599 match = of_match_device(wmt_dt_ids, &pdev->dev);
600 if (!match)
601 return -EINVAL;
602
603 flags = match->data;
604
559 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); 605 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
560 irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 606 irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
561 if (!mmres || !irqres) 607 if (!mmres || !irqres)
@@ -605,6 +651,7 @@ static int vt8500_serial_probe(struct platform_device *pdev)
605 return ret; 651 return ret;
606 } 652 }
607 653
654 vt8500_port->vt8500_uart_flags = *flags;
608 vt8500_port->uart.type = PORT_VT8500; 655 vt8500_port->uart.type = PORT_VT8500;
609 vt8500_port->uart.iotype = UPIO_MEM; 656 vt8500_port->uart.iotype = UPIO_MEM;
610 vt8500_port->uart.mapbase = mmres->start; 657 vt8500_port->uart.mapbase = mmres->start;
@@ -639,11 +686,6 @@ static int vt8500_serial_remove(struct platform_device *pdev)
639 return 0; 686 return 0;
640} 687}
641 688
642static const struct of_device_id wmt_dt_ids[] = {
643 { .compatible = "via,vt8500-uart", },
644 {}
645};
646
647static struct platform_driver vt8500_platform_driver = { 689static struct platform_driver vt8500_platform_driver = {
648 .probe = vt8500_serial_probe, 690 .probe = vt8500_serial_probe,
649 .remove = vt8500_serial_remove, 691 .remove = vt8500_serial_remove,