aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/msm_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/msm_serial.c')
-rw-r--r--drivers/tty/serial/msm_serial.c111
1 files changed, 58 insertions, 53 deletions
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 4b6c78331a64..d1bc6b6cbc70 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -54,6 +54,7 @@ struct msm_port {
54 unsigned int imr; 54 unsigned int imr;
55 int is_uartdm; 55 int is_uartdm;
56 unsigned int old_snap_state; 56 unsigned int old_snap_state;
57 bool break_detected;
57}; 58};
58 59
59static inline void wait_for_xmitr(struct uart_port *port) 60static inline void wait_for_xmitr(struct uart_port *port)
@@ -126,23 +127,38 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr)
126 127
127 while (count > 0) { 128 while (count > 0) {
128 unsigned char buf[4]; 129 unsigned char buf[4];
130 int sysrq, r_count, i;
129 131
130 sr = msm_read(port, UART_SR); 132 sr = msm_read(port, UART_SR);
131 if ((sr & UART_SR_RX_READY) == 0) { 133 if ((sr & UART_SR_RX_READY) == 0) {
132 msm_port->old_snap_state -= count; 134 msm_port->old_snap_state -= count;
133 break; 135 break;
134 } 136 }
137
135 ioread32_rep(port->membase + UARTDM_RF, buf, 1); 138 ioread32_rep(port->membase + UARTDM_RF, buf, 1);
136 if (sr & UART_SR_RX_BREAK) { 139 r_count = min_t(int, count, sizeof(buf));
137 port->icount.brk++;
138 if (uart_handle_break(port))
139 continue;
140 } else if (sr & UART_SR_PAR_FRAME_ERR)
141 port->icount.frame++;
142 140
143 /* TODO: handle sysrq */ 141 for (i = 0; i < r_count; i++) {
144 tty_insert_flip_string(tport, buf, min(count, 4)); 142 char flag = TTY_NORMAL;
145 count -= 4; 143
144 if (msm_port->break_detected && buf[i] == 0) {
145 port->icount.brk++;
146 flag = TTY_BREAK;
147 msm_port->break_detected = false;
148 if (uart_handle_break(port))
149 continue;
150 }
151
152 if (!(port->read_status_mask & UART_SR_RX_BREAK))
153 flag = TTY_NORMAL;
154
155 spin_unlock(&port->lock);
156 sysrq = uart_handle_sysrq_char(port, buf[i]);
157 spin_lock(&port->lock);
158 if (!sysrq)
159 tty_insert_flip_char(tport, buf[i], flag);
160 }
161 count -= r_count;
146 } 162 }
147 163
148 spin_unlock(&port->lock); 164 spin_unlock(&port->lock);
@@ -174,6 +190,7 @@ static void handle_rx(struct uart_port *port)
174 while ((sr = msm_read(port, UART_SR)) & UART_SR_RX_READY) { 190 while ((sr = msm_read(port, UART_SR)) & UART_SR_RX_READY) {
175 unsigned int c; 191 unsigned int c;
176 char flag = TTY_NORMAL; 192 char flag = TTY_NORMAL;
193 int sysrq;
177 194
178 c = msm_read(port, UART_RF); 195 c = msm_read(port, UART_RF);
179 196
@@ -195,7 +212,10 @@ static void handle_rx(struct uart_port *port)
195 else if (sr & UART_SR_PAR_FRAME_ERR) 212 else if (sr & UART_SR_PAR_FRAME_ERR)
196 flag = TTY_FRAME; 213 flag = TTY_FRAME;
197 214
198 if (!uart_handle_sysrq_char(port, c)) 215 spin_unlock(&port->lock);
216 sysrq = uart_handle_sysrq_char(port, c);
217 spin_lock(&port->lock);
218 if (!sysrq)
199 tty_insert_flip_char(tport, c, flag); 219 tty_insert_flip_char(tport, c, flag);
200 } 220 }
201 221
@@ -287,6 +307,11 @@ static irqreturn_t msm_irq(int irq, void *dev_id)
287 misr = msm_read(port, UART_MISR); 307 misr = msm_read(port, UART_MISR);
288 msm_write(port, 0, UART_IMR); /* disable interrupt */ 308 msm_write(port, 0, UART_IMR); /* disable interrupt */
289 309
310 if (misr & UART_IMR_RXBREAK_START) {
311 msm_port->break_detected = true;
312 msm_write(port, UART_CR_CMD_RESET_RXBREAK_START, UART_CR);
313 }
314
290 if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) { 315 if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) {
291 if (msm_port->is_uartdm) 316 if (msm_port->is_uartdm)
292 handle_rx_dm(port, misr); 317 handle_rx_dm(port, misr);
@@ -402,9 +427,6 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
402 427
403 entry = msm_find_best_baud(port, baud); 428 entry = msm_find_best_baud(port, baud);
404 429
405 if (msm_port->is_uartdm)
406 msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
407
408 msm_write(port, entry->code, UART_CSR); 430 msm_write(port, entry->code, UART_CSR);
409 431
410 /* RX stale watermark */ 432 /* RX stale watermark */
@@ -421,6 +443,18 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
421 /* set TX watermark */ 443 /* set TX watermark */
422 msm_write(port, 10, UART_TFWR); 444 msm_write(port, 10, UART_TFWR);
423 445
446 msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
447 msm_reset(port);
448
449 /* Enable RX and TX */
450 msm_write(port, UART_CR_TX_ENABLE | UART_CR_RX_ENABLE, UART_CR);
451
452 /* turn on RX and CTS interrupts */
453 msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE |
454 UART_IMR_CURRENT_CTS | UART_IMR_RXBREAK_START;
455
456 msm_write(port, msm_port->imr, UART_IMR);
457
424 if (msm_port->is_uartdm) { 458 if (msm_port->is_uartdm) {
425 msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); 459 msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
426 msm_write(port, 0xFFFFFF, UARTDM_DMRX); 460 msm_write(port, 0xFFFFFF, UARTDM_DMRX);
@@ -467,40 +501,6 @@ static int msm_startup(struct uart_port *port)
467 data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2); 501 data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
468 data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level; 502 data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
469 msm_write(port, data, UART_MR1); 503 msm_write(port, data, UART_MR1);
470
471 /* make sure that RXSTALE count is non-zero */
472 data = msm_read(port, UART_IPR);
473 if (unlikely(!data)) {
474 data |= UART_IPR_RXSTALE_LAST;
475 data |= UART_IPR_STALE_LSB;
476 msm_write(port, data, UART_IPR);
477 }
478
479 data = 0;
480 if (!port->cons || (port->cons && !(port->cons->flags & CON_ENABLED))) {
481 msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
482 msm_reset(port);
483 data = UART_CR_TX_ENABLE;
484 }
485
486 data |= UART_CR_RX_ENABLE;
487 msm_write(port, data, UART_CR); /* enable TX & RX */
488
489 /* Make sure IPR is not 0 to start with*/
490 if (msm_port->is_uartdm)
491 msm_write(port, UART_IPR_STALE_LSB, UART_IPR);
492
493 /* turn on RX and CTS interrupts */
494 msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE |
495 UART_IMR_CURRENT_CTS;
496
497 if (msm_port->is_uartdm) {
498 msm_write(port, 0xFFFFFF, UARTDM_DMRX);
499 msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
500 msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
501 }
502
503 msm_write(port, msm_port->imr, UART_IMR);
504 return 0; 504 return 0;
505} 505}
506 506
@@ -1044,17 +1044,22 @@ static int msm_serial_probe(struct platform_device *pdev)
1044 struct resource *resource; 1044 struct resource *resource;
1045 struct uart_port *port; 1045 struct uart_port *port;
1046 const struct of_device_id *id; 1046 const struct of_device_id *id;
1047 int irq; 1047 int irq, line;
1048
1049 if (pdev->dev.of_node)
1050 line = of_alias_get_id(pdev->dev.of_node, "serial");
1051 else
1052 line = pdev->id;
1048 1053
1049 if (pdev->id == -1) 1054 if (line < 0)
1050 pdev->id = atomic_inc_return(&msm_uart_next_id) - 1; 1055 line = atomic_inc_return(&msm_uart_next_id) - 1;
1051 1056
1052 if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) 1057 if (unlikely(line < 0 || line >= UART_NR))
1053 return -ENXIO; 1058 return -ENXIO;
1054 1059
1055 dev_info(&pdev->dev, "msm_serial: detected port #%d\n", pdev->id); 1060 dev_info(&pdev->dev, "msm_serial: detected port #%d\n", line);
1056 1061
1057 port = get_port_from_line(pdev->id); 1062 port = get_port_from_line(line);
1058 port->dev = &pdev->dev; 1063 port->dev = &pdev->dev;
1059 msm_port = UART_TO_MSM(port); 1064 msm_port = UART_TO_MSM(port);
1060 1065