aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorJohannes Thumshirn <johannes.thumshirn@men.de>2015-01-19 01:44:41 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 13:11:27 -0500
commit01ba8d6af4b76aee99a8ae3a76748c8c36db49f3 (patch)
tree320426c9174014d2d23e9bef3c6fcb5bfd2020c3 /drivers/tty
parentb164c9721e3ea4c08a4738cd4d0538bbb0c24419 (diff)
tty: serial: men_z135_uart: Fix driver for changes in hardware
16z135 IP Core has changed so the driver needs to be updated to respect these changes. The following changes have been made: * Don't invert the 16z135 modem status register when reading. * Add module parameter to configure the (baud rate dependent) RX timeout. Character timeout in seconds = (timeout_reg * baud_reg * 4)/freq_reg. * Enable the handling of UART core's automatic flow control feature. When AFE is active disable generation of modem status IRQs. * Rework the handling of IRQs to be conform with newer FPGA versions and take precautions not to miss an interrupt because of the destructive read of the IIR register. * Correct men_z135_handle_modem_status(), MSR is stat_reg[15:8] not stat_reg[7:0] * Correct calling of uart_handle_{dcd,cts}_change() * Reset CLOCAL when CRTSCTS is set Signed-off-by: Johannes Thumshirn <johannes.thumshirn@men.de> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/men_z135_uart.c155
1 files changed, 109 insertions, 46 deletions
diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c
index 517cd073dc08..35c55505b3eb 100644
--- a/drivers/tty/serial/men_z135_uart.c
+++ b/drivers/tty/serial/men_z135_uart.c
@@ -23,7 +23,6 @@
23#define MEN_Z135_MAX_PORTS 12 23#define MEN_Z135_MAX_PORTS 12
24#define MEN_Z135_BASECLK 29491200 24#define MEN_Z135_BASECLK 29491200
25#define MEN_Z135_FIFO_SIZE 1024 25#define MEN_Z135_FIFO_SIZE 1024
26#define MEN_Z135_NUM_MSI_VECTORS 2
27#define MEN_Z135_FIFO_WATERMARK 1020 26#define MEN_Z135_FIFO_WATERMARK 1020
28 27
29#define MEN_Z135_STAT_REG 0x0 28#define MEN_Z135_STAT_REG 0x0
@@ -34,12 +33,11 @@
34#define MEN_Z135_CONF_REG 0x808 33#define MEN_Z135_CONF_REG 0x808
35#define MEN_Z135_UART_FREQ 0x80c 34#define MEN_Z135_UART_FREQ 0x80c
36#define MEN_Z135_BAUD_REG 0x810 35#define MEN_Z135_BAUD_REG 0x810
37#define MENZ135_TIMEOUT 0x814 36#define MEN_Z135_TIMEOUT 0x814
38 37
39#define MEN_Z135_MEM_SIZE 0x818 38#define MEN_Z135_MEM_SIZE 0x818
40 39
41#define IS_IRQ(x) ((x) & 1) 40#define IRQ_ID(x) ((x) & 0x1f)
42#define IRQ_ID(x) (((x) >> 1) & 7)
43 41
44#define MEN_Z135_IER_RXCIEN BIT(0) /* RX Space IRQ */ 42#define MEN_Z135_IER_RXCIEN BIT(0) /* RX Space IRQ */
45#define MEN_Z135_IER_TXCIEN BIT(1) /* TX Space IRQ */ 43#define MEN_Z135_IER_TXCIEN BIT(1) /* TX Space IRQ */
@@ -94,11 +92,11 @@
94#define MEN_Z135_LSR_TEXP BIT(6) 92#define MEN_Z135_LSR_TEXP BIT(6)
95#define MEN_Z135_LSR_RXFIFOERR BIT(7) 93#define MEN_Z135_LSR_RXFIFOERR BIT(7)
96 94
97#define MEN_Z135_IRQ_ID_MST 0 95#define MEN_Z135_IRQ_ID_RLS BIT(0)
98#define MEN_Z135_IRQ_ID_TSA 1 96#define MEN_Z135_IRQ_ID_RDA BIT(1)
99#define MEN_Z135_IRQ_ID_RDA 2 97#define MEN_Z135_IRQ_ID_CTI BIT(2)
100#define MEN_Z135_IRQ_ID_RLS 3 98#define MEN_Z135_IRQ_ID_TSA BIT(3)
101#define MEN_Z135_IRQ_ID_CTI 6 99#define MEN_Z135_IRQ_ID_MST BIT(4)
102 100
103#define LCR(x) (((x) >> MEN_Z135_LCR_SHIFT) & 0xff) 101#define LCR(x) (((x) >> MEN_Z135_LCR_SHIFT) & 0xff)
104 102
@@ -118,12 +116,18 @@ static int align;
118module_param(align, int, S_IRUGO); 116module_param(align, int, S_IRUGO);
119MODULE_PARM_DESC(align, "Keep hardware FIFO write pointer aligned, default 0"); 117MODULE_PARM_DESC(align, "Keep hardware FIFO write pointer aligned, default 0");
120 118
119static uint rx_timeout;
120module_param(rx_timeout, uint, S_IRUGO);
121MODULE_PARM_DESC(rx_timeout, "RX timeout. "
122 "Timeout in seconds = (timeout_reg * baud_reg * 4) / freq_reg");
123
121struct men_z135_port { 124struct men_z135_port {
122 struct uart_port port; 125 struct uart_port port;
123 struct mcb_device *mdev; 126 struct mcb_device *mdev;
124 unsigned char *rxbuf; 127 unsigned char *rxbuf;
125 u32 stat_reg; 128 u32 stat_reg;
126 spinlock_t lock; 129 spinlock_t lock;
130 bool automode;
127}; 131};
128#define to_men_z135(port) container_of((port), struct men_z135_port, port) 132#define to_men_z135(port) container_of((port), struct men_z135_port, port)
129 133
@@ -180,12 +184,16 @@ static inline void men_z135_reg_clr(struct men_z135_port *uart,
180 */ 184 */
181static void men_z135_handle_modem_status(struct men_z135_port *uart) 185static void men_z135_handle_modem_status(struct men_z135_port *uart)
182{ 186{
183 if (uart->stat_reg & MEN_Z135_MSR_DDCD) 187 u8 msr;
188
189 msr = (uart->stat_reg >> 8) & 0xff;
190
191 if (msr & MEN_Z135_MSR_DDCD)
184 uart_handle_dcd_change(&uart->port, 192 uart_handle_dcd_change(&uart->port,
185 uart->stat_reg & ~MEN_Z135_MSR_DCD); 193 msr & MEN_Z135_MSR_DCD);
186 if (uart->stat_reg & MEN_Z135_MSR_DCTS) 194 if (msr & MEN_Z135_MSR_DCTS)
187 uart_handle_cts_change(&uart->port, 195 uart_handle_cts_change(&uart->port,
188 uart->stat_reg & ~MEN_Z135_MSR_CTS); 196 msr & MEN_Z135_MSR_CTS);
189} 197}
190 198
191static void men_z135_handle_lsr(struct men_z135_port *uart) 199static void men_z135_handle_lsr(struct men_z135_port *uart)
@@ -322,7 +330,8 @@ static void men_z135_handle_tx(struct men_z135_port *uart)
322 330
323 txfree = MEN_Z135_FIFO_WATERMARK - txc; 331 txfree = MEN_Z135_FIFO_WATERMARK - txc;
324 if (txfree <= 0) { 332 if (txfree <= 0) {
325 pr_err("Not enough room in TX FIFO have %d, need %d\n", 333 dev_err(&uart->mdev->dev,
334 "Not enough room in TX FIFO have %d, need %d\n",
326 txfree, qlen); 335 txfree, qlen);
327 goto irq_en; 336 goto irq_en;
328 } 337 }
@@ -373,43 +382,54 @@ out:
373 * @irq: The IRQ number 382 * @irq: The IRQ number
374 * @data: Pointer to UART port 383 * @data: Pointer to UART port
375 * 384 *
376 * Check IIR register to see which tasklet to start. 385 * Check IIR register to find the cause of the interrupt and handle it.
386 * It is possible that multiple interrupts reason bits are set and reading
387 * the IIR is a destructive read, so we always need to check for all possible
388 * interrupts and handle them.
377 */ 389 */
378static irqreturn_t men_z135_intr(int irq, void *data) 390static irqreturn_t men_z135_intr(int irq, void *data)
379{ 391{
380 struct men_z135_port *uart = (struct men_z135_port *)data; 392 struct men_z135_port *uart = (struct men_z135_port *)data;
381 struct uart_port *port = &uart->port; 393 struct uart_port *port = &uart->port;
394 bool handled = false;
395 unsigned long flags;
382 int irq_id; 396 int irq_id;
383 397
384 uart->stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG); 398 uart->stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG);
385 /* IRQ pending is low active */
386 if (IS_IRQ(uart->stat_reg))
387 return IRQ_NONE;
388
389 irq_id = IRQ_ID(uart->stat_reg); 399 irq_id = IRQ_ID(uart->stat_reg);
390 switch (irq_id) { 400
391 case MEN_Z135_IRQ_ID_MST: 401 if (!irq_id)
392 men_z135_handle_modem_status(uart); 402 goto out;
393 break; 403
394 case MEN_Z135_IRQ_ID_TSA: 404 spin_lock_irqsave(&port->lock, flags);
395 men_z135_handle_tx(uart); 405 /* It's save to write to IIR[7:6] RXC[9:8] */
396 break; 406 iowrite8(irq_id, port->membase + MEN_Z135_STAT_REG);
397 case MEN_Z135_IRQ_ID_CTI: 407
398 dev_dbg(&uart->mdev->dev, "Character Timeout Indication\n"); 408 if (irq_id & MEN_Z135_IRQ_ID_RLS) {
399 /* Fallthrough */
400 case MEN_Z135_IRQ_ID_RDA:
401 /* Reading data clears RX IRQ */
402 men_z135_handle_rx(uart);
403 break;
404 case MEN_Z135_IRQ_ID_RLS:
405 men_z135_handle_lsr(uart); 409 men_z135_handle_lsr(uart);
406 break; 410 handled = true;
407 default: 411 }
408 dev_warn(&uart->mdev->dev, "Unknown IRQ id %d\n", irq_id); 412
409 return IRQ_NONE; 413 if (irq_id & (MEN_Z135_IRQ_ID_RDA | MEN_Z135_IRQ_ID_CTI)) {
414 if (irq_id & MEN_Z135_IRQ_ID_CTI)
415 dev_dbg(&uart->mdev->dev, "Character Timeout Indication\n");
416 men_z135_handle_rx(uart);
417 handled = true;
418 }
419
420 if (irq_id & MEN_Z135_IRQ_ID_TSA) {
421 men_z135_handle_tx(uart);
422 handled = true;
410 } 423 }
411 424
412 return IRQ_HANDLED; 425 if (irq_id & MEN_Z135_IRQ_ID_MST) {
426 men_z135_handle_modem_status(uart);
427 handled = true;
428 }
429
430 spin_unlock_irqrestore(&port->lock, flags);
431out:
432 return IRQ_RETVAL(handled);
413} 433}
414 434
415/** 435/**
@@ -464,21 +484,37 @@ static unsigned int men_z135_tx_empty(struct uart_port *port)
464 */ 484 */
465static void men_z135_set_mctrl(struct uart_port *port, unsigned int mctrl) 485static void men_z135_set_mctrl(struct uart_port *port, unsigned int mctrl)
466{ 486{
467 struct men_z135_port *uart = to_men_z135(port); 487 u32 old;
468 u32 conf_reg = 0; 488 u32 conf_reg;
469 489
490 conf_reg = old = ioread32(port->membase + MEN_Z135_CONF_REG);
470 if (mctrl & TIOCM_RTS) 491 if (mctrl & TIOCM_RTS)
471 conf_reg |= MEN_Z135_MCR_RTS; 492 conf_reg |= MEN_Z135_MCR_RTS;
493 else
494 conf_reg &= ~MEN_Z135_MCR_RTS;
495
472 if (mctrl & TIOCM_DTR) 496 if (mctrl & TIOCM_DTR)
473 conf_reg |= MEN_Z135_MCR_DTR; 497 conf_reg |= MEN_Z135_MCR_DTR;
498 else
499 conf_reg &= ~MEN_Z135_MCR_DTR;
500
474 if (mctrl & TIOCM_OUT1) 501 if (mctrl & TIOCM_OUT1)
475 conf_reg |= MEN_Z135_MCR_OUT1; 502 conf_reg |= MEN_Z135_MCR_OUT1;
503 else
504 conf_reg &= ~MEN_Z135_MCR_OUT1;
505
476 if (mctrl & TIOCM_OUT2) 506 if (mctrl & TIOCM_OUT2)
477 conf_reg |= MEN_Z135_MCR_OUT2; 507 conf_reg |= MEN_Z135_MCR_OUT2;
508 else
509 conf_reg &= ~MEN_Z135_MCR_OUT2;
510
478 if (mctrl & TIOCM_LOOP) 511 if (mctrl & TIOCM_LOOP)
479 conf_reg |= MEN_Z135_MCR_LOOP; 512 conf_reg |= MEN_Z135_MCR_LOOP;
513 else
514 conf_reg &= ~MEN_Z135_MCR_LOOP;
480 515
481 men_z135_reg_set(uart, MEN_Z135_CONF_REG, conf_reg); 516 if (conf_reg != old)
517 iowrite32(conf_reg, port->membase + MEN_Z135_CONF_REG);
482} 518}
483 519
484/** 520/**
@@ -490,12 +526,9 @@ static void men_z135_set_mctrl(struct uart_port *port, unsigned int mctrl)
490static unsigned int men_z135_get_mctrl(struct uart_port *port) 526static unsigned int men_z135_get_mctrl(struct uart_port *port)
491{ 527{
492 unsigned int mctrl = 0; 528 unsigned int mctrl = 0;
493 u32 stat_reg;
494 u8 msr; 529 u8 msr;
495 530
496 stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG); 531 msr = ioread8(port->membase + MEN_Z135_STAT_REG + 1);
497
498 msr = ~((stat_reg >> 8) & 0xff);
499 532
500 if (msr & MEN_Z135_MSR_CTS) 533 if (msr & MEN_Z135_MSR_CTS)
501 mctrl |= TIOCM_CTS; 534 mctrl |= TIOCM_CTS;
@@ -524,6 +557,19 @@ static void men_z135_stop_tx(struct uart_port *port)
524 men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_TXCIEN); 557 men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_TXCIEN);
525} 558}
526 559
560/*
561 * men_z135_disable_ms() - Disable Modem Status
562 * port: The UART port
563 *
564 * Enable Modem Status IRQ.
565 */
566static void men_z135_disable_ms(struct uart_port *port)
567{
568 struct men_z135_port *uart = to_men_z135(port);
569
570 men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_MSIEN);
571}
572
527/** 573/**
528 * men_z135_start_tx() - Start transmitting characters 574 * men_z135_start_tx() - Start transmitting characters
529 * @port: The UART port 575 * @port: The UART port
@@ -535,6 +581,9 @@ static void men_z135_start_tx(struct uart_port *port)
535{ 581{
536 struct men_z135_port *uart = to_men_z135(port); 582 struct men_z135_port *uart = to_men_z135(port);
537 583
584 if (uart->automode)
585 men_z135_disable_ms(port);
586
538 men_z135_handle_tx(uart); 587 men_z135_handle_tx(uart);
539} 588}
540 589
@@ -584,6 +633,9 @@ static int men_z135_startup(struct uart_port *port)
584 633
585 iowrite32(conf_reg, port->membase + MEN_Z135_CONF_REG); 634 iowrite32(conf_reg, port->membase + MEN_Z135_CONF_REG);
586 635
636 if (rx_timeout)
637 iowrite32(rx_timeout, port->membase + MEN_Z135_TIMEOUT);
638
587 return 0; 639 return 0;
588} 640}
589 641
@@ -603,6 +655,7 @@ static void men_z135_set_termios(struct uart_port *port,
603 struct ktermios *termios, 655 struct ktermios *termios,
604 struct ktermios *old) 656 struct ktermios *old)
605{ 657{
658 struct men_z135_port *uart = to_men_z135(port);
606 unsigned int baud; 659 unsigned int baud;
607 u32 conf_reg; 660 u32 conf_reg;
608 u32 bd_reg; 661 u32 bd_reg;
@@ -643,6 +696,16 @@ static void men_z135_set_termios(struct uart_port *port,
643 } else 696 } else
644 lcr |= MEN_Z135_PAR_DIS << MEN_Z135_PEN_SHIFT; 697 lcr |= MEN_Z135_PAR_DIS << MEN_Z135_PEN_SHIFT;
645 698
699 conf_reg |= MEN_Z135_IER_MSIEN;
700 if (termios->c_cflag & CRTSCTS) {
701 conf_reg |= MEN_Z135_MCR_RCFC;
702 uart->automode = true;
703 termios->c_cflag &= ~CLOCAL;
704 } else {
705 conf_reg &= ~MEN_Z135_MCR_RCFC;
706 uart->automode = false;
707 }
708
646 termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */ 709 termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */
647 710
648 conf_reg |= lcr << MEN_Z135_LCR_SHIFT; 711 conf_reg |= lcr << MEN_Z135_LCR_SHIFT;